diff options
-rw-r--r-- | drivers/net/wireless/b43/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/wireless/b43/b43.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy.c | 613 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/b43/tables.c | 101 | ||||
-rw-r--r-- | drivers/net/wireless/b43/tables.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/b43/wa.c | 668 | ||||
-rw-r--r-- | drivers/net/wireless/b43/wa.h | 7 |
9 files changed, 914 insertions, 513 deletions
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 485e59e2dfab..dc270474b33c 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile | |||
@@ -5,6 +5,7 @@ b43-y += phy.o | |||
5 | b43-y += sysfs.o | 5 | b43-y += sysfs.o |
6 | b43-y += xmit.o | 6 | b43-y += xmit.o |
7 | b43-y += lo.o | 7 | b43-y += lo.o |
8 | b43-y += wa.o | ||
8 | # b43 RFKILL button support | 9 | # b43 RFKILL button support |
9 | b43-$(CONFIG_B43_RFKILL) += rfkill.o | 10 | b43-$(CONFIG_B43_RFKILL) += rfkill.o |
10 | # b43 LED support | 11 | # b43 LED support |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 7b6fc1ab2b90..e892ec6f6372 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -544,6 +544,10 @@ struct b43_phy { | |||
544 | u16 lofcal; | 544 | u16 lofcal; |
545 | 545 | ||
546 | u16 initval; //FIXME rename? | 546 | u16 initval; //FIXME rename? |
547 | |||
548 | /* OFDM address read/write caching for hardware auto-increment. */ | ||
549 | u16 ofdm_addr; | ||
550 | u8 ofdm_valid; /* 0: invalid, 1: read, 2: write */ | ||
547 | }; | 551 | }; |
548 | 552 | ||
549 | /* Data structures for DMA transmission, per 80211 core. */ | 553 | /* Data structures for DMA transmission, per 80211 core. */ |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 4373ec903ad1..979e82267d0d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -2254,6 +2254,9 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
2254 | b43_write16(dev, B43_MMIO_POWERUP_DELAY, | 2254 | b43_write16(dev, B43_MMIO_POWERUP_DELAY, |
2255 | dev->dev->bus->chipco.fast_pwrup_delay); | 2255 | dev->dev->bus->chipco.fast_pwrup_delay); |
2256 | 2256 | ||
2257 | /* OFDM address caching. */ | ||
2258 | phy->ofdm_valid = 0; | ||
2259 | |||
2257 | err = 0; | 2260 | err = 0; |
2258 | b43dbg(dev->wl, "Chip initialized\n"); | 2261 | b43dbg(dev->wl, "Chip initialized\n"); |
2259 | out: | 2262 | out: |
diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c index 7ff091e69f05..cc0208e27b9f 100644 --- a/drivers/net/wireless/b43/phy.c +++ b/drivers/net/wireless/b43/phy.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include "main.h" | 34 | #include "main.h" |
35 | #include "tables.h" | 35 | #include "tables.h" |
36 | #include "lo.h" | 36 | #include "lo.h" |
37 | #include "wa.h" | ||
38 | |||
37 | 39 | ||
38 | static const s8 b43_tssi2dbm_b_table[] = { | 40 | static const s8 b43_tssi2dbm_b_table[] = { |
39 | 0x4D, 0x4C, 0x4B, 0x4A, | 41 | 0x4D, 0x4C, 0x4B, 0x4A, |
@@ -303,8 +305,6 @@ void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val) | |||
303 | b43_write16(dev, B43_MMIO_PHY_DATA, val); | 305 | b43_write16(dev, B43_MMIO_PHY_DATA, val); |
304 | } | 306 | } |
305 | 307 | ||
306 | static void b43_radio_set_txpower_a(struct b43_wldev *dev, u16 txpower); | ||
307 | |||
308 | /* Adjust the transmission power output (G-PHY) */ | 308 | /* Adjust the transmission power output (G-PHY) */ |
309 | void b43_set_txpower_g(struct b43_wldev *dev, | 309 | void b43_set_txpower_g(struct b43_wldev *dev, |
310 | const struct b43_bbatt *bbatt, | 310 | const struct b43_bbatt *bbatt, |
@@ -763,366 +763,96 @@ static void b43_phy_init_pctl(struct b43_wldev *dev) | |||
763 | b43_shm_clear_tssi(dev); | 763 | b43_shm_clear_tssi(dev); |
764 | } | 764 | } |
765 | 765 | ||
766 | static void b43_phy_agcsetup(struct b43_wldev *dev) | 766 | static void b43_phy_rssiagc(struct b43_wldev *dev, u8 enable) |
767 | { | ||
768 | struct b43_phy *phy = &dev->phy; | ||
769 | u16 offset = 0x0000; | ||
770 | |||
771 | if (phy->rev == 1) | ||
772 | offset = 0x4C00; | ||
773 | |||
774 | b43_ofdmtab_write16(dev, offset, 0, 0x00FE); | ||
775 | b43_ofdmtab_write16(dev, offset, 1, 0x000D); | ||
776 | b43_ofdmtab_write16(dev, offset, 2, 0x0013); | ||
777 | b43_ofdmtab_write16(dev, offset, 3, 0x0019); | ||
778 | |||
779 | if (phy->rev == 1) { | ||
780 | b43_ofdmtab_write16(dev, 0x1800, 0, 0x2710); | ||
781 | b43_ofdmtab_write16(dev, 0x1801, 0, 0x9B83); | ||
782 | b43_ofdmtab_write16(dev, 0x1802, 0, 0x9B83); | ||
783 | b43_ofdmtab_write16(dev, 0x1803, 0, 0x0F8D); | ||
784 | b43_phy_write(dev, 0x0455, 0x0004); | ||
785 | } | ||
786 | |||
787 | b43_phy_write(dev, 0x04A5, (b43_phy_read(dev, 0x04A5) | ||
788 | & 0x00FF) | 0x5700); | ||
789 | b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A) | ||
790 | & 0xFF80) | 0x000F); | ||
791 | b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A) | ||
792 | & 0xC07F) | 0x2B80); | ||
793 | b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C) | ||
794 | & 0xF0FF) | 0x0300); | ||
795 | |||
796 | b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | ||
797 | | 0x0008); | ||
798 | |||
799 | b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0) | ||
800 | & 0xFFF0) | 0x0008); | ||
801 | b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1) | ||
802 | & 0xF0FF) | 0x0600); | ||
803 | b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2) | ||
804 | & 0xF0FF) | 0x0700); | ||
805 | b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0) | ||
806 | & 0xF0FF) | 0x0100); | ||
807 | |||
808 | if (phy->rev == 1) { | ||
809 | b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2) | ||
810 | & 0xFFF0) | 0x0007); | ||
811 | } | ||
812 | |||
813 | b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488) | ||
814 | & 0xFF00) | 0x001C); | ||
815 | b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488) | ||
816 | & 0xC0FF) | 0x0200); | ||
817 | b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496) | ||
818 | & 0xFF00) | 0x001C); | ||
819 | b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489) | ||
820 | & 0xFF00) | 0x0020); | ||
821 | b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489) | ||
822 | & 0xC0FF) | 0x0200); | ||
823 | b43_phy_write(dev, 0x0482, (b43_phy_read(dev, 0x0482) | ||
824 | & 0xFF00) | 0x002E); | ||
825 | b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496) | ||
826 | & 0x00FF) | 0x1A00); | ||
827 | b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481) | ||
828 | & 0xFF00) | 0x0028); | ||
829 | b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481) | ||
830 | & 0x00FF) | 0x2C00); | ||
831 | |||
832 | if (phy->rev == 1) { | ||
833 | b43_phy_write(dev, 0x0430, 0x092B); | ||
834 | b43_phy_write(dev, 0x041B, (b43_phy_read(dev, 0x041B) | ||
835 | & 0xFFE1) | 0x0002); | ||
836 | } else { | ||
837 | b43_phy_write(dev, 0x041B, b43_phy_read(dev, 0x041B) | ||
838 | & 0xFFE1); | ||
839 | b43_phy_write(dev, 0x041F, 0x287A); | ||
840 | b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420) | ||
841 | & 0xFFF0) | 0x0004); | ||
842 | } | ||
843 | |||
844 | if (phy->rev >= 6) { | ||
845 | b43_phy_write(dev, 0x0422, 0x287A); | ||
846 | b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420) | ||
847 | & 0x0FFF) | 0x3000); | ||
848 | } | ||
849 | |||
850 | b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8) | ||
851 | & 0x8080) | 0x7874); | ||
852 | b43_phy_write(dev, 0x048E, 0x1C00); | ||
853 | |||
854 | offset = 0x0800; | ||
855 | if (phy->rev == 1) { | ||
856 | offset = 0x5400; | ||
857 | b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB) | ||
858 | & 0xF0FF) | 0x0600); | ||
859 | b43_phy_write(dev, 0x048B, 0x005E); | ||
860 | b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C) | ||
861 | & 0xFF00) | 0x001E); | ||
862 | b43_phy_write(dev, 0x048D, 0x0002); | ||
863 | } | ||
864 | b43_ofdmtab_write16(dev, offset, 0, 0x00); | ||
865 | b43_ofdmtab_write16(dev, offset, 1, 0x07); | ||
866 | b43_ofdmtab_write16(dev, offset, 2, 0x10); | ||
867 | b43_ofdmtab_write16(dev, offset, 3, 0x1C); | ||
868 | |||
869 | if (phy->rev >= 6) { | ||
870 | b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426) | ||
871 | & 0xFFFC); | ||
872 | b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426) | ||
873 | & 0xEFFF); | ||
874 | } | ||
875 | } | ||
876 | |||
877 | static void b43_phy_setupg(struct b43_wldev *dev) | ||
878 | { | ||
879 | struct ssb_bus *bus = dev->dev->bus; | ||
880 | struct b43_phy *phy = &dev->phy; | ||
881 | u16 i; | ||
882 | |||
883 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); | ||
884 | if (phy->rev == 1) { | ||
885 | b43_phy_write(dev, 0x0406, 0x4F19); | ||
886 | b43_phy_write(dev, B43_PHY_G_CRS, | ||
887 | (b43_phy_read(dev, B43_PHY_G_CRS) & 0xFC3F) | | ||
888 | 0x0340); | ||
889 | b43_phy_write(dev, 0x042C, 0x005A); | ||
890 | b43_phy_write(dev, 0x0427, 0x001A); | ||
891 | |||
892 | for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++) | ||
893 | b43_ofdmtab_write16(dev, 0x5800, i, | ||
894 | b43_tab_finefreqg[i]); | ||
895 | for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++) | ||
896 | b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg1[i]); | ||
897 | for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) | ||
898 | b43_ofdmtab_write16(dev, 0x2000, i, b43_tab_rotor[i]); | ||
899 | } else { | ||
900 | /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */ | ||
901 | b43_nrssi_hw_write(dev, 0xBA98, (s16) 0x7654); | ||
902 | |||
903 | if (phy->rev == 2) { | ||
904 | b43_phy_write(dev, 0x04C0, 0x1861); | ||
905 | b43_phy_write(dev, 0x04C1, 0x0271); | ||
906 | } else if (phy->rev > 2) { | ||
907 | b43_phy_write(dev, 0x04C0, 0x0098); | ||
908 | b43_phy_write(dev, 0x04C1, 0x0070); | ||
909 | b43_phy_write(dev, 0x04C9, 0x0080); | ||
910 | } | ||
911 | b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x800); | ||
912 | |||
913 | for (i = 0; i < 64; i++) | ||
914 | b43_ofdmtab_write16(dev, 0x4000, i, i); | ||
915 | for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++) | ||
916 | b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg2[i]); | ||
917 | } | ||
918 | |||
919 | if (phy->rev <= 2) | ||
920 | for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++) | ||
921 | b43_ofdmtab_write16(dev, 0x1400, i, | ||
922 | b43_tab_noisescaleg1[i]); | ||
923 | else if ((phy->rev >= 7) && (b43_phy_read(dev, 0x0449) & 0x0200)) | ||
924 | for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++) | ||
925 | b43_ofdmtab_write16(dev, 0x1400, i, | ||
926 | b43_tab_noisescaleg3[i]); | ||
927 | else | ||
928 | for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++) | ||
929 | b43_ofdmtab_write16(dev, 0x1400, i, | ||
930 | b43_tab_noisescaleg2[i]); | ||
931 | |||
932 | if (phy->rev == 2) | ||
933 | for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) | ||
934 | b43_ofdmtab_write16(dev, 0x5000, i, | ||
935 | b43_tab_sigmasqr1[i]); | ||
936 | else if ((phy->rev > 2) && (phy->rev <= 8)) | ||
937 | for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) | ||
938 | b43_ofdmtab_write16(dev, 0x5000, i, | ||
939 | b43_tab_sigmasqr2[i]); | ||
940 | |||
941 | if (phy->rev == 1) { | ||
942 | for (i = 0; i < B43_TAB_RETARD_SIZE; i++) | ||
943 | b43_ofdmtab_write32(dev, 0x2400, i, b43_tab_retard[i]); | ||
944 | for (i = 4; i < 20; i++) | ||
945 | b43_ofdmtab_write16(dev, 0x5400, i, 0x0020); | ||
946 | b43_phy_agcsetup(dev); | ||
947 | |||
948 | if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && | ||
949 | (bus->boardinfo.type == SSB_BOARD_BU4306) && | ||
950 | (bus->boardinfo.rev == 0x17)) | ||
951 | return; | ||
952 | |||
953 | b43_ofdmtab_write16(dev, 0x5001, 0, 0x0002); | ||
954 | b43_ofdmtab_write16(dev, 0x5002, 0, 0x0001); | ||
955 | } else { | ||
956 | for (i = 0; i < 0x20; i++) | ||
957 | b43_ofdmtab_write16(dev, 0x1000, i, 0x0820); | ||
958 | b43_phy_agcsetup(dev); | ||
959 | b43_phy_read(dev, 0x0400); /* dummy read */ | ||
960 | b43_phy_write(dev, 0x0403, 0x1000); | ||
961 | b43_ofdmtab_write16(dev, 0x3C02, 0, 0x000F); | ||
962 | b43_ofdmtab_write16(dev, 0x3C03, 0, 0x0014); | ||
963 | |||
964 | if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && | ||
965 | (bus->boardinfo.type == SSB_BOARD_BU4306) && | ||
966 | (bus->boardinfo.rev == 0x17)) | ||
967 | return; | ||
968 | |||
969 | b43_ofdmtab_write16(dev, 0x0401, 0, 0x0002); | ||
970 | b43_ofdmtab_write16(dev, 0x0402, 0, 0x0001); | ||
971 | } | ||
972 | } | ||
973 | |||
974 | /* Initialize the noisescaletable for APHY */ | ||
975 | static void b43_phy_init_noisescaletbl(struct b43_wldev *dev) | ||
976 | { | 767 | { |
977 | struct b43_phy *phy = &dev->phy; | ||
978 | int i; | 768 | int i; |
979 | 769 | ||
980 | for (i = 0; i < 12; i++) { | 770 | if (dev->phy.rev < 3) { |
981 | if (phy->rev == 2) | 771 | if (enable) |
982 | b43_ofdmtab_write16(dev, 0x1400, i, 0x6767); | 772 | for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) { |
773 | b43_ofdmtab_write16(dev, | ||
774 | B43_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8); | ||
775 | b43_ofdmtab_write16(dev, | ||
776 | B43_OFDMTAB_WRSSI, i, 0xFFF8); | ||
777 | } | ||
983 | else | 778 | else |
984 | b43_ofdmtab_write16(dev, 0x1400, i, 0x2323); | 779 | for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) { |
985 | } | 780 | b43_ofdmtab_write16(dev, |
986 | if (phy->rev == 2) | 781 | B43_OFDMTAB_LNAHPFGAIN1, i, b43_tab_rssiagc1[i]); |
987 | b43_ofdmtab_write16(dev, 0x1400, i, 0x6700); | 782 | b43_ofdmtab_write16(dev, |
988 | else | 783 | B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc1[i]); |
989 | b43_ofdmtab_write16(dev, 0x1400, i, 0x2300); | 784 | } |
990 | for (i = 0; i < 11; i++) { | 785 | } else { |
991 | if (phy->rev == 2) | 786 | if (enable) |
992 | b43_ofdmtab_write16(dev, 0x1400, i, 0x6767); | 787 | for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) |
788 | b43_ofdmtab_write16(dev, | ||
789 | B43_OFDMTAB_WRSSI, i, 0x0820); | ||
993 | else | 790 | else |
994 | b43_ofdmtab_write16(dev, 0x1400, i, 0x2323); | 791 | for (i = 0; i < B43_TAB_RSSIAGC2_SIZE; i++) |
792 | b43_ofdmtab_write16(dev, | ||
793 | B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc2[i]); | ||
995 | } | 794 | } |
996 | if (phy->rev == 2) | ||
997 | b43_ofdmtab_write16(dev, 0x1400, i, 0x0067); | ||
998 | else | ||
999 | b43_ofdmtab_write16(dev, 0x1400, i, 0x0023); | ||
1000 | } | 795 | } |
1001 | 796 | ||
1002 | static void b43_phy_setupa(struct b43_wldev *dev) | 797 | static void b43_phy_ww(struct b43_wldev *dev) |
1003 | { | 798 | { |
1004 | struct b43_phy *phy = &dev->phy; | 799 | u16 b, curr_s, best_s = 0xFFFF; |
1005 | u16 i; | 800 | int i; |
1006 | |||
1007 | B43_WARN_ON(phy->type != B43_PHYTYPE_A); | ||
1008 | switch (phy->rev) { | ||
1009 | case 2: | ||
1010 | b43_phy_write(dev, 0x008E, 0x3800); | ||
1011 | b43_phy_write(dev, 0x0035, 0x03FF); | ||
1012 | b43_phy_write(dev, 0x0036, 0x0400); | ||
1013 | |||
1014 | b43_ofdmtab_write16(dev, 0x3807, 0, 0x0051); | ||
1015 | |||
1016 | b43_phy_write(dev, 0x001C, 0x0FF9); | ||
1017 | b43_phy_write(dev, 0x0020, b43_phy_read(dev, 0x0020) & 0xFF0F); | ||
1018 | b43_ofdmtab_write16(dev, 0x3C0C, 0, 0x07BF); | ||
1019 | b43_radio_write16(dev, 0x0002, 0x07BF); | ||
1020 | |||
1021 | b43_phy_write(dev, 0x0024, 0x4680); | ||
1022 | b43_phy_write(dev, 0x0020, 0x0003); | ||
1023 | b43_phy_write(dev, 0x001D, 0x0F40); | ||
1024 | b43_phy_write(dev, 0x001F, 0x1C00); | ||
1025 | |||
1026 | b43_phy_write(dev, 0x002A, (b43_phy_read(dev, 0x002A) | ||
1027 | & 0x00FF) | 0x0400); | ||
1028 | b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) | ||
1029 | & 0xFBFF); | ||
1030 | b43_phy_write(dev, 0x008E, 0x58C1); | ||
1031 | |||
1032 | b43_ofdmtab_write16(dev, 0x0803, 0, 0x000F); | ||
1033 | b43_ofdmtab_write16(dev, 0x0804, 0, 0x001F); | ||
1034 | b43_ofdmtab_write16(dev, 0x0805, 0, 0x002A); | ||
1035 | b43_ofdmtab_write16(dev, 0x0805, 0, 0x0030); | ||
1036 | b43_ofdmtab_write16(dev, 0x0807, 0, 0x003A); | ||
1037 | |||
1038 | b43_ofdmtab_write16(dev, 0x0000, 0, 0x0013); | ||
1039 | b43_ofdmtab_write16(dev, 0x0000, 1, 0x0013); | ||
1040 | b43_ofdmtab_write16(dev, 0x0000, 2, 0x0013); | ||
1041 | b43_ofdmtab_write16(dev, 0x0000, 3, 0x0013); | ||
1042 | b43_ofdmtab_write16(dev, 0x0000, 4, 0x0015); | ||
1043 | b43_ofdmtab_write16(dev, 0x0000, 5, 0x0015); | ||
1044 | b43_ofdmtab_write16(dev, 0x0000, 6, 0x0019); | ||
1045 | |||
1046 | b43_ofdmtab_write16(dev, 0x0404, 0, 0x0003); | ||
1047 | b43_ofdmtab_write16(dev, 0x0405, 0, 0x0003); | ||
1048 | b43_ofdmtab_write16(dev, 0x0406, 0, 0x0007); | ||
1049 | |||
1050 | for (i = 0; i < 16; i++) | ||
1051 | b43_ofdmtab_write16(dev, 0x4000, i, (0x8 + i) & 0x000F); | ||
1052 | |||
1053 | b43_ofdmtab_write16(dev, 0x3003, 0, 0x1044); | ||
1054 | b43_ofdmtab_write16(dev, 0x3004, 0, 0x7201); | ||
1055 | b43_ofdmtab_write16(dev, 0x3006, 0, 0x0040); | ||
1056 | b43_ofdmtab_write16(dev, 0x3001, 0, | ||
1057 | (b43_ofdmtab_read16(dev, 0x3001, 0) & | ||
1058 | 0x0010) | 0x0008); | ||
1059 | |||
1060 | for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++) | ||
1061 | b43_ofdmtab_write16(dev, 0x5800, i, | ||
1062 | b43_tab_finefreqa[i]); | ||
1063 | for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++) | ||
1064 | b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noisea2[i]); | ||
1065 | for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) | ||
1066 | b43_ofdmtab_write32(dev, 0x2000, i, b43_tab_rotor[i]); | ||
1067 | b43_phy_init_noisescaletbl(dev); | ||
1068 | for (i = 0; i < B43_TAB_RETARD_SIZE; i++) | ||
1069 | b43_ofdmtab_write32(dev, 0x2400, i, b43_tab_retard[i]); | ||
1070 | break; | ||
1071 | case 3: | ||
1072 | for (i = 0; i < 64; i++) | ||
1073 | b43_ofdmtab_write16(dev, 0x4000, i, i); | ||
1074 | |||
1075 | b43_ofdmtab_write16(dev, 0x3807, 0, 0x0051); | ||
1076 | |||
1077 | b43_phy_write(dev, 0x001C, 0x0FF9); | ||
1078 | b43_phy_write(dev, 0x0020, b43_phy_read(dev, 0x0020) & 0xFF0F); | ||
1079 | b43_radio_write16(dev, 0x0002, 0x07BF); | ||
1080 | |||
1081 | b43_phy_write(dev, 0x0024, 0x4680); | ||
1082 | b43_phy_write(dev, 0x0020, 0x0003); | ||
1083 | b43_phy_write(dev, 0x001D, 0x0F40); | ||
1084 | b43_phy_write(dev, 0x001F, 0x1C00); | ||
1085 | b43_phy_write(dev, 0x002A, (b43_phy_read(dev, 0x002A) | ||
1086 | & 0x00FF) | 0x0400); | ||
1087 | |||
1088 | b43_ofdmtab_write16(dev, 0x3000, 1, | ||
1089 | (b43_ofdmtab_read16(dev, 0x3000, 1) | ||
1090 | & 0x0010) | 0x0008); | ||
1091 | for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++) { | ||
1092 | b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noisea3[i]); | ||
1093 | } | ||
1094 | b43_phy_init_noisescaletbl(dev); | ||
1095 | for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) { | ||
1096 | b43_ofdmtab_write16(dev, 0x5000, i, | ||
1097 | b43_tab_sigmasqr1[i]); | ||
1098 | } | ||
1099 | |||
1100 | b43_phy_write(dev, 0x0003, 0x1808); | ||
1101 | |||
1102 | b43_ofdmtab_write16(dev, 0x0803, 0, 0x000F); | ||
1103 | b43_ofdmtab_write16(dev, 0x0804, 0, 0x001F); | ||
1104 | b43_ofdmtab_write16(dev, 0x0805, 0, 0x002A); | ||
1105 | b43_ofdmtab_write16(dev, 0x0805, 0, 0x0030); | ||
1106 | b43_ofdmtab_write16(dev, 0x0807, 0, 0x003A); | ||
1107 | |||
1108 | b43_ofdmtab_write16(dev, 0x0000, 0, 0x0013); | ||
1109 | b43_ofdmtab_write16(dev, 0x0001, 0, 0x0013); | ||
1110 | b43_ofdmtab_write16(dev, 0x0002, 0, 0x0013); | ||
1111 | b43_ofdmtab_write16(dev, 0x0003, 0, 0x0013); | ||
1112 | b43_ofdmtab_write16(dev, 0x0004, 0, 0x0015); | ||
1113 | b43_ofdmtab_write16(dev, 0x0005, 0, 0x0015); | ||
1114 | b43_ofdmtab_write16(dev, 0x0006, 0, 0x0019); | ||
1115 | |||
1116 | b43_ofdmtab_write16(dev, 0x0404, 0, 0x0003); | ||
1117 | b43_ofdmtab_write16(dev, 0x0405, 0, 0x0003); | ||
1118 | b43_ofdmtab_write16(dev, 0x0406, 0, 0x0007); | ||
1119 | 801 | ||
1120 | b43_ofdmtab_write16(dev, 0x3C02, 0, 0x000F); | 802 | b43_phy_write(dev, B43_PHY_CRS0, |
1121 | b43_ofdmtab_write16(dev, 0x3C03, 0, 0x0014); | 803 | b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN); |
1122 | break; | 804 | b43_phy_write(dev, B43_PHY_OFDM(0x1B), |
1123 | default: | 805 | b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000); |
1124 | B43_WARN_ON(1); | 806 | b43_phy_write(dev, B43_PHY_OFDM(0x82), |
1125 | } | 807 | (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300); |
808 | b43_radio_write16(dev, 0x0009, | ||
809 | b43_radio_read16(dev, 0x0009) | 0x0080); | ||
810 | b43_radio_write16(dev, 0x0012, | ||
811 | (b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002); | ||
812 | b43_wa_initgains(dev); | ||
813 | b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5); | ||
814 | b = b43_phy_read(dev, B43_PHY_PWRDOWN); | ||
815 | b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005); | ||
816 | b43_radio_write16(dev, 0x0004, | ||
817 | b43_radio_read16(dev, 0x0004) | 0x0004); | ||
818 | for (i = 0x10; i <= 0x20; i++) { | ||
819 | b43_radio_write16(dev, 0x0013, i); | ||
820 | curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF; | ||
821 | if (!curr_s) { | ||
822 | best_s = 0x0000; | ||
823 | break; | ||
824 | } else if (curr_s >= 0x0080) | ||
825 | curr_s = 0x0100 - curr_s; | ||
826 | if (curr_s < best_s) | ||
827 | best_s = curr_s; | ||
828 | } | ||
829 | b43_phy_write(dev, B43_PHY_PWRDOWN, b); | ||
830 | b43_radio_write16(dev, 0x0004, | ||
831 | b43_radio_read16(dev, 0x0004) & 0xFFFB); | ||
832 | b43_radio_write16(dev, 0x0013, best_s); | ||
833 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC); | ||
834 | b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80); | ||
835 | b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00); | ||
836 | b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0); | ||
837 | b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0); | ||
838 | b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF); | ||
839 | b43_phy_write(dev, B43_PHY_OFDM(0xBB), | ||
840 | (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053); | ||
841 | b43_phy_write(dev, B43_PHY_OFDM61, | ||
842 | (b43_phy_read(dev, B43_PHY_OFDM61 & 0xFE1F)) | 0x0120); | ||
843 | b43_phy_write(dev, B43_PHY_OFDM(0x13), | ||
844 | (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000); | ||
845 | b43_phy_write(dev, B43_PHY_OFDM(0x14), | ||
846 | (b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000); | ||
847 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017); | ||
848 | for (i = 0; i < 6; i++) | ||
849 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F); | ||
850 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E); | ||
851 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011); | ||
852 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013); | ||
853 | b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030); | ||
854 | b43_phy_write(dev, B43_PHY_CRS0, | ||
855 | b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN); | ||
1126 | } | 856 | } |
1127 | 857 | ||
1128 | /* Initialize APHY. This is also called for the GPHY in some cases. */ | 858 | /* Initialize APHY. This is also called for the GPHY in some cases. */ |
@@ -1130,64 +860,54 @@ static void b43_phy_inita(struct b43_wldev *dev) | |||
1130 | { | 860 | { |
1131 | struct ssb_bus *bus = dev->dev->bus; | 861 | struct ssb_bus *bus = dev->dev->bus; |
1132 | struct b43_phy *phy = &dev->phy; | 862 | struct b43_phy *phy = &dev->phy; |
1133 | u16 tval; | ||
1134 | 863 | ||
1135 | might_sleep(); | 864 | might_sleep(); |
1136 | 865 | ||
1137 | if (phy->type == B43_PHYTYPE_A) { | 866 | if (phy->rev >= 6) { |
1138 | b43_phy_setupa(dev); | 867 | if (phy->type == B43_PHYTYPE_A) |
1139 | } else { | 868 | b43_phy_write(dev, B43_PHY_OFDM(0x1B), |
1140 | b43_phy_setupg(dev); | 869 | b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000); |
1141 | if (phy->gmode && | 870 | if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) |
1142 | (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL)) | 871 | b43_phy_write(dev, B43_PHY_ENCORE, |
1143 | b43_phy_write(dev, 0x046E, 0x03CF); | 872 | b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010); |
1144 | return; | 873 | else |
874 | b43_phy_write(dev, B43_PHY_ENCORE, | ||
875 | b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010); | ||
1145 | } | 876 | } |
1146 | 877 | ||
1147 | b43_phy_write(dev, B43_PHY_A_CRS, | 878 | b43_wa_all(dev); |
1148 | (b43_phy_read(dev, B43_PHY_A_CRS) & 0xF83C) | 0x0340); | ||
1149 | b43_phy_write(dev, 0x0034, 0x0001); | ||
1150 | 879 | ||
1151 | //TODO: RSSI AGC | 880 | if (phy->type == B43_PHYTYPE_A) { |
1152 | b43_phy_write(dev, B43_PHY_A_CRS, | 881 | if (phy->gmode && (phy->rev < 3)) |
1153 | b43_phy_read(dev, B43_PHY_A_CRS) | (1 << 14)); | 882 | b43_phy_write(dev, 0x0034, |
1154 | b43_radio_init2060(dev); | 883 | b43_phy_read(dev, 0x0034) | 0x0001); |
884 | b43_phy_rssiagc(dev, 0); | ||
1155 | 885 | ||
1156 | if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && | 886 | b43_phy_write(dev, B43_PHY_CRS0, |
1157 | ((bus->boardinfo.type == SSB_BOARD_BU4306) || | 887 | b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN); |
1158 | (bus->boardinfo.type == SSB_BOARD_BU4309))) { | ||
1159 | if (phy->lofcal == 0xFFFF) { | ||
1160 | //TODO: LOF Cal | ||
1161 | b43_radio_set_tx_iq(dev); | ||
1162 | } else | ||
1163 | b43_radio_write16(dev, 0x001E, phy->lofcal); | ||
1164 | } | ||
1165 | 888 | ||
1166 | b43_phy_write(dev, 0x007A, 0xF111); | 889 | b43_radio_init2060(dev); |
1167 | 890 | ||
1168 | if (phy->cur_idle_tssi == 0) { | 891 | if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && |
1169 | b43_radio_write16(dev, 0x0019, 0x0000); | 892 | ((bus->boardinfo.type == SSB_BOARD_BU4306) || |
1170 | b43_radio_write16(dev, 0x0017, 0x0020); | 893 | (bus->boardinfo.type == SSB_BOARD_BU4309))) { |
1171 | 894 | ; //TODO: A PHY LO | |
1172 | tval = b43_ofdmtab_read16(dev, 0x3001, 0); | ||
1173 | if (phy->rev == 1) { | ||
1174 | b43_ofdmtab_write16(dev, 0x3001, 0, | ||
1175 | (b43_ofdmtab_read16(dev, 0x3001, 0) | ||
1176 | & 0xFF87) | ||
1177 | | 0x0058); | ||
1178 | } else { | ||
1179 | b43_ofdmtab_write16(dev, 0x3001, 0, | ||
1180 | (b43_ofdmtab_read16(dev, 0x3001, 0) | ||
1181 | & 0xFFC3) | ||
1182 | | 0x002C); | ||
1183 | } | 895 | } |
1184 | b43_dummy_transmission(dev); | ||
1185 | phy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_A_PCTL); | ||
1186 | b43_ofdmtab_write16(dev, 0x3001, 0, tval); | ||
1187 | 896 | ||
1188 | b43_radio_set_txpower_a(dev, 0x0018); | 897 | if (phy->rev >= 3) |
898 | b43_phy_ww(dev); | ||
899 | |||
900 | hardware_pctl_init_aphy(dev); | ||
901 | |||
902 | //TODO: radar detection | ||
903 | } | ||
904 | |||
905 | if ((phy->type == B43_PHYTYPE_G) && | ||
906 | (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL)) { | ||
907 | b43_phy_write(dev, B43_PHY_OFDM(0x6E), | ||
908 | (b43_phy_read(dev, B43_PHY_OFDM(0x6E)) | ||
909 | & 0xE000) | 0x3CF); | ||
1189 | } | 910 | } |
1190 | b43_shm_clear_tssi(dev); | ||
1191 | } | 911 | } |
1192 | 912 | ||
1193 | static void b43_phy_initb2(struct b43_wldev *dev) | 913 | static void b43_phy_initb2(struct b43_wldev *dev) |
@@ -4210,103 +3930,6 @@ int b43_radio_selectchannel(struct b43_wldev *dev, | |||
4210 | return 0; | 3930 | return 0; |
4211 | } | 3931 | } |
4212 | 3932 | ||
4213 | /* http://bcm-specs.sipsolutions.net/TX_Gain_Base_Band */ | ||
4214 | static u16 b43_get_txgain_base_band(u16 txpower) | ||
4215 | { | ||
4216 | u16 ret; | ||
4217 | |||
4218 | B43_WARN_ON(txpower > 63); | ||
4219 | |||
4220 | if (txpower >= 54) | ||
4221 | ret = 2; | ||
4222 | else if (txpower >= 49) | ||
4223 | ret = 4; | ||
4224 | else if (txpower >= 44) | ||
4225 | ret = 5; | ||
4226 | else | ||
4227 | ret = 6; | ||
4228 | |||
4229 | return ret; | ||
4230 | } | ||
4231 | |||
4232 | /* http://bcm-specs.sipsolutions.net/TX_Gain_Radio_Frequency_Power_Amplifier */ | ||
4233 | static u16 b43_get_txgain_freq_power_amp(u16 txpower) | ||
4234 | { | ||
4235 | u16 ret; | ||
4236 | |||
4237 | B43_WARN_ON(txpower > 63); | ||
4238 | |||
4239 | if (txpower >= 32) | ||
4240 | ret = 0; | ||
4241 | else if (txpower >= 25) | ||
4242 | ret = 1; | ||
4243 | else if (txpower >= 20) | ||
4244 | ret = 2; | ||
4245 | else if (txpower >= 12) | ||
4246 | ret = 3; | ||
4247 | else | ||
4248 | ret = 4; | ||
4249 | |||
4250 | return ret; | ||
4251 | } | ||
4252 | |||
4253 | /* http://bcm-specs.sipsolutions.net/TX_Gain_Digital_Analog_Converter */ | ||
4254 | static u16 b43_get_txgain_dac(u16 txpower) | ||
4255 | { | ||
4256 | u16 ret; | ||
4257 | |||
4258 | B43_WARN_ON(txpower > 63); | ||
4259 | |||
4260 | if (txpower >= 54) | ||
4261 | ret = txpower - 53; | ||
4262 | else if (txpower >= 49) | ||
4263 | ret = txpower - 42; | ||
4264 | else if (txpower >= 44) | ||
4265 | ret = txpower - 37; | ||
4266 | else if (txpower >= 32) | ||
4267 | ret = txpower - 32; | ||
4268 | else if (txpower >= 25) | ||
4269 | ret = txpower - 20; | ||
4270 | else if (txpower >= 20) | ||
4271 | ret = txpower - 13; | ||
4272 | else if (txpower >= 12) | ||
4273 | ret = txpower - 8; | ||
4274 | else | ||
4275 | ret = txpower; | ||
4276 | |||
4277 | return ret; | ||
4278 | } | ||
4279 | |||
4280 | static void b43_radio_set_txpower_a(struct b43_wldev *dev, u16 txpower) | ||
4281 | { | ||
4282 | struct b43_phy *phy = &dev->phy; | ||
4283 | u16 pamp, base, dac, t; | ||
4284 | |||
4285 | txpower = limit_value(txpower, 0, 63); | ||
4286 | |||
4287 | pamp = b43_get_txgain_freq_power_amp(txpower); | ||
4288 | pamp <<= 5; | ||
4289 | pamp &= 0x00E0; | ||
4290 | b43_phy_write(dev, 0x0019, pamp); | ||
4291 | |||
4292 | base = b43_get_txgain_base_band(txpower); | ||
4293 | base &= 0x000F; | ||
4294 | b43_phy_write(dev, 0x0017, base | 0x0020); | ||
4295 | |||
4296 | t = b43_ofdmtab_read16(dev, 0x3000, 1); | ||
4297 | t &= 0x0007; | ||
4298 | |||
4299 | dac = b43_get_txgain_dac(txpower); | ||
4300 | dac <<= 3; | ||
4301 | dac |= t; | ||
4302 | |||
4303 | b43_ofdmtab_write16(dev, 0x3000, 1, dac); | ||
4304 | |||
4305 | phy->txpwr_offset = txpower; | ||
4306 | |||
4307 | //TODO: FuncPlaceholder (Adjust BB loft cancel) | ||
4308 | } | ||
4309 | |||
4310 | void b43_radio_turn_on(struct b43_wldev *dev) | 3933 | void b43_radio_turn_on(struct b43_wldev *dev) |
4311 | { | 3934 | { |
4312 | struct b43_phy *phy = &dev->phy; | 3935 | struct b43_phy *phy = &dev->phy; |
diff --git a/drivers/net/wireless/b43/phy.h b/drivers/net/wireless/b43/phy.h index c64d74504fc0..1c7eac25a302 100644 --- a/drivers/net/wireless/b43/phy.h +++ b/drivers/net/wireless/b43/phy.h | |||
@@ -27,8 +27,11 @@ struct b43_phy; | |||
27 | #define B43_PHY_PWRDOWN B43_PHY_OFDM(0x03) /* Powerdown */ | 27 | #define B43_PHY_PWRDOWN B43_PHY_OFDM(0x03) /* Powerdown */ |
28 | #define B43_PHY_CRSTHRES1 B43_PHY_OFDM(0x06) /* CRS Threshold 1 */ | 28 | #define B43_PHY_CRSTHRES1 B43_PHY_OFDM(0x06) /* CRS Threshold 1 */ |
29 | #define B43_PHY_LNAHPFCTL B43_PHY_OFDM(0x1C) /* LNA/HPF control */ | 29 | #define B43_PHY_LNAHPFCTL B43_PHY_OFDM(0x1C) /* LNA/HPF control */ |
30 | #define B43_PHY_LPFGAINCTL B43_PHY_OFDM(0x20) /* LPF Gain control */ | ||
30 | #define B43_PHY_ADIVRELATED B43_PHY_OFDM(0x27) /* FIXME rename */ | 31 | #define B43_PHY_ADIVRELATED B43_PHY_OFDM(0x27) /* FIXME rename */ |
31 | #define B43_PHY_CRS0 B43_PHY_OFDM(0x29) | 32 | #define B43_PHY_CRS0 B43_PHY_OFDM(0x29) |
33 | #define B43_PHY_CRS0_EN 0x4000 | ||
34 | #define B43_PHY_PEAK_COUNT B43_PHY_OFDM(0x30) | ||
32 | #define B43_PHY_ANTDWELL B43_PHY_OFDM(0x2B) /* Antenna dwell */ | 35 | #define B43_PHY_ANTDWELL B43_PHY_OFDM(0x2B) /* Antenna dwell */ |
33 | #define B43_PHY_ANTDWELL_AUTODIV1 0x0100 /* Automatic RX diversity start antenna */ | 36 | #define B43_PHY_ANTDWELL_AUTODIV1 0x0100 /* Automatic RX diversity start antenna */ |
34 | #define B43_PHY_ENCORE B43_PHY_OFDM(0x49) /* "Encore" (RangeMax / BroadRange) */ | 37 | #define B43_PHY_ENCORE B43_PHY_OFDM(0x49) /* "Encore" (RangeMax / BroadRange) */ |
@@ -37,6 +40,7 @@ struct b43_phy; | |||
37 | #define B43_PHY_OFDM61 B43_PHY_OFDM(0x61) /* FIXME rename */ | 40 | #define B43_PHY_OFDM61 B43_PHY_OFDM(0x61) /* FIXME rename */ |
38 | #define B43_PHY_OFDM61_10 0x0010 /* FIXME rename */ | 41 | #define B43_PHY_OFDM61_10 0x0010 /* FIXME rename */ |
39 | #define B43_PHY_IQBAL B43_PHY_OFDM(0x69) /* I/Q balance */ | 42 | #define B43_PHY_IQBAL B43_PHY_OFDM(0x69) /* I/Q balance */ |
43 | #define B43_PHY_BBTXDC_BIAS B43_PHY_OFDM(0x6B) /* Baseband TX DC bias */ | ||
40 | #define B43_PHY_OTABLECTL B43_PHY_OFDM(0x72) /* OFDM table control (see below) */ | 44 | #define B43_PHY_OTABLECTL B43_PHY_OFDM(0x72) /* OFDM table control (see below) */ |
41 | #define B43_PHY_OTABLEOFF 0x03FF /* OFDM table offset (see below) */ | 45 | #define B43_PHY_OTABLEOFF 0x03FF /* OFDM table offset (see below) */ |
42 | #define B43_PHY_OTABLENR 0xFC00 /* OFDM table number (see below) */ | 46 | #define B43_PHY_OTABLENR 0xFC00 /* OFDM table number (see below) */ |
@@ -44,6 +48,9 @@ struct b43_phy; | |||
44 | #define B43_PHY_OTABLEI B43_PHY_OFDM(0x73) /* OFDM table data I */ | 48 | #define B43_PHY_OTABLEI B43_PHY_OFDM(0x73) /* OFDM table data I */ |
45 | #define B43_PHY_OTABLEQ B43_PHY_OFDM(0x74) /* OFDM table data Q */ | 49 | #define B43_PHY_OTABLEQ B43_PHY_OFDM(0x74) /* OFDM table data Q */ |
46 | #define B43_PHY_HPWR_TSSICTL B43_PHY_OFDM(0x78) /* Hardware power TSSI control */ | 50 | #define B43_PHY_HPWR_TSSICTL B43_PHY_OFDM(0x78) /* Hardware power TSSI control */ |
51 | #define B43_PHY_ADCCTL B43_PHY_OFDM(0x7A) /* ADC control */ | ||
52 | #define B43_PHY_IDLE_TSSI B43_PHY_OFDM(0x7B) | ||
53 | #define B43_PHY_A_TEMP_SENSE B43_PHY_OFDM(0x7C) /* A PHY temperature sense */ | ||
47 | #define B43_PHY_NRSSITHRES B43_PHY_OFDM(0x8A) /* NRSSI threshold */ | 54 | #define B43_PHY_NRSSITHRES B43_PHY_OFDM(0x8A) /* NRSSI threshold */ |
48 | #define B43_PHY_ANTWRSETT B43_PHY_OFDM(0x8C) /* Antenna WR settle */ | 55 | #define B43_PHY_ANTWRSETT B43_PHY_OFDM(0x8C) /* Antenna WR settle */ |
49 | #define B43_PHY_ANTWRSETT_ARXDIV 0x2000 /* Automatic RX diversity enabled */ | 56 | #define B43_PHY_ANTWRSETT_ARXDIV 0x2000 /* Automatic RX diversity enabled */ |
@@ -54,6 +61,8 @@ struct b43_phy; | |||
54 | #define B43_PHY_N1N2GAIN B43_PHY_OFDM(0xA2) | 61 | #define B43_PHY_N1N2GAIN B43_PHY_OFDM(0xA2) |
55 | #define B43_PHY_CLIPTHRES B43_PHY_OFDM(0xA3) | 62 | #define B43_PHY_CLIPTHRES B43_PHY_OFDM(0xA3) |
56 | #define B43_PHY_CLIPN1P2THRES B43_PHY_OFDM(0xA4) | 63 | #define B43_PHY_CLIPN1P2THRES B43_PHY_OFDM(0xA4) |
64 | #define B43_PHY_CCKSHIFTBITS_WA B43_PHY_OFDM(0xA5) /* CCK shiftbits workaround, FIXME rename */ | ||
65 | #define B43_PHY_CCKSHIFTBITS B43_PHY_OFDM(0xA7) /* FIXME rename */ | ||
57 | #define B43_PHY_DIVSRCHIDX B43_PHY_OFDM(0xA8) /* Divider search gain/index */ | 66 | #define B43_PHY_DIVSRCHIDX B43_PHY_OFDM(0xA8) /* Divider search gain/index */ |
58 | #define B43_PHY_CLIPP2THRES B43_PHY_OFDM(0xA9) | 67 | #define B43_PHY_CLIPP2THRES B43_PHY_OFDM(0xA9) |
59 | #define B43_PHY_CLIPP3THRES B43_PHY_OFDM(0xAA) | 68 | #define B43_PHY_CLIPP3THRES B43_PHY_OFDM(0xAA) |
@@ -125,13 +134,14 @@ struct b43_phy; | |||
125 | #define B43_OFDMTAB_DC B43_OFDMTAB(0x0E, 7) | 134 | #define B43_OFDMTAB_DC B43_OFDMTAB(0x0E, 7) |
126 | #define B43_OFDMTAB_PWRDYN2 B43_OFDMTAB(0x0E, 12) | 135 | #define B43_OFDMTAB_PWRDYN2 B43_OFDMTAB(0x0E, 12) |
127 | #define B43_OFDMTAB_LNAGAIN B43_OFDMTAB(0x0E, 13) | 136 | #define B43_OFDMTAB_LNAGAIN B43_OFDMTAB(0x0E, 13) |
128 | //TODO | 137 | #define B43_OFDMTAB_UNKNOWN_0F B43_OFDMTAB(0x0F, 0) //TODO rename |
138 | #define B43_OFDMTAB_UNKNOWN_APHY B43_OFDMTAB(0x0F, 7) //TODO rename | ||
129 | #define B43_OFDMTAB_LPFGAIN B43_OFDMTAB(0x0F, 12) | 139 | #define B43_OFDMTAB_LPFGAIN B43_OFDMTAB(0x0F, 12) |
130 | #define B43_OFDMTAB_RSSI B43_OFDMTAB(0x10, 0) | 140 | #define B43_OFDMTAB_RSSI B43_OFDMTAB(0x10, 0) |
131 | //TODO | 141 | #define B43_OFDMTAB_UNKNOWN_11 B43_OFDMTAB(0x11, 4) //TODO rename |
132 | #define B43_OFDMTAB_AGC1_R1 B43_OFDMTAB(0x13, 0) | 142 | #define B43_OFDMTAB_AGC1_R1 B43_OFDMTAB(0x13, 0) |
133 | #define B43_OFDMTAB_GAINX_R1 B43_OFDMTAB(0x14, 0) //TODO rename | 143 | #define B43_OFDMTAB_GAINX_R1 B43_OFDMTAB(0x14, 0) //TODO remove! |
134 | #define B43_OFDMTAB_MINSIGSQ B43_OFDMTAB(0x14, 1) | 144 | #define B43_OFDMTAB_MINSIGSQ B43_OFDMTAB(0x14, 0) |
135 | #define B43_OFDMTAB_AGC3_R1 B43_OFDMTAB(0x15, 0) | 145 | #define B43_OFDMTAB_AGC3_R1 B43_OFDMTAB(0x15, 0) |
136 | #define B43_OFDMTAB_WRSSI_R1 B43_OFDMTAB(0x15, 4) | 146 | #define B43_OFDMTAB_WRSSI_R1 B43_OFDMTAB(0x15, 4) |
137 | #define B43_OFDMTAB_TSSI B43_OFDMTAB(0x15, 0) | 147 | #define B43_OFDMTAB_TSSI B43_OFDMTAB(0x15, 0) |
diff --git a/drivers/net/wireless/b43/tables.c b/drivers/net/wireless/b43/tables.c index 15a87183a572..0ac8653767b9 100644 --- a/drivers/net/wireless/b43/tables.c +++ b/drivers/net/wireless/b43/tables.c | |||
@@ -229,7 +229,7 @@ const u16 b43_tab_noisea2[] = { | |||
229 | }; | 229 | }; |
230 | 230 | ||
231 | const u16 b43_tab_noisea3[] = { | 231 | const u16 b43_tab_noisea3[] = { |
232 | 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36, | 232 | 0x5E5E, 0x5E5E, 0x5E5E, 0x3F48, |
233 | 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36, | 233 | 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36, |
234 | }; | 234 | }; |
235 | 235 | ||
@@ -243,6 +243,26 @@ const u16 b43_tab_noiseg2[] = { | |||
243 | 0x0000, 0x0000, 0x0000, 0x0000, | 243 | 0x0000, 0x0000, 0x0000, 0x0000, |
244 | }; | 244 | }; |
245 | 245 | ||
246 | const u16 b43_tab_noisescalea2[] = { | ||
247 | 0x6767, 0x6767, 0x6767, 0x6767, /* 0 */ | ||
248 | 0x6767, 0x6767, 0x6767, 0x6767, | ||
249 | 0x6767, 0x6767, 0x6767, 0x6767, | ||
250 | 0x6767, 0x6700, 0x6767, 0x6767, | ||
251 | 0x6767, 0x6767, 0x6767, 0x6767, /* 16 */ | ||
252 | 0x6767, 0x6767, 0x6767, 0x6767, | ||
253 | 0x6767, 0x6767, 0x0067, | ||
254 | }; | ||
255 | |||
256 | const u16 b43_tab_noisescalea3[] = { | ||
257 | 0x2323, 0x2323, 0x2323, 0x2323, /* 0 */ | ||
258 | 0x2323, 0x2323, 0x2323, 0x2323, | ||
259 | 0x2323, 0x2323, 0x2323, 0x2323, | ||
260 | 0x2323, 0x2300, 0x2323, 0x2323, | ||
261 | 0x2323, 0x2323, 0x2323, 0x2323, /* 16 */ | ||
262 | 0x2323, 0x2323, 0x2323, 0x2323, | ||
263 | 0x2323, 0x2323, 0x0023, | ||
264 | }; | ||
265 | |||
246 | const u16 b43_tab_noisescaleg1[] = { | 266 | const u16 b43_tab_noisescaleg1[] = { |
247 | 0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */ | 267 | 0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */ |
248 | 0x2F2D, 0x2A2A, 0x2527, 0x1F21, | 268 | 0x2F2D, 0x2A2A, 0x2527, 0x1F21, |
@@ -254,7 +274,7 @@ const u16 b43_tab_noisescaleg1[] = { | |||
254 | }; | 274 | }; |
255 | 275 | ||
256 | const u16 b43_tab_noisescaleg2[] = { | 276 | const u16 b43_tab_noisescaleg2[] = { |
257 | 0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */ | 277 | 0xD8DD, 0xCBD4, 0xBCC0, 0xB6B7, /* 0 */ |
258 | 0xB2B0, 0xADAD, 0xA7A9, 0x9FA1, | 278 | 0xB2B0, 0xADAD, 0xA7A9, 0x9FA1, |
259 | 0x969B, 0x9195, 0x8F8F, 0x8A8A, | 279 | 0x969B, 0x9195, 0x8F8F, 0x8A8A, |
260 | 0x8A8A, 0x8A00, 0x8A8A, 0x8F8A, | 280 | 0x8A8A, 0x8A00, 0x8A8A, 0x8F8A, |
@@ -307,6 +327,28 @@ const u16 b43_tab_sigmasqr2[] = { | |||
307 | 0x00DE, | 327 | 0x00DE, |
308 | }; | 328 | }; |
309 | 329 | ||
330 | const u16 b43_tab_rssiagc1[] = { | ||
331 | 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8, /* 0 */ | ||
332 | 0xFFF8, 0xFFF9, 0xFFFC, 0xFFFE, | ||
333 | 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8, | ||
334 | 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8, | ||
335 | }; | ||
336 | |||
337 | const u16 b43_tab_rssiagc2[] = { | ||
338 | 0x0820, 0x0820, 0x0920, 0x0C38, /* 0 */ | ||
339 | 0x0820, 0x0820, 0x0820, 0x0820, | ||
340 | 0x0820, 0x0820, 0x0920, 0x0A38, | ||
341 | 0x0820, 0x0820, 0x0820, 0x0820, | ||
342 | 0x0820, 0x0820, 0x0920, 0x0A38, /* 16 */ | ||
343 | 0x0820, 0x0820, 0x0820, 0x0820, | ||
344 | 0x0820, 0x0820, 0x0920, 0x0A38, | ||
345 | 0x0820, 0x0820, 0x0820, 0x0820, | ||
346 | 0x0820, 0x0820, 0x0920, 0x0A38, /* 32 */ | ||
347 | 0x0820, 0x0820, 0x0820, 0x0820, | ||
348 | 0x0820, 0x0820, 0x0920, 0x0A38, | ||
349 | 0x0820, 0x0820, 0x0820, 0x0820, | ||
350 | }; | ||
351 | |||
310 | static inline void assert_sizes(void) | 352 | static inline void assert_sizes(void) |
311 | { | 353 | { |
312 | BUILD_BUG_ON(B43_TAB_ROTOR_SIZE != ARRAY_SIZE(b43_tab_rotor)); | 354 | BUILD_BUG_ON(B43_TAB_ROTOR_SIZE != ARRAY_SIZE(b43_tab_rotor)); |
@@ -317,36 +359,65 @@ static inline void assert_sizes(void) | |||
317 | BUILD_BUG_ON(B43_TAB_NOISEA3_SIZE != ARRAY_SIZE(b43_tab_noisea3)); | 359 | BUILD_BUG_ON(B43_TAB_NOISEA3_SIZE != ARRAY_SIZE(b43_tab_noisea3)); |
318 | BUILD_BUG_ON(B43_TAB_NOISEG1_SIZE != ARRAY_SIZE(b43_tab_noiseg1)); | 360 | BUILD_BUG_ON(B43_TAB_NOISEG1_SIZE != ARRAY_SIZE(b43_tab_noiseg1)); |
319 | BUILD_BUG_ON(B43_TAB_NOISEG2_SIZE != ARRAY_SIZE(b43_tab_noiseg2)); | 361 | BUILD_BUG_ON(B43_TAB_NOISEG2_SIZE != ARRAY_SIZE(b43_tab_noiseg2)); |
320 | BUILD_BUG_ON(B43_TAB_NOISESCALEG_SIZE != | 362 | BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != |
363 | ARRAY_SIZE(b43_tab_noisescalea2)); | ||
364 | BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != | ||
365 | ARRAY_SIZE(b43_tab_noisescalea3)); | ||
366 | BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != | ||
321 | ARRAY_SIZE(b43_tab_noisescaleg1)); | 367 | ARRAY_SIZE(b43_tab_noisescaleg1)); |
322 | BUILD_BUG_ON(B43_TAB_NOISESCALEG_SIZE != | 368 | BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != |
323 | ARRAY_SIZE(b43_tab_noisescaleg2)); | 369 | ARRAY_SIZE(b43_tab_noisescaleg2)); |
324 | BUILD_BUG_ON(B43_TAB_NOISESCALEG_SIZE != | 370 | BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != |
325 | ARRAY_SIZE(b43_tab_noisescaleg3)); | 371 | ARRAY_SIZE(b43_tab_noisescaleg3)); |
326 | BUILD_BUG_ON(B43_TAB_SIGMASQR_SIZE != ARRAY_SIZE(b43_tab_sigmasqr1)); | 372 | BUILD_BUG_ON(B43_TAB_SIGMASQR_SIZE != ARRAY_SIZE(b43_tab_sigmasqr1)); |
327 | BUILD_BUG_ON(B43_TAB_SIGMASQR_SIZE != ARRAY_SIZE(b43_tab_sigmasqr2)); | 373 | BUILD_BUG_ON(B43_TAB_SIGMASQR_SIZE != ARRAY_SIZE(b43_tab_sigmasqr2)); |
374 | BUILD_BUG_ON(B43_TAB_RSSIAGC1_SIZE != ARRAY_SIZE(b43_tab_rssiagc1)); | ||
375 | BUILD_BUG_ON(B43_TAB_RSSIAGC2_SIZE != ARRAY_SIZE(b43_tab_rssiagc2)); | ||
328 | } | 376 | } |
329 | 377 | ||
330 | u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset) | 378 | u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset) |
331 | { | 379 | { |
332 | assert_sizes(); | 380 | struct b43_phy *phy = &dev->phy; |
381 | u16 addr; | ||
382 | |||
383 | addr = table + offset; | ||
384 | if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 1) { | ||
385 | b43_phy_write(dev, B43_PHY_OTABLECTL, addr); | ||
386 | phy->ofdm_valid = 1; | ||
387 | } | ||
388 | phy->ofdm_addr = addr; | ||
333 | 389 | ||
334 | b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); | ||
335 | return b43_phy_read(dev, B43_PHY_OTABLEI); | 390 | return b43_phy_read(dev, B43_PHY_OTABLEI); |
391 | assert_sizes(); | ||
336 | } | 392 | } |
337 | 393 | ||
338 | void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table, | 394 | void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table, |
339 | u16 offset, u16 value) | 395 | u16 offset, u16 value) |
340 | { | 396 | { |
341 | b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); | 397 | struct b43_phy *phy = &dev->phy; |
398 | u16 addr; | ||
399 | |||
400 | addr = table + offset; | ||
401 | if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 2) { | ||
402 | b43_phy_write(dev, B43_PHY_OTABLECTL, addr); | ||
403 | phy->ofdm_valid = 2; | ||
404 | } | ||
405 | phy->ofdm_addr = addr; | ||
342 | b43_phy_write(dev, B43_PHY_OTABLEI, value); | 406 | b43_phy_write(dev, B43_PHY_OTABLEI, value); |
343 | } | 407 | } |
344 | 408 | ||
345 | u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset) | 409 | u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset) |
346 | { | 410 | { |
411 | struct b43_phy *phy = &dev->phy; | ||
347 | u32 ret; | 412 | u32 ret; |
413 | u16 addr; | ||
348 | 414 | ||
349 | b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); | 415 | addr = table + offset; |
416 | if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 1) { | ||
417 | b43_phy_write(dev, B43_PHY_OTABLECTL, addr); | ||
418 | phy->ofdm_valid = 1; | ||
419 | } | ||
420 | phy->ofdm_addr = addr; | ||
350 | ret = b43_phy_read(dev, B43_PHY_OTABLEQ); | 421 | ret = b43_phy_read(dev, B43_PHY_OTABLEQ); |
351 | ret <<= 16; | 422 | ret <<= 16; |
352 | ret |= b43_phy_read(dev, B43_PHY_OTABLEI); | 423 | ret |= b43_phy_read(dev, B43_PHY_OTABLEI); |
@@ -357,9 +428,17 @@ u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset) | |||
357 | void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table, | 428 | void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table, |
358 | u16 offset, u32 value) | 429 | u16 offset, u32 value) |
359 | { | 430 | { |
360 | b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); | 431 | struct b43_phy *phy = &dev->phy; |
432 | u16 addr; | ||
433 | |||
434 | addr = table + offset; | ||
435 | if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 2) { | ||
436 | b43_phy_write(dev, B43_PHY_OTABLECTL, addr); | ||
437 | phy->ofdm_valid = 2; | ||
438 | } | ||
439 | phy->ofdm_addr = addr; | ||
440 | |||
361 | b43_phy_write(dev, B43_PHY_OTABLEI, value); | 441 | b43_phy_write(dev, B43_PHY_OTABLEI, value); |
362 | b43_phy_write(dev, B43_PHY_OTABLEQ, (value >> 16)); | ||
363 | } | 442 | } |
364 | 443 | ||
365 | u16 b43_gtab_read(struct b43_wldev *dev, u16 table, u16 offset) | 444 | u16 b43_gtab_read(struct b43_wldev *dev, u16 table, u16 offset) |
diff --git a/drivers/net/wireless/b43/tables.h b/drivers/net/wireless/b43/tables.h index 64635d7b518c..80e73c7cbac5 100644 --- a/drivers/net/wireless/b43/tables.h +++ b/drivers/net/wireless/b43/tables.h | |||
@@ -1,9 +1,9 @@ | |||
1 | #ifndef B43_TABLES_H_ | 1 | #ifndef B43_TABLES_H_ |
2 | #define B43_TABLES_H_ | 2 | #define B43_TABLES_H_ |
3 | 3 | ||
4 | #define B43_TAB_ROTOR_SIZE 53 | 4 | #define B43_TAB_ROTOR_SIZE 53 |
5 | extern const u32 b43_tab_rotor[]; | 5 | extern const u32 b43_tab_rotor[]; |
6 | #define B43_TAB_RETARD_SIZE 53 | 6 | #define B43_TAB_RETARD_SIZE 53 |
7 | extern const u32 b43_tab_retard[]; | 7 | extern const u32 b43_tab_retard[]; |
8 | #define B43_TAB_FINEFREQA_SIZE 256 | 8 | #define B43_TAB_FINEFREQA_SIZE 256 |
9 | extern const u16 b43_tab_finefreqa[]; | 9 | extern const u16 b43_tab_finefreqa[]; |
@@ -17,12 +17,18 @@ extern const u16 b43_tab_noisea3[]; | |||
17 | extern const u16 b43_tab_noiseg1[]; | 17 | extern const u16 b43_tab_noiseg1[]; |
18 | #define B43_TAB_NOISEG2_SIZE 8 | 18 | #define B43_TAB_NOISEG2_SIZE 8 |
19 | extern const u16 b43_tab_noiseg2[]; | 19 | extern const u16 b43_tab_noiseg2[]; |
20 | #define B43_TAB_NOISESCALEG_SIZE 27 | 20 | #define B43_TAB_NOISESCALE_SIZE 27 |
21 | extern const u16 b43_tab_noisescalea2[]; | ||
22 | extern const u16 b43_tab_noisescalea3[]; | ||
21 | extern const u16 b43_tab_noisescaleg1[]; | 23 | extern const u16 b43_tab_noisescaleg1[]; |
22 | extern const u16 b43_tab_noisescaleg2[]; | 24 | extern const u16 b43_tab_noisescaleg2[]; |
23 | extern const u16 b43_tab_noisescaleg3[]; | 25 | extern const u16 b43_tab_noisescaleg3[]; |
24 | #define B43_TAB_SIGMASQR_SIZE 53 | 26 | #define B43_TAB_SIGMASQR_SIZE 53 |
25 | extern const u16 b43_tab_sigmasqr1[]; | 27 | extern const u16 b43_tab_sigmasqr1[]; |
26 | extern const u16 b43_tab_sigmasqr2[]; | 28 | extern const u16 b43_tab_sigmasqr2[]; |
29 | #define B43_TAB_RSSIAGC1_SIZE 16 | ||
30 | extern const u16 b43_tab_rssiagc1[]; | ||
31 | #define B43_TAB_RSSIAGC2_SIZE 48 | ||
32 | extern const u16 b43_tab_rssiagc2[]; | ||
27 | 33 | ||
28 | #endif /* B43_TABLES_H_ */ | 34 | #endif /* B43_TABLES_H_ */ |
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c new file mode 100644 index 000000000000..2ccbdc09f49d --- /dev/null +++ b/drivers/net/wireless/b43/wa.c | |||
@@ -0,0 +1,668 @@ | |||
1 | /* | ||
2 | |||
3 | Broadcom B43 wireless driver | ||
4 | |||
5 | PHY workarounds. | ||
6 | |||
7 | Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, | ||
8 | Copyright (c) 2005-2007 Stefano Brivio <st3@riseup.net> | ||
9 | Copyright (c) 2005-2007 Michael Buesch <mbuesch@freenet.de> | ||
10 | Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org> | ||
11 | Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch> | ||
12 | |||
13 | This program is free software; you can redistribute it and/or modify | ||
14 | it under the terms of the GNU General Public License as published by | ||
15 | the Free Software Foundation; either version 2 of the License, or | ||
16 | (at your option) any later version. | ||
17 | |||
18 | This program is distributed in the hope that it will be useful, | ||
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | GNU General Public License for more details. | ||
22 | |||
23 | You should have received a copy of the GNU General Public License | ||
24 | along with this program; see the file COPYING. If not, write to | ||
25 | the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, | ||
26 | Boston, MA 02110-1301, USA. | ||
27 | |||
28 | */ | ||
29 | |||
30 | #include "b43.h" | ||
31 | #include "main.h" | ||
32 | #include "tables.h" | ||
33 | #include "phy.h" | ||
34 | #include "wa.h" | ||
35 | |||
36 | static void b43_wa_papd(struct b43_wldev *dev) | ||
37 | { | ||
38 | u16 backup; | ||
39 | |||
40 | backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0); | ||
41 | b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7); | ||
42 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0); | ||
43 | b43_dummy_transmission(dev); | ||
44 | b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup); | ||
45 | } | ||
46 | |||
47 | static void b43_wa_auxclipthr(struct b43_wldev *dev) | ||
48 | { | ||
49 | b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x3800); | ||
50 | } | ||
51 | |||
52 | static void b43_wa_afcdac(struct b43_wldev *dev) | ||
53 | { | ||
54 | b43_phy_write(dev, 0x0035, 0x03FF); | ||
55 | b43_phy_write(dev, 0x0036, 0x0400); | ||
56 | } | ||
57 | |||
58 | static void b43_wa_txdc_offset(struct b43_wldev *dev) | ||
59 | { | ||
60 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 0, 0x0051); | ||
61 | } | ||
62 | |||
63 | void b43_wa_initgains(struct b43_wldev *dev) | ||
64 | { | ||
65 | struct b43_phy *phy = &dev->phy; | ||
66 | |||
67 | b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9); | ||
68 | b43_phy_write(dev, B43_PHY_LPFGAINCTL, | ||
69 | b43_phy_read(dev, B43_PHY_LPFGAINCTL) & 0xFF0F); | ||
70 | if (phy->rev <= 2) | ||
71 | b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF); | ||
72 | b43_radio_write16(dev, 0x0002, 0x1FBF); | ||
73 | |||
74 | b43_phy_write(dev, 0x0024, 0x4680); | ||
75 | b43_phy_write(dev, 0x0020, 0x0003); | ||
76 | b43_phy_write(dev, 0x001D, 0x0F40); | ||
77 | b43_phy_write(dev, 0x001F, 0x1C00); | ||
78 | if (phy->rev <= 3) | ||
79 | b43_phy_write(dev, 0x002A, | ||
80 | (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x0400); | ||
81 | else if (phy->rev == 5) { | ||
82 | b43_phy_write(dev, 0x002A, | ||
83 | (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x1A00); | ||
84 | b43_phy_write(dev, 0x00CC, 0x2121); | ||
85 | } | ||
86 | if (phy->rev >= 3) | ||
87 | b43_phy_write(dev, 0x00BA, 0x3ED5); | ||
88 | } | ||
89 | |||
90 | static void b43_wa_divider(struct b43_wldev *dev) | ||
91 | { | ||
92 | b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) & ~0x0100); | ||
93 | b43_phy_write(dev, 0x008E, 0x58C1); | ||
94 | } | ||
95 | |||
96 | static void b43_wa_gt(struct b43_wldev *dev) /* Gain table. */ | ||
97 | { | ||
98 | if (dev->phy.rev <= 2) { | ||
99 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 0, 15); | ||
100 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 1, 31); | ||
101 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 2, 42); | ||
102 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 3, 48); | ||
103 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 4, 58); | ||
104 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19); | ||
105 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19); | ||
106 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19); | ||
107 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19); | ||
108 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21); | ||
109 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21); | ||
110 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25); | ||
111 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 0, 3); | ||
112 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 1, 3); | ||
113 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 2, 7); | ||
114 | } else { | ||
115 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19); | ||
116 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19); | ||
117 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19); | ||
118 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19); | ||
119 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21); | ||
120 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21); | ||
121 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */ | ||
126 | { | ||
127 | int i; | ||
128 | |||
129 | for (i = 0; i < 8; i++) | ||
130 | b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i + 8); | ||
131 | for (i = 8; i < 16; i++) | ||
132 | b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i - 8); | ||
133 | } | ||
134 | |||
135 | static void b43_wa_analog(struct b43_wldev *dev) | ||
136 | { | ||
137 | struct b43_phy *phy = &dev->phy; | ||
138 | |||
139 | if (phy->analog > 2) { | ||
140 | if (phy->type == B43_PHYTYPE_A) | ||
141 | b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1808); | ||
142 | else | ||
143 | b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000); | ||
144 | } else { | ||
145 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044); | ||
146 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201); | ||
147 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 6, 0x0040); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static void b43_wa_dac(struct b43_wldev *dev) | ||
152 | { | ||
153 | if (dev->phy.analog == 1) | ||
154 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, | ||
155 | (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0034) | 0x0008); | ||
156 | else | ||
157 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, | ||
158 | (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0078) | 0x0010); | ||
159 | } | ||
160 | |||
161 | static void b43_wa_fft(struct b43_wldev *dev) /* Fine frequency table */ | ||
162 | { | ||
163 | int i; | ||
164 | |||
165 | if (dev->phy.type == B43_PHYTYPE_A) | ||
166 | for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++) | ||
167 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqa[i]); | ||
168 | else | ||
169 | for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++) | ||
170 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqg[i]); | ||
171 | } | ||
172 | |||
173 | static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */ | ||
174 | { | ||
175 | struct b43_phy *phy = &dev->phy; | ||
176 | int i; | ||
177 | |||
178 | if (phy->type == B43_PHYTYPE_A) { | ||
179 | if (phy->rev == 2) | ||
180 | for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++) | ||
181 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea2[i]); | ||
182 | else | ||
183 | for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++) | ||
184 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea3[i]); | ||
185 | } else { | ||
186 | if (phy->rev == 1) | ||
187 | for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++) | ||
188 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg1[i]); | ||
189 | else | ||
190 | for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++) | ||
191 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg2[i]); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */ | ||
196 | { | ||
197 | int i; | ||
198 | |||
199 | for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) | ||
200 | b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]); | ||
201 | } | ||
202 | |||
203 | static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */ | ||
204 | { | ||
205 | struct b43_phy *phy = &dev->phy; | ||
206 | int i; | ||
207 | |||
208 | if (phy->type == B43_PHYTYPE_A) { | ||
209 | if (phy->rev <= 1) | ||
210 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
211 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
212 | i, 0); | ||
213 | else if (phy->rev == 2) | ||
214 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
215 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
216 | i, b43_tab_noisescalea2[i]); | ||
217 | else if (phy->rev == 3) | ||
218 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
219 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
220 | i, b43_tab_noisescalea3[i]); | ||
221 | else | ||
222 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
223 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
224 | i, b43_tab_noisescaleg3[i]); | ||
225 | } else { | ||
226 | if (phy->rev >= 6) { | ||
227 | if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) | ||
228 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
229 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
230 | i, b43_tab_noisescaleg3[i]); | ||
231 | else | ||
232 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
233 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
234 | i, b43_tab_noisescaleg2[i]); | ||
235 | } else { | ||
236 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
237 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
238 | i, b43_tab_noisescaleg1[i]); | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | static void b43_wa_art(struct b43_wldev *dev) /* ADV retard table */ | ||
244 | { | ||
245 | int i; | ||
246 | |||
247 | for (i = 0; i < B43_TAB_RETARD_SIZE; i++) | ||
248 | b43_ofdmtab_write32(dev, B43_OFDMTAB_ADVRETARD, | ||
249 | i, b43_tab_retard[i]); | ||
250 | } | ||
251 | |||
252 | static void b43_wa_txlna_gain(struct b43_wldev *dev) | ||
253 | { | ||
254 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 13, 0x0000); | ||
255 | } | ||
256 | |||
257 | static void b43_wa_crs_reset(struct b43_wldev *dev) | ||
258 | { | ||
259 | b43_phy_write(dev, 0x002C, 0x0064); | ||
260 | } | ||
261 | |||
262 | static void b43_wa_2060txlna_gain(struct b43_wldev *dev) | ||
263 | { | ||
264 | b43_hf_write(dev, b43_hf_read(dev) | | ||
265 | B43_HF_2060W); | ||
266 | } | ||
267 | |||
268 | static void b43_wa_lms(struct b43_wldev *dev) | ||
269 | { | ||
270 | b43_phy_write(dev, 0x0055, | ||
271 | (b43_phy_read(dev, 0x0055) & 0xFFC0) | 0x0004); | ||
272 | } | ||
273 | |||
274 | static void b43_wa_mixedsignal(struct b43_wldev *dev) | ||
275 | { | ||
276 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, 3); | ||
277 | } | ||
278 | |||
279 | static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */ | ||
280 | { | ||
281 | struct b43_phy *phy = &dev->phy; | ||
282 | int i; | ||
283 | const u16 *tab; | ||
284 | |||
285 | if (phy->type == B43_PHYTYPE_A) { | ||
286 | tab = b43_tab_sigmasqr1; | ||
287 | } else if (phy->type == B43_PHYTYPE_G) { | ||
288 | tab = b43_tab_sigmasqr2; | ||
289 | } else { | ||
290 | B43_WARN_ON(1); | ||
291 | return; | ||
292 | } | ||
293 | |||
294 | for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) { | ||
295 | b43_ofdmtab_write16(dev, B43_OFDMTAB_MINSIGSQ, | ||
296 | i, tab[i]); | ||
297 | } | ||
298 | } | ||
299 | |||
300 | static void b43_wa_iqadc(struct b43_wldev *dev) | ||
301 | { | ||
302 | if (dev->phy.analog == 4) | ||
303 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 0, | ||
304 | b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 0) & ~0xF000); | ||
305 | } | ||
306 | |||
307 | static void b43_wa_crs_ed(struct b43_wldev *dev) | ||
308 | { | ||
309 | struct b43_phy *phy = &dev->phy; | ||
310 | |||
311 | if (phy->rev == 1) { | ||
312 | b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x4F19); | ||
313 | } else if (phy->rev == 2) { | ||
314 | b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x1861); | ||
315 | b43_phy_write(dev, B43_PHY_CRSTHRES2_R1, 0x1861); | ||
316 | b43_phy_write(dev, B43_PHY_ANTDWELL, | ||
317 | b43_phy_read(dev, B43_PHY_ANTDWELL) | ||
318 | | 0x0800); | ||
319 | } else { | ||
320 | b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x0098); | ||
321 | b43_phy_write(dev, B43_PHY_CRSTHRES2_R1, 0x0070); | ||
322 | b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080); | ||
323 | b43_phy_write(dev, B43_PHY_ANTDWELL, | ||
324 | b43_phy_read(dev, B43_PHY_ANTDWELL) | ||
325 | | 0x0800); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | static void b43_wa_crs_thr(struct b43_wldev *dev) | ||
330 | { | ||
331 | b43_phy_write(dev, B43_PHY_CRS0, | ||
332 | (b43_phy_read(dev, B43_PHY_CRS0) & ~0x03C0) | 0xD000); | ||
333 | } | ||
334 | |||
335 | static void b43_wa_crs_blank(struct b43_wldev *dev) | ||
336 | { | ||
337 | b43_phy_write(dev, B43_PHY_OFDM(0x2C), 0x005A); | ||
338 | } | ||
339 | |||
340 | static void b43_wa_cck_shiftbits(struct b43_wldev *dev) | ||
341 | { | ||
342 | b43_phy_write(dev, B43_PHY_CCKSHIFTBITS, 0x0026); | ||
343 | } | ||
344 | |||
345 | static void b43_wa_wrssi_offset(struct b43_wldev *dev) | ||
346 | { | ||
347 | int i; | ||
348 | |||
349 | if (dev->phy.rev == 1) { | ||
350 | for (i = 0; i < 16; i++) { | ||
351 | b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI_R1, | ||
352 | i, 0x0020); | ||
353 | } | ||
354 | } else { | ||
355 | for (i = 0; i < 32; i++) { | ||
356 | b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI, | ||
357 | i, 0x0820); | ||
358 | } | ||
359 | } | ||
360 | } | ||
361 | |||
362 | static void b43_wa_txpuoff_rxpuon(struct b43_wldev *dev) | ||
363 | { | ||
364 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 2, 15); | ||
365 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 3, 20); | ||
366 | } | ||
367 | |||
368 | static void b43_wa_altagc(struct b43_wldev *dev) | ||
369 | { | ||
370 | struct b43_phy *phy = &dev->phy; | ||
371 | |||
372 | if (phy->rev == 1) { | ||
373 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 254); | ||
374 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 1, 13); | ||
375 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 2, 19); | ||
376 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 3, 25); | ||
377 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 0, 0x2710); | ||
378 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 1, 0x9B83); | ||
379 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 2, 0x9B83); | ||
380 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 3, 0x0F8D); | ||
381 | b43_phy_write(dev, B43_PHY_LMS, 4); | ||
382 | } else { | ||
383 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0, 254); | ||
384 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 1, 13); | ||
385 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 2, 19); | ||
386 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25); | ||
387 | } | ||
388 | |||
389 | b43_phy_write(dev, B43_PHY_CCKSHIFTBITS_WA, | ||
390 | (b43_phy_read(dev, B43_PHY_CCKSHIFTBITS_WA) & ~0xFF00) | 0x5700); | ||
391 | b43_phy_write(dev, B43_PHY_OFDM(0x1A), | ||
392 | (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x007F) | 0x000F); | ||
393 | b43_phy_write(dev, B43_PHY_OFDM(0x1A), | ||
394 | (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x3F80) | 0x2B80); | ||
395 | b43_phy_write(dev, B43_PHY_ANTWRSETT, | ||
396 | (b43_phy_read(dev, B43_PHY_ANTWRSETT) & 0xF0FF) | 0x0300); | ||
397 | b43_radio_write16(dev, 0x7A, | ||
398 | b43_radio_read16(dev, 0x7A) | 0x0008); | ||
399 | b43_phy_write(dev, B43_PHY_N1P1GAIN, | ||
400 | (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x000F) | 0x0008); | ||
401 | b43_phy_write(dev, B43_PHY_P1P2GAIN, | ||
402 | (b43_phy_read(dev, B43_PHY_P1P2GAIN) & ~0x0F00) | 0x0600); | ||
403 | b43_phy_write(dev, B43_PHY_N1N2GAIN, | ||
404 | (b43_phy_read(dev, B43_PHY_N1N2GAIN) & ~0x0F00) | 0x0700); | ||
405 | b43_phy_write(dev, B43_PHY_N1P1GAIN, | ||
406 | (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x0F00) | 0x0100); | ||
407 | if (phy->rev == 1) { | ||
408 | b43_phy_write(dev, B43_PHY_N1N2GAIN, | ||
409 | (b43_phy_read(dev, B43_PHY_N1N2GAIN) | ||
410 | & ~0x000F) | 0x0007); | ||
411 | } | ||
412 | b43_phy_write(dev, B43_PHY_OFDM(0x88), | ||
413 | (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x00FF) | 0x001C); | ||
414 | b43_phy_write(dev, B43_PHY_OFDM(0x88), | ||
415 | (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x3F00) | 0x0200); | ||
416 | b43_phy_write(dev, B43_PHY_OFDM(0x96), | ||
417 | (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0x00FF) | 0x001C); | ||
418 | b43_phy_write(dev, B43_PHY_OFDM(0x89), | ||
419 | (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x00FF) | 0x0020); | ||
420 | b43_phy_write(dev, B43_PHY_OFDM(0x89), | ||
421 | (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x3F00) | 0x0200); | ||
422 | b43_phy_write(dev, B43_PHY_OFDM(0x82), | ||
423 | (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & ~0x00FF) | 0x002E); | ||
424 | b43_phy_write(dev, B43_PHY_OFDM(0x96), | ||
425 | (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0xFF00) | 0x1A00); | ||
426 | b43_phy_write(dev, B43_PHY_OFDM(0x81), | ||
427 | (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0x00FF) | 0x0028); | ||
428 | b43_phy_write(dev, B43_PHY_OFDM(0x81), | ||
429 | (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0xFF00) | 0x2C00); | ||
430 | if (phy->rev == 1) { | ||
431 | b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B); | ||
432 | b43_phy_write(dev, B43_PHY_OFDM(0x1B), | ||
433 | (b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E) | 0x0002); | ||
434 | } else { | ||
435 | b43_phy_write(dev, B43_PHY_OFDM(0x1B), | ||
436 | b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E); | ||
437 | b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A); | ||
438 | b43_phy_write(dev, B43_PHY_LPFGAINCTL, | ||
439 | (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0x000F) | 0x0004); | ||
440 | if (phy->rev >= 6) { | ||
441 | b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A); | ||
442 | b43_phy_write(dev, B43_PHY_LPFGAINCTL, | ||
443 | (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0xF000) | 0x3000); | ||
444 | } | ||
445 | } | ||
446 | b43_phy_write(dev, B43_PHY_DIVSRCHIDX, | ||
447 | (b43_phy_read(dev, B43_PHY_DIVSRCHIDX) & 0x7F7F) | 0x7874); | ||
448 | b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00); | ||
449 | if (phy->rev == 1) { | ||
450 | b43_phy_write(dev, B43_PHY_DIVP1P2GAIN, | ||
451 | (b43_phy_read(dev, B43_PHY_DIVP1P2GAIN) & ~0x0F00) | 0x0600); | ||
452 | b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E); | ||
453 | b43_phy_write(dev, B43_PHY_ANTWRSETT, | ||
454 | (b43_phy_read(dev, B43_PHY_ANTWRSETT) & ~0x00FF) | 0x001E); | ||
455 | b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002); | ||
456 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0); | ||
457 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7); | ||
458 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 2, 16); | ||
459 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 3, 28); | ||
460 | } else { | ||
461 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 0, 0); | ||
462 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 1, 7); | ||
463 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 2, 16); | ||
464 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28); | ||
465 | } | ||
466 | if (phy->rev >= 6) { | ||
467 | b43_phy_write(dev, B43_PHY_OFDM(0x26), | ||
468 | b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x0003); | ||
469 | b43_phy_write(dev, B43_PHY_OFDM(0x26), | ||
470 | b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x1000); | ||
471 | } | ||
472 | } | ||
473 | |||
474 | static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */ | ||
475 | { | ||
476 | b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0xC480); | ||
477 | } | ||
478 | |||
479 | static void b43_wa_cpll_nonpilot(struct b43_wldev *dev) | ||
480 | { | ||
481 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 0, 0); | ||
482 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 1, 0); | ||
483 | } | ||
484 | |||
485 | static void b43_wa_rssi_adc(struct b43_wldev *dev) | ||
486 | { | ||
487 | if (dev->phy.analog == 4) | ||
488 | b43_phy_write(dev, 0x00DC, 0x7454); | ||
489 | } | ||
490 | |||
491 | static void b43_wa_boards_a(struct b43_wldev *dev) | ||
492 | { | ||
493 | struct ssb_bus *bus = dev->dev->bus; | ||
494 | |||
495 | if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && | ||
496 | bus->boardinfo.type == SSB_BOARD_BU4306 && | ||
497 | bus->boardinfo.rev < 0x30) { | ||
498 | b43_phy_write(dev, 0x0010, 0xE000); | ||
499 | b43_phy_write(dev, 0x0013, 0x0140); | ||
500 | b43_phy_write(dev, 0x0014, 0x0280); | ||
501 | } else { | ||
502 | if (bus->boardinfo.type == SSB_BOARD_MP4318 && | ||
503 | bus->boardinfo.rev < 0x20) { | ||
504 | b43_phy_write(dev, 0x0013, 0x0210); | ||
505 | b43_phy_write(dev, 0x0014, 0x0840); | ||
506 | } else { | ||
507 | b43_phy_write(dev, 0x0013, 0x0140); | ||
508 | b43_phy_write(dev, 0x0014, 0x0280); | ||
509 | } | ||
510 | if (dev->phy.rev <= 4) | ||
511 | b43_phy_write(dev, 0x0010, 0xE000); | ||
512 | else | ||
513 | b43_phy_write(dev, 0x0010, 0x2000); | ||
514 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 1, 0x0039); | ||
515 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 7, 0x0040); | ||
516 | } | ||
517 | } | ||
518 | |||
519 | static void b43_wa_boards_g(struct b43_wldev *dev) | ||
520 | { | ||
521 | struct ssb_bus *bus = dev->dev->bus; | ||
522 | struct b43_phy *phy = &dev->phy; | ||
523 | |||
524 | if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || | ||
525 | bus->boardinfo.type != SSB_BOARD_BU4306 || | ||
526 | bus->boardinfo.rev != 0x17) { | ||
527 | if (phy->rev < 2) { | ||
528 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002); | ||
529 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001); | ||
530 | } else { | ||
531 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002); | ||
532 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001); | ||
533 | if ((bus->sprom.r1.boardflags_lo & B43_BFL_EXTLNA) && | ||
534 | (phy->rev >= 7)) { | ||
535 | b43_phy_write(dev, B43_PHY_EXTG(0x11), | ||
536 | b43_phy_read(dev, B43_PHY_EXTG(0x11)) & 0xF7FF); | ||
537 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001); | ||
538 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001); | ||
539 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001); | ||
540 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0023, 0x0000); | ||
541 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0000, 0x0000); | ||
542 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0003, 0x0002); | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | if (bus->sprom.r1.boardflags_lo & B43_BFL_FEM) { | ||
547 | b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120); | ||
548 | b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480); | ||
549 | } | ||
550 | } | ||
551 | |||
552 | void b43_wa_all(struct b43_wldev *dev) | ||
553 | { | ||
554 | struct b43_phy *phy = &dev->phy; | ||
555 | |||
556 | if (phy->type == B43_PHYTYPE_A) { | ||
557 | switch (phy->rev) { | ||
558 | case 2: | ||
559 | b43_wa_papd(dev); | ||
560 | b43_wa_auxclipthr(dev); | ||
561 | b43_wa_afcdac(dev); | ||
562 | b43_wa_txdc_offset(dev); | ||
563 | b43_wa_initgains(dev); | ||
564 | b43_wa_divider(dev); | ||
565 | b43_wa_gt(dev); | ||
566 | b43_wa_rssi_lt(dev); | ||
567 | b43_wa_analog(dev); | ||
568 | b43_wa_dac(dev); | ||
569 | b43_wa_fft(dev); | ||
570 | b43_wa_nft(dev); | ||
571 | b43_wa_rt(dev); | ||
572 | b43_wa_nst(dev); | ||
573 | b43_wa_art(dev); | ||
574 | b43_wa_txlna_gain(dev); | ||
575 | b43_wa_crs_reset(dev); | ||
576 | b43_wa_2060txlna_gain(dev); | ||
577 | b43_wa_lms(dev); | ||
578 | break; | ||
579 | case 3: | ||
580 | b43_wa_papd(dev); | ||
581 | b43_wa_mixedsignal(dev); | ||
582 | b43_wa_rssi_lt(dev); | ||
583 | b43_wa_txdc_offset(dev); | ||
584 | b43_wa_initgains(dev); | ||
585 | b43_wa_dac(dev); | ||
586 | b43_wa_nft(dev); | ||
587 | b43_wa_nst(dev); | ||
588 | b43_wa_msst(dev); | ||
589 | b43_wa_analog(dev); | ||
590 | b43_wa_gt(dev); | ||
591 | b43_wa_txpuoff_rxpuon(dev); | ||
592 | b43_wa_txlna_gain(dev); | ||
593 | break; | ||
594 | case 5: | ||
595 | b43_wa_iqadc(dev); | ||
596 | case 6: | ||
597 | b43_wa_papd(dev); | ||
598 | b43_wa_rssi_lt(dev); | ||
599 | b43_wa_txdc_offset(dev); | ||
600 | b43_wa_initgains(dev); | ||
601 | b43_wa_dac(dev); | ||
602 | b43_wa_nft(dev); | ||
603 | b43_wa_nst(dev); | ||
604 | b43_wa_msst(dev); | ||
605 | b43_wa_analog(dev); | ||
606 | b43_wa_gt(dev); | ||
607 | b43_wa_txpuoff_rxpuon(dev); | ||
608 | b43_wa_txlna_gain(dev); | ||
609 | break; | ||
610 | case 7: | ||
611 | b43_wa_iqadc(dev); | ||
612 | b43_wa_papd(dev); | ||
613 | b43_wa_rssi_lt(dev); | ||
614 | b43_wa_txdc_offset(dev); | ||
615 | b43_wa_initgains(dev); | ||
616 | b43_wa_dac(dev); | ||
617 | b43_wa_nft(dev); | ||
618 | b43_wa_nst(dev); | ||
619 | b43_wa_msst(dev); | ||
620 | b43_wa_analog(dev); | ||
621 | b43_wa_gt(dev); | ||
622 | b43_wa_txpuoff_rxpuon(dev); | ||
623 | b43_wa_txlna_gain(dev); | ||
624 | b43_wa_rssi_adc(dev); | ||
625 | default: | ||
626 | B43_WARN_ON(1); | ||
627 | } | ||
628 | b43_wa_boards_a(dev); | ||
629 | } else if (phy->type == B43_PHYTYPE_G) { | ||
630 | switch (phy->rev) { | ||
631 | case 1://XXX review rev1 | ||
632 | b43_wa_crs_ed(dev); | ||
633 | b43_wa_crs_thr(dev); | ||
634 | b43_wa_crs_blank(dev); | ||
635 | b43_wa_cck_shiftbits(dev); | ||
636 | b43_wa_fft(dev); | ||
637 | b43_wa_nft(dev); | ||
638 | b43_wa_rt(dev); | ||
639 | b43_wa_nst(dev); | ||
640 | b43_wa_art(dev); | ||
641 | b43_wa_wrssi_offset(dev); | ||
642 | b43_wa_altagc(dev); | ||
643 | break; | ||
644 | case 2: | ||
645 | case 6: | ||
646 | case 7: | ||
647 | case 8: | ||
648 | b43_wa_tr_ltov(dev); | ||
649 | b43_wa_crs_ed(dev); | ||
650 | b43_wa_rssi_lt(dev); | ||
651 | b43_wa_nft(dev); | ||
652 | b43_wa_nst(dev); | ||
653 | b43_wa_msst(dev); | ||
654 | b43_wa_wrssi_offset(dev); | ||
655 | b43_wa_altagc(dev); | ||
656 | b43_wa_analog(dev); | ||
657 | b43_wa_txpuoff_rxpuon(dev); | ||
658 | break; | ||
659 | default: | ||
660 | B43_WARN_ON(1); | ||
661 | } | ||
662 | b43_wa_boards_g(dev); | ||
663 | } else { /* No N PHY support so far */ | ||
664 | B43_WARN_ON(1); | ||
665 | } | ||
666 | |||
667 | b43_wa_cpll_nonpilot(dev); | ||
668 | } | ||
diff --git a/drivers/net/wireless/b43/wa.h b/drivers/net/wireless/b43/wa.h new file mode 100644 index 000000000000..e163c5e56e81 --- /dev/null +++ b/drivers/net/wireless/b43/wa.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef B43_WA_H_ | ||
2 | #define B43_WA_H_ | ||
3 | |||
4 | void b43_wa_initgains(struct b43_wldev *dev); | ||
5 | void b43_wa_all(struct b43_wldev *dev); | ||
6 | |||
7 | #endif /* B43_WA_H_ */ | ||