1 /* 2 3 Broadcom B43 wireless driver 4 IEEE 802.11n LCN-PHY data tables 5 6 Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com> 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; see the file COPYING. If not, write to 20 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, 21 Boston, MA 02110-1301, USA. 22 23 */ 24 25 #include "b43.h" 26 #include "tables_phy_lcn.h" 27 #include "phy_common.h" 28 #include "phy_lcn.h" 29 30 struct b43_lcntab_tx_gain_tbl_entry { 31 u8 gm; 32 u8 pga; 33 u8 pad; 34 u8 dac; 35 u8 bb_mult; 36 }; 37 38 /************************************************** 39 * Static tables. 40 **************************************************/ 41 42 static const u16 b43_lcntab_0x02[] = { 43 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 44 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 45 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 46 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 47 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 48 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 49 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 50 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 51 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 52 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 53 0x014d, 0x014d, 0x014d, 0x014d, 54 }; 55 56 static const u16 b43_lcntab_0x01[] = { 57 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 58 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 59 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 60 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 61 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 62 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 63 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 64 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 65 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 66 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 67 0x0000, 0x0000, 0x0000, 0x0000, 68 }; 69 70 static const u32 b43_lcntab_0x0b[] = { 71 0x000141f8, 0x000021f8, 0x000021fb, 0x000041fb, 72 0x0001fedb, 0x0000217b, 0x00002133, 0x000040eb, 73 0x0001fea3, 0x0000024b, 74 }; 75 76 static const u32 b43_lcntab_0x0c[] = { 77 0x00100001, 0x00200010, 0x00300001, 0x00400010, 78 0x00500022, 0x00600122, 0x00700222, 0x00800322, 79 0x00900422, 0x00a00522, 0x00b00622, 0x00c00722, 80 0x00d00822, 0x00f00922, 0x00100a22, 0x00200b22, 81 0x00300c22, 0x00400d22, 0x00500e22, 0x00600f22, 82 }; 83 84 static const u32 b43_lcntab_0x0d[] = { 85 0x00000000, 0x00000000, 0x10000000, 0x00000000, 86 0x20000000, 0x00000000, 0x30000000, 0x00000000, 87 0x40000000, 0x00000000, 0x50000000, 0x00000000, 88 0x60000000, 0x00000000, 0x70000000, 0x00000000, 89 0x80000000, 0x00000000, 0x90000000, 0x00000008, 90 0xa0000000, 0x00000008, 0xb0000000, 0x00000008, 91 0xc0000000, 0x00000008, 0xd0000000, 0x00000008, 92 0xe0000000, 0x00000008, 0xf0000000, 0x00000008, 93 0x00000000, 0x00000009, 0x10000000, 0x00000009, 94 0x20000000, 0x00000019, 0x30000000, 0x00000019, 95 0x40000000, 0x00000019, 0x50000000, 0x00000019, 96 0x60000000, 0x00000019, 0x70000000, 0x00000019, 97 0x80000000, 0x00000019, 0x90000000, 0x00000019, 98 0xa0000000, 0x00000019, 0xb0000000, 0x00000019, 99 0xc0000000, 0x00000019, 0xd0000000, 0x00000019, 100 0xe0000000, 0x00000019, 0xf0000000, 0x00000019, 101 0x00000000, 0x0000001a, 0x10000000, 0x0000001a, 102 0x20000000, 0x0000001a, 0x30000000, 0x0000001a, 103 0x40000000, 0x0000001a, 0x50000000, 0x00000002, 104 0x60000000, 0x00000002, 0x70000000, 0x00000002, 105 0x80000000, 0x00000002, 0x90000000, 0x00000002, 106 0xa0000000, 0x00000002, 0xb0000000, 0x00000002, 107 0xc0000000, 0x0000000a, 0xd0000000, 0x0000000a, 108 0xe0000000, 0x0000000a, 0xf0000000, 0x0000000a, 109 0x00000000, 0x0000000b, 0x10000000, 0x0000000b, 110 0x20000000, 0x0000000b, 0x30000000, 0x0000000b, 111 0x40000000, 0x0000000b, 0x50000000, 0x0000001b, 112 0x60000000, 0x0000001b, 0x70000000, 0x0000001b, 113 0x80000000, 0x0000001b, 0x90000000, 0x0000001b, 114 0xa0000000, 0x0000001b, 0xb0000000, 0x0000001b, 115 0xc0000000, 0x0000001b, 0xd0000000, 0x0000001b, 116 0xe0000000, 0x0000001b, 0xf0000000, 0x0000001b, 117 0x00000000, 0x0000001c, 0x10000000, 0x0000001c, 118 0x20000000, 0x0000001c, 0x30000000, 0x0000001c, 119 0x40000000, 0x0000001c, 0x50000000, 0x0000001c, 120 0x60000000, 0x0000001c, 0x70000000, 0x0000001c, 121 0x80000000, 0x0000001c, 0x90000000, 0x0000001c, 122 }; 123 124 static const u16 b43_lcntab_0x0e[] = { 125 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 126 0x0407, 0x0408, 0x0409, 0x040a, 0x058b, 0x058c, 127 0x058d, 0x058e, 0x058f, 0x0090, 0x0091, 0x0092, 128 0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x0198, 129 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e, 130 0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4, 131 0x01a5, 0x0000, 132 }; 133 134 static const u16 b43_lcntab_0x0f[] = { 135 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009, 136 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005, 137 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009, 138 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005, 139 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009, 140 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005, 141 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009, 142 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005, 143 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009, 144 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005, 145 0x000a, 0x0009, 0x0006, 0x0005, 146 }; 147 148 static const u16 b43_lcntab_0x10[] = { 149 0x005f, 0x0036, 0x0029, 0x001f, 0x005f, 0x0036, 150 0x0029, 0x001f, 0x005f, 0x0036, 0x0029, 0x001f, 151 0x005f, 0x0036, 0x0029, 0x001f, 152 }; 153 154 static const u16 b43_lcntab_0x11[] = { 155 0x0009, 0x000f, 0x0014, 0x0018, 0x00fe, 0x0007, 156 0x000b, 0x000f, 0x00fb, 0x00fe, 0x0001, 0x0005, 157 0x0008, 0x000b, 0x000e, 0x0011, 0x0014, 0x0017, 158 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 159 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 160 0x0012, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 161 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 162 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, 163 0x0018, 0x001b, 0x0000, 0x0000, 0x0000, 0x0000, 164 0x0000, 0x0000, 0x0003, 0x00eb, 0x0000, 0x0000, 165 }; 166 167 static const u32 b43_lcntab_0x12[] = { 168 0x00000000, 0x00000000, 0x00000000, 0x00000000, 169 0x00000000, 0x00000000, 0x00000000, 0x00000000, 170 0x00000004, 0x00000000, 0x00000004, 0x00000008, 171 0x00000001, 0x00000005, 0x00000009, 0x0000000d, 172 0x0000004d, 0x0000008d, 0x0000000d, 0x0000004d, 173 0x0000008d, 0x000000cd, 0x0000004f, 0x0000008f, 174 0x000000cf, 0x000000d3, 0x00000113, 0x00000513, 175 0x00000913, 0x00000953, 0x00000d53, 0x00001153, 176 0x00001193, 0x00005193, 0x00009193, 0x0000d193, 177 0x00011193, 0x00000000, 0x00000000, 0x00000000, 178 0x00000000, 0x00000000, 0x00000000, 0x00000004, 179 0x00000000, 0x00000004, 0x00000008, 0x00000001, 180 0x00000005, 0x00000009, 0x0000000d, 0x0000004d, 181 0x0000008d, 0x0000000d, 0x0000004d, 0x0000008d, 182 0x000000cd, 0x0000004f, 0x0000008f, 0x000000cf, 183 0x000000d3, 0x00000113, 0x00000513, 0x00000913, 184 0x00000953, 0x00000d53, 0x00001153, 0x00005153, 185 0x00009153, 0x0000d153, 0x00011153, 0x00015153, 186 0x00019153, 0x0001d153, 0x00000000, 0x00000000, 187 0x00000000, 0x00000000, 0x00000000, 0x00000000, 188 0x00000000, 0x00000000, 0x00000000, 0x00000000, 189 0x00000000, 0x00000000, 0x00000000, 0x00000000, 190 0x00000000, 0x00000000, 0x00000000, 0x00000000, 191 0x00000000, 0x00000000, 0x00000000, 0x00000000, 192 }; 193 194 static const u16 b43_lcntab_0x14[] = { 195 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 196 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 197 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 198 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 199 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 200 0x0002, 0x0003, 0x0001, 0x0003, 0x0002, 0x0001, 201 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 202 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 203 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 204 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 205 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 206 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 207 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 208 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 209 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 210 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003, 211 0x0001, 0x0003, 0x0002, 0x0001, 0x0001, 0x0001, 212 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 213 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 214 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 215 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 216 0x0001, 0x0001, 217 }; 218 219 static const u16 b43_lcntab_0x17[] = { 220 0x001a, 0x0034, 0x004e, 0x0068, 0x009c, 0x00d0, 221 0x00ea, 0x0104, 0x0034, 0x0068, 0x009c, 0x00d0, 222 0x0138, 0x01a0, 0x01d4, 0x0208, 0x004e, 0x009c, 223 0x00ea, 0x0138, 0x01d4, 0x0270, 0x02be, 0x030c, 224 0x0068, 0x00d0, 0x0138, 0x01a0, 0x0270, 0x0340, 225 0x03a8, 0x0410, 0x0018, 0x009c, 0x00d0, 0x0104, 226 0x00ea, 0x0138, 0x0186, 0x00d0, 0x0104, 0x0104, 227 0x0138, 0x016c, 0x016c, 0x01a0, 0x0138, 0x0186, 228 0x0186, 0x01d4, 0x0222, 0x0222, 0x0270, 0x0104, 229 0x0138, 0x016c, 0x0138, 0x016c, 0x01a0, 0x01d4, 230 0x01a0, 0x01d4, 0x0208, 0x0208, 0x023c, 0x0186, 231 0x01d4, 0x0222, 0x01d4, 0x0222, 0x0270, 0x02be, 232 0x0270, 0x02be, 0x030c, 0x030c, 0x035a, 0x0036, 233 0x006c, 0x00a2, 0x00d8, 0x0144, 0x01b0, 0x01e6, 234 0x021c, 0x006c, 0x00d8, 0x0144, 0x01b0, 0x0288, 235 0x0360, 0x03cc, 0x0438, 0x00a2, 0x0144, 0x01e6, 236 0x0288, 0x03cc, 0x0510, 0x05b2, 0x0654, 0x00d8, 237 0x01b0, 0x0288, 0x0360, 0x0510, 0x06c0, 0x0798, 238 0x0870, 0x0018, 0x0144, 0x01b0, 0x021c, 0x01e6, 239 0x0288, 0x032a, 0x01b0, 0x021c, 0x021c, 0x0288, 240 0x02f4, 0x02f4, 0x0360, 0x0288, 0x032a, 0x032a, 241 0x03cc, 0x046e, 0x046e, 0x0510, 0x021c, 0x0288, 242 0x02f4, 0x0288, 0x02f4, 0x0360, 0x03cc, 0x0360, 243 0x03cc, 0x0438, 0x0438, 0x04a4, 0x032a, 0x03cc, 244 0x046e, 0x03cc, 0x046e, 0x0510, 0x05b2, 0x0510, 245 0x05b2, 0x0654, 0x0654, 0x06f6, 246 }; 247 248 static const u16 b43_lcntab_0x00[] = { 249 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 250 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 251 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 252 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 253 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 254 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 255 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 256 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 257 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 258 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 259 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 260 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 261 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 262 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 263 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 264 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 265 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 266 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 267 }; 268 269 static const u32 b43_lcntab_0x18[] = { 270 0x00080000, 0x00080000, 0x00080000, 0x00080000, 271 0x00080000, 0x00080000, 0x00080000, 0x00080000, 272 0x00080000, 0x00080000, 0x00080000, 0x00080000, 273 0x00080000, 0x00080000, 0x00080000, 0x00080000, 274 0x00080000, 0x00080000, 0x00080000, 0x00080000, 275 0x00080000, 0x00080000, 0x00080000, 0x00080000, 276 0x00080000, 0x00080000, 0x00080000, 0x00080000, 277 0x00080000, 0x00080000, 0x00080000, 0x00080000, 278 0x00080000, 0x00080000, 0x00080000, 0x00080000, 279 0x00080000, 0x00080000, 0x00080000, 0x00080000, 280 0x00080000, 0x00080000, 0x00080000, 0x00080000, 281 0x00080000, 0x00080000, 0x00080000, 0x00080000, 282 0x00080000, 0x00080000, 0x00080000, 0x00080000, 283 0x00080000, 0x00080000, 0x00080000, 0x00080000, 284 0x00080000, 0x00080000, 0x00080000, 0x00080000, 285 0x00080000, 0x00080000, 0x00080000, 0x00080000, 286 0x00080000, 0x00080000, 0x00080000, 0x00080000, 287 0x00080000, 0x00080000, 0x00080000, 0x00080000, 288 0x00080000, 0x00080000, 0x00080000, 0x00080000, 289 0x00080000, 0x00080000, 0x00080000, 0x00080000, 290 0x00080000, 0x00080000, 0x00080000, 0x00080000, 291 0x00080000, 0x00080000, 0x00080000, 0x00080000, 292 0x00080000, 0x00080000, 0x00080000, 0x00080000, 293 0x00080000, 0x00080000, 0x00080000, 0x00080000, 294 0x00080000, 0x00080000, 0x00080000, 0x00080000, 295 0x00080000, 0x00080000, 0x00080000, 0x00080000, 296 0x00080000, 0x00080000, 0x00080000, 0x00080000, 297 0x00080000, 0x00080000, 0x00080000, 0x00080000, 298 0x00080000, 0x00080000, 0x00080000, 0x00080000, 299 0x00080000, 0x00080000, 0x00080000, 0x00080000, 300 0x00080000, 0x00080000, 0x00080000, 0x00080000, 301 0x00080000, 0x00080000, 0x00080000, 0x00080000, 302 0x00080000, 0x00080000, 0x00080000, 0x00080000, 303 0x00080000, 0x00080000, 0x00080000, 0x00080000, 304 0x00080000, 0x00080000, 0x00080000, 0x00080000, 305 0x00080000, 0x00080000, 0x00080000, 0x00080000, 306 0x00080000, 0x00080000, 0x00080000, 0x00080000, 307 0x00080000, 0x00080000, 0x00080000, 0x00080000, 308 0x00080000, 0x00080000, 0x00080000, 0x00080000, 309 0x00080000, 0x00080000, 0x00080000, 0x00080000, 310 }; 311 312 /************************************************** 313 * TX gain. 314 **************************************************/ 315 316 static const struct b43_lcntab_tx_gain_tbl_entry 317 b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0[B43_LCNTAB_TX_GAIN_SIZE] = { 318 { 0x03, 0x00, 0x1f, 0x0, 0x48 }, 319 { 0x03, 0x00, 0x1f, 0x0, 0x46 }, 320 { 0x03, 0x00, 0x1f, 0x0, 0x44 }, 321 { 0x03, 0x00, 0x1e, 0x0, 0x43 }, 322 { 0x03, 0x00, 0x1d, 0x0, 0x44 }, 323 { 0x03, 0x00, 0x1c, 0x0, 0x44 }, 324 { 0x03, 0x00, 0x1b, 0x0, 0x45 }, 325 { 0x03, 0x00, 0x1a, 0x0, 0x46 }, 326 { 0x03, 0x00, 0x19, 0x0, 0x46 }, 327 { 0x03, 0x00, 0x18, 0x0, 0x47 }, 328 { 0x03, 0x00, 0x17, 0x0, 0x48 }, 329 { 0x03, 0x00, 0x17, 0x0, 0x46 }, 330 { 0x03, 0x00, 0x16, 0x0, 0x47 }, 331 { 0x03, 0x00, 0x15, 0x0, 0x48 }, 332 { 0x03, 0x00, 0x15, 0x0, 0x46 }, 333 { 0x03, 0x00, 0x15, 0x0, 0x44 }, 334 { 0x03, 0x00, 0x15, 0x0, 0x42 }, 335 { 0x03, 0x00, 0x15, 0x0, 0x40 }, 336 { 0x03, 0x00, 0x15, 0x0, 0x3f }, 337 { 0x03, 0x00, 0x14, 0x0, 0x40 }, 338 { 0x03, 0x00, 0x13, 0x0, 0x41 }, 339 { 0x03, 0x00, 0x13, 0x0, 0x40 }, 340 { 0x03, 0x00, 0x12, 0x0, 0x41 }, 341 { 0x03, 0x00, 0x12, 0x0, 0x40 }, 342 { 0x03, 0x00, 0x11, 0x0, 0x41 }, 343 { 0x03, 0x00, 0x11, 0x0, 0x40 }, 344 { 0x03, 0x00, 0x10, 0x0, 0x41 }, 345 { 0x03, 0x00, 0x10, 0x0, 0x40 }, 346 { 0x03, 0x00, 0x10, 0x0, 0x3e }, 347 { 0x03, 0x00, 0x10, 0x0, 0x3c }, 348 { 0x03, 0x00, 0x10, 0x0, 0x3a }, 349 { 0x03, 0x00, 0x0f, 0x0, 0x3d }, 350 { 0x03, 0x00, 0x0f, 0x0, 0x3b }, 351 { 0x03, 0x00, 0x0e, 0x0, 0x3d }, 352 { 0x03, 0x00, 0x0e, 0x0, 0x3c }, 353 { 0x03, 0x00, 0x0e, 0x0, 0x3a }, 354 { 0x03, 0x00, 0x0d, 0x0, 0x3c }, 355 { 0x03, 0x00, 0x0d, 0x0, 0x3b }, 356 { 0x03, 0x00, 0x0c, 0x0, 0x3e }, 357 { 0x03, 0x00, 0x0c, 0x0, 0x3c }, 358 { 0x03, 0x00, 0x0c, 0x0, 0x3a }, 359 { 0x03, 0x00, 0x0b, 0x0, 0x3e }, 360 { 0x03, 0x00, 0x0b, 0x0, 0x3c }, 361 { 0x03, 0x00, 0x0b, 0x0, 0x3b }, 362 { 0x03, 0x00, 0x0b, 0x0, 0x39 }, 363 { 0x03, 0x00, 0x0a, 0x0, 0x3d }, 364 { 0x03, 0x00, 0x0a, 0x0, 0x3b }, 365 { 0x03, 0x00, 0x0a, 0x0, 0x39 }, 366 { 0x03, 0x00, 0x09, 0x0, 0x3e }, 367 { 0x03, 0x00, 0x09, 0x0, 0x3c }, 368 { 0x03, 0x00, 0x09, 0x0, 0x3a }, 369 { 0x03, 0x00, 0x09, 0x0, 0x39 }, 370 { 0x03, 0x00, 0x08, 0x0, 0x3e }, 371 { 0x03, 0x00, 0x08, 0x0, 0x3c }, 372 { 0x03, 0x00, 0x08, 0x0, 0x3a }, 373 { 0x03, 0x00, 0x08, 0x0, 0x39 }, 374 { 0x03, 0x00, 0x08, 0x0, 0x37 }, 375 { 0x03, 0x00, 0x07, 0x0, 0x3d }, 376 { 0x03, 0x00, 0x07, 0x0, 0x3c }, 377 { 0x03, 0x00, 0x07, 0x0, 0x3a }, 378 { 0x03, 0x00, 0x07, 0x0, 0x38 }, 379 { 0x03, 0x00, 0x07, 0x0, 0x37 }, 380 { 0x03, 0x00, 0x06, 0x0, 0x3e }, 381 { 0x03, 0x00, 0x06, 0x0, 0x3c }, 382 { 0x03, 0x00, 0x06, 0x0, 0x3a }, 383 { 0x03, 0x00, 0x06, 0x0, 0x39 }, 384 { 0x03, 0x00, 0x06, 0x0, 0x37 }, 385 { 0x03, 0x00, 0x06, 0x0, 0x36 }, 386 { 0x03, 0x00, 0x06, 0x0, 0x34 }, 387 { 0x03, 0x00, 0x05, 0x0, 0x3d }, 388 { 0x03, 0x00, 0x05, 0x0, 0x3b }, 389 { 0x03, 0x00, 0x05, 0x0, 0x39 }, 390 { 0x03, 0x00, 0x05, 0x0, 0x38 }, 391 { 0x03, 0x00, 0x05, 0x0, 0x36 }, 392 { 0x03, 0x00, 0x05, 0x0, 0x35 }, 393 { 0x03, 0x00, 0x05, 0x0, 0x33 }, 394 { 0x03, 0x00, 0x04, 0x0, 0x3e }, 395 { 0x03, 0x00, 0x04, 0x0, 0x3c }, 396 { 0x03, 0x00, 0x04, 0x0, 0x3a }, 397 { 0x03, 0x00, 0x04, 0x0, 0x39 }, 398 { 0x03, 0x00, 0x04, 0x0, 0x37 }, 399 { 0x03, 0x00, 0x04, 0x0, 0x36 }, 400 { 0x03, 0x00, 0x04, 0x0, 0x34 }, 401 { 0x03, 0x00, 0x04, 0x0, 0x33 }, 402 { 0x03, 0x00, 0x04, 0x0, 0x31 }, 403 { 0x03, 0x00, 0x04, 0x0, 0x30 }, 404 { 0x03, 0x00, 0x04, 0x0, 0x2e }, 405 { 0x03, 0x00, 0x03, 0x0, 0x3c }, 406 { 0x03, 0x00, 0x03, 0x0, 0x3a }, 407 { 0x03, 0x00, 0x03, 0x0, 0x39 }, 408 { 0x03, 0x00, 0x03, 0x0, 0x37 }, 409 { 0x03, 0x00, 0x03, 0x0, 0x36 }, 410 { 0x03, 0x00, 0x03, 0x0, 0x34 }, 411 { 0x03, 0x00, 0x03, 0x0, 0x33 }, 412 { 0x03, 0x00, 0x03, 0x0, 0x31 }, 413 { 0x03, 0x00, 0x03, 0x0, 0x30 }, 414 { 0x03, 0x00, 0x03, 0x0, 0x2e }, 415 { 0x03, 0x00, 0x03, 0x0, 0x2d }, 416 { 0x03, 0x00, 0x03, 0x0, 0x2c }, 417 { 0x03, 0x00, 0x03, 0x0, 0x2b }, 418 { 0x03, 0x00, 0x03, 0x0, 0x29 }, 419 { 0x03, 0x00, 0x02, 0x0, 0x3d }, 420 { 0x03, 0x00, 0x02, 0x0, 0x3b }, 421 { 0x03, 0x00, 0x02, 0x0, 0x39 }, 422 { 0x03, 0x00, 0x02, 0x0, 0x38 }, 423 { 0x03, 0x00, 0x02, 0x0, 0x36 }, 424 { 0x03, 0x00, 0x02, 0x0, 0x35 }, 425 { 0x03, 0x00, 0x02, 0x0, 0x33 }, 426 { 0x03, 0x00, 0x02, 0x0, 0x32 }, 427 { 0x03, 0x00, 0x02, 0x0, 0x30 }, 428 { 0x03, 0x00, 0x02, 0x0, 0x2f }, 429 { 0x03, 0x00, 0x02, 0x0, 0x2e }, 430 { 0x03, 0x00, 0x02, 0x0, 0x2c }, 431 { 0x03, 0x00, 0x02, 0x0, 0x2b }, 432 { 0x03, 0x00, 0x02, 0x0, 0x2a }, 433 { 0x03, 0x00, 0x02, 0x0, 0x29 }, 434 { 0x03, 0x00, 0x02, 0x0, 0x27 }, 435 { 0x03, 0x00, 0x02, 0x0, 0x26 }, 436 { 0x03, 0x00, 0x02, 0x0, 0x25 }, 437 { 0x03, 0x00, 0x02, 0x0, 0x24 }, 438 { 0x03, 0x00, 0x02, 0x0, 0x23 }, 439 { 0x03, 0x00, 0x02, 0x0, 0x22 }, 440 { 0x03, 0x00, 0x02, 0x0, 0x21 }, 441 { 0x03, 0x00, 0x02, 0x0, 0x20 }, 442 { 0x03, 0x00, 0x01, 0x0, 0x3f }, 443 { 0x03, 0x00, 0x01, 0x0, 0x3d }, 444 { 0x03, 0x00, 0x01, 0x0, 0x3b }, 445 { 0x03, 0x00, 0x01, 0x0, 0x39 }, 446 }; 447 448 /************************************************** 449 * SW control. 450 **************************************************/ 451 452 static const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = { 453 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 454 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 455 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 456 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 457 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 458 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 459 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 460 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 461 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 462 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 463 0x0002, 0x0008, 0x0004, 0x0001, 464 }; 465 466 /************************************************** 467 * R/W ops. 468 **************************************************/ 469 470 u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset) 471 { 472 u32 type, value; 473 474 type = offset & B43_LCNTAB_TYPEMASK; 475 offset &= ~B43_LCNTAB_TYPEMASK; 476 B43_WARN_ON(offset > 0xFFFF); 477 478 switch (type) { 479 case B43_LCNTAB_8BIT: 480 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); 481 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO) & 0xFF; 482 break; 483 case B43_LCNTAB_16BIT: 484 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); 485 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO); 486 break; 487 case B43_LCNTAB_32BIT: 488 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); 489 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO); 490 value |= (b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI) << 16); 491 break; 492 default: 493 B43_WARN_ON(1); 494 value = 0; 495 } 496 497 return value; 498 } 499 500 void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset, 501 unsigned int nr_elements, void *_data) 502 { 503 u32 type; 504 u8 *data = _data; 505 unsigned int i; 506 507 type = offset & B43_LCNTAB_TYPEMASK; 508 offset &= ~B43_LCNTAB_TYPEMASK; 509 B43_WARN_ON(offset > 0xFFFF); 510 511 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); 512 513 for (i = 0; i < nr_elements; i++) { 514 switch (type) { 515 case B43_LCNTAB_8BIT: 516 *data = b43_phy_read(dev, 517 B43_PHY_LCN_TABLE_DATALO) & 0xFF; 518 data++; 519 break; 520 case B43_LCNTAB_16BIT: 521 *((u16 *)data) = b43_phy_read(dev, 522 B43_PHY_LCN_TABLE_DATALO); 523 data += 2; 524 break; 525 case B43_LCNTAB_32BIT: 526 *((u32 *)data) = b43_phy_read(dev, 527 B43_PHY_LCN_TABLE_DATALO); 528 *((u32 *)data) |= (b43_phy_read(dev, 529 B43_PHY_LCN_TABLE_DATAHI) << 16); 530 data += 4; 531 break; 532 default: 533 B43_WARN_ON(1); 534 } 535 } 536 } 537 538 void b43_lcntab_write(struct b43_wldev *dev, u32 offset, u32 value) 539 { 540 u32 type; 541 542 type = offset & B43_LCNTAB_TYPEMASK; 543 offset &= 0xFFFF; 544 545 switch (type) { 546 case B43_LCNTAB_8BIT: 547 B43_WARN_ON(value & ~0xFF); 548 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); 549 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value); 550 break; 551 case B43_LCNTAB_16BIT: 552 B43_WARN_ON(value & ~0xFFFF); 553 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); 554 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value); 555 break; 556 case B43_LCNTAB_32BIT: 557 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); 558 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, value >> 16); 559 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value & 0xFFFF); 560 break; 561 default: 562 B43_WARN_ON(1); 563 } 564 565 return; 566 } 567 568 void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset, 569 unsigned int nr_elements, const void *_data) 570 { 571 u32 type, value; 572 const u8 *data = _data; 573 unsigned int i; 574 575 type = offset & B43_LCNTAB_TYPEMASK; 576 offset &= ~B43_LCNTAB_TYPEMASK; 577 B43_WARN_ON(offset > 0xFFFF); 578 579 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); 580 581 for (i = 0; i < nr_elements; i++) { 582 switch (type) { 583 case B43_LCNTAB_8BIT: 584 value = *data; 585 data++; 586 B43_WARN_ON(value & ~0xFF); 587 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value); 588 break; 589 case B43_LCNTAB_16BIT: 590 value = *((u16 *)data); 591 data += 2; 592 B43_WARN_ON(value & ~0xFFFF); 593 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value); 594 break; 595 case B43_LCNTAB_32BIT: 596 value = *((u32 *)data); 597 data += 4; 598 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, 599 value >> 16); 600 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, 601 value & 0xFFFF); 602 break; 603 default: 604 B43_WARN_ON(1); 605 } 606 } 607 } 608 609 /************************************************** 610 * Tables ops. 611 **************************************************/ 612 613 #define lcntab_upload(dev, offset, data) do { \ 614 b43_lcntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ 615 } while (0) 616 static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev) 617 { 618 lcntab_upload(dev, B43_LCNTAB16(0x02, 0), b43_lcntab_0x02); 619 lcntab_upload(dev, B43_LCNTAB16(0x01, 0), b43_lcntab_0x01); 620 lcntab_upload(dev, B43_LCNTAB32(0x0b, 0), b43_lcntab_0x0b); 621 lcntab_upload(dev, B43_LCNTAB32(0x0c, 0), b43_lcntab_0x0c); 622 lcntab_upload(dev, B43_LCNTAB32(0x0d, 0), b43_lcntab_0x0d); 623 lcntab_upload(dev, B43_LCNTAB16(0x0e, 0), b43_lcntab_0x0e); 624 lcntab_upload(dev, B43_LCNTAB16(0x0f, 0), b43_lcntab_0x0f); 625 lcntab_upload(dev, B43_LCNTAB16(0x10, 0), b43_lcntab_0x10); 626 lcntab_upload(dev, B43_LCNTAB16(0x11, 0), b43_lcntab_0x11); 627 lcntab_upload(dev, B43_LCNTAB32(0x12, 0), b43_lcntab_0x12); 628 lcntab_upload(dev, B43_LCNTAB16(0x14, 0), b43_lcntab_0x14); 629 lcntab_upload(dev, B43_LCNTAB16(0x17, 0), b43_lcntab_0x17); 630 lcntab_upload(dev, B43_LCNTAB16(0x00, 0), b43_lcntab_0x00); 631 lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18); 632 } 633 634 static void b43_phy_lcn_load_tx_gain_tab(struct b43_wldev *dev, 635 const struct b43_lcntab_tx_gain_tbl_entry *gain_table) 636 { 637 u32 i; 638 u32 val; 639 640 u16 pa_gain = 0x70; 641 if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM) 642 pa_gain = 0x10; 643 644 for (i = 0; i < B43_LCNTAB_TX_GAIN_SIZE; i++) { 645 val = ((pa_gain << 24) | 646 (gain_table[i].pad << 16) | 647 (gain_table[i].pga << 8) | 648 gain_table[i].gm); 649 b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0xc0 + i), val); 650 651 /* brcmsmac doesn't maskset, we follow newer wl here */ 652 val = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i)); 653 val &= 0x000fffff; 654 val |= ((gain_table[i].dac << 28) | 655 (gain_table[i].bb_mult << 20)); 656 b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x140 + i), val); 657 } 658 } 659 660 /* wlc_lcnphy_load_rfpower */ 661 static void b43_phy_lcn_load_rfpower(struct b43_wldev *dev) 662 { 663 u32 bbmult, rfgain; 664 u8 i; 665 666 for (i = 0; i < 128; i++) { 667 bbmult = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i)); 668 bbmult >>= 20; 669 rfgain = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0xc0 + i)); 670 671 /* TODO: calculate value for 0x240 + i table offset 672 * b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), val); 673 */ 674 } 675 } 676 677 /* Not implemented in brcmsmac, noticed in wl in MMIO dump */ 678 static void b43_phy_lcn_rewrite_rfpower_table(struct b43_wldev *dev) 679 { 680 int i; 681 u32 tmp; 682 for (i = 0; i < 128; i++) { 683 tmp = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x240 + i)); 684 b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), tmp); 685 } 686 } 687 688 /* wlc_lcnphy_clear_papd_comptable */ 689 static void b43_phy_lcn_clean_papd_comp_table(struct b43_wldev *dev) 690 { 691 u8 i; 692 693 for (i = 0; i < 0x80; i++) 694 b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000); 695 } 696 697 /* wlc_lcnphy_tbl_init */ 698 void b43_phy_lcn_tables_init(struct b43_wldev *dev) 699 { 700 struct ssb_sprom *sprom = dev->dev->bus_sprom; 701 702 b43_phy_lcn_upload_static_tables(dev); 703 704 if (b43_current_band(dev->wl) == NL80211_BAND_2GHZ) { 705 if (sprom->boardflags_lo & B43_BFL_FEM) 706 b43_phy_lcn_load_tx_gain_tab(dev, 707 b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0); 708 else 709 b43err(dev->wl, 710 "TX gain table unknown for this card\n"); 711 } 712 713 if (sprom->boardflags_lo & B43_BFL_FEM && 714 !(sprom->boardflags_hi & B43_BFH_FEM_BT)) 715 b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0), 716 ARRAY_SIZE(b43_lcntab_sw_ctl_4313_epa_rev0), 717 b43_lcntab_sw_ctl_4313_epa_rev0); 718 else 719 b43err(dev->wl, "SW ctl table is unknown for this card\n"); 720 721 b43_phy_lcn_load_rfpower(dev); 722 b43_phy_lcn_rewrite_rfpower_table(dev); 723 b43_phy_lcn_clean_papd_comp_table(dev); 724 } 725