diff options
author | Stefano Brivio <stefano.brivio@polimi.it> | 2007-11-06 16:49:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:04:31 -0500 |
commit | 61bca6eb85c863603d6054530e2f65c3b9aba85b (patch) | |
tree | 9b67e165af38ae504d64d3b03882fb4ce3efb016 /drivers/net/wireless/b43/phy.c | |
parent | db9683fb19a0f0da1cb4c296ffe1a8db03333cbc (diff) |
b43: rewrite A PHY initialization
Rewrite and sync A PHY initialization with specs, thus allowing for further
work to be done on 802.11a support. Note that A PHY initialization involves
G PHYs as well.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Acked-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/phy.c')
-rw-r--r-- | drivers/net/wireless/b43/phy.c | 613 |
1 files changed, 118 insertions, 495 deletions
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; |