diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 119 |
1 files changed, 6 insertions, 113 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 39b3846fa340..4390f2b74b2e 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> | 3 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> |
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | 4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> |
5 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> | 5 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> |
@@ -566,15 +566,11 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
566 | /* | 566 | /* |
567 | * TX descriptor initialization | 567 | * TX descriptor initialization |
568 | */ | 568 | */ |
569 | static void rt2800pci_write_tx_data(struct queue_entry* entry, | 569 | static __le32 *rt2800pci_get_txwi(struct queue_entry *entry) |
570 | struct txentry_desc *txdesc) | ||
571 | { | 570 | { |
572 | __le32 *txwi = (__le32 *) entry->skb->data; | 571 | return (__le32 *) entry->skb->data; |
573 | |||
574 | rt2800_write_txwi(txwi, txdesc); | ||
575 | } | 572 | } |
576 | 573 | ||
577 | |||
578 | static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 574 | static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
579 | struct sk_buff *skb, | 575 | struct sk_buff *skb, |
580 | struct txentry_desc *txdesc) | 576 | struct txentry_desc *txdesc) |
@@ -728,110 +724,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, | |||
728 | /* | 724 | /* |
729 | * Interrupt functions. | 725 | * Interrupt functions. |
730 | */ | 726 | */ |
731 | static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | ||
732 | { | ||
733 | struct data_queue *queue; | ||
734 | struct queue_entry *entry; | ||
735 | __le32 *txwi; | ||
736 | struct txdone_entry_desc txdesc; | ||
737 | u32 word; | ||
738 | u32 reg; | ||
739 | int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; | ||
740 | u16 mcs, real_mcs; | ||
741 | int i; | ||
742 | |||
743 | /* | ||
744 | * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO | ||
745 | * at most X times and also stop processing once the TX_STA_FIFO_VALID | ||
746 | * flag is not set anymore. | ||
747 | * | ||
748 | * The legacy drivers use X=TX_RING_SIZE but state in a comment | ||
749 | * that the TX_STA_FIFO stack has a size of 16. We stick to our | ||
750 | * tx ring size for now. | ||
751 | */ | ||
752 | for (i = 0; i < TX_ENTRIES; i++) { | ||
753 | rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); | ||
754 | if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) | ||
755 | break; | ||
756 | |||
757 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
758 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
759 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
760 | |||
761 | /* | ||
762 | * Skip this entry when it contains an invalid | ||
763 | * queue identication number. | ||
764 | */ | ||
765 | if (pid <= 0 || pid > QID_RX) | ||
766 | continue; | ||
767 | |||
768 | queue = rt2x00queue_get_queue(rt2x00dev, pid - 1); | ||
769 | if (unlikely(!queue)) | ||
770 | continue; | ||
771 | |||
772 | /* | ||
773 | * Inside each queue, we process each entry in a chronological | ||
774 | * order. We first check that the queue is not empty. | ||
775 | */ | ||
776 | if (rt2x00queue_empty(queue)) | ||
777 | continue; | ||
778 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
779 | |||
780 | /* Check if we got a match by looking at WCID/ACK/PID | ||
781 | * fields */ | ||
782 | txwi = (__le32 *) entry->skb->data; | ||
783 | |||
784 | rt2x00_desc_read(txwi, 1, &word); | ||
785 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | ||
786 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | ||
787 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
788 | |||
789 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) | ||
790 | WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n"); | ||
791 | |||
792 | /* | ||
793 | * Obtain the status about this packet. | ||
794 | */ | ||
795 | txdesc.flags = 0; | ||
796 | rt2x00_desc_read(txwi, 0, &word); | ||
797 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); | ||
798 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); | ||
799 | |||
800 | /* | ||
801 | * Ralink has a retry mechanism using a global fallback | ||
802 | * table. We setup this fallback table to try the immediate | ||
803 | * lower rate for all rates. In the TX_STA_FIFO, the MCS field | ||
804 | * always contains the MCS used for the last transmission, be | ||
805 | * it successful or not. | ||
806 | */ | ||
807 | if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) { | ||
808 | /* | ||
809 | * Transmission succeeded. The number of retries is | ||
810 | * mcs - real_mcs | ||
811 | */ | ||
812 | __set_bit(TXDONE_SUCCESS, &txdesc.flags); | ||
813 | txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); | ||
814 | } else { | ||
815 | /* | ||
816 | * Transmission failed. The number of retries is | ||
817 | * always 7 in this case (for a total number of 8 | ||
818 | * frames sent). | ||
819 | */ | ||
820 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | ||
821 | txdesc.retry = 7; | ||
822 | } | ||
823 | |||
824 | /* | ||
825 | * the frame was retried at least once | ||
826 | * -> hw used fallback rates | ||
827 | */ | ||
828 | if (txdesc.retry) | ||
829 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | ||
830 | |||
831 | rt2x00lib_txdone(entry, &txdesc); | ||
832 | } | ||
833 | } | ||
834 | |||
835 | static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) | 727 | static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) |
836 | { | 728 | { |
837 | struct ieee80211_conf conf = { .flags = 0 }; | 729 | struct ieee80211_conf conf = { .flags = 0 }; |
@@ -867,7 +759,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) | |||
867 | * 4 - Tx done interrupt. | 759 | * 4 - Tx done interrupt. |
868 | */ | 760 | */ |
869 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) | 761 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) |
870 | rt2800pci_txdone(rt2x00dev); | 762 | rt2800_txdone(rt2x00dev); |
871 | 763 | ||
872 | /* | 764 | /* |
873 | * 5 - Auto wakeup interrupt. | 765 | * 5 - Auto wakeup interrupt. |
@@ -1011,6 +903,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { | |||
1011 | .regbusy_read = rt2x00pci_regbusy_read, | 903 | .regbusy_read = rt2x00pci_regbusy_read, |
1012 | .drv_write_firmware = rt2800pci_write_firmware, | 904 | .drv_write_firmware = rt2800pci_write_firmware, |
1013 | .drv_init_registers = rt2800pci_init_registers, | 905 | .drv_init_registers = rt2800pci_init_registers, |
906 | .drv_get_txwi = rt2800pci_get_txwi, | ||
1014 | }; | 907 | }; |
1015 | 908 | ||
1016 | static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | 909 | static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { |
@@ -1030,7 +923,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | |||
1030 | .reset_tuner = rt2800_reset_tuner, | 923 | .reset_tuner = rt2800_reset_tuner, |
1031 | .link_tuner = rt2800_link_tuner, | 924 | .link_tuner = rt2800_link_tuner, |
1032 | .write_tx_desc = rt2800pci_write_tx_desc, | 925 | .write_tx_desc = rt2800pci_write_tx_desc, |
1033 | .write_tx_data = rt2800pci_write_tx_data, | 926 | .write_tx_data = rt2800_write_tx_data, |
1034 | .write_beacon = rt2800_write_beacon, | 927 | .write_beacon = rt2800_write_beacon, |
1035 | .kick_tx_queue = rt2800pci_kick_tx_queue, | 928 | .kick_tx_queue = rt2800pci_kick_tx_queue, |
1036 | .kill_tx_queue = rt2800pci_kill_tx_queue, | 929 | .kill_tx_queue = rt2800pci_kill_tx_queue, |