diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2010-07-11 06:30:37 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-12 16:05:37 -0400 |
commit | f31c9a8c1380e20e95d06925f2e42baf61af4db7 (patch) | |
tree | 266ad6eb4cfe9fcd5951d9ed5bdeae958c904486 /drivers/net/wireless/rt2x00/rt2800usb.c | |
parent | ab8966ddc2f7fa3e631efa7478ea2c76d6c9942f (diff) |
rt2x00: Move common firmware loading into rt2800lib
Large parts of the firmware initialization are shared
between rt2800pci and rt2800usb. Move this code into
rt2800lib.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 119 |
1 files changed, 4 insertions, 115 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f8eb6d776d99..7b8d51f58038 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 | ||
60 | static bool rt2800usb_check_crc(const u8 *data, const size_t len) | 59 | static 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 | |||
92 | static 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 | |||
132 | static 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, ®); | ||
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, ®); | ||
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 | ||
@@ -593,6 +481,7 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = { | |||
593 | 481 | ||
594 | .regbusy_read = rt2x00usb_regbusy_read, | 482 | .regbusy_read = rt2x00usb_regbusy_read, |
595 | 483 | ||
484 | .drv_write_firmware = rt2800usb_write_firmware, | ||
596 | .drv_init_registers = rt2800usb_init_registers, | 485 | .drv_init_registers = rt2800usb_init_registers, |
597 | }; | 486 | }; |
598 | 487 | ||
@@ -670,8 +559,8 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { | |||
670 | static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | 559 | static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { |
671 | .probe_hw = rt2800usb_probe_hw, | 560 | .probe_hw = rt2800usb_probe_hw, |
672 | .get_firmware_name = rt2800usb_get_firmware_name, | 561 | .get_firmware_name = rt2800usb_get_firmware_name, |
673 | .check_firmware = rt2800usb_check_firmware, | 562 | .check_firmware = rt2800_check_firmware, |
674 | .load_firmware = rt2800usb_load_firmware, | 563 | .load_firmware = rt2800_load_firmware, |
675 | .initialize = rt2x00usb_initialize, | 564 | .initialize = rt2x00usb_initialize, |
676 | .uninitialize = rt2x00usb_uninitialize, | 565 | .uninitialize = rt2x00usb_uninitialize, |
677 | .clear_entry = rt2x00usb_clear_entry, | 566 | .clear_entry = rt2x00usb_clear_entry, |