diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 104 |
1 files changed, 49 insertions, 55 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 0f8b84b7224c..c437960de3ed 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -169,11 +169,8 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
169 | /* | 169 | /* |
170 | * Write firmware to device. | 170 | * Write firmware to device. |
171 | */ | 171 | */ |
172 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | 172 | rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, |
173 | USB_VENDOR_REQUEST_OUT, | 173 | data + offset, length); |
174 | FIRMWARE_IMAGE_BASE, | ||
175 | data + offset, length, | ||
176 | REGISTER_TIMEOUT32(length)); | ||
177 | 174 | ||
178 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); | 175 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); |
179 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); | 176 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); |
@@ -196,7 +193,7 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
196 | /* | 193 | /* |
197 | * Send signal to firmware during boot time. | 194 | * Send signal to firmware during boot time. |
198 | */ | 195 | */ |
199 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0); | 196 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); |
200 | 197 | ||
201 | if (rt2x00_rt(rt2x00dev, RT3070) || | 198 | if (rt2x00_rt(rt2x00dev, RT3070) || |
202 | rt2x00_rt(rt2x00dev, RT3071) || | 199 | rt2x00_rt(rt2x00dev, RT3071) || |
@@ -246,6 +243,44 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
246 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 243 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
247 | } | 244 | } |
248 | 245 | ||
246 | static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) | ||
247 | { | ||
248 | u32 reg; | ||
249 | int i; | ||
250 | |||
251 | /* | ||
252 | * Wait until BBP and RF are ready. | ||
253 | */ | ||
254 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
255 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
256 | if (reg && reg != ~0) | ||
257 | break; | ||
258 | msleep(1); | ||
259 | } | ||
260 | |||
261 | if (i == REGISTER_BUSY_COUNT) { | ||
262 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
263 | return -EBUSY; | ||
264 | } | ||
265 | |||
266 | rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); | ||
267 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); | ||
268 | |||
269 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
270 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | ||
271 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | ||
272 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
273 | |||
274 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); | ||
275 | |||
276 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, | ||
277 | USB_MODE_RESET, REGISTER_TIMEOUT); | ||
278 | |||
279 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
249 | static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) | 284 | static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) |
250 | { | 285 | { |
251 | u32 reg; | 286 | u32 reg; |
@@ -400,20 +435,21 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
400 | struct txentry_desc *txdesc) | 435 | struct txentry_desc *txdesc) |
401 | { | 436 | { |
402 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 437 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
403 | __le32 *txi = (__le32 *)(skb->data - TXWI_DESC_SIZE - TXINFO_DESC_SIZE); | 438 | __le32 *txi = (__le32 *) skb->data; |
439 | __le32 *txwi = (__le32 *) (skb->data + TXINFO_DESC_SIZE); | ||
404 | u32 word; | 440 | u32 word; |
405 | 441 | ||
406 | /* | 442 | /* |
407 | * Initialize TXWI descriptor | 443 | * Initialize TXWI descriptor |
408 | */ | 444 | */ |
409 | rt2800_write_txwi(skb, txdesc); | 445 | rt2800_write_txwi(txwi, txdesc); |
410 | 446 | ||
411 | /* | 447 | /* |
412 | * Initialize TXINFO descriptor | 448 | * Initialize TXINFO descriptor |
413 | */ | 449 | */ |
414 | rt2x00_desc_read(txi, 0, &word); | 450 | rt2x00_desc_read(txi, 0, &word); |
415 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, | 451 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, |
416 | skb->len + TXWI_DESC_SIZE); | 452 | skb->len - TXINFO_DESC_SIZE); |
417 | rt2x00_set_field32(&word, TXINFO_W0_WIV, | 453 | rt2x00_set_field32(&word, TXINFO_W0_WIV, |
418 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); | 454 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); |
419 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); | 455 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); |
@@ -426,6 +462,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
426 | /* | 462 | /* |
427 | * Register descriptor details in skb frame descriptor. | 463 | * Register descriptor details in skb frame descriptor. |
428 | */ | 464 | */ |
465 | skbdesc->flags |= SKBDESC_DESC_IN_SKB; | ||
429 | skbdesc->desc = txi; | 466 | skbdesc->desc = txi; |
430 | skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; | 467 | skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; |
431 | } | 468 | } |
@@ -433,51 +470,6 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
433 | /* | 470 | /* |
434 | * TX data initialization | 471 | * TX data initialization |
435 | */ | 472 | */ |
436 | static void rt2800usb_write_beacon(struct queue_entry *entry, | ||
437 | struct txentry_desc *txdesc) | ||
438 | { | ||
439 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
440 | unsigned int beacon_base; | ||
441 | u32 reg; | ||
442 | |||
443 | /* | ||
444 | * Disable beaconing while we are reloading the beacon data, | ||
445 | * otherwise we might be sending out invalid data. | ||
446 | */ | ||
447 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
448 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | ||
449 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
450 | |||
451 | /* | ||
452 | * Add the TXWI for the beacon to the skb. | ||
453 | */ | ||
454 | rt2800_write_txwi(entry->skb, txdesc); | ||
455 | skb_push(entry->skb, TXWI_DESC_SIZE); | ||
456 | |||
457 | /* | ||
458 | * Write entire beacon with descriptor to register. | ||
459 | */ | ||
460 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
461 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | ||
462 | USB_VENDOR_REQUEST_OUT, beacon_base, | ||
463 | entry->skb->data, entry->skb->len, | ||
464 | REGISTER_TIMEOUT32(entry->skb->len)); | ||
465 | |||
466 | /* | ||
467 | * Enable beaconing again. | ||
468 | */ | ||
469 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
470 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
471 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
472 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
473 | |||
474 | /* | ||
475 | * Clean up the beacon skb. | ||
476 | */ | ||
477 | dev_kfree_skb(entry->skb); | ||
478 | entry->skb = NULL; | ||
479 | } | ||
480 | |||
481 | static int rt2800usb_get_tx_data_len(struct queue_entry *entry) | 473 | static int rt2800usb_get_tx_data_len(struct queue_entry *entry) |
482 | { | 474 | { |
483 | int length; | 475 | int length; |
@@ -595,6 +587,8 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = { | |||
595 | .register_multiwrite = rt2x00usb_register_multiwrite, | 587 | .register_multiwrite = rt2x00usb_register_multiwrite, |
596 | 588 | ||
597 | .regbusy_read = rt2x00usb_regbusy_read, | 589 | .regbusy_read = rt2x00usb_regbusy_read, |
590 | |||
591 | .drv_init_registers = rt2800usb_init_registers, | ||
598 | }; | 592 | }; |
599 | 593 | ||
600 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 594 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
@@ -659,7 +653,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
659 | .link_tuner = rt2800_link_tuner, | 653 | .link_tuner = rt2800_link_tuner, |
660 | .write_tx_desc = rt2800usb_write_tx_desc, | 654 | .write_tx_desc = rt2800usb_write_tx_desc, |
661 | .write_tx_data = rt2x00usb_write_tx_data, | 655 | .write_tx_data = rt2x00usb_write_tx_data, |
662 | .write_beacon = rt2800usb_write_beacon, | 656 | .write_beacon = rt2800_write_beacon, |
663 | .get_tx_data_len = rt2800usb_get_tx_data_len, | 657 | .get_tx_data_len = rt2800usb_get_tx_data_len, |
664 | .kick_tx_queue = rt2x00usb_kick_tx_queue, | 658 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |
665 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 659 | .kill_tx_queue = rt2x00usb_kill_tx_queue, |