diff options
author | Michael Buesch <mbuesch@freenet.de> | 2006-03-21 12:16:28 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-03-27 11:19:43 -0500 |
commit | e382c234cbc6fcd76e9ed1168c77fe88d75df73c (patch) | |
tree | 3f0a38c5e9712f62384019e670126a9b46a18c39 | |
parent | 6ecb26904c9db15ca964d60b9483f19dc51bda5b (diff) |
[PATCH] bcm43xx: sync interference mitigation code to the specs.
This also includes a rewritten valuesave-stack.
Signed-off-by: Michael Buesch <mbuesch@freenet.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_radio.c | 447 |
2 files changed, 309 insertions, 150 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index 1fca1f9c48fe..57fcaafcf7dd 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h | |||
@@ -526,8 +526,16 @@ struct bcm43xx_radioinfo { | |||
526 | 526 | ||
527 | /* Current Interference Mitigation mode */ | 527 | /* Current Interference Mitigation mode */ |
528 | int interfmode; | 528 | int interfmode; |
529 | /* Stack of saved values from the Interference Mitigation code */ | 529 | /* Stack of saved values from the Interference Mitigation code. |
530 | u16 interfstack[20]; | 530 | * Each value in the stack is layed out as follows: |
531 | * bit 0-11: offset | ||
532 | * bit 12-15: register ID | ||
533 | * bit 16-32: value | ||
534 | * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT | ||
535 | */ | ||
536 | #define BCM43xx_INTERFSTACK_SIZE 26 | ||
537 | u32 interfstack[BCM43xx_INTERFSTACK_SIZE]; | ||
538 | |||
531 | /* Saved values from the NRSSI Slope calculation */ | 539 | /* Saved values from the NRSSI Slope calculation */ |
532 | s16 nrssi[2]; | 540 | s16 nrssi[2]; |
533 | s32 nrssislope; | 541 | s32 nrssislope; |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c index 4e8d8c936ab4..63aae43ba838 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c | |||
@@ -879,24 +879,76 @@ void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm) | |||
879 | } | 879 | } |
880 | } | 880 | } |
881 | 881 | ||
882 | /* Helper macros to save on and restore values from the radio->interfstack */ | 882 | /* Stack implementation to save/restore values from the |
883 | #ifdef stack_save | 883 | * interference mitigation code. |
884 | # undef stack_save | 884 | * It is save to restore values in random order. |
885 | #endif | 885 | */ |
886 | #ifdef stack_restore | 886 | static void _stack_save(u32 *_stackptr, size_t *stackidx, |
887 | # undef stack_restore | 887 | u8 id, u16 offset, u16 value) |
888 | #endif | 888 | { |
889 | #define stack_save(value) \ | 889 | u32 *stackptr = &(_stackptr[*stackidx]); |
890 | |||
891 | assert((offset & 0xF000) == 0x0000); | ||
892 | assert((id & 0xF0) == 0x00); | ||
893 | *stackptr = offset; | ||
894 | *stackptr |= ((u32)id) << 12; | ||
895 | *stackptr |= ((u32)value) << 16; | ||
896 | (*stackidx)++; | ||
897 | assert(*stackidx < BCM43xx_INTERFSTACK_SIZE); | ||
898 | } | ||
899 | |||
900 | static u16 _stack_restore(u32 *stackptr, | ||
901 | u8 id, u16 offset) | ||
902 | { | ||
903 | size_t i; | ||
904 | |||
905 | assert((offset & 0xF000) == 0x0000); | ||
906 | assert((id & 0xF0) == 0x00); | ||
907 | for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) { | ||
908 | if ((*stackptr & 0x00000FFF) != offset) | ||
909 | continue; | ||
910 | if (((*stackptr & 0x0000F000) >> 12) != id) | ||
911 | continue; | ||
912 | return ((*stackptr & 0xFFFF0000) >> 16); | ||
913 | } | ||
914 | assert(0); | ||
915 | |||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | #define phy_stacksave(offset) \ | ||
890 | do { \ | 920 | do { \ |
891 | assert(i < ARRAY_SIZE(radio->interfstack)); \ | 921 | _stack_save(stack, &stackidx, 0x1, (offset), \ |
892 | stack[i++] = (value); \ | 922 | bcm43xx_phy_read(bcm, (offset))); \ |
923 | } while (0) | ||
924 | #define phy_stackrestore(offset) \ | ||
925 | do { \ | ||
926 | bcm43xx_phy_write(bcm, (offset), \ | ||
927 | _stack_restore(stack, 0x1, \ | ||
928 | (offset))); \ | ||
929 | } while (0) | ||
930 | #define radio_stacksave(offset) \ | ||
931 | do { \ | ||
932 | _stack_save(stack, &stackidx, 0x2, (offset), \ | ||
933 | bcm43xx_radio_read16(bcm, (offset))); \ | ||
934 | } while (0) | ||
935 | #define radio_stackrestore(offset) \ | ||
936 | do { \ | ||
937 | bcm43xx_radio_write16(bcm, (offset), \ | ||
938 | _stack_restore(stack, 0x2, \ | ||
939 | (offset))); \ | ||
940 | } while (0) | ||
941 | #define ilt_stacksave(offset) \ | ||
942 | do { \ | ||
943 | _stack_save(stack, &stackidx, 0x3, (offset), \ | ||
944 | bcm43xx_ilt_read(bcm, (offset))); \ | ||
945 | } while (0) | ||
946 | #define ilt_stackrestore(offset) \ | ||
947 | do { \ | ||
948 | bcm43xx_ilt_write(bcm, (offset), \ | ||
949 | _stack_restore(stack, 0x3, \ | ||
950 | (offset))); \ | ||
893 | } while (0) | 951 | } while (0) |
894 | |||
895 | #define stack_restore() \ | ||
896 | ({ \ | ||
897 | assert(i < ARRAY_SIZE(radio->interfstack)); \ | ||
898 | stack[i++]; \ | ||
899 | }) | ||
900 | 952 | ||
901 | static void | 953 | static void |
902 | bcm43xx_radio_interference_mitigation_enable(struct bcm43xx_private *bcm, | 954 | bcm43xx_radio_interference_mitigation_enable(struct bcm43xx_private *bcm, |
@@ -904,144 +956,231 @@ bcm43xx_radio_interference_mitigation_enable(struct bcm43xx_private *bcm, | |||
904 | { | 956 | { |
905 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); | 957 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); |
906 | struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); | 958 | struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); |
907 | int i = 0; | ||
908 | u16 *stack = radio->interfstack; | ||
909 | u16 tmp, flipped; | 959 | u16 tmp, flipped; |
960 | u32 tmp32; | ||
961 | size_t stackidx = 0; | ||
962 | u32 *stack = radio->interfstack; | ||
910 | 963 | ||
911 | switch (mode) { | 964 | switch (mode) { |
912 | case BCM43xx_RADIO_INTERFMODE_NONWLAN: | 965 | case BCM43xx_RADIO_INTERFMODE_NONWLAN: |
913 | if (phy->rev != 1) { | 966 | if (phy->rev != 1) { |
914 | bcm43xx_phy_write(bcm, 0x042B, | 967 | bcm43xx_phy_write(bcm, 0x042B, |
915 | bcm43xx_phy_read(bcm, 0x042B) & 0x0800); | 968 | bcm43xx_phy_read(bcm, 0x042B) | 0x0800); |
916 | bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, | 969 | bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, |
917 | bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & ~0x4000); | 970 | bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & ~0x4000); |
918 | break; | 971 | break; |
919 | } | 972 | } |
973 | radio_stacksave(0x0078); | ||
920 | tmp = (bcm43xx_radio_read16(bcm, 0x0078) & 0x001E); | 974 | tmp = (bcm43xx_radio_read16(bcm, 0x0078) & 0x001E); |
921 | flipped = flip_4bit(tmp); | 975 | flipped = flip_4bit(tmp); |
922 | if ((flipped >> 1) >= 4) | 976 | if (flipped < 10 && flipped >= 8) |
923 | tmp = flipped - 3; | 977 | flipped = 7; |
924 | tmp = flip_4bit(tmp); | 978 | else if (flipped >= 10) |
925 | bcm43xx_radio_write16(bcm, 0x0078, tmp << 1); | 979 | flipped -= 3; |
980 | flipped = flip_4bit(flipped); | ||
981 | flipped = (flipped << 1) | 0x0020; | ||
982 | bcm43xx_radio_write16(bcm, 0x0078, flipped); | ||
926 | 983 | ||
927 | bcm43xx_calc_nrssi_threshold(bcm); | 984 | bcm43xx_calc_nrssi_threshold(bcm); |
928 | 985 | ||
929 | if (bcm->current_core->rev < 5) { | 986 | phy_stacksave(0x0406); |
930 | stack_save(bcm43xx_phy_read(bcm, 0x0406)); | 987 | bcm43xx_phy_write(bcm, 0x0406, 0x7E28); |
931 | bcm43xx_phy_write(bcm, 0x0406, 0x7E28); | ||
932 | } else { | ||
933 | stack_save(bcm43xx_phy_read(bcm, 0x04C0)); | ||
934 | stack_save(bcm43xx_phy_read(bcm, 0x04C1)); | ||
935 | bcm43xx_phy_write(bcm, 0x04C0, 0x3E04); | ||
936 | bcm43xx_phy_write(bcm, 0x04C1, 0x0640); | ||
937 | } | ||
938 | 988 | ||
939 | bcm43xx_phy_write(bcm, 0x042B, | 989 | bcm43xx_phy_write(bcm, 0x042B, |
940 | bcm43xx_phy_read(bcm, 0x042B) | 0x0800); | 990 | bcm43xx_phy_read(bcm, 0x042B) | 0x0800); |
941 | bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, | 991 | bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, |
942 | bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | 0x1000); | 992 | bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | 0x1000); |
943 | 993 | ||
944 | stack_save(bcm43xx_phy_read(bcm, 0x04A0)); | 994 | phy_stacksave(0x04A0); |
945 | bcm43xx_phy_write(bcm, 0x04A0, | 995 | bcm43xx_phy_write(bcm, 0x04A0, |
946 | (bcm43xx_phy_read(bcm, 0x04A0) & 0xC0C0) | 0x0008); | 996 | (bcm43xx_phy_read(bcm, 0x04A0) & 0xC0C0) | 0x0008); |
947 | stack_save(bcm43xx_phy_read(bcm, 0x04A1)); | 997 | phy_stacksave(0x04A1); |
948 | bcm43xx_phy_write(bcm, 0x04A1, | 998 | bcm43xx_phy_write(bcm, 0x04A1, |
949 | (bcm43xx_phy_read(bcm, 0x04A1) & 0xC0C0) | 0x0605); | 999 | (bcm43xx_phy_read(bcm, 0x04A1) & 0xC0C0) | 0x0605); |
950 | stack_save(bcm43xx_phy_read(bcm, 0x04A2)); | 1000 | phy_stacksave(0x04A2); |
951 | bcm43xx_phy_write(bcm, 0x04A2, | 1001 | bcm43xx_phy_write(bcm, 0x04A2, |
952 | (bcm43xx_phy_read(bcm, 0x04A2) & 0xC0C0) | 0x0204); | 1002 | (bcm43xx_phy_read(bcm, 0x04A2) & 0xC0C0) | 0x0204); |
953 | stack_save(bcm43xx_phy_read(bcm, 0x04A8)); | 1003 | phy_stacksave(0x04A8); |
954 | bcm43xx_phy_write(bcm, 0x04A8, | 1004 | bcm43xx_phy_write(bcm, 0x04A8, |
955 | (bcm43xx_phy_read(bcm, 0x04A8) & 0xC0C0) | 0x0403); | 1005 | (bcm43xx_phy_read(bcm, 0x04A8) & 0xC0C0) | 0x0803); |
956 | stack_save(bcm43xx_phy_read(bcm, 0x04AB)); | 1006 | phy_stacksave(0x04AB); |
957 | bcm43xx_phy_write(bcm, 0x04AB, | 1007 | bcm43xx_phy_write(bcm, 0x04AB, |
958 | (bcm43xx_phy_read(bcm, 0x04AB) & 0xC0C0) | 0x0504); | 1008 | (bcm43xx_phy_read(bcm, 0x04AB) & 0xC0C0) | 0x0605); |
959 | 1009 | ||
960 | stack_save(bcm43xx_phy_read(bcm, 0x04A7)); | 1010 | phy_stacksave(0x04A7); |
961 | bcm43xx_phy_write(bcm, 0x04A7, 0x0002); | 1011 | bcm43xx_phy_write(bcm, 0x04A7, 0x0002); |
962 | stack_save(bcm43xx_phy_read(bcm, 0x04A3)); | 1012 | phy_stacksave(0x04A3); |
963 | bcm43xx_phy_write(bcm, 0x04A3, 0x287A); | 1013 | bcm43xx_phy_write(bcm, 0x04A3, 0x287A); |
964 | stack_save(bcm43xx_phy_read(bcm, 0x04A9)); | 1014 | phy_stacksave(0x04A9); |
965 | bcm43xx_phy_write(bcm, 0x04A9, 0x2027); | 1015 | bcm43xx_phy_write(bcm, 0x04A9, 0x2027); |
966 | stack_save(bcm43xx_phy_read(bcm, 0x0493)); | 1016 | phy_stacksave(0x0493); |
967 | bcm43xx_phy_write(bcm, 0x0493, 0x32F5); | 1017 | bcm43xx_phy_write(bcm, 0x0493, 0x32F5); |
968 | stack_save(bcm43xx_phy_read(bcm, 0x04AA)); | 1018 | phy_stacksave(0x04AA); |
969 | bcm43xx_phy_write(bcm, 0x04AA, 0x2027); | 1019 | bcm43xx_phy_write(bcm, 0x04AA, 0x2027); |
970 | stack_save(bcm43xx_phy_read(bcm, 0x04AC)); | 1020 | phy_stacksave(0x04AC); |
971 | bcm43xx_phy_write(bcm, 0x04AC, 0x32F5); | 1021 | bcm43xx_phy_write(bcm, 0x04AC, 0x32F5); |
972 | break; | 1022 | break; |
973 | case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: | 1023 | case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: |
974 | if (bcm43xx_phy_read(bcm, 0x0033) == 0x0800) | 1024 | if (bcm43xx_phy_read(bcm, 0x0033) & 0x0800) |
975 | break; | 1025 | break; |
976 | 1026 | ||
977 | radio->aci_enable = 1; | 1027 | radio->aci_enable = 1; |
978 | 1028 | ||
979 | stack_save(bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD)); | 1029 | phy_stacksave(BCM43xx_PHY_RADIO_BITFIELD); |
980 | stack_save(bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS)); | 1030 | phy_stacksave(BCM43xx_PHY_G_CRS); |
981 | if (bcm->current_core->rev < 5) { | 1031 | if (phy->rev < 2) { |
982 | stack_save(bcm43xx_phy_read(bcm, 0x0406)); | 1032 | phy_stacksave(0x0406); |
983 | } else { | 1033 | } else { |
984 | stack_save(bcm43xx_phy_read(bcm, 0x04C0)); | 1034 | phy_stacksave(0x04C0); |
985 | stack_save(bcm43xx_phy_read(bcm, 0x04C1)); | 1035 | phy_stacksave(0x04C1); |
986 | } | 1036 | } |
987 | stack_save(bcm43xx_phy_read(bcm, 0x0033)); | 1037 | phy_stacksave(0x0033); |
988 | stack_save(bcm43xx_phy_read(bcm, 0x04A7)); | 1038 | phy_stacksave(0x04A7); |
989 | stack_save(bcm43xx_phy_read(bcm, 0x04A3)); | 1039 | phy_stacksave(0x04A3); |
990 | stack_save(bcm43xx_phy_read(bcm, 0x04A9)); | 1040 | phy_stacksave(0x04A9); |
991 | stack_save(bcm43xx_phy_read(bcm, 0x04AA)); | 1041 | phy_stacksave(0x04AA); |
992 | stack_save(bcm43xx_phy_read(bcm, 0x04AC)); | 1042 | phy_stacksave(0x04AC); |
993 | stack_save(bcm43xx_phy_read(bcm, 0x0493)); | 1043 | phy_stacksave(0x0493); |
994 | stack_save(bcm43xx_phy_read(bcm, 0x04A1)); | 1044 | phy_stacksave(0x04A1); |
995 | stack_save(bcm43xx_phy_read(bcm, 0x04A0)); | 1045 | phy_stacksave(0x04A0); |
996 | stack_save(bcm43xx_phy_read(bcm, 0x04A2)); | 1046 | phy_stacksave(0x04A2); |
997 | stack_save(bcm43xx_phy_read(bcm, 0x048A)); | 1047 | phy_stacksave(0x048A); |
998 | stack_save(bcm43xx_phy_read(bcm, 0x04A8)); | 1048 | phy_stacksave(0x04A8); |
999 | stack_save(bcm43xx_phy_read(bcm, 0x04AB)); | 1049 | phy_stacksave(0x04AB); |
1050 | if (phy->rev == 2) { | ||
1051 | phy_stacksave(0x04AD); | ||
1052 | phy_stacksave(0x04AE); | ||
1053 | } else if (phy->rev >= 3) { | ||
1054 | phy_stacksave(0x04AD); | ||
1055 | phy_stacksave(0x0415); | ||
1056 | phy_stacksave(0x0416); | ||
1057 | phy_stacksave(0x0417); | ||
1058 | ilt_stacksave(0x1A00 + 0x2); | ||
1059 | ilt_stacksave(0x1A00 + 0x3); | ||
1060 | } | ||
1061 | phy_stacksave(0x042B); | ||
1062 | phy_stacksave(0x048C); | ||
1000 | 1063 | ||
1001 | bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, | 1064 | bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, |
1002 | bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) & 0xEFFF); | 1065 | bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) |
1066 | & ~0x1000); | ||
1003 | bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, | 1067 | bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, |
1004 | (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0xEFFF) | 0x0002); | 1068 | (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) |
1069 | & 0xFFFC) | 0x0002); | ||
1005 | 1070 | ||
1006 | bcm43xx_phy_write(bcm, 0x04A7, 0x0800); | 1071 | bcm43xx_phy_write(bcm, 0x0033, 0x0800); |
1007 | bcm43xx_phy_write(bcm, 0x04A3, 0x287A); | 1072 | bcm43xx_phy_write(bcm, 0x04A3, 0x2027); |
1008 | bcm43xx_phy_write(bcm, 0x04A9, 0x2027); | 1073 | bcm43xx_phy_write(bcm, 0x04A9, 0x1CA8); |
1009 | bcm43xx_phy_write(bcm, 0x0493, 0x32F5); | 1074 | bcm43xx_phy_write(bcm, 0x0493, 0x287A); |
1010 | bcm43xx_phy_write(bcm, 0x04AA, 0x2027); | 1075 | bcm43xx_phy_write(bcm, 0x04AA, 0x1CA8); |
1011 | bcm43xx_phy_write(bcm, 0x04AC, 0x32F5); | 1076 | bcm43xx_phy_write(bcm, 0x04AC, 0x287A); |
1012 | 1077 | ||
1013 | bcm43xx_phy_write(bcm, 0x04A0, | 1078 | bcm43xx_phy_write(bcm, 0x04A0, |
1014 | (bcm43xx_phy_read(bcm, 0x04A0) & 0xFFC0) | 0x001A); | 1079 | (bcm43xx_phy_read(bcm, 0x04A0) |
1015 | if (bcm->current_core->rev < 5) { | 1080 | & 0xFFC0) | 0x001A); |
1016 | bcm43xx_phy_write(bcm, 0x0406, 0x280D); | 1081 | bcm43xx_phy_write(bcm, 0x04A7, 0x000D); |
1017 | } else { | 1082 | |
1018 | bcm43xx_phy_write(bcm, 0x04C0, 0x0640); | 1083 | if (phy->rev < 2) { |
1084 | bcm43xx_phy_write(bcm, 0x0406, 0xFF0D); | ||
1085 | } else if (phy->rev == 2) { | ||
1086 | bcm43xx_phy_write(bcm, 0x04C0, 0xFFFF); | ||
1019 | bcm43xx_phy_write(bcm, 0x04C1, 0x00A9); | 1087 | bcm43xx_phy_write(bcm, 0x04C1, 0x00A9); |
1088 | } else { | ||
1089 | bcm43xx_phy_write(bcm, 0x04C0, 0x00C1); | ||
1090 | bcm43xx_phy_write(bcm, 0x04C1, 0x0059); | ||
1020 | } | 1091 | } |
1021 | 1092 | ||
1022 | bcm43xx_phy_write(bcm, 0x04A1, | 1093 | bcm43xx_phy_write(bcm, 0x04A1, |
1023 | (bcm43xx_phy_read(bcm, 0x04A1) & 0xC0FF) | 0x1800); | 1094 | (bcm43xx_phy_read(bcm, 0x04A1) |
1095 | & 0xC0FF) | 0x1800); | ||
1024 | bcm43xx_phy_write(bcm, 0x04A1, | 1096 | bcm43xx_phy_write(bcm, 0x04A1, |
1025 | (bcm43xx_phy_read(bcm, 0x04A1) & 0xFFC0) | 0x0016); | 1097 | (bcm43xx_phy_read(bcm, 0x04A1) |
1026 | bcm43xx_phy_write(bcm, 0x04A2, | 1098 | & 0xFFC0) | 0x0015); |
1027 | (bcm43xx_phy_read(bcm, 0x04A2) & 0xF0FF) | 0x0900); | ||
1028 | bcm43xx_phy_write(bcm, 0x04A0, | ||
1029 | (bcm43xx_phy_read(bcm, 0x04A0) & 0xF0FF) | 0x0700); | ||
1030 | bcm43xx_phy_write(bcm, 0x04A2, | ||
1031 | (bcm43xx_phy_read(bcm, 0x04A2) & 0xFFF0) | 0x000D); | ||
1032 | bcm43xx_phy_write(bcm, 0x04A8, | 1099 | bcm43xx_phy_write(bcm, 0x04A8, |
1033 | (bcm43xx_phy_read(bcm, 0x04A8) & 0xCFFF) | 0x1000); | 1100 | (bcm43xx_phy_read(bcm, 0x04A8) |
1101 | & 0xCFFF) | 0x1000); | ||
1034 | bcm43xx_phy_write(bcm, 0x04A8, | 1102 | bcm43xx_phy_write(bcm, 0x04A8, |
1035 | (bcm43xx_phy_read(bcm, 0x04A8) & 0xF0FF) | 0x0A00); | 1103 | (bcm43xx_phy_read(bcm, 0x04A8) |
1104 | & 0xF0FF) | 0x0A00); | ||
1036 | bcm43xx_phy_write(bcm, 0x04AB, | 1105 | bcm43xx_phy_write(bcm, 0x04AB, |
1037 | (bcm43xx_phy_read(bcm, 0x04AB) & 0xCFFF) | 0x1000); | 1106 | (bcm43xx_phy_read(bcm, 0x04AB) |
1107 | & 0xCFFF) | 0x1000); | ||
1038 | bcm43xx_phy_write(bcm, 0x04AB, | 1108 | bcm43xx_phy_write(bcm, 0x04AB, |
1039 | (bcm43xx_phy_read(bcm, 0x04AB) & 0xF0FF) | 0x0800); | 1109 | (bcm43xx_phy_read(bcm, 0x04AB) |
1110 | & 0xF0FF) | 0x0800); | ||
1040 | bcm43xx_phy_write(bcm, 0x04AB, | 1111 | bcm43xx_phy_write(bcm, 0x04AB, |
1041 | (bcm43xx_phy_read(bcm, 0x04AB) & 0xFFCF) | 0x0010); | 1112 | (bcm43xx_phy_read(bcm, 0x04AB) |
1113 | & 0xFFCF) | 0x0010); | ||
1042 | bcm43xx_phy_write(bcm, 0x04AB, | 1114 | bcm43xx_phy_write(bcm, 0x04AB, |
1043 | (bcm43xx_phy_read(bcm, 0x04AB) & 0xFFF0) | 0x0006); | 1115 | (bcm43xx_phy_read(bcm, 0x04AB) |
1116 | & 0xFFF0) | 0x0005); | ||
1117 | bcm43xx_phy_write(bcm, 0x04A8, | ||
1118 | (bcm43xx_phy_read(bcm, 0x04A8) | ||
1119 | & 0xFFCF) | 0x0010); | ||
1120 | bcm43xx_phy_write(bcm, 0x04A8, | ||
1121 | (bcm43xx_phy_read(bcm, 0x04A8) | ||
1122 | & 0xFFF0) | 0x0006); | ||
1123 | bcm43xx_phy_write(bcm, 0x04A2, | ||
1124 | (bcm43xx_phy_read(bcm, 0x04A2) | ||
1125 | & 0xF0FF) | 0x0800); | ||
1126 | bcm43xx_phy_write(bcm, 0x04A0, | ||
1127 | (bcm43xx_phy_read(bcm, 0x04A0) | ||
1128 | & 0xF0FF) | 0x0500); | ||
1129 | bcm43xx_phy_write(bcm, 0x04A2, | ||
1130 | (bcm43xx_phy_read(bcm, 0x04A2) | ||
1131 | & 0xFFF0) | 0x000B); | ||
1044 | 1132 | ||
1133 | if (phy->rev >= 3) { | ||
1134 | bcm43xx_phy_write(bcm, 0x048A, | ||
1135 | bcm43xx_phy_read(bcm, 0x048A) | ||
1136 | & ~0x8000); | ||
1137 | bcm43xx_phy_write(bcm, 0x0415, | ||
1138 | (bcm43xx_phy_read(bcm, 0x0415) | ||
1139 | & 0x8000) | 0x36D8); | ||
1140 | bcm43xx_phy_write(bcm, 0x0416, | ||
1141 | (bcm43xx_phy_read(bcm, 0x0416) | ||
1142 | & 0x8000) | 0x36D8); | ||
1143 | bcm43xx_phy_write(bcm, 0x0417, | ||
1144 | (bcm43xx_phy_read(bcm, 0x0417) | ||
1145 | & 0xFE00) | 0x016D); | ||
1146 | } else { | ||
1147 | bcm43xx_phy_write(bcm, 0x048A, | ||
1148 | bcm43xx_phy_read(bcm, 0x048A) | ||
1149 | | 0x1000); | ||
1150 | bcm43xx_phy_write(bcm, 0x048A, | ||
1151 | (bcm43xx_phy_read(bcm, 0x048A) | ||
1152 | & 0x9FFF) | 0x2000); | ||
1153 | tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, | ||
1154 | BCM43xx_UCODEFLAGS_OFFSET); | ||
1155 | if (!(tmp32 & 0x800)) { | ||
1156 | tmp32 |= 0x800; | ||
1157 | bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, | ||
1158 | BCM43xx_UCODEFLAGS_OFFSET, | ||
1159 | tmp32); | ||
1160 | } | ||
1161 | } | ||
1162 | if (phy->rev >= 2) { | ||
1163 | bcm43xx_phy_write(bcm, 0x042B, | ||
1164 | bcm43xx_phy_read(bcm, 0x042B) | ||
1165 | | 0x0800); | ||
1166 | } | ||
1167 | bcm43xx_phy_write(bcm, 0x048C, | ||
1168 | (bcm43xx_phy_read(bcm, 0x048C) | ||
1169 | & 0xF0FF) | 0x0200); | ||
1170 | if (phy->rev == 2) { | ||
1171 | bcm43xx_phy_write(bcm, 0x04AE, | ||
1172 | (bcm43xx_phy_read(bcm, 0x04AE) | ||
1173 | & 0xFF00) | 0x007F); | ||
1174 | bcm43xx_phy_write(bcm, 0x04AD, | ||
1175 | (bcm43xx_phy_read(bcm, 0x04AD) | ||
1176 | & 0x00FF) | 0x1300); | ||
1177 | } else if (phy->rev >= 6) { | ||
1178 | bcm43xx_ilt_write(bcm, 0x1A00 + 0x3, 0x007F); | ||
1179 | bcm43xx_ilt_write(bcm, 0x1A00 + 0x2, 0x007F); | ||
1180 | bcm43xx_phy_write(bcm, 0x04AD, | ||
1181 | bcm43xx_phy_read(bcm, 0x04AD) | ||
1182 | & 0x00FF); | ||
1183 | } | ||
1045 | bcm43xx_calc_nrssi_slope(bcm); | 1184 | bcm43xx_calc_nrssi_slope(bcm); |
1046 | break; | 1185 | break; |
1047 | default: | 1186 | default: |
@@ -1055,9 +1194,8 @@ bcm43xx_radio_interference_mitigation_disable(struct bcm43xx_private *bcm, | |||
1055 | { | 1194 | { |
1056 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); | 1195 | struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); |
1057 | struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); | 1196 | struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); |
1058 | int i = 0; | 1197 | u32 tmp32; |
1059 | u16 *stack = radio->interfstack; | 1198 | u32 *stack = radio->interfstack; |
1060 | u16 tmp, flipped; | ||
1061 | 1199 | ||
1062 | switch (mode) { | 1200 | switch (mode) { |
1063 | case BCM43xx_RADIO_INTERFMODE_NONWLAN: | 1201 | case BCM43xx_RADIO_INTERFMODE_NONWLAN: |
@@ -1065,71 +1203,80 @@ bcm43xx_radio_interference_mitigation_disable(struct bcm43xx_private *bcm, | |||
1065 | bcm43xx_phy_write(bcm, 0x042B, | 1203 | bcm43xx_phy_write(bcm, 0x042B, |
1066 | bcm43xx_phy_read(bcm, 0x042B) & ~0x0800); | 1204 | bcm43xx_phy_read(bcm, 0x042B) & ~0x0800); |
1067 | bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, | 1205 | bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, |
1068 | bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x4000); | 1206 | bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000); |
1069 | break; | 1207 | break; |
1070 | } | 1208 | } |
1071 | tmp = (bcm43xx_radio_read16(bcm, 0x0078) & 0x001E); | 1209 | phy_stackrestore(0x0078); |
1072 | flipped = flip_4bit(tmp); | ||
1073 | if ((flipped >> 1) >= 0x000C) | ||
1074 | tmp = flipped + 3; | ||
1075 | tmp = flip_4bit(tmp); | ||
1076 | bcm43xx_radio_write16(bcm, 0x0078, tmp << 1); | ||
1077 | |||
1078 | bcm43xx_calc_nrssi_threshold(bcm); | 1210 | bcm43xx_calc_nrssi_threshold(bcm); |
1079 | 1211 | phy_stackrestore(0x0406); | |
1080 | if (bcm->current_core->rev < 5) { | ||
1081 | bcm43xx_phy_write(bcm, 0x0406, stack_restore()); | ||
1082 | } else { | ||
1083 | bcm43xx_phy_write(bcm, 0x04C0, stack_restore()); | ||
1084 | bcm43xx_phy_write(bcm, 0x04C1, stack_restore()); | ||
1085 | } | ||
1086 | bcm43xx_phy_write(bcm, 0x042B, | 1212 | bcm43xx_phy_write(bcm, 0x042B, |
1087 | bcm43xx_phy_read(bcm, 0x042B) & ~0x0800); | 1213 | bcm43xx_phy_read(bcm, 0x042B) & ~0x0800); |
1088 | 1214 | if (!bcm->bad_frames_preempt) { | |
1089 | if (!bcm->bad_frames_preempt) | ||
1090 | bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, | 1215 | bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, |
1091 | bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) & ~(1 << 11)); | 1216 | bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) |
1217 | & ~(1 << 11)); | ||
1218 | } | ||
1092 | bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, | 1219 | bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, |
1093 | bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x4000); | 1220 | bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000); |
1094 | bcm43xx_phy_write(bcm, 0x04A0, stack_restore()); | 1221 | phy_stackrestore(0x04A0); |
1095 | bcm43xx_phy_write(bcm, 0x04A1, stack_restore()); | 1222 | phy_stackrestore(0x04A1); |
1096 | bcm43xx_phy_write(bcm, 0x04A2, stack_restore()); | 1223 | phy_stackrestore(0x04A2); |
1097 | bcm43xx_phy_write(bcm, 0x04A8, stack_restore()); | 1224 | phy_stackrestore(0x04A8); |
1098 | bcm43xx_phy_write(bcm, 0x04AB, stack_restore()); | 1225 | phy_stackrestore(0x04AB); |
1099 | bcm43xx_phy_write(bcm, 0x04A7, stack_restore()); | 1226 | phy_stackrestore(0x04A7); |
1100 | bcm43xx_phy_write(bcm, 0x04A3, stack_restore()); | 1227 | phy_stackrestore(0x04A3); |
1101 | bcm43xx_phy_write(bcm, 0x04A9, stack_restore()); | 1228 | phy_stackrestore(0x04A9); |
1102 | bcm43xx_phy_write(bcm, 0x0493, stack_restore()); | 1229 | phy_stackrestore(0x0493); |
1103 | bcm43xx_phy_write(bcm, 0x04AA, stack_restore()); | 1230 | phy_stackrestore(0x04AA); |
1104 | bcm43xx_phy_write(bcm, 0x04AC, stack_restore()); | 1231 | phy_stackrestore(0x04AC); |
1105 | break; | 1232 | break; |
1106 | case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: | 1233 | case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: |
1107 | if (bcm43xx_phy_read(bcm, 0x0033) != 0x0800) | 1234 | if (!(bcm43xx_phy_read(bcm, 0x0033) & 0x0800)) |
1108 | break; | 1235 | break; |
1109 | 1236 | ||
1110 | radio->aci_enable = 0; | 1237 | radio->aci_enable = 0; |
1111 | 1238 | ||
1112 | bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, stack_restore()); | 1239 | phy_stackrestore(BCM43xx_PHY_RADIO_BITFIELD); |
1113 | bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, stack_restore()); | 1240 | phy_stackrestore(BCM43xx_PHY_G_CRS); |
1114 | if (bcm->current_core->rev < 5) { | 1241 | phy_stackrestore(0x0033); |
1115 | bcm43xx_phy_write(bcm, 0x0406, stack_restore()); | 1242 | phy_stackrestore(0x04A3); |
1116 | } else { | 1243 | phy_stackrestore(0x04A9); |
1117 | bcm43xx_phy_write(bcm, 0x04C0, stack_restore()); | 1244 | phy_stackrestore(0x0493); |
1118 | bcm43xx_phy_write(bcm, 0x04C1, stack_restore()); | 1245 | phy_stackrestore(0x04AA); |
1246 | phy_stackrestore(0x04AC); | ||
1247 | phy_stackrestore(0x04A0); | ||
1248 | phy_stackrestore(0x04A7); | ||
1249 | if (phy->rev >= 2) { | ||
1250 | phy_stackrestore(0x04C0); | ||
1251 | phy_stackrestore(0x04C1); | ||
1252 | } else | ||
1253 | phy_stackrestore(0x0406); | ||
1254 | phy_stackrestore(0x04A1); | ||
1255 | phy_stackrestore(0x04AB); | ||
1256 | phy_stackrestore(0x04A8); | ||
1257 | if (phy->rev == 2) { | ||
1258 | phy_stackrestore(0x04AD); | ||
1259 | phy_stackrestore(0x04AE); | ||
1260 | } else if (phy->rev >= 3) { | ||
1261 | phy_stackrestore(0x04AD); | ||
1262 | phy_stackrestore(0x0415); | ||
1263 | phy_stackrestore(0x0416); | ||
1264 | phy_stackrestore(0x0417); | ||
1265 | ilt_stackrestore(0x1A00 + 0x2); | ||
1266 | ilt_stackrestore(0x1A00 + 0x3); | ||
1267 | } | ||
1268 | phy_stackrestore(0x04A2); | ||
1269 | phy_stackrestore(0x04A8); | ||
1270 | phy_stackrestore(0x042B); | ||
1271 | phy_stackrestore(0x048C); | ||
1272 | tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, | ||
1273 | BCM43xx_UCODEFLAGS_OFFSET); | ||
1274 | if (tmp32 & 0x800) { | ||
1275 | tmp32 &= ~0x800; | ||
1276 | bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, | ||
1277 | BCM43xx_UCODEFLAGS_OFFSET, | ||
1278 | tmp32); | ||
1119 | } | 1279 | } |
1120 | bcm43xx_phy_write(bcm, 0x0033, stack_restore()); | ||
1121 | bcm43xx_phy_write(bcm, 0x04A7, stack_restore()); | ||
1122 | bcm43xx_phy_write(bcm, 0x04A3, stack_restore()); | ||
1123 | bcm43xx_phy_write(bcm, 0x04A9, stack_restore()); | ||
1124 | bcm43xx_phy_write(bcm, 0x04AA, stack_restore()); | ||
1125 | bcm43xx_phy_write(bcm, 0x04AC, stack_restore()); | ||
1126 | bcm43xx_phy_write(bcm, 0x0493, stack_restore()); | ||
1127 | bcm43xx_phy_write(bcm, 0x04A1, stack_restore()); | ||
1128 | bcm43xx_phy_write(bcm, 0x04A0, stack_restore()); | ||
1129 | bcm43xx_phy_write(bcm, 0x04A2, stack_restore()); | ||
1130 | bcm43xx_phy_write(bcm, 0x04A8, stack_restore()); | ||
1131 | bcm43xx_phy_write(bcm, 0x04AB, stack_restore()); | ||
1132 | |||
1133 | bcm43xx_calc_nrssi_slope(bcm); | 1280 | bcm43xx_calc_nrssi_slope(bcm); |
1134 | break; | 1281 | break; |
1135 | default: | 1282 | default: |
@@ -1137,8 +1284,12 @@ bcm43xx_radio_interference_mitigation_disable(struct bcm43xx_private *bcm, | |||
1137 | } | 1284 | } |
1138 | } | 1285 | } |
1139 | 1286 | ||
1140 | #undef stack_save | 1287 | #undef phy_stacksave |
1141 | #undef stack_restore | 1288 | #undef phy_stackrestore |
1289 | #undef radio_stacksave | ||
1290 | #undef radio_stackrestore | ||
1291 | #undef ilt_stacksave | ||
1292 | #undef ilt_stackrestore | ||
1142 | 1293 | ||
1143 | int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm, | 1294 | int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm, |
1144 | int mode) | 1295 | int mode) |