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/rt2800pci.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/rt2800pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 101 |
1 files changed, 5 insertions, 96 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 520236d0dc78..0fdd58b9dece 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -31,7 +31,6 @@ | |||
31 | Supported chipsets: RT2800E & RT2800ED. | 31 | Supported chipsets: RT2800E & RT2800ED. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <linux/crc-ccitt.h> | ||
35 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
36 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
37 | #include <linux/init.h> | 36 | #include <linux/init.h> |
@@ -192,82 +191,14 @@ static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) | |||
192 | return FIRMWARE_RT2860; | 191 | return FIRMWARE_RT2860; |
193 | } | 192 | } |
194 | 193 | ||
195 | static int rt2800pci_check_firmware(struct rt2x00_dev *rt2x00dev, | 194 | static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, |
196 | const u8 *data, const size_t len) | 195 | const u8 *data, const size_t len) |
197 | { | 196 | { |
198 | u16 fw_crc; | ||
199 | u16 crc; | ||
200 | |||
201 | /* | ||
202 | * Only support 8kb firmware files. | ||
203 | */ | ||
204 | if (len != 8192) | ||
205 | return FW_BAD_LENGTH; | ||
206 | |||
207 | /* | ||
208 | * The last 2 bytes in the firmware array are the crc checksum itself, | ||
209 | * this means that we should never pass those 2 bytes to the crc | ||
210 | * algorithm. | ||
211 | */ | ||
212 | fw_crc = (data[len - 2] << 8 | data[len - 1]); | ||
213 | |||
214 | /* | ||
215 | * Use the crc ccitt algorithm. | ||
216 | * This will return the same value as the legacy driver which | ||
217 | * used bit ordering reversion on the both the firmware bytes | ||
218 | * before input input as well as on the final output. | ||
219 | * Obviously using crc ccitt directly is much more efficient. | ||
220 | */ | ||
221 | crc = crc_ccitt(~0, data, len - 2); | ||
222 | |||
223 | /* | ||
224 | * There is a small difference between the crc-itu-t + bitrev and | ||
225 | * the crc-ccitt crc calculation. In the latter method the 2 bytes | ||
226 | * will be swapped, use swab16 to convert the crc to the correct | ||
227 | * value. | ||
228 | */ | ||
229 | crc = swab16(crc); | ||
230 | |||
231 | return (fw_crc == crc) ? FW_OK : FW_BAD_CRC; | ||
232 | } | ||
233 | |||
234 | static int rt2800pci_load_firmware(struct rt2x00_dev *rt2x00dev, | ||
235 | const u8 *data, const size_t len) | ||
236 | { | ||
237 | unsigned int i; | ||
238 | u32 reg; | 197 | u32 reg; |
239 | 198 | ||
240 | /* | ||
241 | * Wait for stable hardware. | ||
242 | */ | ||
243 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
244 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
245 | if (reg && reg != ~0) | ||
246 | break; | ||
247 | msleep(1); | ||
248 | } | ||
249 | |||
250 | if (i == REGISTER_BUSY_COUNT) { | ||
251 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
252 | return -EBUSY; | ||
253 | } | ||
254 | |||
255 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); | ||
256 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); | 199 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); |
257 | 200 | ||
258 | /* | 201 | /* |
259 | * Disable DMA, will be reenabled later when enabling | ||
260 | * the radio. | ||
261 | */ | ||
262 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
263 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | ||
264 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); | ||
265 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | ||
266 | rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); | ||
267 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
268 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
269 | |||
270 | /* | ||
271 | * enable Host program ram write selection | 202 | * enable Host program ram write selection |
272 | */ | 203 | */ |
273 | reg = 0; | 204 | reg = 0; |
@@ -278,34 +209,11 @@ static int rt2800pci_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
278 | * Write firmware to device. | 209 | * Write firmware to device. |
279 | */ | 210 | */ |
280 | rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | 211 | rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, |
281 | data, len); | 212 | data, len); |
282 | 213 | ||
283 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); | 214 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); |
284 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); | 215 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); |
285 | 216 | ||
286 | /* | ||
287 | * Wait for device to stabilize. | ||
288 | */ | ||
289 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
290 | rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); | ||
291 | if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY)) | ||
292 | break; | ||
293 | msleep(1); | ||
294 | } | ||
295 | |||
296 | if (i == REGISTER_BUSY_COUNT) { | ||
297 | ERROR(rt2x00dev, "PBF system register not ready.\n"); | ||
298 | return -EBUSY; | ||
299 | } | ||
300 | |||
301 | /* | ||
302 | * Disable interrupts | ||
303 | */ | ||
304 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
305 | |||
306 | /* | ||
307 | * Initialize BBP R/W access agent | ||
308 | */ | ||
309 | rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); | 217 | rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); |
310 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | 218 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); |
311 | 219 | ||
@@ -1029,6 +937,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { | |||
1029 | 937 | ||
1030 | .regbusy_read = rt2x00pci_regbusy_read, | 938 | .regbusy_read = rt2x00pci_regbusy_read, |
1031 | 939 | ||
940 | .drv_write_firmware = rt2800pci_write_firmware, | ||
1032 | .drv_init_registers = rt2800pci_init_registers, | 941 | .drv_init_registers = rt2800pci_init_registers, |
1033 | }; | 942 | }; |
1034 | 943 | ||
@@ -1114,8 +1023,8 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | |||
1114 | .irq_handler_thread = rt2800pci_interrupt_thread, | 1023 | .irq_handler_thread = rt2800pci_interrupt_thread, |
1115 | .probe_hw = rt2800pci_probe_hw, | 1024 | .probe_hw = rt2800pci_probe_hw, |
1116 | .get_firmware_name = rt2800pci_get_firmware_name, | 1025 | .get_firmware_name = rt2800pci_get_firmware_name, |
1117 | .check_firmware = rt2800pci_check_firmware, | 1026 | .check_firmware = rt2800_check_firmware, |
1118 | .load_firmware = rt2800pci_load_firmware, | 1027 | .load_firmware = rt2800_load_firmware, |
1119 | .initialize = rt2x00pci_initialize, | 1028 | .initialize = rt2x00pci_initialize, |
1120 | .uninitialize = rt2x00pci_uninitialize, | 1029 | .uninitialize = rt2x00pci_uninitialize, |
1121 | .get_entry_state = rt2800pci_get_entry_state, | 1030 | .get_entry_state = rt2800pci_get_entry_state, |