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 /drivers/net/wireless | |
| 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>
Diffstat (limited to 'drivers/net/wireless')
| -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) |
