aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2800usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c178
1 files changed, 45 insertions, 133 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 4f85f7b4244..5a2dfe87c6b 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -28,7 +28,6 @@
28 Supported chipsets: RT2800U. 28 Supported chipsets: RT2800U.
29 */ 29 */
30 30
31#include <linux/crc-ccitt.h>
32#include <linux/delay.h> 31#include <linux/delay.h>
33#include <linux/etherdevice.h> 32#include <linux/etherdevice.h>
34#include <linux/init.h> 33#include <linux/init.h>
@@ -57,84 +56,10 @@ static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
57 return FIRMWARE_RT2870; 56 return FIRMWARE_RT2870;
58} 57}
59 58
60static bool rt2800usb_check_crc(const u8 *data, const size_t len) 59static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
61{
62 u16 fw_crc;
63 u16 crc;
64
65 /*
66 * The last 2 bytes in the firmware array are the crc checksum itself,
67 * this means that we should never pass those 2 bytes to the crc
68 * algorithm.
69 */
70 fw_crc = (data[len - 2] << 8 | data[len - 1]);
71
72 /*
73 * Use the crc ccitt algorithm.
74 * This will return the same value as the legacy driver which
75 * used bit ordering reversion on the both the firmware bytes
76 * before input input as well as on the final output.
77 * Obviously using crc ccitt directly is much more efficient.
78 */
79 crc = crc_ccitt(~0, data, len - 2);
80
81 /*
82 * There is a small difference between the crc-itu-t + bitrev and
83 * the crc-ccitt crc calculation. In the latter method the 2 bytes
84 * will be swapped, use swab16 to convert the crc to the correct
85 * value.
86 */
87 crc = swab16(crc);
88
89 return fw_crc == crc;
90}
91
92static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
93 const u8 *data, const size_t len) 60 const u8 *data, const size_t len)
94{ 61{
95 size_t offset = 0;
96
97 /*
98 * Firmware files:
99 * There are 2 variations of the rt2870 firmware.
100 * a) size: 4kb
101 * b) size: 8kb
102 * Note that (b) contains 2 separate firmware blobs of 4k
103 * within the file. The first blob is the same firmware as (a),
104 * but the second blob is for the additional chipsets.
105 */
106 if (len != 4096 && len != 8192)
107 return FW_BAD_LENGTH;
108
109 /*
110 * Check if we need the upper 4kb firmware data or not.
111 */
112 if ((len == 4096) &&
113 !rt2x00_rt(rt2x00dev, RT2860) &&
114 !rt2x00_rt(rt2x00dev, RT2872) &&
115 !rt2x00_rt(rt2x00dev, RT3070))
116 return FW_BAD_VERSION;
117
118 /*
119 * 8kb firmware files must be checked as if it were
120 * 2 separate firmware files.
121 */
122 while (offset < len) {
123 if (!rt2800usb_check_crc(data + offset, 4096))
124 return FW_BAD_CRC;
125
126 offset += 4096;
127 }
128
129 return FW_OK;
130}
131
132static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
133 const u8 *data, const size_t len)
134{
135 unsigned int i;
136 int status; 62 int status;
137 u32 reg;
138 u32 offset; 63 u32 offset;
139 u32 length; 64 u32 length;
140 65
@@ -152,21 +77,6 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
152 } 77 }
153 78
154 /* 79 /*
155 * Wait for stable hardware.
156 */
157 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
158 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
159 if (reg && reg != ~0)
160 break;
161 msleep(1);
162 }
163
164 if (i == REGISTER_BUSY_COUNT) {
165 ERROR(rt2x00dev, "Unstable hardware.\n");
166 return -EBUSY;
167 }
168
169 /*
170 * Write firmware to device. 80 * Write firmware to device.
171 */ 81 */
172 rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, 82 rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
@@ -203,28 +113,6 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
203 udelay(10); 113 udelay(10);
204 } 114 }
205 115
206 /*
207 * Wait for device to stabilize.
208 */
209 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
210 rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
211 if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
212 break;
213 msleep(1);
214 }
215
216 if (i == REGISTER_BUSY_COUNT) {
217 ERROR(rt2x00dev, "PBF system register not ready.\n");
218 return -EBUSY;
219 }
220
221 /*
222 * Initialize firmware.
223 */
224 rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
225 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
226 msleep(1);
227
228 return 0; 116 return 0;
229} 117}
230 118
@@ -406,7 +294,9 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
406 rt2800usb_toggle_rx(rt2x00dev, state); 294 rt2800usb_toggle_rx(rt2x00dev, state);
407 break; 295 break;
408 case STATE_RADIO_IRQ_ON: 296 case STATE_RADIO_IRQ_ON:
297 case STATE_RADIO_IRQ_ON_ISR:
409 case STATE_RADIO_IRQ_OFF: 298 case STATE_RADIO_IRQ_OFF:
299 case STATE_RADIO_IRQ_OFF_ISR:
410 /* No support, but no error either */ 300 /* No support, but no error either */
411 break; 301 break;
412 case STATE_DEEP_SLEEP: 302 case STATE_DEEP_SLEEP:
@@ -563,7 +453,7 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
563 /* 453 /*
564 * Process the RXWI structure. 454 * Process the RXWI structure.
565 */ 455 */
566 rt2800_process_rxwi(entry->skb, rxdesc); 456 rt2800_process_rxwi(entry, rxdesc);
567} 457}
568 458
569/* 459/*
@@ -580,26 +470,10 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
580 return rt2800_validate_eeprom(rt2x00dev); 470 return rt2800_validate_eeprom(rt2x00dev);
581} 471}
582 472
583static const struct rt2800_ops rt2800usb_rt2800_ops = {
584 .register_read = rt2x00usb_register_read,
585 .register_read_lock = rt2x00usb_register_read_lock,
586 .register_write = rt2x00usb_register_write,
587 .register_write_lock = rt2x00usb_register_write_lock,
588
589 .register_multiread = rt2x00usb_register_multiread,
590 .register_multiwrite = rt2x00usb_register_multiwrite,
591
592 .regbusy_read = rt2x00usb_regbusy_read,
593
594 .drv_init_registers = rt2800usb_init_registers,
595};
596
597static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) 473static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
598{ 474{
599 int retval; 475 int retval;
600 476
601 rt2x00dev->priv = (void *)&rt2800usb_rt2800_ops;
602
603 /* 477 /*
604 * Allocate eeprom data. 478 * Allocate eeprom data.
605 */ 479 */
@@ -632,6 +506,8 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
632 __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); 506 __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
633 if (!modparam_nohwcrypt) 507 if (!modparam_nohwcrypt)
634 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 508 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
509 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
510 __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
635 511
636 /* 512 /*
637 * Set the rssi offset. 513 * Set the rssi offset.
@@ -641,11 +517,45 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
641 return 0; 517 return 0;
642} 518}
643 519
520static const struct ieee80211_ops rt2800usb_mac80211_ops = {
521 .tx = rt2x00mac_tx,
522 .start = rt2x00mac_start,
523 .stop = rt2x00mac_stop,
524 .add_interface = rt2x00mac_add_interface,
525 .remove_interface = rt2x00mac_remove_interface,
526 .config = rt2x00mac_config,
527 .configure_filter = rt2x00mac_configure_filter,
528 .set_tim = rt2x00mac_set_tim,
529 .set_key = rt2x00mac_set_key,
530 .sw_scan_start = rt2x00mac_sw_scan_start,
531 .sw_scan_complete = rt2x00mac_sw_scan_complete,
532 .get_stats = rt2x00mac_get_stats,
533 .get_tkip_seq = rt2800_get_tkip_seq,
534 .set_rts_threshold = rt2800_set_rts_threshold,
535 .bss_info_changed = rt2x00mac_bss_info_changed,
536 .conf_tx = rt2800_conf_tx,
537 .get_tsf = rt2800_get_tsf,
538 .rfkill_poll = rt2x00mac_rfkill_poll,
539 .ampdu_action = rt2800_ampdu_action,
540};
541
542static const struct rt2800_ops rt2800usb_rt2800_ops = {
543 .register_read = rt2x00usb_register_read,
544 .register_read_lock = rt2x00usb_register_read_lock,
545 .register_write = rt2x00usb_register_write,
546 .register_write_lock = rt2x00usb_register_write_lock,
547 .register_multiread = rt2x00usb_register_multiread,
548 .register_multiwrite = rt2x00usb_register_multiwrite,
549 .regbusy_read = rt2x00usb_regbusy_read,
550 .drv_write_firmware = rt2800usb_write_firmware,
551 .drv_init_registers = rt2800usb_init_registers,
552};
553
644static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { 554static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
645 .probe_hw = rt2800usb_probe_hw, 555 .probe_hw = rt2800usb_probe_hw,
646 .get_firmware_name = rt2800usb_get_firmware_name, 556 .get_firmware_name = rt2800usb_get_firmware_name,
647 .check_firmware = rt2800usb_check_firmware, 557 .check_firmware = rt2800_check_firmware,
648 .load_firmware = rt2800usb_load_firmware, 558 .load_firmware = rt2800_load_firmware,
649 .initialize = rt2x00usb_initialize, 559 .initialize = rt2x00usb_initialize,
650 .uninitialize = rt2x00usb_uninitialize, 560 .uninitialize = rt2x00usb_uninitialize,
651 .clear_entry = rt2x00usb_clear_entry, 561 .clear_entry = rt2x00usb_clear_entry,
@@ -654,6 +564,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
654 .link_stats = rt2800_link_stats, 564 .link_stats = rt2800_link_stats,
655 .reset_tuner = rt2800_reset_tuner, 565 .reset_tuner = rt2800_reset_tuner,
656 .link_tuner = rt2800_link_tuner, 566 .link_tuner = rt2800_link_tuner,
567 .watchdog = rt2x00usb_watchdog,
657 .write_tx_desc = rt2800usb_write_tx_desc, 568 .write_tx_desc = rt2800usb_write_tx_desc,
658 .write_tx_data = rt2800usb_write_tx_data, 569 .write_tx_data = rt2800usb_write_tx_data,
659 .write_beacon = rt2800_write_beacon, 570 .write_beacon = rt2800_write_beacon,
@@ -703,7 +614,8 @@ static const struct rt2x00_ops rt2800usb_ops = {
703 .tx = &rt2800usb_queue_tx, 614 .tx = &rt2800usb_queue_tx,
704 .bcn = &rt2800usb_queue_bcn, 615 .bcn = &rt2800usb_queue_bcn,
705 .lib = &rt2800usb_rt2x00_ops, 616 .lib = &rt2800usb_rt2x00_ops,
706 .hw = &rt2800_mac80211_ops, 617 .drv = &rt2800usb_rt2800_ops,
618 .hw = &rt2800usb_mac80211_ops,
707#ifdef CONFIG_RT2X00_LIB_DEBUGFS 619#ifdef CONFIG_RT2X00_LIB_DEBUGFS
708 .debugfs = &rt2800_rt2x00debug, 620 .debugfs = &rt2800_rt2x00debug,
709#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 621#endif /* CONFIG_RT2X00_LIB_DEBUGFS */