diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 136 |
1 files changed, 59 insertions, 77 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b2f23272c3aa..e5ea670a18db 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -51,7 +51,7 @@ | |||
51 | /* | 51 | /* |
52 | * Allow hardware encryption to be disabled. | 52 | * Allow hardware encryption to be disabled. |
53 | */ | 53 | */ |
54 | static int modparam_nohwcrypt = 1; | 54 | static int modparam_nohwcrypt = 0; |
55 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 55 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); |
56 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 56 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
57 | 57 | ||
@@ -446,6 +446,38 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
446 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); | 446 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); |
447 | } | 447 | } |
448 | 448 | ||
449 | static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | ||
450 | { | ||
451 | u32 reg; | ||
452 | |||
453 | /* | ||
454 | * Reset DMA indexes | ||
455 | */ | ||
456 | rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); | ||
457 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); | ||
458 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); | ||
459 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); | ||
460 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); | ||
461 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); | ||
462 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); | ||
463 | rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); | ||
464 | rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); | ||
465 | |||
466 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | ||
467 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | ||
468 | |||
469 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | ||
470 | |||
471 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
472 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | ||
473 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | ||
474 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
475 | |||
476 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); | ||
477 | |||
478 | return 0; | ||
479 | } | ||
480 | |||
449 | static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) | 481 | static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) |
450 | { | 482 | { |
451 | u32 reg; | 483 | u32 reg; |
@@ -465,7 +497,7 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
465 | /* | 497 | /* |
466 | * Send signal to firmware during boot time. | 498 | * Send signal to firmware during boot time. |
467 | */ | 499 | */ |
468 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0); | 500 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); |
469 | 501 | ||
470 | /* | 502 | /* |
471 | * Enable RX. | 503 | * Enable RX. |
@@ -613,18 +645,10 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
613 | /* | 645 | /* |
614 | * TX descriptor initialization | 646 | * TX descriptor initialization |
615 | */ | 647 | */ |
616 | static int rt2800pci_write_tx_data(struct queue_entry* entry, | 648 | static void rt2800pci_write_tx_datadesc(struct queue_entry* entry, |
617 | struct txentry_desc *txdesc) | 649 | struct txentry_desc *txdesc) |
618 | { | 650 | { |
619 | int ret; | 651 | rt2800_write_txwi((__le32 *) entry->skb->data, txdesc); |
620 | |||
621 | ret = rt2x00pci_write_tx_data(entry, txdesc); | ||
622 | if (ret) | ||
623 | return ret; | ||
624 | |||
625 | rt2800_write_txwi(entry->skb, txdesc); | ||
626 | |||
627 | return 0; | ||
628 | } | 652 | } |
629 | 653 | ||
630 | 654 | ||
@@ -684,49 +708,6 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
684 | /* | 708 | /* |
685 | * TX data initialization | 709 | * TX data initialization |
686 | */ | 710 | */ |
687 | static void rt2800pci_write_beacon(struct queue_entry *entry, | ||
688 | struct txentry_desc *txdesc) | ||
689 | { | ||
690 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
691 | unsigned int beacon_base; | ||
692 | u32 reg; | ||
693 | |||
694 | /* | ||
695 | * Disable beaconing while we are reloading the beacon data, | ||
696 | * otherwise we might be sending out invalid data. | ||
697 | */ | ||
698 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
699 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | ||
700 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
701 | |||
702 | /* | ||
703 | * Add the TXWI for the beacon to the skb. | ||
704 | */ | ||
705 | rt2800_write_txwi(entry->skb, txdesc); | ||
706 | skb_push(entry->skb, TXWI_DESC_SIZE); | ||
707 | |||
708 | /* | ||
709 | * Write entire beacon with TXWI to register. | ||
710 | */ | ||
711 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
712 | rt2800_register_multiwrite(rt2x00dev, beacon_base, | ||
713 | entry->skb->data, entry->skb->len); | ||
714 | |||
715 | /* | ||
716 | * Enable beaconing again. | ||
717 | */ | ||
718 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
719 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
720 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
721 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
722 | |||
723 | /* | ||
724 | * Clean up beacon skb. | ||
725 | */ | ||
726 | dev_kfree_skb_any(entry->skb); | ||
727 | entry->skb = NULL; | ||
728 | } | ||
729 | |||
730 | static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 711 | static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
731 | const enum data_queue_qid queue_idx) | 712 | const enum data_queue_qid queue_idx) |
732 | { | 713 | { |
@@ -832,29 +813,24 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
832 | struct txdone_entry_desc txdesc; | 813 | struct txdone_entry_desc txdesc; |
833 | u32 word; | 814 | u32 word; |
834 | u32 reg; | 815 | u32 reg; |
835 | u32 old_reg; | ||
836 | int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; | 816 | int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; |
837 | u16 mcs, real_mcs; | 817 | u16 mcs, real_mcs; |
818 | int i; | ||
838 | 819 | ||
839 | /* | 820 | /* |
840 | * During each loop we will compare the freshly read | 821 | * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO |
841 | * TX_STA_FIFO register value with the value read from | 822 | * at most X times and also stop processing once the TX_STA_FIFO_VALID |
842 | * the previous loop. If the 2 values are equal then | 823 | * flag is not set anymore. |
843 | * we should stop processing because the chance it | 824 | * |
844 | * quite big that the device has been unplugged and | 825 | * The legacy drivers use X=TX_RING_SIZE but state in a comment |
845 | * we risk going into an endless loop. | 826 | * that the TX_STA_FIFO stack has a size of 16. We stick to our |
827 | * tx ring size for now. | ||
846 | */ | 828 | */ |
847 | old_reg = 0; | 829 | for (i = 0; i < TX_ENTRIES; i++) { |
848 | |||
849 | while (1) { | ||
850 | rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); | 830 | rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); |
851 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) | 831 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) |
852 | break; | 832 | break; |
853 | 833 | ||
854 | if (old_reg == reg) | ||
855 | break; | ||
856 | old_reg = reg; | ||
857 | |||
858 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | 834 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); |
859 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | 835 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); |
860 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | 836 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); |
@@ -880,8 +856,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
880 | 856 | ||
881 | /* Check if we got a match by looking at WCID/ACK/PID | 857 | /* Check if we got a match by looking at WCID/ACK/PID |
882 | * fields */ | 858 | * fields */ |
883 | txwi = (__le32 *)(entry->skb->data - | 859 | txwi = (__le32 *) entry->skb->data; |
884 | rt2x00dev->ops->extra_tx_headroom); | ||
885 | 860 | ||
886 | rt2x00_desc_read(txwi, 1, &word); | 861 | rt2x00_desc_read(txwi, 1, &word); |
887 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | 862 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); |
@@ -923,10 +898,14 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
923 | txdesc.retry = 7; | 898 | txdesc.retry = 7; |
924 | } | 899 | } |
925 | 900 | ||
926 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | 901 | /* |
927 | 902 | * the frame was retried at least once | |
903 | * -> hw used fallback rates | ||
904 | */ | ||
905 | if (txdesc.retry) | ||
906 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | ||
928 | 907 | ||
929 | rt2x00lib_txdone(entry, &txdesc); | 908 | rt2x00pci_txdone(entry, &txdesc); |
930 | } | 909 | } |
931 | } | 910 | } |
932 | 911 | ||
@@ -996,6 +975,8 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { | |||
996 | .register_multiwrite = rt2x00pci_register_multiwrite, | 975 | .register_multiwrite = rt2x00pci_register_multiwrite, |
997 | 976 | ||
998 | .regbusy_read = rt2x00pci_regbusy_read, | 977 | .regbusy_read = rt2x00pci_regbusy_read, |
978 | |||
979 | .drv_init_registers = rt2800pci_init_registers, | ||
999 | }; | 980 | }; |
1000 | 981 | ||
1001 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 982 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
@@ -1063,8 +1044,9 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | |||
1063 | .reset_tuner = rt2800_reset_tuner, | 1044 | .reset_tuner = rt2800_reset_tuner, |
1064 | .link_tuner = rt2800_link_tuner, | 1045 | .link_tuner = rt2800_link_tuner, |
1065 | .write_tx_desc = rt2800pci_write_tx_desc, | 1046 | .write_tx_desc = rt2800pci_write_tx_desc, |
1066 | .write_tx_data = rt2800pci_write_tx_data, | 1047 | .write_tx_data = rt2x00pci_write_tx_data, |
1067 | .write_beacon = rt2800pci_write_beacon, | 1048 | .write_tx_datadesc = rt2800pci_write_tx_datadesc, |
1049 | .write_beacon = rt2800_write_beacon, | ||
1068 | .kick_tx_queue = rt2800pci_kick_tx_queue, | 1050 | .kick_tx_queue = rt2800pci_kick_tx_queue, |
1069 | .kill_tx_queue = rt2800pci_kill_tx_queue, | 1051 | .kill_tx_queue = rt2800pci_kill_tx_queue, |
1070 | .fill_rxdone = rt2800pci_fill_rxdone, | 1052 | .fill_rxdone = rt2800pci_fill_rxdone, |