diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 418 |
1 files changed, 19 insertions, 399 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index ce2e893856c..b1d63935f44 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -1,5 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> | ||
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | ||
5 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> | ||
6 | Copyright (C) 2009 Axel Kollhofer <rain_maker@root-forum.org> | ||
3 | <http://rt2x00.serialmonkey.com> | 7 | <http://rt2x00.serialmonkey.com> |
4 | 8 | ||
5 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
@@ -594,16 +598,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
594 | rt2x00_desc_read(rxwi, 2, &rxwi2); | 598 | rt2x00_desc_read(rxwi, 2, &rxwi2); |
595 | rt2x00_desc_read(rxwi, 3, &rxwi3); | 599 | rt2x00_desc_read(rxwi, 3, &rxwi3); |
596 | 600 | ||
597 | if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR)) | 601 | if (rt2x00_get_field32(rxd0, RXINFO_W0_CRC_ERROR)) |
598 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 602 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
599 | 603 | ||
600 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | 604 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { |
601 | rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); | 605 | rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); |
602 | rxdesc->cipher_status = | 606 | rxdesc->cipher_status = |
603 | rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR); | 607 | rt2x00_get_field32(rxd0, RXINFO_W0_CIPHER_ERROR); |
604 | } | 608 | } |
605 | 609 | ||
606 | if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) { | 610 | if (rt2x00_get_field32(rxd0, RXINFO_W0_DECRYPTED)) { |
607 | /* | 611 | /* |
608 | * Hardware has stripped IV/EIV data from 802.11 frame during | 612 | * Hardware has stripped IV/EIV data from 802.11 frame during |
609 | * decryption. Unfortunately the descriptor doesn't contain | 613 | * decryption. Unfortunately the descriptor doesn't contain |
@@ -618,10 +622,10 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
618 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; | 622 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; |
619 | } | 623 | } |
620 | 624 | ||
621 | if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS)) | 625 | if (rt2x00_get_field32(rxd0, RXINFO_W0_MY_BSS)) |
622 | rxdesc->dev_flags |= RXDONE_MY_BSS; | 626 | rxdesc->dev_flags |= RXDONE_MY_BSS; |
623 | 627 | ||
624 | if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) { | 628 | if (rt2x00_get_field32(rxd0, RXINFO_W0_L2PAD)) { |
625 | rxdesc->dev_flags |= RXDONE_L2PAD; | 629 | rxdesc->dev_flags |= RXDONE_L2PAD; |
626 | skbdesc->flags |= SKBDESC_L2_PADDED; | 630 | skbdesc->flags |= SKBDESC_L2_PADDED; |
627 | } | 631 | } |
@@ -667,400 +671,18 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
667 | */ | 671 | */ |
668 | static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | 672 | static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) |
669 | { | 673 | { |
670 | u16 word; | 674 | if (rt2800_efuse_detect(rt2x00dev)) |
671 | u8 *mac; | 675 | rt2800_read_eeprom_efuse(rt2x00dev); |
672 | u8 default_lna_gain; | 676 | else |
673 | 677 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, | |
674 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); | 678 | EEPROM_SIZE); |
675 | |||
676 | /* | ||
677 | * Start validation of the data that has been read. | ||
678 | */ | ||
679 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
680 | if (!is_valid_ether_addr(mac)) { | ||
681 | random_ether_addr(mac); | ||
682 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | ||
683 | } | ||
684 | |||
685 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
686 | if (word == 0xffff) { | ||
687 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | ||
688 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1); | ||
689 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820); | ||
690 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
691 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | ||
692 | } else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) { | ||
693 | /* | ||
694 | * There is a max of 2 RX streams for RT2870 series | ||
695 | */ | ||
696 | if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2) | ||
697 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | ||
698 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
699 | } | ||
700 | |||
701 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | ||
702 | if (word == 0xffff) { | ||
703 | rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0); | ||
704 | rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0); | ||
705 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); | ||
706 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); | ||
707 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | ||
708 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0); | ||
709 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0); | ||
710 | rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0); | ||
711 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0); | ||
712 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0); | ||
713 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | ||
714 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | ||
715 | } | ||
716 | |||
717 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | ||
718 | if ((word & 0x00ff) == 0x00ff) { | ||
719 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | ||
720 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, | ||
721 | LED_MODE_TXRX_ACTIVITY); | ||
722 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); | ||
723 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | ||
724 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555); | ||
725 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221); | ||
726 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8); | ||
727 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | ||
728 | } | ||
729 | |||
730 | /* | ||
731 | * During the LNA validation we are going to use | ||
732 | * lna0 as correct value. Note that EEPROM_LNA | ||
733 | * is never validated. | ||
734 | */ | ||
735 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word); | ||
736 | default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0); | ||
737 | |||
738 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word); | ||
739 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10) | ||
740 | rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0); | ||
741 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10) | ||
742 | rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0); | ||
743 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word); | ||
744 | |||
745 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); | ||
746 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) | ||
747 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); | ||
748 | if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || | ||
749 | rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) | ||
750 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, | ||
751 | default_lna_gain); | ||
752 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word); | ||
753 | |||
754 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word); | ||
755 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10) | ||
756 | rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0); | ||
757 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10) | ||
758 | rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0); | ||
759 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word); | ||
760 | |||
761 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word); | ||
762 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) | ||
763 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); | ||
764 | if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || | ||
765 | rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) | ||
766 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, | ||
767 | default_lna_gain); | ||
768 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); | ||
769 | |||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static int rt2800usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
774 | { | ||
775 | u32 reg; | ||
776 | u16 value; | ||
777 | u16 eeprom; | ||
778 | |||
779 | /* | ||
780 | * Read EEPROM word for configuration. | ||
781 | */ | ||
782 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
783 | |||
784 | /* | ||
785 | * Identify RF chipset. | ||
786 | */ | ||
787 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
788 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
789 | rt2x00_set_chip(rt2x00dev, RT2870, value, reg); | ||
790 | |||
791 | /* | ||
792 | * The check for rt2860 is not a typo, some rt2870 hardware | ||
793 | * identifies itself as rt2860 in the CSR register. | ||
794 | */ | ||
795 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28600000) && | ||
796 | !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28700000) && | ||
797 | !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28800000) && | ||
798 | !rt2x00_check_rev(&rt2x00dev->chip, 0xffff0000, 0x30700000)) { | ||
799 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | ||
800 | return -ENODEV; | ||
801 | } | ||
802 | |||
803 | if (!rt2x00_rf(&rt2x00dev->chip, RF2820) && | ||
804 | !rt2x00_rf(&rt2x00dev->chip, RF2850) && | ||
805 | !rt2x00_rf(&rt2x00dev->chip, RF2720) && | ||
806 | !rt2x00_rf(&rt2x00dev->chip, RF2750) && | ||
807 | !rt2x00_rf(&rt2x00dev->chip, RF3020) && | ||
808 | !rt2x00_rf(&rt2x00dev->chip, RF2020)) { | ||
809 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
810 | return -ENODEV; | ||
811 | } | ||
812 | |||
813 | /* | ||
814 | * Identify default antenna configuration. | ||
815 | */ | ||
816 | rt2x00dev->default_ant.tx = | ||
817 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH); | ||
818 | rt2x00dev->default_ant.rx = | ||
819 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH); | ||
820 | |||
821 | /* | ||
822 | * Read frequency offset and RF programming sequence. | ||
823 | */ | ||
824 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
825 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | ||
826 | |||
827 | /* | ||
828 | * Read external LNA informations. | ||
829 | */ | ||
830 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
831 | |||
832 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) | ||
833 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
834 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) | ||
835 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
836 | |||
837 | /* | ||
838 | * Detect if this device has an hardware controlled radio. | ||
839 | */ | ||
840 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO)) | ||
841 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
842 | |||
843 | /* | ||
844 | * Store led settings, for correct led behaviour. | ||
845 | */ | ||
846 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
847 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); | ||
848 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); | ||
849 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); | ||
850 | |||
851 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, | ||
852 | &rt2x00dev->led_mcu_reg); | ||
853 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
854 | |||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | /* | ||
859 | * RF value list for rt2870 | ||
860 | * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750) | ||
861 | */ | ||
862 | static const struct rf_channel rf_vals[] = { | ||
863 | { 1, 0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b }, | ||
864 | { 2, 0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f }, | ||
865 | { 3, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b }, | ||
866 | { 4, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f }, | ||
867 | { 5, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b }, | ||
868 | { 6, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f }, | ||
869 | { 7, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b }, | ||
870 | { 8, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f }, | ||
871 | { 9, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b }, | ||
872 | { 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f }, | ||
873 | { 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b }, | ||
874 | { 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f }, | ||
875 | { 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b }, | ||
876 | { 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 }, | ||
877 | |||
878 | /* 802.11 UNI / HyperLan 2 */ | ||
879 | { 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 }, | ||
880 | { 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 }, | ||
881 | { 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 }, | ||
882 | { 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 }, | ||
883 | { 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b }, | ||
884 | { 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b }, | ||
885 | { 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 }, | ||
886 | { 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 }, | ||
887 | { 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b }, | ||
888 | { 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 }, | ||
889 | { 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 }, | ||
890 | { 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 }, | ||
891 | |||
892 | /* 802.11 HyperLan 2 */ | ||
893 | { 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 }, | ||
894 | { 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 }, | ||
895 | { 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 }, | ||
896 | { 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 }, | ||
897 | { 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 }, | ||
898 | { 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b }, | ||
899 | { 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 }, | ||
900 | { 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 }, | ||
901 | { 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 }, | ||
902 | { 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 }, | ||
903 | { 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b }, | ||
904 | { 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 }, | ||
905 | { 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b }, | ||
906 | { 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 }, | ||
907 | { 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b }, | ||
908 | { 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 }, | ||
909 | |||
910 | /* 802.11 UNII */ | ||
911 | { 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 }, | ||
912 | { 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 }, | ||
913 | { 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f }, | ||
914 | { 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f }, | ||
915 | { 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 }, | ||
916 | { 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 }, | ||
917 | { 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 }, | ||
918 | { 167, 0x18402ec4, 0x184c03d2, 0x18179855, 0x1815531f }, | ||
919 | { 169, 0x18402ec4, 0x184c03d2, 0x18179855, 0x18155327 }, | ||
920 | { 171, 0x18402ec4, 0x184c03d6, 0x18179855, 0x18155307 }, | ||
921 | { 173, 0x18402ec4, 0x184c03d6, 0x18179855, 0x1815530f }, | ||
922 | |||
923 | /* 802.11 Japan */ | ||
924 | { 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b }, | ||
925 | { 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 }, | ||
926 | { 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b }, | ||
927 | { 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 }, | ||
928 | { 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 }, | ||
929 | { 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b }, | ||
930 | { 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 }, | ||
931 | }; | ||
932 | |||
933 | /* | ||
934 | * RF value list for rt3070 | ||
935 | * Supports: 2.4 GHz | ||
936 | */ | ||
937 | static const struct rf_channel rf_vals_3070[] = { | ||
938 | {1, 241, 2, 2 }, | ||
939 | {2, 241, 2, 7 }, | ||
940 | {3, 242, 2, 2 }, | ||
941 | {4, 242, 2, 7 }, | ||
942 | {5, 243, 2, 2 }, | ||
943 | {6, 243, 2, 7 }, | ||
944 | {7, 244, 2, 2 }, | ||
945 | {8, 244, 2, 7 }, | ||
946 | {9, 245, 2, 2 }, | ||
947 | {10, 245, 2, 7 }, | ||
948 | {11, 246, 2, 2 }, | ||
949 | {12, 246, 2, 7 }, | ||
950 | {13, 247, 2, 2 }, | ||
951 | {14, 248, 2, 4 }, | ||
952 | }; | ||
953 | |||
954 | static int rt2800usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
955 | { | ||
956 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
957 | struct channel_info *info; | ||
958 | char *tx_power1; | ||
959 | char *tx_power2; | ||
960 | unsigned int i; | ||
961 | u16 eeprom; | ||
962 | |||
963 | /* | ||
964 | * Initialize all hw fields. | ||
965 | */ | ||
966 | rt2x00dev->hw->flags = | ||
967 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
968 | IEEE80211_HW_SIGNAL_DBM | | ||
969 | IEEE80211_HW_SUPPORTS_PS | | ||
970 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
971 | rt2x00dev->hw->extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; | ||
972 | |||
973 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | ||
974 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
975 | rt2x00_eeprom_addr(rt2x00dev, | ||
976 | EEPROM_MAC_ADDR_0)); | ||
977 | |||
978 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
979 | |||
980 | /* | ||
981 | * Initialize HT information. | ||
982 | */ | ||
983 | spec->ht.ht_supported = true; | ||
984 | spec->ht.cap = | ||
985 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
986 | IEEE80211_HT_CAP_GRN_FLD | | ||
987 | IEEE80211_HT_CAP_SGI_20 | | ||
988 | IEEE80211_HT_CAP_SGI_40 | | ||
989 | IEEE80211_HT_CAP_TX_STBC | | ||
990 | IEEE80211_HT_CAP_RX_STBC | | ||
991 | IEEE80211_HT_CAP_PSMP_SUPPORT; | ||
992 | spec->ht.ampdu_factor = 3; | ||
993 | spec->ht.ampdu_density = 4; | ||
994 | spec->ht.mcs.tx_params = | ||
995 | IEEE80211_HT_MCS_TX_DEFINED | | ||
996 | IEEE80211_HT_MCS_TX_RX_DIFF | | ||
997 | ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) << | ||
998 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
999 | |||
1000 | switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) { | ||
1001 | case 3: | ||
1002 | spec->ht.mcs.rx_mask[2] = 0xff; | ||
1003 | case 2: | ||
1004 | spec->ht.mcs.rx_mask[1] = 0xff; | ||
1005 | case 1: | ||
1006 | spec->ht.mcs.rx_mask[0] = 0xff; | ||
1007 | spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */ | ||
1008 | break; | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * Initialize hw_mode information. | ||
1013 | */ | ||
1014 | spec->supported_bands = SUPPORT_BAND_2GHZ; | ||
1015 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; | ||
1016 | |||
1017 | if (rt2x00_rf(&rt2x00dev->chip, RF2820) || | ||
1018 | rt2x00_rf(&rt2x00dev->chip, RF2720)) { | ||
1019 | spec->num_channels = 14; | ||
1020 | spec->channels = rf_vals; | ||
1021 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2850) || | ||
1022 | rt2x00_rf(&rt2x00dev->chip, RF2750)) { | ||
1023 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1024 | spec->num_channels = ARRAY_SIZE(rf_vals); | ||
1025 | spec->channels = rf_vals; | ||
1026 | } else if (rt2x00_rf(&rt2x00dev->chip, RF3020) || | ||
1027 | rt2x00_rf(&rt2x00dev->chip, RF2020)) { | ||
1028 | spec->num_channels = ARRAY_SIZE(rf_vals_3070); | ||
1029 | spec->channels = rf_vals_3070; | ||
1030 | } | ||
1031 | |||
1032 | /* | ||
1033 | * Create channel information array | ||
1034 | */ | ||
1035 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | ||
1036 | if (!info) | ||
1037 | return -ENOMEM; | ||
1038 | |||
1039 | spec->channels_info = info; | ||
1040 | |||
1041 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | ||
1042 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | ||
1043 | |||
1044 | for (i = 0; i < 14; i++) { | ||
1045 | info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); | ||
1046 | info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); | ||
1047 | } | ||
1048 | |||
1049 | if (spec->num_channels > 14) { | ||
1050 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | ||
1051 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | ||
1052 | |||
1053 | for (i = 14; i < spec->num_channels; i++) { | ||
1054 | info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); | ||
1055 | info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); | ||
1056 | } | ||
1057 | } | ||
1058 | 679 | ||
1059 | return 0; | 680 | return rt2800_validate_eeprom(rt2x00dev); |
1060 | } | 681 | } |
1061 | 682 | ||
1062 | static const struct rt2800_ops rt2800usb_rt2800_ops = { | 683 | static const struct rt2800_ops rt2800usb_rt2800_ops = { |
1063 | .register_read = rt2x00usb_register_read, | 684 | .register_read = rt2x00usb_register_read, |
685 | .register_read_lock = rt2x00usb_register_read_lock, | ||
1064 | .register_write = rt2x00usb_register_write, | 686 | .register_write = rt2x00usb_register_write, |
1065 | .register_write_lock = rt2x00usb_register_write_lock, | 687 | .register_write_lock = rt2x00usb_register_write_lock, |
1066 | 688 | ||
@@ -1074,8 +696,6 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1074 | { | 696 | { |
1075 | int retval; | 697 | int retval; |
1076 | 698 | ||
1077 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB); | ||
1078 | |||
1079 | rt2x00dev->priv = (void *)&rt2800usb_rt2800_ops; | 699 | rt2x00dev->priv = (void *)&rt2800usb_rt2800_ops; |
1080 | 700 | ||
1081 | /* | 701 | /* |
@@ -1085,14 +705,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1085 | if (retval) | 705 | if (retval) |
1086 | return retval; | 706 | return retval; |
1087 | 707 | ||
1088 | retval = rt2800usb_init_eeprom(rt2x00dev); | 708 | retval = rt2800_init_eeprom(rt2x00dev); |
1089 | if (retval) | 709 | if (retval) |
1090 | return retval; | 710 | return retval; |
1091 | 711 | ||
1092 | /* | 712 | /* |
1093 | * Initialize hw specifications. | 713 | * Initialize hw specifications. |
1094 | */ | 714 | */ |
1095 | retval = rt2800usb_probe_hw_mode(rt2x00dev); | 715 | retval = rt2800_probe_hw_mode(rt2x00dev); |
1096 | if (retval) | 716 | if (retval) |
1097 | return retval; | 717 | return retval; |
1098 | 718 | ||