diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800lib.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 1896 |
1 files changed, 1555 insertions, 341 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b66e0fd8f0fa..2a6aa85cc6c9 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1,4 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> | ||
2 | Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com> | 3 | Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 4 | Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> |
4 | Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com> | 5 | Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com> |
@@ -254,18 +255,39 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
254 | } | 255 | } |
255 | EXPORT_SYMBOL_GPL(rt2800_mcu_request); | 256 | EXPORT_SYMBOL_GPL(rt2800_mcu_request); |
256 | 257 | ||
258 | int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev) | ||
259 | { | ||
260 | unsigned int i = 0; | ||
261 | u32 reg; | ||
262 | |||
263 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
264 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
265 | if (reg && reg != ~0) | ||
266 | return 0; | ||
267 | msleep(1); | ||
268 | } | ||
269 | |||
270 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
271 | return -EBUSY; | ||
272 | } | ||
273 | EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready); | ||
274 | |||
257 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) | 275 | int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) |
258 | { | 276 | { |
259 | unsigned int i; | 277 | unsigned int i; |
260 | u32 reg; | 278 | u32 reg; |
261 | 279 | ||
280 | /* | ||
281 | * Some devices are really slow to respond here. Wait a whole second | ||
282 | * before timing out. | ||
283 | */ | ||
262 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 284 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
263 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | 285 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); |
264 | if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) && | 286 | if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) && |
265 | !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY)) | 287 | !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY)) |
266 | return 0; | 288 | return 0; |
267 | 289 | ||
268 | msleep(1); | 290 | msleep(10); |
269 | } | 291 | } |
270 | 292 | ||
271 | ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n"); | 293 | ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n"); |
@@ -367,22 +389,26 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
367 | u32 reg; | 389 | u32 reg; |
368 | 390 | ||
369 | /* | 391 | /* |
370 | * Wait for stable hardware. | 392 | * If driver doesn't wake up firmware here, |
393 | * rt2800_load_firmware will hang forever when interface is up again. | ||
371 | */ | 394 | */ |
372 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 395 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); |
373 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
374 | if (reg && reg != ~0) | ||
375 | break; | ||
376 | msleep(1); | ||
377 | } | ||
378 | 396 | ||
379 | if (i == REGISTER_BUSY_COUNT) { | 397 | /* |
380 | ERROR(rt2x00dev, "Unstable hardware.\n"); | 398 | * Wait for stable hardware. |
399 | */ | ||
400 | if (rt2800_wait_csr_ready(rt2x00dev)) | ||
381 | return -EBUSY; | 401 | return -EBUSY; |
382 | } | ||
383 | 402 | ||
384 | if (rt2x00_is_pci(rt2x00dev)) | 403 | if (rt2x00_is_pci(rt2x00dev)) { |
404 | if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
405 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); | ||
406 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); | ||
407 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); | ||
408 | rt2800_register_write(rt2x00dev, AUX_CTRL, reg); | ||
409 | } | ||
385 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); | 410 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); |
411 | } | ||
386 | 412 | ||
387 | /* | 413 | /* |
388 | * Disable DMA, will be reenabled later when enabling | 414 | * Disable DMA, will be reenabled later when enabling |
@@ -427,8 +453,10 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
427 | } | 453 | } |
428 | EXPORT_SYMBOL_GPL(rt2800_load_firmware); | 454 | EXPORT_SYMBOL_GPL(rt2800_load_firmware); |
429 | 455 | ||
430 | void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) | 456 | void rt2800_write_tx_data(struct queue_entry *entry, |
457 | struct txentry_desc *txdesc) | ||
431 | { | 458 | { |
459 | __le32 *txwi = rt2800_drv_get_txwi(entry); | ||
432 | u32 word; | 460 | u32 word; |
433 | 461 | ||
434 | /* | 462 | /* |
@@ -437,20 +465,22 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) | |||
437 | rt2x00_desc_read(txwi, 0, &word); | 465 | rt2x00_desc_read(txwi, 0, &word); |
438 | rt2x00_set_field32(&word, TXWI_W0_FRAG, | 466 | rt2x00_set_field32(&word, TXWI_W0_FRAG, |
439 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); | 467 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
440 | rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0); | 468 | rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, |
469 | test_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags)); | ||
441 | rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0); | 470 | rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0); |
442 | rt2x00_set_field32(&word, TXWI_W0_TS, | 471 | rt2x00_set_field32(&word, TXWI_W0_TS, |
443 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 472 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
444 | rt2x00_set_field32(&word, TXWI_W0_AMPDU, | 473 | rt2x00_set_field32(&word, TXWI_W0_AMPDU, |
445 | test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags)); | 474 | test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags)); |
446 | rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density); | 475 | rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, |
447 | rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->txop); | 476 | txdesc->u.ht.mpdu_density); |
448 | rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs); | 477 | rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->u.ht.txop); |
478 | rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->u.ht.mcs); | ||
449 | rt2x00_set_field32(&word, TXWI_W0_BW, | 479 | rt2x00_set_field32(&word, TXWI_W0_BW, |
450 | test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags)); | 480 | test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags)); |
451 | rt2x00_set_field32(&word, TXWI_W0_SHORT_GI, | 481 | rt2x00_set_field32(&word, TXWI_W0_SHORT_GI, |
452 | test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags)); | 482 | test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags)); |
453 | rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc); | 483 | rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->u.ht.stbc); |
454 | rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode); | 484 | rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode); |
455 | rt2x00_desc_write(txwi, 0, word); | 485 | rt2x00_desc_write(txwi, 0, word); |
456 | 486 | ||
@@ -459,13 +489,14 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) | |||
459 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); | 489 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
460 | rt2x00_set_field32(&word, TXWI_W1_NSEQ, | 490 | rt2x00_set_field32(&word, TXWI_W1_NSEQ, |
461 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); | 491 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); |
462 | rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size); | 492 | rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->u.ht.ba_size); |
463 | rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, | 493 | rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, |
464 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? | 494 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? |
465 | txdesc->key_idx : 0xff); | 495 | txdesc->key_idx : 0xff); |
466 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | 496 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, |
467 | txdesc->length); | 497 | txdesc->length); |
468 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1); | 498 | rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid); |
499 | rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1); | ||
469 | rt2x00_desc_write(txwi, 1, word); | 500 | rt2x00_desc_write(txwi, 1, word); |
470 | 501 | ||
471 | /* | 502 | /* |
@@ -478,9 +509,9 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) | |||
478 | _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); | 509 | _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); |
479 | _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); | 510 | _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); |
480 | } | 511 | } |
481 | EXPORT_SYMBOL_GPL(rt2800_write_txwi); | 512 | EXPORT_SYMBOL_GPL(rt2800_write_tx_data); |
482 | 513 | ||
483 | static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) | 514 | static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2) |
484 | { | 515 | { |
485 | int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0); | 516 | int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0); |
486 | int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1); | 517 | int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1); |
@@ -490,7 +521,7 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) | |||
490 | u8 offset1; | 521 | u8 offset1; |
491 | u8 offset2; | 522 | u8 offset2; |
492 | 523 | ||
493 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_2GHZ) { | 524 | if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { |
494 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom); | 525 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom); |
495 | offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0); | 526 | offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0); |
496 | offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1); | 527 | offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1); |
@@ -569,18 +600,184 @@ void rt2800_process_rxwi(struct queue_entry *entry, | |||
569 | } | 600 | } |
570 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); | 601 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); |
571 | 602 | ||
603 | static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) | ||
604 | { | ||
605 | __le32 *txwi; | ||
606 | u32 word; | ||
607 | int wcid, ack, pid; | ||
608 | int tx_wcid, tx_ack, tx_pid; | ||
609 | |||
610 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
611 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
612 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
613 | |||
614 | /* | ||
615 | * This frames has returned with an IO error, | ||
616 | * so the status report is not intended for this | ||
617 | * frame. | ||
618 | */ | ||
619 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { | ||
620 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
621 | return false; | ||
622 | } | ||
623 | |||
624 | /* | ||
625 | * Validate if this TX status report is intended for | ||
626 | * this entry by comparing the WCID/ACK/PID fields. | ||
627 | */ | ||
628 | txwi = rt2800_drv_get_txwi(entry); | ||
629 | |||
630 | rt2x00_desc_read(txwi, 1, &word); | ||
631 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | ||
632 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | ||
633 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
634 | |||
635 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { | ||
636 | WARNING(entry->queue->rt2x00dev, | ||
637 | "TX status report missed for queue %d entry %d\n", | ||
638 | entry->queue->qid, entry->entry_idx); | ||
639 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); | ||
640 | return false; | ||
641 | } | ||
642 | |||
643 | return true; | ||
644 | } | ||
645 | |||
646 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status) | ||
647 | { | ||
648 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
649 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
650 | struct txdone_entry_desc txdesc; | ||
651 | u32 word; | ||
652 | u16 mcs, real_mcs; | ||
653 | int aggr, ampdu; | ||
654 | __le32 *txwi; | ||
655 | |||
656 | /* | ||
657 | * Obtain the status about this packet. | ||
658 | */ | ||
659 | txdesc.flags = 0; | ||
660 | txwi = rt2800_drv_get_txwi(entry); | ||
661 | rt2x00_desc_read(txwi, 0, &word); | ||
662 | |||
663 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); | ||
664 | ampdu = rt2x00_get_field32(word, TXWI_W0_AMPDU); | ||
665 | |||
666 | real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS); | ||
667 | aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE); | ||
668 | |||
669 | /* | ||
670 | * If a frame was meant to be sent as a single non-aggregated MPDU | ||
671 | * but ended up in an aggregate the used tx rate doesn't correlate | ||
672 | * with the one specified in the TXWI as the whole aggregate is sent | ||
673 | * with the same rate. | ||
674 | * | ||
675 | * For example: two frames are sent to rt2x00, the first one sets | ||
676 | * AMPDU=1 and requests MCS7 whereas the second frame sets AMDPU=0 | ||
677 | * and requests MCS15. If the hw aggregates both frames into one | ||
678 | * AMDPU the tx status for both frames will contain MCS7 although | ||
679 | * the frame was sent successfully. | ||
680 | * | ||
681 | * Hence, replace the requested rate with the real tx rate to not | ||
682 | * confuse the rate control algortihm by providing clearly wrong | ||
683 | * data. | ||
684 | */ | ||
685 | if (unlikely(aggr == 1 && ampdu == 0 && real_mcs != mcs)) { | ||
686 | skbdesc->tx_rate_idx = real_mcs; | ||
687 | mcs = real_mcs; | ||
688 | } | ||
689 | |||
690 | if (aggr == 1 || ampdu == 1) | ||
691 | __set_bit(TXDONE_AMPDU, &txdesc.flags); | ||
692 | |||
693 | /* | ||
694 | * Ralink has a retry mechanism using a global fallback | ||
695 | * table. We setup this fallback table to try the immediate | ||
696 | * lower rate for all rates. In the TX_STA_FIFO, the MCS field | ||
697 | * always contains the MCS used for the last transmission, be | ||
698 | * it successful or not. | ||
699 | */ | ||
700 | if (rt2x00_get_field32(status, TX_STA_FIFO_TX_SUCCESS)) { | ||
701 | /* | ||
702 | * Transmission succeeded. The number of retries is | ||
703 | * mcs - real_mcs | ||
704 | */ | ||
705 | __set_bit(TXDONE_SUCCESS, &txdesc.flags); | ||
706 | txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); | ||
707 | } else { | ||
708 | /* | ||
709 | * Transmission failed. The number of retries is | ||
710 | * always 7 in this case (for a total number of 8 | ||
711 | * frames sent). | ||
712 | */ | ||
713 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | ||
714 | txdesc.retry = rt2x00dev->long_retry; | ||
715 | } | ||
716 | |||
717 | /* | ||
718 | * the frame was retried at least once | ||
719 | * -> hw used fallback rates | ||
720 | */ | ||
721 | if (txdesc.retry) | ||
722 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | ||
723 | |||
724 | rt2x00lib_txdone(entry, &txdesc); | ||
725 | } | ||
726 | EXPORT_SYMBOL_GPL(rt2800_txdone_entry); | ||
727 | |||
728 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | ||
729 | { | ||
730 | struct data_queue *queue; | ||
731 | struct queue_entry *entry; | ||
732 | u32 reg; | ||
733 | u8 qid; | ||
734 | |||
735 | while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { | ||
736 | |||
737 | /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus | ||
738 | * qid is guaranteed to be one of the TX QIDs | ||
739 | */ | ||
740 | qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); | ||
741 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); | ||
742 | if (unlikely(!queue)) { | ||
743 | WARNING(rt2x00dev, "Got TX status for an unavailable " | ||
744 | "queue %u, dropping\n", qid); | ||
745 | continue; | ||
746 | } | ||
747 | |||
748 | /* | ||
749 | * Inside each queue, we process each entry in a chronological | ||
750 | * order. We first check that the queue is not empty. | ||
751 | */ | ||
752 | entry = NULL; | ||
753 | while (!rt2x00queue_empty(queue)) { | ||
754 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
755 | if (rt2800_txdone_entry_check(entry, reg)) | ||
756 | break; | ||
757 | } | ||
758 | |||
759 | if (!entry || rt2x00queue_empty(queue)) | ||
760 | break; | ||
761 | |||
762 | rt2800_txdone_entry(entry, reg); | ||
763 | } | ||
764 | } | ||
765 | EXPORT_SYMBOL_GPL(rt2800_txdone); | ||
766 | |||
572 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | 767 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) |
573 | { | 768 | { |
574 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 769 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
575 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 770 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
576 | unsigned int beacon_base; | 771 | unsigned int beacon_base; |
577 | u32 reg; | 772 | unsigned int padding_len; |
773 | u32 orig_reg, reg; | ||
578 | 774 | ||
579 | /* | 775 | /* |
580 | * Disable beaconing while we are reloading the beacon data, | 776 | * Disable beaconing while we are reloading the beacon data, |
581 | * otherwise we might be sending out invalid data. | 777 | * otherwise we might be sending out invalid data. |
582 | */ | 778 | */ |
583 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 779 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
780 | orig_reg = reg; | ||
584 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | 781 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); |
585 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 782 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
586 | 783 | ||
@@ -600,7 +797,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |||
600 | /* | 797 | /* |
601 | * Add the TXWI for the beacon to the skb. | 798 | * Add the TXWI for the beacon to the skb. |
602 | */ | 799 | */ |
603 | rt2800_write_txwi((__le32 *)entry->skb->data, txdesc); | 800 | rt2800_write_tx_data(entry, txdesc); |
604 | 801 | ||
605 | /* | 802 | /* |
606 | * Dump beacon to userspace through debugfs. | 803 | * Dump beacon to userspace through debugfs. |
@@ -608,17 +805,24 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |||
608 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); | 805 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); |
609 | 806 | ||
610 | /* | 807 | /* |
611 | * Write entire beacon with TXWI to register. | 808 | * Write entire beacon with TXWI and padding to register. |
612 | */ | 809 | */ |
810 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; | ||
811 | if (padding_len && skb_pad(entry->skb, padding_len)) { | ||
812 | ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); | ||
813 | /* skb freed by skb_pad() on failure */ | ||
814 | entry->skb = NULL; | ||
815 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg); | ||
816 | return; | ||
817 | } | ||
818 | |||
613 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 819 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
614 | rt2800_register_multiwrite(rt2x00dev, beacon_base, | 820 | rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, |
615 | entry->skb->data, entry->skb->len); | 821 | entry->skb->len + padding_len); |
616 | 822 | ||
617 | /* | 823 | /* |
618 | * Enable beaconing again. | 824 | * Enable beaconing again. |
619 | */ | 825 | */ |
620 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
621 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
622 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | 826 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); |
623 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 827 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
624 | 828 | ||
@@ -630,8 +834,8 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |||
630 | } | 834 | } |
631 | EXPORT_SYMBOL_GPL(rt2800_write_beacon); | 835 | EXPORT_SYMBOL_GPL(rt2800_write_beacon); |
632 | 836 | ||
633 | static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, | 837 | static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev, |
634 | unsigned int beacon_base) | 838 | unsigned int beacon_base) |
635 | { | 839 | { |
636 | int i; | 840 | int i; |
637 | 841 | ||
@@ -644,6 +848,33 @@ static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, | |||
644 | rt2800_register_write(rt2x00dev, beacon_base + i, 0); | 848 | rt2800_register_write(rt2x00dev, beacon_base + i, 0); |
645 | } | 849 | } |
646 | 850 | ||
851 | void rt2800_clear_beacon(struct queue_entry *entry) | ||
852 | { | ||
853 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
854 | u32 reg; | ||
855 | |||
856 | /* | ||
857 | * Disable beaconing while we are reloading the beacon data, | ||
858 | * otherwise we might be sending out invalid data. | ||
859 | */ | ||
860 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
861 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | ||
862 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
863 | |||
864 | /* | ||
865 | * Clear beacon. | ||
866 | */ | ||
867 | rt2800_clear_beacon_register(rt2x00dev, | ||
868 | HW_BEACON_OFFSET(entry->entry_idx)); | ||
869 | |||
870 | /* | ||
871 | * Enabled beaconing again. | ||
872 | */ | ||
873 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
874 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
875 | } | ||
876 | EXPORT_SYMBOL_GPL(rt2800_clear_beacon); | ||
877 | |||
647 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 878 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
648 | const struct rt2x00debug rt2800_rt2x00debug = { | 879 | const struct rt2x00debug rt2800_rt2x00debug = { |
649 | .owner = THIS_MODULE, | 880 | .owner = THIS_MODULE, |
@@ -704,25 +935,49 @@ static void rt2800_brightness_set(struct led_classdev *led_cdev, | |||
704 | unsigned int ledmode = | 935 | unsigned int ledmode = |
705 | rt2x00_get_field16(led->rt2x00dev->led_mcu_reg, | 936 | rt2x00_get_field16(led->rt2x00dev->led_mcu_reg, |
706 | EEPROM_FREQ_LED_MODE); | 937 | EEPROM_FREQ_LED_MODE); |
938 | u32 reg; | ||
707 | 939 | ||
708 | if (led->type == LED_TYPE_RADIO) { | 940 | /* Check for SoC (SOC devices don't support MCU requests) */ |
709 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | 941 | if (rt2x00_is_soc(led->rt2x00dev)) { |
710 | enabled ? 0x20 : 0); | 942 | rt2800_register_read(led->rt2x00dev, LED_CFG, ®); |
711 | } else if (led->type == LED_TYPE_ASSOC) { | 943 | |
712 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | 944 | /* Set LED Polarity */ |
713 | enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20); | 945 | rt2x00_set_field32(®, LED_CFG_LED_POLAR, polarity); |
714 | } else if (led->type == LED_TYPE_QUALITY) { | 946 | |
715 | /* | 947 | /* Set LED Mode */ |
716 | * The brightness is divided into 6 levels (0 - 5), | 948 | if (led->type == LED_TYPE_RADIO) { |
717 | * The specs tell us the following levels: | 949 | rt2x00_set_field32(®, LED_CFG_G_LED_MODE, |
718 | * 0, 1 ,3, 7, 15, 31 | 950 | enabled ? 3 : 0); |
719 | * to determine the level in a simple way we can simply | 951 | } else if (led->type == LED_TYPE_ASSOC) { |
720 | * work with bitshifting: | 952 | rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, |
721 | * (1 << level) - 1 | 953 | enabled ? 3 : 0); |
722 | */ | 954 | } else if (led->type == LED_TYPE_QUALITY) { |
723 | rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, | 955 | rt2x00_set_field32(®, LED_CFG_R_LED_MODE, |
724 | (1 << brightness / (LED_FULL / 6)) - 1, | 956 | enabled ? 3 : 0); |
725 | polarity); | 957 | } |
958 | |||
959 | rt2800_register_write(led->rt2x00dev, LED_CFG, reg); | ||
960 | |||
961 | } else { | ||
962 | if (led->type == LED_TYPE_RADIO) { | ||
963 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | ||
964 | enabled ? 0x20 : 0); | ||
965 | } else if (led->type == LED_TYPE_ASSOC) { | ||
966 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | ||
967 | enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20); | ||
968 | } else if (led->type == LED_TYPE_QUALITY) { | ||
969 | /* | ||
970 | * The brightness is divided into 6 levels (0 - 5), | ||
971 | * The specs tell us the following levels: | ||
972 | * 0, 1 ,3, 7, 15, 31 | ||
973 | * to determine the level in a simple way we can simply | ||
974 | * work with bitshifting: | ||
975 | * (1 << level) - 1 | ||
976 | */ | ||
977 | rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, | ||
978 | (1 << brightness / (LED_FULL / 6)) - 1, | ||
979 | polarity); | ||
980 | } | ||
726 | } | 981 | } |
727 | } | 982 | } |
728 | 983 | ||
@@ -804,7 +1059,7 @@ static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev, | |||
804 | 1059 | ||
805 | memset(&wcid_entry, 0, sizeof(wcid_entry)); | 1060 | memset(&wcid_entry, 0, sizeof(wcid_entry)); |
806 | if (crypto->cmd == SET_KEY) | 1061 | if (crypto->cmd == SET_KEY) |
807 | memcpy(&wcid_entry, crypto->address, ETH_ALEN); | 1062 | memcpy(wcid_entry.mac, crypto->address, ETH_ALEN); |
808 | rt2800_register_multiwrite(rt2x00dev, offset, | 1063 | rt2800_register_multiwrite(rt2x00dev, offset, |
809 | &wcid_entry, sizeof(wcid_entry)); | 1064 | &wcid_entry, sizeof(wcid_entry)); |
810 | } | 1065 | } |
@@ -859,23 +1114,44 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
859 | } | 1114 | } |
860 | EXPORT_SYMBOL_GPL(rt2800_config_shared_key); | 1115 | EXPORT_SYMBOL_GPL(rt2800_config_shared_key); |
861 | 1116 | ||
1117 | static inline int rt2800_find_pairwise_keyslot(struct rt2x00_dev *rt2x00dev) | ||
1118 | { | ||
1119 | int idx; | ||
1120 | u32 offset, reg; | ||
1121 | |||
1122 | /* | ||
1123 | * Search for the first free pairwise key entry and return the | ||
1124 | * corresponding index. | ||
1125 | * | ||
1126 | * Make sure the WCID starts _after_ the last possible shared key | ||
1127 | * entry (>32). | ||
1128 | * | ||
1129 | * Since parts of the pairwise key table might be shared with | ||
1130 | * the beacon frame buffers 6 & 7 we should only write into the | ||
1131 | * first 222 entries. | ||
1132 | */ | ||
1133 | for (idx = 33; idx <= 222; idx++) { | ||
1134 | offset = MAC_WCID_ATTR_ENTRY(idx); | ||
1135 | rt2800_register_read(rt2x00dev, offset, ®); | ||
1136 | if (!reg) | ||
1137 | return idx; | ||
1138 | } | ||
1139 | return -1; | ||
1140 | } | ||
1141 | |||
862 | int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | 1142 | int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, |
863 | struct rt2x00lib_crypto *crypto, | 1143 | struct rt2x00lib_crypto *crypto, |
864 | struct ieee80211_key_conf *key) | 1144 | struct ieee80211_key_conf *key) |
865 | { | 1145 | { |
866 | struct hw_key_entry key_entry; | 1146 | struct hw_key_entry key_entry; |
867 | u32 offset; | 1147 | u32 offset; |
1148 | int idx; | ||
868 | 1149 | ||
869 | if (crypto->cmd == SET_KEY) { | 1150 | if (crypto->cmd == SET_KEY) { |
870 | /* | 1151 | idx = rt2800_find_pairwise_keyslot(rt2x00dev); |
871 | * 1 pairwise key is possible per AID, this means that the AID | 1152 | if (idx < 0) |
872 | * equals our hw_key_idx. Make sure the WCID starts _after_ the | ||
873 | * last possible shared key entry. | ||
874 | */ | ||
875 | if (crypto->aid > (256 - 32)) | ||
876 | return -ENOSPC; | 1153 | return -ENOSPC; |
877 | 1154 | key->hw_key_idx = idx; | |
878 | key->hw_key_idx = 32 + crypto->aid; | ||
879 | 1155 | ||
880 | memcpy(key_entry.key, crypto->key, | 1156 | memcpy(key_entry.key, crypto->key, |
881 | sizeof(key_entry.key)); | 1157 | sizeof(key_entry.key)); |
@@ -946,48 +1222,64 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | |||
946 | struct rt2x00intf_conf *conf, const unsigned int flags) | 1222 | struct rt2x00intf_conf *conf, const unsigned int flags) |
947 | { | 1223 | { |
948 | u32 reg; | 1224 | u32 reg; |
1225 | bool update_bssid = false; | ||
949 | 1226 | ||
950 | if (flags & CONFIG_UPDATE_TYPE) { | 1227 | if (flags & CONFIG_UPDATE_TYPE) { |
951 | /* | 1228 | /* |
952 | * Clear current synchronisation setup. | ||
953 | */ | ||
954 | rt2800_clear_beacon(rt2x00dev, | ||
955 | HW_BEACON_OFFSET(intf->beacon->entry_idx)); | ||
956 | /* | ||
957 | * Enable synchronisation. | 1229 | * Enable synchronisation. |
958 | */ | 1230 | */ |
959 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 1231 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
960 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
961 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); | 1232 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); |
962 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, | ||
963 | (conf->sync == TSF_SYNC_ADHOC || | ||
964 | conf->sync == TSF_SYNC_AP_NONE)); | ||
965 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 1233 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
966 | 1234 | ||
967 | /* | 1235 | if (conf->sync == TSF_SYNC_AP_NONE) { |
968 | * Enable pre tbtt interrupt for beaconing modes | 1236 | /* |
969 | */ | 1237 | * Tune beacon queue transmit parameters for AP mode |
970 | rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); | 1238 | */ |
971 | rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, | 1239 | rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, ®); |
972 | (conf->sync == TSF_SYNC_AP_NONE)); | 1240 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_CWMIN, 0); |
973 | rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); | 1241 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_AIFSN, 1); |
974 | 1242 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_EXP_WIN, 32); | |
1243 | rt2x00_set_field32(®, TBTT_SYNC_CFG_TBTT_ADJUST, 0); | ||
1244 | rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg); | ||
1245 | } else { | ||
1246 | rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, ®); | ||
1247 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_CWMIN, 4); | ||
1248 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_AIFSN, 2); | ||
1249 | rt2x00_set_field32(®, TBTT_SYNC_CFG_BCN_EXP_WIN, 32); | ||
1250 | rt2x00_set_field32(®, TBTT_SYNC_CFG_TBTT_ADJUST, 16); | ||
1251 | rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg); | ||
1252 | } | ||
975 | } | 1253 | } |
976 | 1254 | ||
977 | if (flags & CONFIG_UPDATE_MAC) { | 1255 | if (flags & CONFIG_UPDATE_MAC) { |
978 | reg = le32_to_cpu(conf->mac[1]); | 1256 | if (flags & CONFIG_UPDATE_TYPE && |
979 | rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); | 1257 | conf->sync == TSF_SYNC_AP_NONE) { |
980 | conf->mac[1] = cpu_to_le32(reg); | 1258 | /* |
1259 | * The BSSID register has to be set to our own mac | ||
1260 | * address in AP mode. | ||
1261 | */ | ||
1262 | memcpy(conf->bssid, conf->mac, sizeof(conf->mac)); | ||
1263 | update_bssid = true; | ||
1264 | } | ||
1265 | |||
1266 | if (!is_zero_ether_addr((const u8 *)conf->mac)) { | ||
1267 | reg = le32_to_cpu(conf->mac[1]); | ||
1268 | rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); | ||
1269 | conf->mac[1] = cpu_to_le32(reg); | ||
1270 | } | ||
981 | 1271 | ||
982 | rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, | 1272 | rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, |
983 | conf->mac, sizeof(conf->mac)); | 1273 | conf->mac, sizeof(conf->mac)); |
984 | } | 1274 | } |
985 | 1275 | ||
986 | if (flags & CONFIG_UPDATE_BSSID) { | 1276 | if ((flags & CONFIG_UPDATE_BSSID) || update_bssid) { |
987 | reg = le32_to_cpu(conf->bssid[1]); | 1277 | if (!is_zero_ether_addr((const u8 *)conf->bssid)) { |
988 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); | 1278 | reg = le32_to_cpu(conf->bssid[1]); |
989 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); | 1279 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); |
990 | conf->bssid[1] = cpu_to_le32(reg); | 1280 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); |
1281 | conf->bssid[1] = cpu_to_le32(reg); | ||
1282 | } | ||
991 | 1283 | ||
992 | rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, | 1284 | rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, |
993 | conf->bssid, sizeof(conf->bssid)); | 1285 | conf->bssid, sizeof(conf->bssid)); |
@@ -995,45 +1287,178 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | |||
995 | } | 1287 | } |
996 | EXPORT_SYMBOL_GPL(rt2800_config_intf); | 1288 | EXPORT_SYMBOL_GPL(rt2800_config_intf); |
997 | 1289 | ||
998 | void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp) | 1290 | static void rt2800_config_ht_opmode(struct rt2x00_dev *rt2x00dev, |
1291 | struct rt2x00lib_erp *erp) | ||
999 | { | 1292 | { |
1293 | bool any_sta_nongf = !!(erp->ht_opmode & | ||
1294 | IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
1295 | u8 protection = erp->ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION; | ||
1296 | u8 mm20_mode, mm40_mode, gf20_mode, gf40_mode; | ||
1297 | u16 mm20_rate, mm40_rate, gf20_rate, gf40_rate; | ||
1000 | u32 reg; | 1298 | u32 reg; |
1001 | 1299 | ||
1002 | rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®); | 1300 | /* default protection rate for HT20: OFDM 24M */ |
1003 | rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, | 1301 | mm20_rate = gf20_rate = 0x4004; |
1004 | !!erp->short_preamble); | ||
1005 | rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, | ||
1006 | !!erp->short_preamble); | ||
1007 | rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); | ||
1008 | 1302 | ||
1009 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); | 1303 | /* default protection rate for HT40: duplicate OFDM 24M */ |
1010 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, | 1304 | mm40_rate = gf40_rate = 0x4084; |
1011 | erp->cts_protection ? 2 : 0); | ||
1012 | rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); | ||
1013 | 1305 | ||
1014 | rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, | 1306 | switch (protection) { |
1015 | erp->basic_rates); | 1307 | case IEEE80211_HT_OP_MODE_PROTECTION_NONE: |
1016 | rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); | 1308 | /* |
1309 | * All STAs in this BSS are HT20/40 but there might be | ||
1310 | * STAs not supporting greenfield mode. | ||
1311 | * => Disable protection for HT transmissions. | ||
1312 | */ | ||
1313 | mm20_mode = mm40_mode = gf20_mode = gf40_mode = 0; | ||
1017 | 1314 | ||
1018 | rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®); | 1315 | break; |
1019 | rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time); | 1316 | case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: |
1020 | rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); | 1317 | /* |
1318 | * All STAs in this BSS are HT20 or HT20/40 but there | ||
1319 | * might be STAs not supporting greenfield mode. | ||
1320 | * => Protect all HT40 transmissions. | ||
1321 | */ | ||
1322 | mm20_mode = gf20_mode = 0; | ||
1323 | mm40_mode = gf40_mode = 2; | ||
1021 | 1324 | ||
1022 | rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); | 1325 | break; |
1023 | rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); | 1326 | case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER: |
1024 | rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); | 1327 | /* |
1328 | * Nonmember protection: | ||
1329 | * According to 802.11n we _should_ protect all | ||
1330 | * HT transmissions (but we don't have to). | ||
1331 | * | ||
1332 | * But if cts_protection is enabled we _shall_ protect | ||
1333 | * all HT transmissions using a CCK rate. | ||
1334 | * | ||
1335 | * And if any station is non GF we _shall_ protect | ||
1336 | * GF transmissions. | ||
1337 | * | ||
1338 | * We decide to protect everything | ||
1339 | * -> fall through to mixed mode. | ||
1340 | */ | ||
1341 | case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED: | ||
1342 | /* | ||
1343 | * Legacy STAs are present | ||
1344 | * => Protect all HT transmissions. | ||
1345 | */ | ||
1346 | mm20_mode = mm40_mode = gf20_mode = gf40_mode = 2; | ||
1025 | 1347 | ||
1026 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 1348 | /* |
1027 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, | 1349 | * If erp protection is needed we have to protect HT |
1028 | erp->beacon_int * 16); | 1350 | * transmissions with CCK 11M long preamble. |
1029 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 1351 | */ |
1352 | if (erp->cts_protection) { | ||
1353 | /* don't duplicate RTS/CTS in CCK mode */ | ||
1354 | mm20_rate = mm40_rate = 0x0003; | ||
1355 | gf20_rate = gf40_rate = 0x0003; | ||
1356 | } | ||
1357 | break; | ||
1358 | }; | ||
1359 | |||
1360 | /* check for STAs not supporting greenfield mode */ | ||
1361 | if (any_sta_nongf) | ||
1362 | gf20_mode = gf40_mode = 2; | ||
1363 | |||
1364 | /* Update HT protection config */ | ||
1365 | rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); | ||
1366 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, mm20_rate); | ||
1367 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, mm20_mode); | ||
1368 | rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg); | ||
1369 | |||
1370 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); | ||
1371 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, mm40_rate); | ||
1372 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, mm40_mode); | ||
1373 | rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg); | ||
1374 | |||
1375 | rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); | ||
1376 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, gf20_rate); | ||
1377 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, gf20_mode); | ||
1378 | rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg); | ||
1379 | |||
1380 | rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); | ||
1381 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, gf40_rate); | ||
1382 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, gf40_mode); | ||
1383 | rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg); | ||
1384 | } | ||
1385 | |||
1386 | void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, | ||
1387 | u32 changed) | ||
1388 | { | ||
1389 | u32 reg; | ||
1390 | |||
1391 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | ||
1392 | rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®); | ||
1393 | rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, | ||
1394 | !!erp->short_preamble); | ||
1395 | rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, | ||
1396 | !!erp->short_preamble); | ||
1397 | rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); | ||
1398 | } | ||
1399 | |||
1400 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | ||
1401 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); | ||
1402 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, | ||
1403 | erp->cts_protection ? 2 : 0); | ||
1404 | rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); | ||
1405 | } | ||
1406 | |||
1407 | if (changed & BSS_CHANGED_BASIC_RATES) { | ||
1408 | rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, | ||
1409 | erp->basic_rates); | ||
1410 | rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); | ||
1411 | } | ||
1412 | |||
1413 | if (changed & BSS_CHANGED_ERP_SLOT) { | ||
1414 | rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®); | ||
1415 | rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, | ||
1416 | erp->slot_time); | ||
1417 | rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); | ||
1418 | |||
1419 | rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); | ||
1420 | rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); | ||
1421 | rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); | ||
1422 | } | ||
1423 | |||
1424 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
1425 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
1426 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, | ||
1427 | erp->beacon_int * 16); | ||
1428 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
1429 | } | ||
1430 | |||
1431 | if (changed & BSS_CHANGED_HT) | ||
1432 | rt2800_config_ht_opmode(rt2x00dev, erp); | ||
1030 | } | 1433 | } |
1031 | EXPORT_SYMBOL_GPL(rt2800_config_erp); | 1434 | EXPORT_SYMBOL_GPL(rt2800_config_erp); |
1032 | 1435 | ||
1436 | static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev, | ||
1437 | enum antenna ant) | ||
1438 | { | ||
1439 | u32 reg; | ||
1440 | u8 eesk_pin = (ant == ANTENNA_A) ? 1 : 0; | ||
1441 | u8 gpio_bit3 = (ant == ANTENNA_A) ? 0 : 1; | ||
1442 | |||
1443 | if (rt2x00_is_pci(rt2x00dev)) { | ||
1444 | rt2800_register_read(rt2x00dev, E2PROM_CSR, ®); | ||
1445 | rt2x00_set_field32(®, E2PROM_CSR_DATA_CLOCK, eesk_pin); | ||
1446 | rt2800_register_write(rt2x00dev, E2PROM_CSR, reg); | ||
1447 | } else if (rt2x00_is_usb(rt2x00dev)) | ||
1448 | rt2800_mcu_request(rt2x00dev, MCU_ANT_SELECT, 0xff, | ||
1449 | eesk_pin, 0); | ||
1450 | |||
1451 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
1452 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); | ||
1453 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, gpio_bit3); | ||
1454 | rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
1455 | } | ||
1456 | |||
1033 | void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | 1457 | void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) |
1034 | { | 1458 | { |
1035 | u8 r1; | 1459 | u8 r1; |
1036 | u8 r3; | 1460 | u8 r3; |
1461 | u16 eeprom; | ||
1037 | 1462 | ||
1038 | rt2800_bbp_read(rt2x00dev, 1, &r1); | 1463 | rt2800_bbp_read(rt2x00dev, 1, &r1); |
1039 | rt2800_bbp_read(rt2x00dev, 3, &r3); | 1464 | rt2800_bbp_read(rt2x00dev, 3, &r3); |
@@ -1041,7 +1466,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | |||
1041 | /* | 1466 | /* |
1042 | * Configure the TX antenna. | 1467 | * Configure the TX antenna. |
1043 | */ | 1468 | */ |
1044 | switch ((int)ant->tx) { | 1469 | switch (ant->tx_chain_num) { |
1045 | case 1: | 1470 | case 1: |
1046 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); | 1471 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); |
1047 | break; | 1472 | break; |
@@ -1056,8 +1481,18 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | |||
1056 | /* | 1481 | /* |
1057 | * Configure the RX antenna. | 1482 | * Configure the RX antenna. |
1058 | */ | 1483 | */ |
1059 | switch ((int)ant->rx) { | 1484 | switch (ant->rx_chain_num) { |
1060 | case 1: | 1485 | case 1: |
1486 | if (rt2x00_rt(rt2x00dev, RT3070) || | ||
1487 | rt2x00_rt(rt2x00dev, RT3090) || | ||
1488 | rt2x00_rt(rt2x00dev, RT3390)) { | ||
1489 | rt2x00_eeprom_read(rt2x00dev, | ||
1490 | EEPROM_NIC_CONF1, &eeprom); | ||
1491 | if (rt2x00_get_field16(eeprom, | ||
1492 | EEPROM_NIC_CONF1_ANT_DIVERSITY)) | ||
1493 | rt2800_set_ant_diversity(rt2x00dev, | ||
1494 | rt2x00dev->default_ant.rx); | ||
1495 | } | ||
1061 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); | 1496 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); |
1062 | break; | 1497 | break; |
1063 | case 2: | 1498 | case 2: |
@@ -1103,44 +1538,40 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, | |||
1103 | { | 1538 | { |
1104 | rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); | 1539 | rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); |
1105 | 1540 | ||
1106 | if (rt2x00dev->default_ant.tx == 1) | 1541 | if (rt2x00dev->default_ant.tx_chain_num == 1) |
1107 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1); | 1542 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1); |
1108 | 1543 | ||
1109 | if (rt2x00dev->default_ant.rx == 1) { | 1544 | if (rt2x00dev->default_ant.rx_chain_num == 1) { |
1110 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1); | 1545 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1); |
1111 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); | 1546 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); |
1112 | } else if (rt2x00dev->default_ant.rx == 2) | 1547 | } else if (rt2x00dev->default_ant.rx_chain_num == 2) |
1113 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); | 1548 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); |
1114 | 1549 | ||
1115 | if (rf->channel > 14) { | 1550 | if (rf->channel > 14) { |
1116 | /* | 1551 | /* |
1117 | * When TX power is below 0, we should increase it by 7 to | 1552 | * When TX power is below 0, we should increase it by 7 to |
1118 | * make it a positive value (Minumum value is -7). | 1553 | * make it a positive value (Minimum value is -7). |
1119 | * However this means that values between 0 and 7 have | 1554 | * However this means that values between 0 and 7 have |
1120 | * double meaning, and we should set a 7DBm boost flag. | 1555 | * double meaning, and we should set a 7DBm boost flag. |
1121 | */ | 1556 | */ |
1122 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, | 1557 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, |
1123 | (info->tx_power1 >= 0)); | 1558 | (info->default_power1 >= 0)); |
1124 | 1559 | ||
1125 | if (info->tx_power1 < 0) | 1560 | if (info->default_power1 < 0) |
1126 | info->tx_power1 += 7; | 1561 | info->default_power1 += 7; |
1127 | 1562 | ||
1128 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, | 1563 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->default_power1); |
1129 | TXPOWER_A_TO_DEV(info->tx_power1)); | ||
1130 | 1564 | ||
1131 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, | 1565 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, |
1132 | (info->tx_power2 >= 0)); | 1566 | (info->default_power2 >= 0)); |
1133 | 1567 | ||
1134 | if (info->tx_power2 < 0) | 1568 | if (info->default_power2 < 0) |
1135 | info->tx_power2 += 7; | 1569 | info->default_power2 += 7; |
1136 | 1570 | ||
1137 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, | 1571 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->default_power2); |
1138 | TXPOWER_A_TO_DEV(info->tx_power2)); | ||
1139 | } else { | 1572 | } else { |
1140 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, | 1573 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->default_power1); |
1141 | TXPOWER_G_TO_DEV(info->tx_power1)); | 1574 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->default_power2); |
1142 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, | ||
1143 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
1144 | } | 1575 | } |
1145 | 1576 | ||
1146 | rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); | 1577 | rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); |
@@ -1180,13 +1611,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, | |||
1180 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | 1611 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); |
1181 | 1612 | ||
1182 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); | 1613 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); |
1183 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, | 1614 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->default_power1); |
1184 | TXPOWER_G_TO_DEV(info->tx_power1)); | ||
1185 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); | 1615 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); |
1186 | 1616 | ||
1187 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); | 1617 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); |
1188 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, | 1618 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2); |
1189 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
1190 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); | 1619 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); |
1191 | 1620 | ||
1192 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); | 1621 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); |
@@ -1201,6 +1630,103 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, | |||
1201 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); | 1630 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); |
1202 | } | 1631 | } |
1203 | 1632 | ||
1633 | |||
1634 | #define RT5390_POWER_BOUND 0x27 | ||
1635 | #define RT5390_FREQ_OFFSET_BOUND 0x5f | ||
1636 | |||
1637 | static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, | ||
1638 | struct ieee80211_conf *conf, | ||
1639 | struct rf_channel *rf, | ||
1640 | struct channel_info *info) | ||
1641 | { | ||
1642 | u8 rfcsr; | ||
1643 | |||
1644 | rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); | ||
1645 | rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); | ||
1646 | rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); | ||
1647 | rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); | ||
1648 | rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); | ||
1649 | |||
1650 | rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); | ||
1651 | if (info->default_power1 > RT5390_POWER_BOUND) | ||
1652 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT5390_POWER_BOUND); | ||
1653 | else | ||
1654 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); | ||
1655 | rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); | ||
1656 | |||
1657 | rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); | ||
1658 | rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); | ||
1659 | rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); | ||
1660 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); | ||
1661 | rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); | ||
1662 | rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); | ||
1663 | |||
1664 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | ||
1665 | if (rt2x00dev->freq_offset > RT5390_FREQ_OFFSET_BOUND) | ||
1666 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, | ||
1667 | RT5390_FREQ_OFFSET_BOUND); | ||
1668 | else | ||
1669 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); | ||
1670 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | ||
1671 | |||
1672 | if (rf->channel <= 14) { | ||
1673 | int idx = rf->channel-1; | ||
1674 | |||
1675 | if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { | ||
1676 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { | ||
1677 | /* r55/r59 value array of channel 1~14 */ | ||
1678 | static const char r55_bt_rev[] = {0x83, 0x83, | ||
1679 | 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, | ||
1680 | 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; | ||
1681 | static const char r59_bt_rev[] = {0x0e, 0x0e, | ||
1682 | 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, | ||
1683 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; | ||
1684 | |||
1685 | rt2800_rfcsr_write(rt2x00dev, 55, | ||
1686 | r55_bt_rev[idx]); | ||
1687 | rt2800_rfcsr_write(rt2x00dev, 59, | ||
1688 | r59_bt_rev[idx]); | ||
1689 | } else { | ||
1690 | static const char r59_bt[] = {0x8b, 0x8b, 0x8b, | ||
1691 | 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, | ||
1692 | 0x88, 0x88, 0x86, 0x85, 0x84}; | ||
1693 | |||
1694 | rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); | ||
1695 | } | ||
1696 | } else { | ||
1697 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { | ||
1698 | static const char r55_nonbt_rev[] = {0x23, 0x23, | ||
1699 | 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, | ||
1700 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; | ||
1701 | static const char r59_nonbt_rev[] = {0x07, 0x07, | ||
1702 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, | ||
1703 | 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; | ||
1704 | |||
1705 | rt2800_rfcsr_write(rt2x00dev, 55, | ||
1706 | r55_nonbt_rev[idx]); | ||
1707 | rt2800_rfcsr_write(rt2x00dev, 59, | ||
1708 | r59_nonbt_rev[idx]); | ||
1709 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
1710 | static const char r59_non_bt[] = {0x8f, 0x8f, | ||
1711 | 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, | ||
1712 | 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; | ||
1713 | |||
1714 | rt2800_rfcsr_write(rt2x00dev, 59, | ||
1715 | r59_non_bt[idx]); | ||
1716 | } | ||
1717 | } | ||
1718 | } | ||
1719 | |||
1720 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | ||
1721 | rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); | ||
1722 | rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); | ||
1723 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
1724 | |||
1725 | rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); | ||
1726 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | ||
1727 | rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); | ||
1728 | } | ||
1729 | |||
1204 | static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | 1730 | static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, |
1205 | struct ieee80211_conf *conf, | 1731 | struct ieee80211_conf *conf, |
1206 | struct rf_channel *rf, | 1732 | struct rf_channel *rf, |
@@ -1210,11 +1736,24 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1210 | unsigned int tx_pin; | 1736 | unsigned int tx_pin; |
1211 | u8 bbp; | 1737 | u8 bbp; |
1212 | 1738 | ||
1739 | if (rf->channel <= 14) { | ||
1740 | info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); | ||
1741 | info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2); | ||
1742 | } else { | ||
1743 | info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1); | ||
1744 | info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2); | ||
1745 | } | ||
1746 | |||
1213 | if (rt2x00_rf(rt2x00dev, RF2020) || | 1747 | if (rt2x00_rf(rt2x00dev, RF2020) || |
1214 | rt2x00_rf(rt2x00dev, RF3020) || | 1748 | rt2x00_rf(rt2x00dev, RF3020) || |
1215 | rt2x00_rf(rt2x00dev, RF3021) || | 1749 | rt2x00_rf(rt2x00dev, RF3021) || |
1216 | rt2x00_rf(rt2x00dev, RF3022)) | 1750 | rt2x00_rf(rt2x00dev, RF3022) || |
1751 | rt2x00_rf(rt2x00dev, RF3052) || | ||
1752 | rt2x00_rf(rt2x00dev, RF3320)) | ||
1217 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); | 1753 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); |
1754 | else if (rt2x00_rf(rt2x00dev, RF5370) || | ||
1755 | rt2x00_rf(rt2x00dev, RF5390)) | ||
1756 | rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); | ||
1218 | else | 1757 | else |
1219 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); | 1758 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); |
1220 | 1759 | ||
@@ -1227,17 +1766,20 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1227 | rt2800_bbp_write(rt2x00dev, 86, 0); | 1766 | rt2800_bbp_write(rt2x00dev, 86, 0); |
1228 | 1767 | ||
1229 | if (rf->channel <= 14) { | 1768 | if (rf->channel <= 14) { |
1230 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { | 1769 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
1231 | rt2800_bbp_write(rt2x00dev, 82, 0x62); | 1770 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, |
1232 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 1771 | &rt2x00dev->cap_flags)) { |
1233 | } else { | 1772 | rt2800_bbp_write(rt2x00dev, 82, 0x62); |
1234 | rt2800_bbp_write(rt2x00dev, 82, 0x84); | 1773 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
1235 | rt2800_bbp_write(rt2x00dev, 75, 0x50); | 1774 | } else { |
1775 | rt2800_bbp_write(rt2x00dev, 82, 0x84); | ||
1776 | rt2800_bbp_write(rt2x00dev, 75, 0x50); | ||
1777 | } | ||
1236 | } | 1778 | } |
1237 | } else { | 1779 | } else { |
1238 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); | 1780 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); |
1239 | 1781 | ||
1240 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | 1782 | if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) |
1241 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 1783 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
1242 | else | 1784 | else |
1243 | rt2800_bbp_write(rt2x00dev, 75, 0x50); | 1785 | rt2800_bbp_write(rt2x00dev, 75, 0x50); |
@@ -1252,13 +1794,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1252 | tx_pin = 0; | 1794 | tx_pin = 0; |
1253 | 1795 | ||
1254 | /* Turn on unused PA or LNA when not using 1T or 1R */ | 1796 | /* Turn on unused PA or LNA when not using 1T or 1R */ |
1255 | if (rt2x00dev->default_ant.tx != 1) { | 1797 | if (rt2x00dev->default_ant.tx_chain_num == 2) { |
1256 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); | 1798 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); |
1257 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); | 1799 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); |
1258 | } | 1800 | } |
1259 | 1801 | ||
1260 | /* Turn on unused PA or LNA when not using 1T or 1R */ | 1802 | /* Turn on unused PA or LNA when not using 1T or 1R */ |
1261 | if (rt2x00dev->default_ant.rx != 1) { | 1803 | if (rt2x00dev->default_ant.rx_chain_num == 2) { |
1262 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); | 1804 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); |
1263 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); | 1805 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); |
1264 | } | 1806 | } |
@@ -1293,32 +1835,243 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1293 | } | 1835 | } |
1294 | 1836 | ||
1295 | msleep(1); | 1837 | msleep(1); |
1838 | |||
1839 | /* | ||
1840 | * Clear channel statistic counters | ||
1841 | */ | ||
1842 | rt2800_register_read(rt2x00dev, CH_IDLE_STA, ®); | ||
1843 | rt2800_register_read(rt2x00dev, CH_BUSY_STA, ®); | ||
1844 | rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); | ||
1845 | } | ||
1846 | |||
1847 | static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) | ||
1848 | { | ||
1849 | u8 tssi_bounds[9]; | ||
1850 | u8 current_tssi; | ||
1851 | u16 eeprom; | ||
1852 | u8 step; | ||
1853 | int i; | ||
1854 | |||
1855 | /* | ||
1856 | * Read TSSI boundaries for temperature compensation from | ||
1857 | * the EEPROM. | ||
1858 | * | ||
1859 | * Array idx 0 1 2 3 4 5 6 7 8 | ||
1860 | * Matching Delta value -4 -3 -2 -1 0 +1 +2 +3 +4 | ||
1861 | * Example TSSI bounds 0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00 | ||
1862 | */ | ||
1863 | if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { | ||
1864 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom); | ||
1865 | tssi_bounds[0] = rt2x00_get_field16(eeprom, | ||
1866 | EEPROM_TSSI_BOUND_BG1_MINUS4); | ||
1867 | tssi_bounds[1] = rt2x00_get_field16(eeprom, | ||
1868 | EEPROM_TSSI_BOUND_BG1_MINUS3); | ||
1869 | |||
1870 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom); | ||
1871 | tssi_bounds[2] = rt2x00_get_field16(eeprom, | ||
1872 | EEPROM_TSSI_BOUND_BG2_MINUS2); | ||
1873 | tssi_bounds[3] = rt2x00_get_field16(eeprom, | ||
1874 | EEPROM_TSSI_BOUND_BG2_MINUS1); | ||
1875 | |||
1876 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom); | ||
1877 | tssi_bounds[4] = rt2x00_get_field16(eeprom, | ||
1878 | EEPROM_TSSI_BOUND_BG3_REF); | ||
1879 | tssi_bounds[5] = rt2x00_get_field16(eeprom, | ||
1880 | EEPROM_TSSI_BOUND_BG3_PLUS1); | ||
1881 | |||
1882 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom); | ||
1883 | tssi_bounds[6] = rt2x00_get_field16(eeprom, | ||
1884 | EEPROM_TSSI_BOUND_BG4_PLUS2); | ||
1885 | tssi_bounds[7] = rt2x00_get_field16(eeprom, | ||
1886 | EEPROM_TSSI_BOUND_BG4_PLUS3); | ||
1887 | |||
1888 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom); | ||
1889 | tssi_bounds[8] = rt2x00_get_field16(eeprom, | ||
1890 | EEPROM_TSSI_BOUND_BG5_PLUS4); | ||
1891 | |||
1892 | step = rt2x00_get_field16(eeprom, | ||
1893 | EEPROM_TSSI_BOUND_BG5_AGC_STEP); | ||
1894 | } else { | ||
1895 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom); | ||
1896 | tssi_bounds[0] = rt2x00_get_field16(eeprom, | ||
1897 | EEPROM_TSSI_BOUND_A1_MINUS4); | ||
1898 | tssi_bounds[1] = rt2x00_get_field16(eeprom, | ||
1899 | EEPROM_TSSI_BOUND_A1_MINUS3); | ||
1900 | |||
1901 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom); | ||
1902 | tssi_bounds[2] = rt2x00_get_field16(eeprom, | ||
1903 | EEPROM_TSSI_BOUND_A2_MINUS2); | ||
1904 | tssi_bounds[3] = rt2x00_get_field16(eeprom, | ||
1905 | EEPROM_TSSI_BOUND_A2_MINUS1); | ||
1906 | |||
1907 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom); | ||
1908 | tssi_bounds[4] = rt2x00_get_field16(eeprom, | ||
1909 | EEPROM_TSSI_BOUND_A3_REF); | ||
1910 | tssi_bounds[5] = rt2x00_get_field16(eeprom, | ||
1911 | EEPROM_TSSI_BOUND_A3_PLUS1); | ||
1912 | |||
1913 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom); | ||
1914 | tssi_bounds[6] = rt2x00_get_field16(eeprom, | ||
1915 | EEPROM_TSSI_BOUND_A4_PLUS2); | ||
1916 | tssi_bounds[7] = rt2x00_get_field16(eeprom, | ||
1917 | EEPROM_TSSI_BOUND_A4_PLUS3); | ||
1918 | |||
1919 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom); | ||
1920 | tssi_bounds[8] = rt2x00_get_field16(eeprom, | ||
1921 | EEPROM_TSSI_BOUND_A5_PLUS4); | ||
1922 | |||
1923 | step = rt2x00_get_field16(eeprom, | ||
1924 | EEPROM_TSSI_BOUND_A5_AGC_STEP); | ||
1925 | } | ||
1926 | |||
1927 | /* | ||
1928 | * Check if temperature compensation is supported. | ||
1929 | */ | ||
1930 | if (tssi_bounds[4] == 0xff) | ||
1931 | return 0; | ||
1932 | |||
1933 | /* | ||
1934 | * Read current TSSI (BBP 49). | ||
1935 | */ | ||
1936 | rt2800_bbp_read(rt2x00dev, 49, ¤t_tssi); | ||
1937 | |||
1938 | /* | ||
1939 | * Compare TSSI value (BBP49) with the compensation boundaries | ||
1940 | * from the EEPROM and increase or decrease tx power. | ||
1941 | */ | ||
1942 | for (i = 0; i <= 3; i++) { | ||
1943 | if (current_tssi > tssi_bounds[i]) | ||
1944 | break; | ||
1945 | } | ||
1946 | |||
1947 | if (i == 4) { | ||
1948 | for (i = 8; i >= 5; i--) { | ||
1949 | if (current_tssi < tssi_bounds[i]) | ||
1950 | break; | ||
1951 | } | ||
1952 | } | ||
1953 | |||
1954 | return (i - 4) * step; | ||
1955 | } | ||
1956 | |||
1957 | static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, | ||
1958 | enum ieee80211_band band) | ||
1959 | { | ||
1960 | u16 eeprom; | ||
1961 | u8 comp_en; | ||
1962 | u8 comp_type; | ||
1963 | int comp_value = 0; | ||
1964 | |||
1965 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom); | ||
1966 | |||
1967 | /* | ||
1968 | * HT40 compensation not required. | ||
1969 | */ | ||
1970 | if (eeprom == 0xffff || | ||
1971 | !test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) | ||
1972 | return 0; | ||
1973 | |||
1974 | if (band == IEEE80211_BAND_2GHZ) { | ||
1975 | comp_en = rt2x00_get_field16(eeprom, | ||
1976 | EEPROM_TXPOWER_DELTA_ENABLE_2G); | ||
1977 | if (comp_en) { | ||
1978 | comp_type = rt2x00_get_field16(eeprom, | ||
1979 | EEPROM_TXPOWER_DELTA_TYPE_2G); | ||
1980 | comp_value = rt2x00_get_field16(eeprom, | ||
1981 | EEPROM_TXPOWER_DELTA_VALUE_2G); | ||
1982 | if (!comp_type) | ||
1983 | comp_value = -comp_value; | ||
1984 | } | ||
1985 | } else { | ||
1986 | comp_en = rt2x00_get_field16(eeprom, | ||
1987 | EEPROM_TXPOWER_DELTA_ENABLE_5G); | ||
1988 | if (comp_en) { | ||
1989 | comp_type = rt2x00_get_field16(eeprom, | ||
1990 | EEPROM_TXPOWER_DELTA_TYPE_5G); | ||
1991 | comp_value = rt2x00_get_field16(eeprom, | ||
1992 | EEPROM_TXPOWER_DELTA_VALUE_5G); | ||
1993 | if (!comp_type) | ||
1994 | comp_value = -comp_value; | ||
1995 | } | ||
1996 | } | ||
1997 | |||
1998 | return comp_value; | ||
1999 | } | ||
2000 | |||
2001 | static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, | ||
2002 | enum ieee80211_band band, int power_level, | ||
2003 | u8 txpower, int delta) | ||
2004 | { | ||
2005 | u32 reg; | ||
2006 | u16 eeprom; | ||
2007 | u8 criterion; | ||
2008 | u8 eirp_txpower; | ||
2009 | u8 eirp_txpower_criterion; | ||
2010 | u8 reg_limit; | ||
2011 | |||
2012 | if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) | ||
2013 | return txpower; | ||
2014 | |||
2015 | if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) { | ||
2016 | /* | ||
2017 | * Check if eirp txpower exceed txpower_limit. | ||
2018 | * We use OFDM 6M as criterion and its eirp txpower | ||
2019 | * is stored at EEPROM_EIRP_MAX_TX_POWER. | ||
2020 | * .11b data rate need add additional 4dbm | ||
2021 | * when calculating eirp txpower. | ||
2022 | */ | ||
2023 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®); | ||
2024 | criterion = rt2x00_get_field32(reg, TX_PWR_CFG_0_6MBS); | ||
2025 | |||
2026 | rt2x00_eeprom_read(rt2x00dev, | ||
2027 | EEPROM_EIRP_MAX_TX_POWER, &eeprom); | ||
2028 | |||
2029 | if (band == IEEE80211_BAND_2GHZ) | ||
2030 | eirp_txpower_criterion = rt2x00_get_field16(eeprom, | ||
2031 | EEPROM_EIRP_MAX_TX_POWER_2GHZ); | ||
2032 | else | ||
2033 | eirp_txpower_criterion = rt2x00_get_field16(eeprom, | ||
2034 | EEPROM_EIRP_MAX_TX_POWER_5GHZ); | ||
2035 | |||
2036 | eirp_txpower = eirp_txpower_criterion + (txpower - criterion) + | ||
2037 | (is_rate_b ? 4 : 0) + delta; | ||
2038 | |||
2039 | reg_limit = (eirp_txpower > power_level) ? | ||
2040 | (eirp_txpower - power_level) : 0; | ||
2041 | } else | ||
2042 | reg_limit = 0; | ||
2043 | |||
2044 | return txpower + delta - reg_limit; | ||
1296 | } | 2045 | } |
1297 | 2046 | ||
1298 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | 2047 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, |
1299 | const int max_txpower) | 2048 | enum ieee80211_band band, |
2049 | int power_level) | ||
1300 | { | 2050 | { |
1301 | u8 txpower; | 2051 | u8 txpower; |
1302 | u8 max_value = (u8)max_txpower; | ||
1303 | u16 eeprom; | 2052 | u16 eeprom; |
1304 | int i; | 2053 | int i, is_rate_b; |
1305 | u32 reg; | 2054 | u32 reg; |
1306 | u8 r1; | 2055 | u8 r1; |
1307 | u32 offset; | 2056 | u32 offset; |
2057 | int delta; | ||
1308 | 2058 | ||
1309 | /* | 2059 | /* |
1310 | * set to normal tx power mode: +/- 0dBm | 2060 | * Calculate HT40 compensation delta |
1311 | */ | 2061 | */ |
1312 | rt2800_bbp_read(rt2x00dev, 1, &r1); | 2062 | delta = rt2800_get_txpower_bw_comp(rt2x00dev, band); |
1313 | rt2x00_set_field8(&r1, BBP1_TX_POWER, 0); | ||
1314 | rt2800_bbp_write(rt2x00dev, 1, r1); | ||
1315 | 2063 | ||
1316 | /* | 2064 | /* |
1317 | * The eeprom contains the tx power values for each rate. These | 2065 | * calculate temperature compensation delta |
1318 | * values map to 100% tx power. Each 16bit word contains four tx | ||
1319 | * power values and the order is the same as used in the TX_PWR_CFG | ||
1320 | * registers. | ||
1321 | */ | 2066 | */ |
2067 | delta += rt2800_get_gain_calibration_delta(rt2x00dev); | ||
2068 | |||
2069 | /* | ||
2070 | * set to normal bbp tx power control mode: +/- 0dBm | ||
2071 | */ | ||
2072 | rt2800_bbp_read(rt2x00dev, 1, &r1); | ||
2073 | rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0); | ||
2074 | rt2800_bbp_write(rt2x00dev, 1, r1); | ||
1322 | offset = TX_PWR_CFG_0; | 2075 | offset = TX_PWR_CFG_0; |
1323 | 2076 | ||
1324 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { | 2077 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { |
@@ -1332,73 +2085,99 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | |||
1332 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, | 2085 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, |
1333 | &eeprom); | 2086 | &eeprom); |
1334 | 2087 | ||
1335 | /* TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS, | 2088 | is_rate_b = i ? 0 : 1; |
2089 | /* | ||
2090 | * TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS, | ||
1336 | * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12, | 2091 | * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12, |
1337 | * TX_PWR_CFG_4: unknown */ | 2092 | * TX_PWR_CFG_4: unknown |
2093 | */ | ||
1338 | txpower = rt2x00_get_field16(eeprom, | 2094 | txpower = rt2x00_get_field16(eeprom, |
1339 | EEPROM_TXPOWER_BYRATE_RATE0); | 2095 | EEPROM_TXPOWER_BYRATE_RATE0); |
1340 | rt2x00_set_field32(®, TX_PWR_CFG_RATE0, | 2096 | txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, |
1341 | min(txpower, max_value)); | 2097 | power_level, txpower, delta); |
2098 | rt2x00_set_field32(®, TX_PWR_CFG_RATE0, txpower); | ||
1342 | 2099 | ||
1343 | /* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS, | 2100 | /* |
2101 | * TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS, | ||
1344 | * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13, | 2102 | * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13, |
1345 | * TX_PWR_CFG_4: unknown */ | 2103 | * TX_PWR_CFG_4: unknown |
2104 | */ | ||
1346 | txpower = rt2x00_get_field16(eeprom, | 2105 | txpower = rt2x00_get_field16(eeprom, |
1347 | EEPROM_TXPOWER_BYRATE_RATE1); | 2106 | EEPROM_TXPOWER_BYRATE_RATE1); |
1348 | rt2x00_set_field32(®, TX_PWR_CFG_RATE1, | 2107 | txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, |
1349 | min(txpower, max_value)); | 2108 | power_level, txpower, delta); |
2109 | rt2x00_set_field32(®, TX_PWR_CFG_RATE1, txpower); | ||
1350 | 2110 | ||
1351 | /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS, | 2111 | /* |
2112 | * TX_PWR_CFG_0: 5.5MBS, TX_PWR_CFG_1: 48MBS, | ||
1352 | * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14, | 2113 | * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14, |
1353 | * TX_PWR_CFG_4: unknown */ | 2114 | * TX_PWR_CFG_4: unknown |
2115 | */ | ||
1354 | txpower = rt2x00_get_field16(eeprom, | 2116 | txpower = rt2x00_get_field16(eeprom, |
1355 | EEPROM_TXPOWER_BYRATE_RATE2); | 2117 | EEPROM_TXPOWER_BYRATE_RATE2); |
1356 | rt2x00_set_field32(®, TX_PWR_CFG_RATE2, | 2118 | txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, |
1357 | min(txpower, max_value)); | 2119 | power_level, txpower, delta); |
2120 | rt2x00_set_field32(®, TX_PWR_CFG_RATE2, txpower); | ||
1358 | 2121 | ||
1359 | /* TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS, | 2122 | /* |
2123 | * TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS, | ||
1360 | * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15, | 2124 | * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15, |
1361 | * TX_PWR_CFG_4: unknown */ | 2125 | * TX_PWR_CFG_4: unknown |
2126 | */ | ||
1362 | txpower = rt2x00_get_field16(eeprom, | 2127 | txpower = rt2x00_get_field16(eeprom, |
1363 | EEPROM_TXPOWER_BYRATE_RATE3); | 2128 | EEPROM_TXPOWER_BYRATE_RATE3); |
1364 | rt2x00_set_field32(®, TX_PWR_CFG_RATE3, | 2129 | txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, |
1365 | min(txpower, max_value)); | 2130 | power_level, txpower, delta); |
2131 | rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower); | ||
1366 | 2132 | ||
1367 | /* read the next four txpower values */ | 2133 | /* read the next four txpower values */ |
1368 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1, | 2134 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1, |
1369 | &eeprom); | 2135 | &eeprom); |
1370 | 2136 | ||
1371 | /* TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0, | 2137 | is_rate_b = 0; |
2138 | /* | ||
2139 | * TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0, | ||
1372 | * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown, | 2140 | * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown, |
1373 | * TX_PWR_CFG_4: unknown */ | 2141 | * TX_PWR_CFG_4: unknown |
2142 | */ | ||
1374 | txpower = rt2x00_get_field16(eeprom, | 2143 | txpower = rt2x00_get_field16(eeprom, |
1375 | EEPROM_TXPOWER_BYRATE_RATE0); | 2144 | EEPROM_TXPOWER_BYRATE_RATE0); |
1376 | rt2x00_set_field32(®, TX_PWR_CFG_RATE4, | 2145 | txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, |
1377 | min(txpower, max_value)); | 2146 | power_level, txpower, delta); |
2147 | rt2x00_set_field32(®, TX_PWR_CFG_RATE4, txpower); | ||
1378 | 2148 | ||
1379 | /* TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1, | 2149 | /* |
2150 | * TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1, | ||
1380 | * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown, | 2151 | * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown, |
1381 | * TX_PWR_CFG_4: unknown */ | 2152 | * TX_PWR_CFG_4: unknown |
2153 | */ | ||
1382 | txpower = rt2x00_get_field16(eeprom, | 2154 | txpower = rt2x00_get_field16(eeprom, |
1383 | EEPROM_TXPOWER_BYRATE_RATE1); | 2155 | EEPROM_TXPOWER_BYRATE_RATE1); |
1384 | rt2x00_set_field32(®, TX_PWR_CFG_RATE5, | 2156 | txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, |
1385 | min(txpower, max_value)); | 2157 | power_level, txpower, delta); |
2158 | rt2x00_set_field32(®, TX_PWR_CFG_RATE5, txpower); | ||
1386 | 2159 | ||
1387 | /* TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2, | 2160 | /* |
2161 | * TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2, | ||
1388 | * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown, | 2162 | * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown, |
1389 | * TX_PWR_CFG_4: unknown */ | 2163 | * TX_PWR_CFG_4: unknown |
2164 | */ | ||
1390 | txpower = rt2x00_get_field16(eeprom, | 2165 | txpower = rt2x00_get_field16(eeprom, |
1391 | EEPROM_TXPOWER_BYRATE_RATE2); | 2166 | EEPROM_TXPOWER_BYRATE_RATE2); |
1392 | rt2x00_set_field32(®, TX_PWR_CFG_RATE6, | 2167 | txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, |
1393 | min(txpower, max_value)); | 2168 | power_level, txpower, delta); |
2169 | rt2x00_set_field32(®, TX_PWR_CFG_RATE6, txpower); | ||
1394 | 2170 | ||
1395 | /* TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3, | 2171 | /* |
2172 | * TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3, | ||
1396 | * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown, | 2173 | * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown, |
1397 | * TX_PWR_CFG_4: unknown */ | 2174 | * TX_PWR_CFG_4: unknown |
2175 | */ | ||
1398 | txpower = rt2x00_get_field16(eeprom, | 2176 | txpower = rt2x00_get_field16(eeprom, |
1399 | EEPROM_TXPOWER_BYRATE_RATE3); | 2177 | EEPROM_TXPOWER_BYRATE_RATE3); |
1400 | rt2x00_set_field32(®, TX_PWR_CFG_RATE7, | 2178 | txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, |
1401 | min(txpower, max_value)); | 2179 | power_level, txpower, delta); |
2180 | rt2x00_set_field32(®, TX_PWR_CFG_RATE7, txpower); | ||
1402 | 2181 | ||
1403 | rt2800_register_write(rt2x00dev, offset, reg); | 2182 | rt2800_register_write(rt2x00dev, offset, reg); |
1404 | 2183 | ||
@@ -1407,6 +2186,13 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | |||
1407 | } | 2186 | } |
1408 | } | 2187 | } |
1409 | 2188 | ||
2189 | void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) | ||
2190 | { | ||
2191 | rt2800_config_txpower(rt2x00dev, rt2x00dev->curr_band, | ||
2192 | rt2x00dev->tx_power); | ||
2193 | } | ||
2194 | EXPORT_SYMBOL_GPL(rt2800_gain_calibration); | ||
2195 | |||
1410 | static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev, | 2196 | static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev, |
1411 | struct rt2x00lib_conf *libconf) | 2197 | struct rt2x00lib_conf *libconf) |
1412 | { | 2198 | { |
@@ -1457,11 +2243,15 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev, | |||
1457 | /* Always recalculate LNA gain before changing configuration */ | 2243 | /* Always recalculate LNA gain before changing configuration */ |
1458 | rt2800_config_lna_gain(rt2x00dev, libconf); | 2244 | rt2800_config_lna_gain(rt2x00dev, libconf); |
1459 | 2245 | ||
1460 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) | 2246 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { |
1461 | rt2800_config_channel(rt2x00dev, libconf->conf, | 2247 | rt2800_config_channel(rt2x00dev, libconf->conf, |
1462 | &libconf->rf, &libconf->channel); | 2248 | &libconf->rf, &libconf->channel); |
2249 | rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band, | ||
2250 | libconf->conf->power_level); | ||
2251 | } | ||
1463 | if (flags & IEEE80211_CONF_CHANGE_POWER) | 2252 | if (flags & IEEE80211_CONF_CHANGE_POWER) |
1464 | rt2800_config_txpower(rt2x00dev, libconf->conf->power_level); | 2253 | rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band, |
2254 | libconf->conf->power_level); | ||
1465 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) | 2255 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) |
1466 | rt2800_config_retry_limit(rt2x00dev, libconf); | 2256 | rt2800_config_retry_limit(rt2x00dev, libconf); |
1467 | if (flags & IEEE80211_CONF_CHANGE_PS) | 2257 | if (flags & IEEE80211_CONF_CHANGE_PS) |
@@ -1490,7 +2280,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) | |||
1490 | if (rt2x00_rt(rt2x00dev, RT3070) || | 2280 | if (rt2x00_rt(rt2x00dev, RT3070) || |
1491 | rt2x00_rt(rt2x00dev, RT3071) || | 2281 | rt2x00_rt(rt2x00dev, RT3071) || |
1492 | rt2x00_rt(rt2x00dev, RT3090) || | 2282 | rt2x00_rt(rt2x00dev, RT3090) || |
1493 | rt2x00_rt(rt2x00dev, RT3390)) | 2283 | rt2x00_rt(rt2x00dev, RT3390) || |
2284 | rt2x00_rt(rt2x00dev, RT5390)) | ||
1494 | return 0x1c + (2 * rt2x00dev->lna_gain); | 2285 | return 0x1c + (2 * rt2x00dev->lna_gain); |
1495 | else | 2286 | else |
1496 | return 0x2e + rt2x00dev->lna_gain; | 2287 | return 0x2e + rt2x00dev->lna_gain; |
@@ -1536,7 +2327,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); | |||
1536 | /* | 2327 | /* |
1537 | * Initialization functions. | 2328 | * Initialization functions. |
1538 | */ | 2329 | */ |
1539 | int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | 2330 | static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) |
1540 | { | 2331 | { |
1541 | u32 reg; | 2332 | u32 reg; |
1542 | u16 eeprom; | 2333 | u16 eeprom; |
@@ -1598,8 +2389,8 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1598 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 2389 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
1599 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || | 2390 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || |
1600 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { | 2391 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { |
1601 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | 2392 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); |
1602 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST)) | 2393 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) |
1603 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, | 2394 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, |
1604 | 0x0000002c); | 2395 | 0x0000002c); |
1605 | else | 2396 | else |
@@ -1621,7 +2412,11 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1621 | } else if (rt2800_is_305x_soc(rt2x00dev)) { | 2412 | } else if (rt2800_is_305x_soc(rt2x00dev)) { |
1622 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); | 2413 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); |
1623 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); | 2414 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); |
1624 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); | 2415 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030); |
2416 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
2417 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); | ||
2418 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | ||
2419 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); | ||
1625 | } else { | 2420 | } else { |
1626 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); | 2421 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); |
1627 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | 2422 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); |
@@ -1690,7 +2485,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1690 | rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®); | 2485 | rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®); |
1691 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_RATE, 3); | 2486 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_RATE, 3); |
1692 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_CTRL, 0); | 2487 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_CTRL, 0); |
1693 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_NAV, 1); | 2488 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_NAV_SHORT, 1); |
1694 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2489 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
1695 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2490 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
1696 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2491 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -1703,7 +2498,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1703 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); | 2498 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); |
1704 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_RATE, 3); | 2499 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_RATE, 3); |
1705 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, 0); | 2500 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, 0); |
1706 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_NAV, 1); | 2501 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_NAV_SHORT, 1); |
1707 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2502 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
1708 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2503 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
1709 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2504 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -1716,7 +2511,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1716 | rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); | 2511 | rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); |
1717 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, 0x4004); | 2512 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, 0x4004); |
1718 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, 0); | 2513 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, 0); |
1719 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_NAV, 1); | 2514 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_NAV_SHORT, 1); |
1720 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2515 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
1721 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2516 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
1722 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2517 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -1728,9 +2523,8 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1728 | 2523 | ||
1729 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); | 2524 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); |
1730 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084); | 2525 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084); |
1731 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, | 2526 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0); |
1732 | !rt2x00_is_usb(rt2x00dev)); | 2527 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV_SHORT, 1); |
1733 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV, 1); | ||
1734 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2528 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
1735 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2529 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
1736 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2530 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -1743,7 +2537,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1743 | rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); | 2537 | rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); |
1744 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, 0x4004); | 2538 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, 0x4004); |
1745 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, 0); | 2539 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, 0); |
1746 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_NAV, 1); | 2540 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_NAV_SHORT, 1); |
1747 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2541 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
1748 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2542 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
1749 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2543 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -1756,7 +2550,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1756 | rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); | 2550 | rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); |
1757 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, 0x4084); | 2551 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, 0x4084); |
1758 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, 0); | 2552 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, 0); |
1759 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_NAV, 1); | 2553 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_NAV_SHORT, 1); |
1760 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2554 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
1761 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2555 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
1762 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2556 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -1782,7 +2576,23 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1782 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | 2576 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); |
1783 | } | 2577 | } |
1784 | 2578 | ||
1785 | rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f); | 2579 | /* |
2580 | * The legacy driver also sets TXOP_CTRL_CFG_RESERVED_TRUN_EN to 1 | ||
2581 | * although it is reserved. | ||
2582 | */ | ||
2583 | rt2800_register_read(rt2x00dev, TXOP_CTRL_CFG, ®); | ||
2584 | rt2x00_set_field32(®, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1); | ||
2585 | rt2x00_set_field32(®, TXOP_CTRL_CFG_AC_TRUN_EN, 1); | ||
2586 | rt2x00_set_field32(®, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1); | ||
2587 | rt2x00_set_field32(®, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1); | ||
2588 | rt2x00_set_field32(®, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1); | ||
2589 | rt2x00_set_field32(®, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1); | ||
2590 | rt2x00_set_field32(®, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0); | ||
2591 | rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_EN, 0); | ||
2592 | rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_DLY, 88); | ||
2593 | rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CWMIN, 0); | ||
2594 | rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg); | ||
2595 | |||
1786 | rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002); | 2596 | rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002); |
1787 | 2597 | ||
1788 | rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); | 2598 | rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); |
@@ -1819,30 +2629,34 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1819 | SHARED_KEY_MODE_ENTRY(i), 0); | 2629 | SHARED_KEY_MODE_ENTRY(i), 0); |
1820 | 2630 | ||
1821 | for (i = 0; i < 256; i++) { | 2631 | for (i = 0; i < 256; i++) { |
1822 | u32 wcid[2] = { 0xffffffff, 0x00ffffff }; | 2632 | static const u32 wcid[2] = { 0xffffffff, 0x00ffffff }; |
1823 | rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), | 2633 | rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), |
1824 | wcid, sizeof(wcid)); | 2634 | wcid, sizeof(wcid)); |
1825 | 2635 | ||
1826 | rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1); | 2636 | rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 0); |
1827 | rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); | 2637 | rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); |
1828 | } | 2638 | } |
1829 | 2639 | ||
1830 | /* | 2640 | /* |
1831 | * Clear all beacons | 2641 | * Clear all beacons |
1832 | */ | 2642 | */ |
1833 | rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE0); | 2643 | rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE0); |
1834 | rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE1); | 2644 | rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE1); |
1835 | rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE2); | 2645 | rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE2); |
1836 | rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE3); | 2646 | rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE3); |
1837 | rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE4); | 2647 | rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE4); |
1838 | rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE5); | 2648 | rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE5); |
1839 | rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE6); | 2649 | rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE6); |
1840 | rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE7); | 2650 | rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE7); |
1841 | 2651 | ||
1842 | if (rt2x00_is_usb(rt2x00dev)) { | 2652 | if (rt2x00_is_usb(rt2x00dev)) { |
1843 | rt2800_register_read(rt2x00dev, US_CYC_CNT, ®); | 2653 | rt2800_register_read(rt2x00dev, US_CYC_CNT, ®); |
1844 | rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 30); | 2654 | rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 30); |
1845 | rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); | 2655 | rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); |
2656 | } else if (rt2x00_is_pcie(rt2x00dev)) { | ||
2657 | rt2800_register_read(rt2x00dev, US_CYC_CNT, ®); | ||
2658 | rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 125); | ||
2659 | rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); | ||
1846 | } | 2660 | } |
1847 | 2661 | ||
1848 | rt2800_register_read(rt2x00dev, HT_FBK_CFG0, ®); | 2662 | rt2800_register_read(rt2x00dev, HT_FBK_CFG0, ®); |
@@ -1886,6 +2700,14 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1886 | rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg); | 2700 | rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg); |
1887 | 2701 | ||
1888 | /* | 2702 | /* |
2703 | * Do not force the BA window size, we use the TXWI to set it | ||
2704 | */ | ||
2705 | rt2800_register_read(rt2x00dev, AMPDU_BA_WINSIZE, ®); | ||
2706 | rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE, 0); | ||
2707 | rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE, 0); | ||
2708 | rt2800_register_write(rt2x00dev, AMPDU_BA_WINSIZE, reg); | ||
2709 | |||
2710 | /* | ||
1889 | * We must clear the error counters. | 2711 | * We must clear the error counters. |
1890 | * These registers are cleared on read, | 2712 | * These registers are cleared on read, |
1891 | * so we may pass a useless variable to store the value. | 2713 | * so we may pass a useless variable to store the value. |
@@ -1904,9 +2726,19 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1904 | rt2x00_set_field32(®, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4); | 2726 | rt2x00_set_field32(®, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4); |
1905 | rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg); | 2727 | rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg); |
1906 | 2728 | ||
2729 | /* | ||
2730 | * Set up channel statistics timer | ||
2731 | */ | ||
2732 | rt2800_register_read(rt2x00dev, CH_TIME_CFG, ®); | ||
2733 | rt2x00_set_field32(®, CH_TIME_CFG_EIFS_BUSY, 1); | ||
2734 | rt2x00_set_field32(®, CH_TIME_CFG_NAV_BUSY, 1); | ||
2735 | rt2x00_set_field32(®, CH_TIME_CFG_RX_BUSY, 1); | ||
2736 | rt2x00_set_field32(®, CH_TIME_CFG_TX_BUSY, 1); | ||
2737 | rt2x00_set_field32(®, CH_TIME_CFG_TMR_EN, 1); | ||
2738 | rt2800_register_write(rt2x00dev, CH_TIME_CFG, reg); | ||
2739 | |||
1907 | return 0; | 2740 | return 0; |
1908 | } | 2741 | } |
1909 | EXPORT_SYMBOL_GPL(rt2800_init_registers); | ||
1910 | 2742 | ||
1911 | static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) | 2743 | static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) |
1912 | { | 2744 | { |
@@ -1949,7 +2781,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
1949 | return -EACCES; | 2781 | return -EACCES; |
1950 | } | 2782 | } |
1951 | 2783 | ||
1952 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | 2784 | static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) |
1953 | { | 2785 | { |
1954 | unsigned int i; | 2786 | unsigned int i; |
1955 | u16 eeprom; | 2787 | u16 eeprom; |
@@ -1960,15 +2792,31 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
1960 | rt2800_wait_bbp_ready(rt2x00dev))) | 2792 | rt2800_wait_bbp_ready(rt2x00dev))) |
1961 | return -EACCES; | 2793 | return -EACCES; |
1962 | 2794 | ||
1963 | if (rt2800_is_305x_soc(rt2x00dev)) | 2795 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
2796 | rt2800_bbp_read(rt2x00dev, 4, &value); | ||
2797 | rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); | ||
2798 | rt2800_bbp_write(rt2x00dev, 4, value); | ||
2799 | } | ||
2800 | |||
2801 | if (rt2800_is_305x_soc(rt2x00dev) || | ||
2802 | rt2x00_rt(rt2x00dev, RT5390)) | ||
1964 | rt2800_bbp_write(rt2x00dev, 31, 0x08); | 2803 | rt2800_bbp_write(rt2x00dev, 31, 0x08); |
1965 | 2804 | ||
1966 | rt2800_bbp_write(rt2x00dev, 65, 0x2c); | 2805 | rt2800_bbp_write(rt2x00dev, 65, 0x2c); |
1967 | rt2800_bbp_write(rt2x00dev, 66, 0x38); | 2806 | rt2800_bbp_write(rt2x00dev, 66, 0x38); |
1968 | 2807 | ||
2808 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2809 | rt2800_bbp_write(rt2x00dev, 68, 0x0b); | ||
2810 | |||
1969 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { | 2811 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { |
1970 | rt2800_bbp_write(rt2x00dev, 69, 0x16); | 2812 | rt2800_bbp_write(rt2x00dev, 69, 0x16); |
1971 | rt2800_bbp_write(rt2x00dev, 73, 0x12); | 2813 | rt2800_bbp_write(rt2x00dev, 73, 0x12); |
2814 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
2815 | rt2800_bbp_write(rt2x00dev, 69, 0x12); | ||
2816 | rt2800_bbp_write(rt2x00dev, 73, 0x13); | ||
2817 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | ||
2818 | rt2800_bbp_write(rt2x00dev, 76, 0x28); | ||
2819 | rt2800_bbp_write(rt2x00dev, 77, 0x59); | ||
1972 | } else { | 2820 | } else { |
1973 | rt2800_bbp_write(rt2x00dev, 69, 0x12); | 2821 | rt2800_bbp_write(rt2x00dev, 69, 0x12); |
1974 | rt2800_bbp_write(rt2x00dev, 73, 0x10); | 2822 | rt2800_bbp_write(rt2x00dev, 73, 0x10); |
@@ -1979,7 +2827,8 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
1979 | if (rt2x00_rt(rt2x00dev, RT3070) || | 2827 | if (rt2x00_rt(rt2x00dev, RT3070) || |
1980 | rt2x00_rt(rt2x00dev, RT3071) || | 2828 | rt2x00_rt(rt2x00dev, RT3071) || |
1981 | rt2x00_rt(rt2x00dev, RT3090) || | 2829 | rt2x00_rt(rt2x00dev, RT3090) || |
1982 | rt2x00_rt(rt2x00dev, RT3390)) { | 2830 | rt2x00_rt(rt2x00dev, RT3390) || |
2831 | rt2x00_rt(rt2x00dev, RT5390)) { | ||
1983 | rt2800_bbp_write(rt2x00dev, 79, 0x13); | 2832 | rt2800_bbp_write(rt2x00dev, 79, 0x13); |
1984 | rt2800_bbp_write(rt2x00dev, 80, 0x05); | 2833 | rt2800_bbp_write(rt2x00dev, 80, 0x05); |
1985 | rt2800_bbp_write(rt2x00dev, 81, 0x33); | 2834 | rt2800_bbp_write(rt2x00dev, 81, 0x33); |
@@ -1991,46 +2840,108 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
1991 | } | 2840 | } |
1992 | 2841 | ||
1993 | rt2800_bbp_write(rt2x00dev, 82, 0x62); | 2842 | rt2800_bbp_write(rt2x00dev, 82, 0x62); |
1994 | rt2800_bbp_write(rt2x00dev, 83, 0x6a); | 2843 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2844 | rt2800_bbp_write(rt2x00dev, 83, 0x7a); | ||
2845 | else | ||
2846 | rt2800_bbp_write(rt2x00dev, 83, 0x6a); | ||
1995 | 2847 | ||
1996 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) | 2848 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) |
1997 | rt2800_bbp_write(rt2x00dev, 84, 0x19); | 2849 | rt2800_bbp_write(rt2x00dev, 84, 0x19); |
2850 | else if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2851 | rt2800_bbp_write(rt2x00dev, 84, 0x9a); | ||
1998 | else | 2852 | else |
1999 | rt2800_bbp_write(rt2x00dev, 84, 0x99); | 2853 | rt2800_bbp_write(rt2x00dev, 84, 0x99); |
2000 | 2854 | ||
2001 | rt2800_bbp_write(rt2x00dev, 86, 0x00); | 2855 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2856 | rt2800_bbp_write(rt2x00dev, 86, 0x38); | ||
2857 | else | ||
2858 | rt2800_bbp_write(rt2x00dev, 86, 0x00); | ||
2859 | |||
2002 | rt2800_bbp_write(rt2x00dev, 91, 0x04); | 2860 | rt2800_bbp_write(rt2x00dev, 91, 0x04); |
2003 | rt2800_bbp_write(rt2x00dev, 92, 0x00); | 2861 | |
2862 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2863 | rt2800_bbp_write(rt2x00dev, 92, 0x02); | ||
2864 | else | ||
2865 | rt2800_bbp_write(rt2x00dev, 92, 0x00); | ||
2004 | 2866 | ||
2005 | if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || | 2867 | if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || |
2006 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || | 2868 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || |
2007 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || | 2869 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || |
2008 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || | 2870 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || |
2871 | rt2x00_rt(rt2x00dev, RT5390) || | ||
2009 | rt2800_is_305x_soc(rt2x00dev)) | 2872 | rt2800_is_305x_soc(rt2x00dev)) |
2010 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); | 2873 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); |
2011 | else | 2874 | else |
2012 | rt2800_bbp_write(rt2x00dev, 103, 0x00); | 2875 | rt2800_bbp_write(rt2x00dev, 103, 0x00); |
2013 | 2876 | ||
2877 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2878 | rt2800_bbp_write(rt2x00dev, 104, 0x92); | ||
2879 | |||
2014 | if (rt2800_is_305x_soc(rt2x00dev)) | 2880 | if (rt2800_is_305x_soc(rt2x00dev)) |
2015 | rt2800_bbp_write(rt2x00dev, 105, 0x01); | 2881 | rt2800_bbp_write(rt2x00dev, 105, 0x01); |
2882 | else if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2883 | rt2800_bbp_write(rt2x00dev, 105, 0x3c); | ||
2016 | else | 2884 | else |
2017 | rt2800_bbp_write(rt2x00dev, 105, 0x05); | 2885 | rt2800_bbp_write(rt2x00dev, 105, 0x05); |
2018 | rt2800_bbp_write(rt2x00dev, 106, 0x35); | 2886 | |
2887 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2888 | rt2800_bbp_write(rt2x00dev, 106, 0x03); | ||
2889 | else | ||
2890 | rt2800_bbp_write(rt2x00dev, 106, 0x35); | ||
2891 | |||
2892 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2893 | rt2800_bbp_write(rt2x00dev, 128, 0x12); | ||
2019 | 2894 | ||
2020 | if (rt2x00_rt(rt2x00dev, RT3071) || | 2895 | if (rt2x00_rt(rt2x00dev, RT3071) || |
2021 | rt2x00_rt(rt2x00dev, RT3090) || | 2896 | rt2x00_rt(rt2x00dev, RT3090) || |
2022 | rt2x00_rt(rt2x00dev, RT3390)) { | 2897 | rt2x00_rt(rt2x00dev, RT3390) || |
2898 | rt2x00_rt(rt2x00dev, RT5390)) { | ||
2023 | rt2800_bbp_read(rt2x00dev, 138, &value); | 2899 | rt2800_bbp_read(rt2x00dev, 138, &value); |
2024 | 2900 | ||
2025 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | 2901 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); |
2026 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1) | 2902 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) |
2027 | value |= 0x20; | 2903 | value |= 0x20; |
2028 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1) | 2904 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) |
2029 | value &= ~0x02; | 2905 | value &= ~0x02; |
2030 | 2906 | ||
2031 | rt2800_bbp_write(rt2x00dev, 138, value); | 2907 | rt2800_bbp_write(rt2x00dev, 138, value); |
2032 | } | 2908 | } |
2033 | 2909 | ||
2910 | if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
2911 | int ant, div_mode; | ||
2912 | |||
2913 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
2914 | div_mode = rt2x00_get_field16(eeprom, | ||
2915 | EEPROM_NIC_CONF1_ANT_DIVERSITY); | ||
2916 | ant = (div_mode == 3) ? 1 : 0; | ||
2917 | |||
2918 | /* check if this is a Bluetooth combo card */ | ||
2919 | if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { | ||
2920 | u32 reg; | ||
2921 | |||
2922 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
2923 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); | ||
2924 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT6, 0); | ||
2925 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 0); | ||
2926 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 0); | ||
2927 | if (ant == 0) | ||
2928 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 1); | ||
2929 | else if (ant == 1) | ||
2930 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 1); | ||
2931 | rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
2932 | } | ||
2933 | |||
2934 | rt2800_bbp_read(rt2x00dev, 152, &value); | ||
2935 | if (ant == 0) | ||
2936 | rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1); | ||
2937 | else | ||
2938 | rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); | ||
2939 | rt2800_bbp_write(rt2x00dev, 152, value); | ||
2940 | |||
2941 | /* Init frequency calibration */ | ||
2942 | rt2800_bbp_write(rt2x00dev, 142, 1); | ||
2943 | rt2800_bbp_write(rt2x00dev, 143, 57); | ||
2944 | } | ||
2034 | 2945 | ||
2035 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 2946 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
2036 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 2947 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
@@ -2044,7 +2955,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2044 | 2955 | ||
2045 | return 0; | 2956 | return 0; |
2046 | } | 2957 | } |
2047 | EXPORT_SYMBOL_GPL(rt2800_init_bbp); | ||
2048 | 2958 | ||
2049 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | 2959 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, |
2050 | bool bw40, u8 rfcsr24, u8 filter_target) | 2960 | bool bw40, u8 rfcsr24, u8 filter_target) |
@@ -2062,6 +2972,10 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | |||
2062 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40); | 2972 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40); |
2063 | rt2800_bbp_write(rt2x00dev, 4, bbp); | 2973 | rt2800_bbp_write(rt2x00dev, 4, bbp); |
2064 | 2974 | ||
2975 | rt2800_rfcsr_read(rt2x00dev, 31, &rfcsr); | ||
2976 | rt2x00_set_field8(&rfcsr, RFCSR31_RX_H20M, bw40); | ||
2977 | rt2800_rfcsr_write(rt2x00dev, 31, rfcsr); | ||
2978 | |||
2065 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); | 2979 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); |
2066 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1); | 2980 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1); |
2067 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); | 2981 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); |
@@ -2106,7 +3020,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | |||
2106 | return rfcsr24; | 3020 | return rfcsr24; |
2107 | } | 3021 | } |
2108 | 3022 | ||
2109 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | 3023 | static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) |
2110 | { | 3024 | { |
2111 | u8 rfcsr; | 3025 | u8 rfcsr; |
2112 | u8 bbp; | 3026 | u8 bbp; |
@@ -2117,18 +3031,28 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2117 | !rt2x00_rt(rt2x00dev, RT3071) && | 3031 | !rt2x00_rt(rt2x00dev, RT3071) && |
2118 | !rt2x00_rt(rt2x00dev, RT3090) && | 3032 | !rt2x00_rt(rt2x00dev, RT3090) && |
2119 | !rt2x00_rt(rt2x00dev, RT3390) && | 3033 | !rt2x00_rt(rt2x00dev, RT3390) && |
3034 | !rt2x00_rt(rt2x00dev, RT5390) && | ||
2120 | !rt2800_is_305x_soc(rt2x00dev)) | 3035 | !rt2800_is_305x_soc(rt2x00dev)) |
2121 | return 0; | 3036 | return 0; |
2122 | 3037 | ||
2123 | /* | 3038 | /* |
2124 | * Init RF calibration. | 3039 | * Init RF calibration. |
2125 | */ | 3040 | */ |
2126 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | 3041 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
2127 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | 3042 | rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); |
2128 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | 3043 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); |
2129 | msleep(1); | 3044 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); |
2130 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); | 3045 | msleep(1); |
2131 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | 3046 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); |
3047 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); | ||
3048 | } else { | ||
3049 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | ||
3050 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | ||
3051 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
3052 | msleep(1); | ||
3053 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); | ||
3054 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
3055 | } | ||
2132 | 3056 | ||
2133 | if (rt2x00_rt(rt2x00dev, RT3070) || | 3057 | if (rt2x00_rt(rt2x00dev, RT3070) || |
2134 | rt2x00_rt(rt2x00dev, RT3071) || | 3058 | rt2x00_rt(rt2x00dev, RT3071) || |
@@ -2136,7 +3060,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2136 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); | 3060 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); |
2137 | rt2800_rfcsr_write(rt2x00dev, 5, 0x03); | 3061 | rt2800_rfcsr_write(rt2x00dev, 5, 0x03); |
2138 | rt2800_rfcsr_write(rt2x00dev, 6, 0x02); | 3062 | rt2800_rfcsr_write(rt2x00dev, 6, 0x02); |
2139 | rt2800_rfcsr_write(rt2x00dev, 7, 0x70); | 3063 | rt2800_rfcsr_write(rt2x00dev, 7, 0x60); |
2140 | rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); | 3064 | rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); |
2141 | rt2800_rfcsr_write(rt2x00dev, 10, 0x41); | 3065 | rt2800_rfcsr_write(rt2x00dev, 10, 0x41); |
2142 | rt2800_rfcsr_write(rt2x00dev, 11, 0x21); | 3066 | rt2800_rfcsr_write(rt2x00dev, 11, 0x21); |
@@ -2219,6 +3143,87 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2219 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | 3143 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); |
2220 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); | 3144 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); |
2221 | return 0; | 3145 | return 0; |
3146 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
3147 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); | ||
3148 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | ||
3149 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); | ||
3150 | rt2800_rfcsr_write(rt2x00dev, 5, 0x10); | ||
3151 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3152 | rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); | ||
3153 | else | ||
3154 | rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); | ||
3155 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | ||
3156 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); | ||
3157 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); | ||
3158 | rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); | ||
3159 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); | ||
3160 | rt2800_rfcsr_write(rt2x00dev, 14, 0x00); | ||
3161 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | ||
3162 | rt2800_rfcsr_write(rt2x00dev, 16, 0x00); | ||
3163 | rt2800_rfcsr_write(rt2x00dev, 18, 0x03); | ||
3164 | rt2800_rfcsr_write(rt2x00dev, 19, 0x00); | ||
3165 | |||
3166 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); | ||
3167 | rt2800_rfcsr_write(rt2x00dev, 21, 0x00); | ||
3168 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); | ||
3169 | rt2800_rfcsr_write(rt2x00dev, 23, 0x00); | ||
3170 | rt2800_rfcsr_write(rt2x00dev, 24, 0x00); | ||
3171 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3172 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | ||
3173 | else | ||
3174 | rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); | ||
3175 | rt2800_rfcsr_write(rt2x00dev, 26, 0x00); | ||
3176 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); | ||
3177 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | ||
3178 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | ||
3179 | |||
3180 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | ||
3181 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
3182 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | ||
3183 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); | ||
3184 | rt2800_rfcsr_write(rt2x00dev, 34, 0x07); | ||
3185 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | ||
3186 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | ||
3187 | rt2800_rfcsr_write(rt2x00dev, 37, 0x08); | ||
3188 | rt2800_rfcsr_write(rt2x00dev, 38, 0x85); | ||
3189 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); | ||
3190 | |||
3191 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3192 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); | ||
3193 | else | ||
3194 | rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); | ||
3195 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); | ||
3196 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); | ||
3197 | rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); | ||
3198 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); | ||
3199 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); | ||
3200 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3201 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); | ||
3202 | else | ||
3203 | rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); | ||
3204 | rt2800_rfcsr_write(rt2x00dev, 47, 0x00); | ||
3205 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | ||
3206 | rt2800_rfcsr_write(rt2x00dev, 49, 0x94); | ||
3207 | |||
3208 | rt2800_rfcsr_write(rt2x00dev, 52, 0x38); | ||
3209 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3210 | rt2800_rfcsr_write(rt2x00dev, 53, 0x00); | ||
3211 | else | ||
3212 | rt2800_rfcsr_write(rt2x00dev, 53, 0x84); | ||
3213 | rt2800_rfcsr_write(rt2x00dev, 54, 0x78); | ||
3214 | rt2800_rfcsr_write(rt2x00dev, 55, 0x44); | ||
3215 | rt2800_rfcsr_write(rt2x00dev, 56, 0x22); | ||
3216 | rt2800_rfcsr_write(rt2x00dev, 57, 0x80); | ||
3217 | rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); | ||
3218 | rt2800_rfcsr_write(rt2x00dev, 59, 0x63); | ||
3219 | |||
3220 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | ||
3221 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3222 | rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); | ||
3223 | else | ||
3224 | rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); | ||
3225 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); | ||
3226 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); | ||
2222 | } | 3227 | } |
2223 | 3228 | ||
2224 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { | 3229 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { |
@@ -2228,23 +3233,27 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2228 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 3233 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
2229 | } else if (rt2x00_rt(rt2x00dev, RT3071) || | 3234 | } else if (rt2x00_rt(rt2x00dev, RT3071) || |
2230 | rt2x00_rt(rt2x00dev, RT3090)) { | 3235 | rt2x00_rt(rt2x00dev, RT3090)) { |
3236 | rt2800_rfcsr_write(rt2x00dev, 31, 0x14); | ||
3237 | |||
2231 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); | 3238 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); |
2232 | rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); | 3239 | rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); |
2233 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | 3240 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); |
2234 | 3241 | ||
2235 | rt2800_rfcsr_write(rt2x00dev, 31, 0x14); | ||
2236 | |||
2237 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | 3242 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); |
2238 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | 3243 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); |
2239 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 3244 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
2240 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) { | 3245 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) { |
2241 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | 3246 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); |
2242 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST)) | 3247 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) |
2243 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); | 3248 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); |
2244 | else | 3249 | else |
2245 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | 3250 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); |
2246 | } | 3251 | } |
2247 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 3252 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
3253 | |||
3254 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); | ||
3255 | rt2x00_set_field32(®, GPIO_SWITCH_5, 0); | ||
3256 | rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); | ||
2248 | } else if (rt2x00_rt(rt2x00dev, RT3390)) { | 3257 | } else if (rt2x00_rt(rt2x00dev, RT3390)) { |
2249 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); | 3258 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); |
2250 | rt2x00_set_field32(®, GPIO_SWITCH_5, 0); | 3259 | rt2x00_set_field32(®, GPIO_SWITCH_5, 0); |
@@ -2268,21 +3277,23 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2268 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); | 3277 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); |
2269 | } | 3278 | } |
2270 | 3279 | ||
2271 | /* | 3280 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
2272 | * Set back to initial state | 3281 | /* |
2273 | */ | 3282 | * Set back to initial state |
2274 | rt2800_bbp_write(rt2x00dev, 24, 0); | 3283 | */ |
3284 | rt2800_bbp_write(rt2x00dev, 24, 0); | ||
2275 | 3285 | ||
2276 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); | 3286 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); |
2277 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); | 3287 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); |
2278 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); | 3288 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); |
2279 | 3289 | ||
2280 | /* | 3290 | /* |
2281 | * set BBP back to BW20 | 3291 | * Set BBP back to BW20 |
2282 | */ | 3292 | */ |
2283 | rt2800_bbp_read(rt2x00dev, 4, &bbp); | 3293 | rt2800_bbp_read(rt2x00dev, 4, &bbp); |
2284 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); | 3294 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); |
2285 | rt2800_bbp_write(rt2x00dev, 4, bbp); | 3295 | rt2800_bbp_write(rt2x00dev, 4, bbp); |
3296 | } | ||
2286 | 3297 | ||
2287 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || | 3298 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || |
2288 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 3299 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
@@ -2294,28 +3305,33 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2294 | rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); | 3305 | rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); |
2295 | rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); | 3306 | rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); |
2296 | 3307 | ||
2297 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | 3308 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
2298 | rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); | 3309 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); |
2299 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 3310 | rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); |
2300 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || | 3311 | if (rt2x00_rt(rt2x00dev, RT3070) || |
2301 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { | 3312 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
2302 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | 3313 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || |
2303 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); | 3314 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { |
2304 | } | 3315 | if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG, |
2305 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); | 3316 | &rt2x00dev->cap_flags)) |
2306 | if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) | 3317 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); |
2307 | rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, | 3318 | } |
2308 | rt2x00_get_field16(eeprom, | 3319 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); |
2309 | EEPROM_TXMIXER_GAIN_BG_VAL)); | 3320 | if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) |
2310 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | 3321 | rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, |
3322 | rt2x00_get_field16(eeprom, | ||
3323 | EEPROM_TXMIXER_GAIN_BG_VAL)); | ||
3324 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | ||
3325 | } | ||
2311 | 3326 | ||
2312 | if (rt2x00_rt(rt2x00dev, RT3090)) { | 3327 | if (rt2x00_rt(rt2x00dev, RT3090)) { |
2313 | rt2800_bbp_read(rt2x00dev, 138, &bbp); | 3328 | rt2800_bbp_read(rt2x00dev, 138, &bbp); |
2314 | 3329 | ||
2315 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | 3330 | /* Turn off unused DAC1 and ADC1 to reduce power consumption */ |
2316 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1) | 3331 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); |
3332 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) | ||
2317 | rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); | 3333 | rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); |
2318 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1) | 3334 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) |
2319 | rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1); | 3335 | rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1); |
2320 | 3336 | ||
2321 | rt2800_bbp_write(rt2x00dev, 138, bbp); | 3337 | rt2800_bbp_write(rt2x00dev, 138, bbp); |
@@ -2345,10 +3361,9 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2345 | rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); | 3361 | rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); |
2346 | } | 3362 | } |
2347 | 3363 | ||
2348 | if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071)) { | 3364 | if (rt2x00_rt(rt2x00dev, RT3070)) { |
2349 | rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr); | 3365 | rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr); |
2350 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || | 3366 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) |
2351 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E)) | ||
2352 | rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3); | 3367 | rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3); |
2353 | else | 3368 | else |
2354 | rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0); | 3369 | rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0); |
@@ -2358,9 +3373,110 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2358 | rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); | 3373 | rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); |
2359 | } | 3374 | } |
2360 | 3375 | ||
3376 | if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
3377 | rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); | ||
3378 | rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); | ||
3379 | rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); | ||
3380 | |||
3381 | rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr); | ||
3382 | rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0); | ||
3383 | rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); | ||
3384 | |||
3385 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | ||
3386 | rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2); | ||
3387 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
3388 | } | ||
3389 | |||
2361 | return 0; | 3390 | return 0; |
2362 | } | 3391 | } |
2363 | EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); | 3392 | |
3393 | int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
3394 | { | ||
3395 | u32 reg; | ||
3396 | u16 word; | ||
3397 | |||
3398 | /* | ||
3399 | * Initialize all registers. | ||
3400 | */ | ||
3401 | if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || | ||
3402 | rt2800_init_registers(rt2x00dev) || | ||
3403 | rt2800_init_bbp(rt2x00dev) || | ||
3404 | rt2800_init_rfcsr(rt2x00dev))) | ||
3405 | return -EIO; | ||
3406 | |||
3407 | /* | ||
3408 | * Send signal to firmware during boot time. | ||
3409 | */ | ||
3410 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | ||
3411 | |||
3412 | if (rt2x00_is_usb(rt2x00dev) && | ||
3413 | (rt2x00_rt(rt2x00dev, RT3070) || | ||
3414 | rt2x00_rt(rt2x00dev, RT3071) || | ||
3415 | rt2x00_rt(rt2x00dev, RT3572))) { | ||
3416 | udelay(200); | ||
3417 | rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); | ||
3418 | udelay(10); | ||
3419 | } | ||
3420 | |||
3421 | /* | ||
3422 | * Enable RX. | ||
3423 | */ | ||
3424 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
3425 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
3426 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
3427 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
3428 | |||
3429 | udelay(50); | ||
3430 | |||
3431 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
3432 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); | ||
3433 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); | ||
3434 | rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); | ||
3435 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | ||
3436 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
3437 | |||
3438 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
3439 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); | ||
3440 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | ||
3441 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
3442 | |||
3443 | /* | ||
3444 | * Initialize LED control | ||
3445 | */ | ||
3446 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word); | ||
3447 | rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff, | ||
3448 | word & 0xff, (word >> 8) & 0xff); | ||
3449 | |||
3450 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word); | ||
3451 | rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff, | ||
3452 | word & 0xff, (word >> 8) & 0xff); | ||
3453 | |||
3454 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word); | ||
3455 | rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff, | ||
3456 | word & 0xff, (word >> 8) & 0xff); | ||
3457 | |||
3458 | return 0; | ||
3459 | } | ||
3460 | EXPORT_SYMBOL_GPL(rt2800_enable_radio); | ||
3461 | |||
3462 | void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
3463 | { | ||
3464 | u32 reg; | ||
3465 | |||
3466 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | ||
3467 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | ||
3468 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); | ||
3469 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | ||
3470 | |||
3471 | /* Wait for DMA, ignore error */ | ||
3472 | rt2800_wait_wpdma_ready(rt2x00dev); | ||
3473 | |||
3474 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
3475 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 0); | ||
3476 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | ||
3477 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
3478 | } | ||
3479 | EXPORT_SYMBOL_GPL(rt2800_disable_radio); | ||
2364 | 3480 | ||
2365 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) | 3481 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) |
2366 | { | 3482 | { |
@@ -2424,38 +3540,41 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2424 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | 3540 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); |
2425 | } | 3541 | } |
2426 | 3542 | ||
2427 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | 3543 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word); |
2428 | if (word == 0xffff) { | 3544 | if (word == 0xffff) { |
2429 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | 3545 | rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2); |
2430 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1); | 3546 | rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1); |
2431 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820); | 3547 | rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820); |
2432 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | 3548 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); |
2433 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | 3549 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); |
2434 | } else if (rt2x00_rt(rt2x00dev, RT2860) || | 3550 | } else if (rt2x00_rt(rt2x00dev, RT2860) || |
2435 | rt2x00_rt(rt2x00dev, RT2872)) { | 3551 | rt2x00_rt(rt2x00dev, RT2872)) { |
2436 | /* | 3552 | /* |
2437 | * There is a max of 2 RX streams for RT28x0 series | 3553 | * There is a max of 2 RX streams for RT28x0 series |
2438 | */ | 3554 | */ |
2439 | if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2) | 3555 | if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2) |
2440 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | 3556 | rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2); |
2441 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | 3557 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); |
2442 | } | 3558 | } |
2443 | 3559 | ||
2444 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | 3560 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word); |
2445 | if (word == 0xffff) { | 3561 | if (word == 0xffff) { |
2446 | rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0); | 3562 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0); |
2447 | rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0); | 3563 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0); |
2448 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); | 3564 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G, 0); |
2449 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); | 3565 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G, 0); |
2450 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | 3566 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_CARDBUS_ACCEL, 0); |
2451 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0); | 3567 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_2G, 0); |
2452 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0); | 3568 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_5G, 0); |
2453 | rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0); | 3569 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_WPS_PBC, 0); |
2454 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0); | 3570 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_2G, 0); |
2455 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0); | 3571 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_5G, 0); |
2456 | rt2x00_set_field16(&word, EEPROM_NIC_ANT_DIVERSITY, 0); | 3572 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BROADBAND_EXT_LNA, 0); |
2457 | rt2x00_set_field16(&word, EEPROM_NIC_DAC_TEST, 0); | 3573 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_ANT_DIVERSITY, 0); |
2458 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | 3574 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0); |
3575 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0); | ||
3576 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0); | ||
3577 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word); | ||
2459 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | 3578 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); |
2460 | } | 3579 | } |
2461 | 3580 | ||
@@ -2470,9 +3589,9 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2470 | LED_MODE_TXRX_ACTIVITY); | 3589 | LED_MODE_TXRX_ACTIVITY); |
2471 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); | 3590 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); |
2472 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | 3591 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); |
2473 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555); | 3592 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555); |
2474 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221); | 3593 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221); |
2475 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8); | 3594 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8); |
2476 | EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word); | 3595 | EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word); |
2477 | } | 3596 | } |
2478 | 3597 | ||
@@ -2529,13 +3648,18 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2529 | /* | 3648 | /* |
2530 | * Read EEPROM word for configuration. | 3649 | * Read EEPROM word for configuration. |
2531 | */ | 3650 | */ |
2532 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | 3651 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); |
2533 | 3652 | ||
2534 | /* | 3653 | /* |
2535 | * Identify RF chipset. | 3654 | * Identify RF chipset by EEPROM value |
3655 | * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field | ||
3656 | * RT53xx: defined in "EEPROM_CHIP_ID" field | ||
2536 | */ | 3657 | */ |
2537 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
2538 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | 3658 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); |
3659 | if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390) | ||
3660 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); | ||
3661 | else | ||
3662 | value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); | ||
2539 | 3663 | ||
2540 | rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), | 3664 | rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), |
2541 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); | 3665 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); |
@@ -2547,7 +3671,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2547 | !rt2x00_rt(rt2x00dev, RT3071) && | 3671 | !rt2x00_rt(rt2x00dev, RT3071) && |
2548 | !rt2x00_rt(rt2x00dev, RT3090) && | 3672 | !rt2x00_rt(rt2x00dev, RT3090) && |
2549 | !rt2x00_rt(rt2x00dev, RT3390) && | 3673 | !rt2x00_rt(rt2x00dev, RT3390) && |
2550 | !rt2x00_rt(rt2x00dev, RT3572)) { | 3674 | !rt2x00_rt(rt2x00dev, RT3572) && |
3675 | !rt2x00_rt(rt2x00dev, RT5390)) { | ||
2551 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | 3676 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); |
2552 | return -ENODEV; | 3677 | return -ENODEV; |
2553 | } | 3678 | } |
@@ -2560,7 +3685,10 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2560 | !rt2x00_rf(rt2x00dev, RF2020) && | 3685 | !rt2x00_rf(rt2x00dev, RF2020) && |
2561 | !rt2x00_rf(rt2x00dev, RF3021) && | 3686 | !rt2x00_rf(rt2x00dev, RF3021) && |
2562 | !rt2x00_rf(rt2x00dev, RF3022) && | 3687 | !rt2x00_rf(rt2x00dev, RF3022) && |
2563 | !rt2x00_rf(rt2x00dev, RF3052)) { | 3688 | !rt2x00_rf(rt2x00dev, RF3052) && |
3689 | !rt2x00_rf(rt2x00dev, RF3320) && | ||
3690 | !rt2x00_rf(rt2x00dev, RF5370) && | ||
3691 | !rt2x00_rf(rt2x00dev, RF5390)) { | ||
2564 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | 3692 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); |
2565 | return -ENODEV; | 3693 | return -ENODEV; |
2566 | } | 3694 | } |
@@ -2568,32 +3696,60 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2568 | /* | 3696 | /* |
2569 | * Identify default antenna configuration. | 3697 | * Identify default antenna configuration. |
2570 | */ | 3698 | */ |
2571 | rt2x00dev->default_ant.tx = | 3699 | rt2x00dev->default_ant.tx_chain_num = |
2572 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH); | 3700 | rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH); |
2573 | rt2x00dev->default_ant.rx = | 3701 | rt2x00dev->default_ant.rx_chain_num = |
2574 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH); | 3702 | rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH); |
3703 | |||
3704 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
3705 | |||
3706 | if (rt2x00_rt(rt2x00dev, RT3070) || | ||
3707 | rt2x00_rt(rt2x00dev, RT3090) || | ||
3708 | rt2x00_rt(rt2x00dev, RT3390)) { | ||
3709 | value = rt2x00_get_field16(eeprom, | ||
3710 | EEPROM_NIC_CONF1_ANT_DIVERSITY); | ||
3711 | switch (value) { | ||
3712 | case 0: | ||
3713 | case 1: | ||
3714 | case 2: | ||
3715 | rt2x00dev->default_ant.tx = ANTENNA_A; | ||
3716 | rt2x00dev->default_ant.rx = ANTENNA_A; | ||
3717 | break; | ||
3718 | case 3: | ||
3719 | rt2x00dev->default_ant.tx = ANTENNA_A; | ||
3720 | rt2x00dev->default_ant.rx = ANTENNA_B; | ||
3721 | break; | ||
3722 | } | ||
3723 | } else { | ||
3724 | rt2x00dev->default_ant.tx = ANTENNA_A; | ||
3725 | rt2x00dev->default_ant.rx = ANTENNA_A; | ||
3726 | } | ||
2575 | 3727 | ||
2576 | /* | 3728 | /* |
2577 | * Read frequency offset and RF programming sequence. | 3729 | * Determine external LNA informations. |
2578 | */ | 3730 | */ |
2579 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | 3731 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G)) |
2580 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | 3732 | __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); |
3733 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G)) | ||
3734 | __set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); | ||
2581 | 3735 | ||
2582 | /* | 3736 | /* |
2583 | * Read external LNA informations. | 3737 | * Detect if this device has an hardware controlled radio. |
2584 | */ | 3738 | */ |
2585 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | 3739 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO)) |
3740 | __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); | ||
2586 | 3741 | ||
2587 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) | 3742 | /* |
2588 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 3743 | * Detect if this device has Bluetooth co-existence. |
2589 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) | 3744 | */ |
2590 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | 3745 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) |
3746 | __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags); | ||
2591 | 3747 | ||
2592 | /* | 3748 | /* |
2593 | * Detect if this device has an hardware controlled radio. | 3749 | * Read frequency offset and RF programming sequence. |
2594 | */ | 3750 | */ |
2595 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO)) | 3751 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); |
2596 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | 3752 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); |
2597 | 3753 | ||
2598 | /* | 3754 | /* |
2599 | * Store led settings, for correct led behaviour. | 3755 | * Store led settings, for correct led behaviour. |
@@ -2603,9 +3759,18 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2603 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); | 3759 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); |
2604 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); | 3760 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); |
2605 | 3761 | ||
2606 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg); | 3762 | rt2x00dev->led_mcu_reg = eeprom; |
2607 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 3763 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
2608 | 3764 | ||
3765 | /* | ||
3766 | * Check if support EIRP tx power limit feature. | ||
3767 | */ | ||
3768 | rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom); | ||
3769 | |||
3770 | if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) < | ||
3771 | EIRP_MAX_TX_POWER_LIMIT) | ||
3772 | __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags); | ||
3773 | |||
2609 | return 0; | 3774 | return 0; |
2610 | } | 3775 | } |
2611 | EXPORT_SYMBOL_GPL(rt2800_init_eeprom); | 3776 | EXPORT_SYMBOL_GPL(rt2800_init_eeprom); |
@@ -2755,8 +3920,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2755 | { | 3920 | { |
2756 | struct hw_mode_spec *spec = &rt2x00dev->spec; | 3921 | struct hw_mode_spec *spec = &rt2x00dev->spec; |
2757 | struct channel_info *info; | 3922 | struct channel_info *info; |
2758 | char *tx_power1; | 3923 | char *default_power1; |
2759 | char *tx_power2; | 3924 | char *default_power2; |
2760 | unsigned int i; | 3925 | unsigned int i; |
2761 | u16 eeprom; | 3926 | u16 eeprom; |
2762 | 3927 | ||
@@ -2770,11 +3935,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2770 | * Initialize all hw fields. | 3935 | * Initialize all hw fields. |
2771 | */ | 3936 | */ |
2772 | rt2x00dev->hw->flags = | 3937 | rt2x00dev->hw->flags = |
2773 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
2774 | IEEE80211_HW_SIGNAL_DBM | | 3938 | IEEE80211_HW_SIGNAL_DBM | |
2775 | IEEE80211_HW_SUPPORTS_PS | | 3939 | IEEE80211_HW_SUPPORTS_PS | |
2776 | IEEE80211_HW_PS_NULLFUNC_STACK | | 3940 | IEEE80211_HW_PS_NULLFUNC_STACK | |
2777 | IEEE80211_HW_AMPDU_AGGREGATION; | 3941 | IEEE80211_HW_AMPDU_AGGREGATION; |
3942 | /* | ||
3943 | * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices | ||
3944 | * unless we are capable of sending the buffered frames out after the | ||
3945 | * DTIM transmission using rt2x00lib_beacondone. This will send out | ||
3946 | * multicast and broadcast traffic immediately instead of buffering it | ||
3947 | * infinitly and thus dropping it after some time. | ||
3948 | */ | ||
3949 | if (!rt2x00_is_usb(rt2x00dev)) | ||
3950 | rt2x00dev->hw->flags |= | ||
3951 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | ||
2778 | 3952 | ||
2779 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | 3953 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
2780 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 3954 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -2785,15 +3959,16 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2785 | * As rt2800 has a global fallback table we cannot specify | 3959 | * As rt2800 has a global fallback table we cannot specify |
2786 | * more then one tx rate per frame but since the hw will | 3960 | * more then one tx rate per frame but since the hw will |
2787 | * try several rates (based on the fallback table) we should | 3961 | * try several rates (based on the fallback table) we should |
2788 | * still initialize max_rates to the maximum number of rates | 3962 | * initialize max_report_rates to the maximum number of rates |
2789 | * we are going to try. Otherwise mac80211 will truncate our | 3963 | * we are going to try. Otherwise mac80211 will truncate our |
2790 | * reported tx rates and the rc algortihm will end up with | 3964 | * reported tx rates and the rc algortihm will end up with |
2791 | * incorrect data. | 3965 | * incorrect data. |
2792 | */ | 3966 | */ |
2793 | rt2x00dev->hw->max_rates = 7; | 3967 | rt2x00dev->hw->max_rates = 1; |
3968 | rt2x00dev->hw->max_report_rates = 7; | ||
2794 | rt2x00dev->hw->max_rate_tries = 1; | 3969 | rt2x00dev->hw->max_rate_tries = 1; |
2795 | 3970 | ||
2796 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | 3971 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); |
2797 | 3972 | ||
2798 | /* | 3973 | /* |
2799 | * Initialize hw_mode information. | 3974 | * Initialize hw_mode information. |
@@ -2813,7 +3988,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2813 | } else if (rt2x00_rf(rt2x00dev, RF3020) || | 3988 | } else if (rt2x00_rf(rt2x00dev, RF3020) || |
2814 | rt2x00_rf(rt2x00dev, RF2020) || | 3989 | rt2x00_rf(rt2x00dev, RF2020) || |
2815 | rt2x00_rf(rt2x00dev, RF3021) || | 3990 | rt2x00_rf(rt2x00dev, RF3021) || |
2816 | rt2x00_rf(rt2x00dev, RF3022)) { | 3991 | rt2x00_rf(rt2x00dev, RF3022) || |
3992 | rt2x00_rf(rt2x00dev, RF3320) || | ||
3993 | rt2x00_rf(rt2x00dev, RF5370) || | ||
3994 | rt2x00_rf(rt2x00dev, RF5390)) { | ||
2817 | spec->num_channels = 14; | 3995 | spec->num_channels = 14; |
2818 | spec->channels = rf_vals_3x; | 3996 | spec->channels = rf_vals_3x; |
2819 | } else if (rt2x00_rf(rt2x00dev, RF3052)) { | 3997 | } else if (rt2x00_rf(rt2x00dev, RF3052)) { |
@@ -2836,11 +4014,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2836 | IEEE80211_HT_CAP_SGI_20 | | 4014 | IEEE80211_HT_CAP_SGI_20 | |
2837 | IEEE80211_HT_CAP_SGI_40; | 4015 | IEEE80211_HT_CAP_SGI_40; |
2838 | 4016 | ||
2839 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2) | 4017 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) >= 2) |
2840 | spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC; | 4018 | spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC; |
2841 | 4019 | ||
2842 | spec->ht.cap |= | 4020 | spec->ht.cap |= |
2843 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) << | 4021 | rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) << |
2844 | IEEE80211_HT_CAP_RX_STBC_SHIFT; | 4022 | IEEE80211_HT_CAP_RX_STBC_SHIFT; |
2845 | 4023 | ||
2846 | spec->ht.ampdu_factor = 3; | 4024 | spec->ht.ampdu_factor = 3; |
@@ -2848,10 +4026,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2848 | spec->ht.mcs.tx_params = | 4026 | spec->ht.mcs.tx_params = |
2849 | IEEE80211_HT_MCS_TX_DEFINED | | 4027 | IEEE80211_HT_MCS_TX_DEFINED | |
2850 | IEEE80211_HT_MCS_TX_RX_DIFF | | 4028 | IEEE80211_HT_MCS_TX_RX_DIFF | |
2851 | ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) << | 4029 | ((rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) - 1) << |
2852 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | 4030 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); |
2853 | 4031 | ||
2854 | switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) { | 4032 | switch (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH)) { |
2855 | case 3: | 4033 | case 3: |
2856 | spec->ht.mcs.rx_mask[2] = 0xff; | 4034 | spec->ht.mcs.rx_mask[2] = 0xff; |
2857 | case 2: | 4035 | case 2: |
@@ -2865,27 +4043,27 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2865 | /* | 4043 | /* |
2866 | * Create channel information array | 4044 | * Create channel information array |
2867 | */ | 4045 | */ |
2868 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | 4046 | info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); |
2869 | if (!info) | 4047 | if (!info) |
2870 | return -ENOMEM; | 4048 | return -ENOMEM; |
2871 | 4049 | ||
2872 | spec->channels_info = info; | 4050 | spec->channels_info = info; |
2873 | 4051 | ||
2874 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | 4052 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); |
2875 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | 4053 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); |
2876 | 4054 | ||
2877 | for (i = 0; i < 14; i++) { | 4055 | for (i = 0; i < 14; i++) { |
2878 | info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); | 4056 | info[i].default_power1 = default_power1[i]; |
2879 | info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); | 4057 | info[i].default_power2 = default_power2[i]; |
2880 | } | 4058 | } |
2881 | 4059 | ||
2882 | if (spec->num_channels > 14) { | 4060 | if (spec->num_channels > 14) { |
2883 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | 4061 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); |
2884 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | 4062 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); |
2885 | 4063 | ||
2886 | for (i = 14; i < spec->num_channels; i++) { | 4064 | for (i = 14; i < spec->num_channels; i++) { |
2887 | info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); | 4065 | info[i].default_power1 = default_power1[i]; |
2888 | info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); | 4066 | info[i].default_power2 = default_power2[i]; |
2889 | } | 4067 | } |
2890 | } | 4068 | } |
2891 | 4069 | ||
@@ -2977,7 +4155,7 @@ int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
2977 | if (queue_idx >= 4) | 4155 | if (queue_idx >= 4) |
2978 | return 0; | 4156 | return 0; |
2979 | 4157 | ||
2980 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 4158 | queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
2981 | 4159 | ||
2982 | /* Update WMM TXOP register */ | 4160 | /* Update WMM TXOP register */ |
2983 | offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); | 4161 | offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); |
@@ -3035,15 +4213,20 @@ EXPORT_SYMBOL_GPL(rt2800_get_tsf); | |||
3035 | 4213 | ||
3036 | int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 4214 | int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
3037 | enum ieee80211_ampdu_mlme_action action, | 4215 | enum ieee80211_ampdu_mlme_action action, |
3038 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 4216 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, |
4217 | u8 buf_size) | ||
3039 | { | 4218 | { |
3040 | int ret = 0; | 4219 | int ret = 0; |
3041 | 4220 | ||
3042 | switch (action) { | 4221 | switch (action) { |
3043 | case IEEE80211_AMPDU_RX_START: | 4222 | case IEEE80211_AMPDU_RX_START: |
3044 | case IEEE80211_AMPDU_RX_STOP: | 4223 | case IEEE80211_AMPDU_RX_STOP: |
3045 | /* we don't support RX aggregation yet */ | 4224 | /* |
3046 | ret = -ENOTSUPP; | 4225 | * The hw itself takes care of setting up BlockAck mechanisms. |
4226 | * So, we only have to allow mac80211 to nagotiate a BlockAck | ||
4227 | * agreement. Once that is done, the hw will BlockAck incoming | ||
4228 | * AMPDUs without further setup. | ||
4229 | */ | ||
3047 | break; | 4230 | break; |
3048 | case IEEE80211_AMPDU_TX_START: | 4231 | case IEEE80211_AMPDU_TX_START: |
3049 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 4232 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
@@ -3061,6 +4244,37 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
3061 | } | 4244 | } |
3062 | EXPORT_SYMBOL_GPL(rt2800_ampdu_action); | 4245 | EXPORT_SYMBOL_GPL(rt2800_ampdu_action); |
3063 | 4246 | ||
4247 | int rt2800_get_survey(struct ieee80211_hw *hw, int idx, | ||
4248 | struct survey_info *survey) | ||
4249 | { | ||
4250 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
4251 | struct ieee80211_conf *conf = &hw->conf; | ||
4252 | u32 idle, busy, busy_ext; | ||
4253 | |||
4254 | if (idx != 0) | ||
4255 | return -ENOENT; | ||
4256 | |||
4257 | survey->channel = conf->channel; | ||
4258 | |||
4259 | rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle); | ||
4260 | rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy); | ||
4261 | rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext); | ||
4262 | |||
4263 | if (idle || busy) { | ||
4264 | survey->filled = SURVEY_INFO_CHANNEL_TIME | | ||
4265 | SURVEY_INFO_CHANNEL_TIME_BUSY | | ||
4266 | SURVEY_INFO_CHANNEL_TIME_EXT_BUSY; | ||
4267 | |||
4268 | survey->channel_time = (idle + busy) / 1000; | ||
4269 | survey->channel_time_busy = busy / 1000; | ||
4270 | survey->channel_time_ext_busy = busy_ext / 1000; | ||
4271 | } | ||
4272 | |||
4273 | return 0; | ||
4274 | |||
4275 | } | ||
4276 | EXPORT_SYMBOL_GPL(rt2800_get_survey); | ||
4277 | |||
3064 | MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz"); | 4278 | MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz"); |
3065 | MODULE_VERSION(DRV_VERSION); | 4279 | MODULE_VERSION(DRV_VERSION); |
3066 | MODULE_DESCRIPTION("Ralink RT2800 library"); | 4280 | MODULE_DESCRIPTION("Ralink RT2800 library"); |