diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 166 |
1 files changed, 36 insertions, 130 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index f08b6a37bf2d..7d4778d66e77 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -616,67 +616,13 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
616 | static int rt2800pci_write_tx_data(struct queue_entry* entry, | 616 | static int rt2800pci_write_tx_data(struct queue_entry* entry, |
617 | struct txentry_desc *txdesc) | 617 | struct txentry_desc *txdesc) |
618 | { | 618 | { |
619 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
620 | struct sk_buff *skb = entry->skb; | ||
621 | struct skb_frame_desc *skbdesc; | ||
622 | int ret; | 619 | int ret; |
623 | __le32 *txwi; | ||
624 | u32 word; | ||
625 | 620 | ||
626 | ret = rt2x00pci_write_tx_data(entry, txdesc); | 621 | ret = rt2x00pci_write_tx_data(entry, txdesc); |
627 | if (ret) | 622 | if (ret) |
628 | return ret; | 623 | return ret; |
629 | 624 | ||
630 | skbdesc = get_skb_frame_desc(skb); | 625 | rt2800_write_txwi(entry->skb, txdesc); |
631 | txwi = (__le32 *)(skb->data - rt2x00dev->ops->extra_tx_headroom); | ||
632 | |||
633 | /* | ||
634 | * Initialize TX Info descriptor | ||
635 | */ | ||
636 | rt2x00_desc_read(txwi, 0, &word); | ||
637 | rt2x00_set_field32(&word, TXWI_W0_FRAG, | ||
638 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); | ||
639 | rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0); | ||
640 | rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0); | ||
641 | rt2x00_set_field32(&word, TXWI_W0_TS, | ||
642 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | ||
643 | rt2x00_set_field32(&word, TXWI_W0_AMPDU, | ||
644 | test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags)); | ||
645 | rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density); | ||
646 | rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->ifs); | ||
647 | rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs); | ||
648 | rt2x00_set_field32(&word, TXWI_W0_BW, | ||
649 | test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags)); | ||
650 | rt2x00_set_field32(&word, TXWI_W0_SHORT_GI, | ||
651 | test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags)); | ||
652 | rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc); | ||
653 | rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode); | ||
654 | rt2x00_desc_write(txwi, 0, word); | ||
655 | |||
656 | rt2x00_desc_read(txwi, 1, &word); | ||
657 | rt2x00_set_field32(&word, TXWI_W1_ACK, | ||
658 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); | ||
659 | rt2x00_set_field32(&word, TXWI_W1_NSEQ, | ||
660 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); | ||
661 | rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size); | ||
662 | rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, | ||
663 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? | ||
664 | txdesc->key_idx : 0xff); | ||
665 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | ||
666 | txdesc->length); | ||
667 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, | ||
668 | skbdesc->entry->queue->qid + 1); | ||
669 | rt2x00_desc_write(txwi, 1, word); | ||
670 | |||
671 | /* | ||
672 | * Always write 0 to IV/EIV fields, hardware will insert the IV | ||
673 | * from the IVEIV register when TXD_W3_WIV is set to 0. | ||
674 | * When TXD_W3_WIV is set to 1 it will use the IV data | ||
675 | * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which | ||
676 | * crypto entry in the registers should be used to encrypt the frame. | ||
677 | */ | ||
678 | _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); | ||
679 | _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); | ||
680 | 626 | ||
681 | return 0; | 627 | return 0; |
682 | } | 628 | } |
@@ -732,10 +678,10 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
732 | /* | 678 | /* |
733 | * TX data initialization | 679 | * TX data initialization |
734 | */ | 680 | */ |
735 | static void rt2800pci_write_beacon(struct queue_entry *entry) | 681 | static void rt2800pci_write_beacon(struct queue_entry *entry, |
682 | struct txentry_desc *txdesc) | ||
736 | { | 683 | { |
737 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 684 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
738 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
739 | unsigned int beacon_base; | 685 | unsigned int beacon_base; |
740 | u32 reg; | 686 | u32 reg; |
741 | 687 | ||
@@ -748,15 +694,25 @@ static void rt2800pci_write_beacon(struct queue_entry *entry) | |||
748 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 694 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
749 | 695 | ||
750 | /* | 696 | /* |
751 | * Write entire beacon with descriptor to register. | 697 | * Add the TXWI for the beacon to the skb. |
698 | */ | ||
699 | rt2800_write_txwi(entry->skb, txdesc); | ||
700 | skb_push(entry->skb, TXWI_DESC_SIZE); | ||
701 | |||
702 | /* | ||
703 | * Write entire beacon with TXWI to register. | ||
752 | */ | 704 | */ |
753 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 705 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
754 | rt2800_register_multiwrite(rt2x00dev, | 706 | rt2800_register_multiwrite(rt2x00dev, beacon_base, |
755 | beacon_base, | 707 | entry->skb->data, entry->skb->len); |
756 | skbdesc->desc, skbdesc->desc_len); | 708 | |
757 | rt2800_register_multiwrite(rt2x00dev, | 709 | /* |
758 | beacon_base + skbdesc->desc_len, | 710 | * Enable beaconing again. |
759 | entry->skb->data, entry->skb->len); | 711 | */ |
712 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
713 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
714 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
715 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
760 | 716 | ||
761 | /* | 717 | /* |
762 | * Clean up beacon skb. | 718 | * Clean up beacon skb. |
@@ -770,18 +726,6 @@ static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
770 | { | 726 | { |
771 | struct data_queue *queue; | 727 | struct data_queue *queue; |
772 | unsigned int idx, qidx = 0; | 728 | unsigned int idx, qidx = 0; |
773 | u32 reg; | ||
774 | |||
775 | if (queue_idx == QID_BEACON) { | ||
776 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
777 | if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) { | ||
778 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
779 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
780 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
781 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
782 | } | ||
783 | return; | ||
784 | } | ||
785 | 729 | ||
786 | if (queue_idx > QID_HCCA && queue_idx != QID_MGMT) | 730 | if (queue_idx > QID_HCCA && queue_idx != QID_MGMT) |
787 | return; | 731 | return; |
@@ -824,34 +768,21 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, | |||
824 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 768 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
825 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 769 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
826 | __le32 *rxd = entry_priv->desc; | 770 | __le32 *rxd = entry_priv->desc; |
827 | __le32 *rxwi = (__le32 *)entry->skb->data; | 771 | u32 word; |
828 | u32 rxd3; | 772 | |
829 | u32 rxwi0; | 773 | rt2x00_desc_read(rxd, 3, &word); |
830 | u32 rxwi1; | 774 | |
831 | u32 rxwi2; | 775 | if (rt2x00_get_field32(word, RXD_W3_CRC_ERROR)) |
832 | u32 rxwi3; | ||
833 | |||
834 | rt2x00_desc_read(rxd, 3, &rxd3); | ||
835 | rt2x00_desc_read(rxwi, 0, &rxwi0); | ||
836 | rt2x00_desc_read(rxwi, 1, &rxwi1); | ||
837 | rt2x00_desc_read(rxwi, 2, &rxwi2); | ||
838 | rt2x00_desc_read(rxwi, 3, &rxwi3); | ||
839 | |||
840 | if (rt2x00_get_field32(rxd3, RXD_W3_CRC_ERROR)) | ||
841 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 776 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
842 | 777 | ||
843 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | 778 | /* |
844 | /* | 779 | * Unfortunately we don't know the cipher type used during |
845 | * Unfortunately we don't know the cipher type used during | 780 | * decryption. This prevents us from correct providing |
846 | * decryption. This prevents us from correct providing | 781 | * correct statistics through debugfs. |
847 | * correct statistics through debugfs. | 782 | */ |
848 | */ | 783 | rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W3_CIPHER_ERROR); |
849 | rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); | ||
850 | rxdesc->cipher_status = | ||
851 | rt2x00_get_field32(rxd3, RXD_W3_CIPHER_ERROR); | ||
852 | } | ||
853 | 784 | ||
854 | if (rt2x00_get_field32(rxd3, RXD_W3_DECRYPTED)) { | 785 | if (rt2x00_get_field32(word, RXD_W3_DECRYPTED)) { |
855 | /* | 786 | /* |
856 | * Hardware has stripped IV/EIV data from 802.11 frame during | 787 | * Hardware has stripped IV/EIV data from 802.11 frame during |
857 | * decryption. Unfortunately the descriptor doesn't contain | 788 | * decryption. Unfortunately the descriptor doesn't contain |
@@ -866,47 +797,22 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, | |||
866 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; | 797 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; |
867 | } | 798 | } |
868 | 799 | ||
869 | if (rt2x00_get_field32(rxd3, RXD_W3_MY_BSS)) | 800 | if (rt2x00_get_field32(word, RXD_W3_MY_BSS)) |
870 | rxdesc->dev_flags |= RXDONE_MY_BSS; | 801 | rxdesc->dev_flags |= RXDONE_MY_BSS; |
871 | 802 | ||
872 | if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD)) | 803 | if (rt2x00_get_field32(word, RXD_W3_L2PAD)) |
873 | rxdesc->dev_flags |= RXDONE_L2PAD; | 804 | rxdesc->dev_flags |= RXDONE_L2PAD; |
874 | 805 | ||
875 | if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI)) | ||
876 | rxdesc->flags |= RX_FLAG_SHORT_GI; | ||
877 | |||
878 | if (rt2x00_get_field32(rxwi1, RXWI_W1_BW)) | ||
879 | rxdesc->flags |= RX_FLAG_40MHZ; | ||
880 | |||
881 | /* | ||
882 | * Detect RX rate, always use MCS as signal type. | ||
883 | */ | ||
884 | rxdesc->dev_flags |= RXDONE_SIGNAL_MCS; | ||
885 | rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE); | ||
886 | rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS); | ||
887 | |||
888 | /* | 806 | /* |
889 | * Mask of 0x8 bit to remove the short preamble flag. | 807 | * Process the RXWI structure that is at the start of the buffer. |
890 | */ | 808 | */ |
891 | if (rxdesc->rate_mode == RATE_MODE_CCK) | 809 | rt2800_process_rxwi(entry->skb, rxdesc); |
892 | rxdesc->signal &= ~0x8; | ||
893 | |||
894 | rxdesc->rssi = | ||
895 | (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) + | ||
896 | rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2; | ||
897 | |||
898 | rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT); | ||
899 | 810 | ||
900 | /* | 811 | /* |
901 | * Set RX IDX in register to inform hardware that we have handled | 812 | * Set RX IDX in register to inform hardware that we have handled |
902 | * this entry and it is available for reuse again. | 813 | * this entry and it is available for reuse again. |
903 | */ | 814 | */ |
904 | rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx); | 815 | rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx); |
905 | |||
906 | /* | ||
907 | * Remove TXWI descriptor from start of buffer. | ||
908 | */ | ||
909 | skb_pull(entry->skb, RXWI_DESC_SIZE); | ||
910 | } | 816 | } |
911 | 817 | ||
912 | /* | 818 | /* |