1 2 /* 3 4 Broadcom B43 wireless driver 5 IEEE 802.11n PHY data tables 6 7 Copyright (c) 2008 Michael Buesch <m@bues.ch> 8 Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com> 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 2 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; see the file COPYING. If not, write to 22 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, 23 Boston, MA 02110-1301, USA. 24 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 /* 31 * The Broadcom Wireless LAN controller driver. 32 */ 33 34 #include "opt_wlan.h" 35 #include "opt_bwn.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/module.h> 42 #include <sys/endian.h> 43 #include <sys/errno.h> 44 #include <sys/firmware.h> 45 #include <sys/lock.h> 46 #include <sys/mutex.h> 47 #include <machine/bus.h> 48 #include <machine/resource.h> 49 #include <sys/bus.h> 50 #include <sys/rman.h> 51 #include <sys/socket.h> 52 #include <sys/sockio.h> 53 54 #include <net/ethernet.h> 55 #include <net/if.h> 56 #include <net/if_var.h> 57 #include <net/if_arp.h> 58 #include <net/if_dl.h> 59 #include <net/if_llc.h> 60 #include <net/if_media.h> 61 #include <net/if_types.h> 62 63 #include <dev/pci/pcivar.h> 64 #include <dev/pci/pcireg.h> 65 66 #include <net80211/ieee80211_var.h> 67 #include <net80211/ieee80211_radiotap.h> 68 #include <net80211/ieee80211_regdomain.h> 69 #include <net80211/ieee80211_phy.h> 70 #include <net80211/ieee80211_ratectl.h> 71 72 #include <dev/bwn/if_bwnreg.h> 73 #include <dev/bwn/if_bwnvar.h> 74 #include <dev/bwn/if_bwn_debug.h> 75 76 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_regs.h> 77 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h> 78 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.h> 79 #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h> 80 #include <gnu/dev/bwn/phy_n/if_bwn_radio_2057.h> 81 82 static uint16_t r2057_rev4_init[][2] = { 83 { 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, 84 { 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff }, 85 { 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 }, 86 { 0x8C, 0xf0 }, { 0x91, 0x3f }, { 0x92, 0x36 }, { 0xA4, 0x8c }, 87 { 0xA8, 0x55 }, { 0xAF, 0x01 }, { 0x10F, 0xf0 }, { 0x110, 0x10 }, 88 { 0x111, 0xf0 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x129, 0x8c }, 89 { 0x12D, 0x55 }, { 0x134, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, 90 { 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, 91 { 0x169, 0x02 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 }, 92 { 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, 93 { 0x1AB, 0x00 }, { 0x1AC, 0x00 }, 94 }; 95 96 static uint16_t r2057_rev5_init[][2] = { 97 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 }, 98 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, 99 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, 100 { 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 }, 101 { 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 }, 102 { 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f }, 103 { 0x117, 0x36 }, { 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, 104 { 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, 105 { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, 106 { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, 107 { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 }, 108 }; 109 110 static uint16_t r2057_rev5a_init[][2] = { 111 { 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 }, 112 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, 113 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, 114 { 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 }, 115 { 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 }, 116 { 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f }, 117 { 0x117, 0x36 }, { 0x126, 0x20 }, { 0x14E, 0x01 }, { 0x15E, 0x00 }, 118 { 0x15F, 0x00 }, { 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, 119 { 0x163, 0x00 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 }, 120 { 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, 121 { 0x1AB, 0x00 }, { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, 122 { 0x1C2, 0x80 }, 123 }; 124 125 static uint16_t r2057_rev7_init[][2] = { 126 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 }, 127 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 }, 128 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 }, 129 { 0x66, 0xee }, { 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 }, 130 { 0x7C, 0x14 }, { 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f }, 131 { 0x92, 0x36 }, { 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, 132 { 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x13 }, { 0xEB, 0xee }, 133 { 0xF3, 0x58 }, { 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x14 }, 134 { 0x102, 0xee }, { 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 }, 135 { 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 }, 136 { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 }, 137 { 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 }, 138 { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 }, 139 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 }, 140 }; 141 142 /* TODO: Which devices should use it? 143 static uint16_t r2057_rev8_init[][2] = { 144 { 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 }, 145 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 }, 146 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f }, 147 { 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 }, { 0x7C, 0x0f }, 148 { 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 }, 149 { 0xA1, 0x20 }, { 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, 150 { 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0xF3, 0x58 }, 151 { 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x0f }, { 0x102, 0xee }, 152 { 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x126, 0x20 }, 153 { 0x14E, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 }, 154 { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 }, 155 { 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 }, 156 { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 }, 157 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 }, 158 }; 159 */ 160 161 /* Extracted from MMIO dump of 6.30.223.141 */ 162 static uint16_t r2057_rev9_init[][2] = { 163 { 0x27, 0x1f }, { 0x28, 0x0a }, { 0x29, 0x2f }, { 0x42, 0x1f }, 164 { 0x48, 0x3f }, { 0x5c, 0x41 }, { 0x63, 0x14 }, { 0x64, 0x12 }, 165 { 0x66, 0xff }, { 0x74, 0xa3 }, { 0x7b, 0x14 }, { 0x7c, 0x14 }, 166 { 0x7d, 0xee }, { 0x86, 0xc0 }, { 0xc4, 0x10 }, { 0xc9, 0x01 }, 167 { 0xe1, 0x41 }, { 0xe8, 0x14 }, { 0xe9, 0x12 }, { 0xeb, 0xff }, 168 { 0xf5, 0x0a }, { 0xf8, 0x09 }, { 0xf9, 0xa3 }, { 0x100, 0x14 }, 169 { 0x101, 0x10 }, { 0x102, 0xee }, { 0x10b, 0xc0 }, { 0x149, 0x10 }, 170 { 0x14e, 0x01 }, { 0x1b7, 0x05 }, { 0x1c2, 0xa0 }, 171 }; 172 173 /* Extracted from MMIO dump of 6.30.223.248 */ 174 static uint16_t r2057_rev14_init[][2] = { 175 { 0x011, 0xfc }, { 0x030, 0x24 }, { 0x040, 0x1c }, { 0x082, 0x08 }, 176 { 0x0b4, 0x44 }, { 0x0c8, 0x01 }, { 0x0c9, 0x01 }, { 0x107, 0x08 }, 177 { 0x14d, 0x01 }, { 0x14e, 0x01 }, { 0x1af, 0x40 }, { 0x1b0, 0x40 }, 178 { 0x1cc, 0x01 }, { 0x1cf, 0x10 }, { 0x1d0, 0x0f }, { 0x1d3, 0x10 }, 179 { 0x1d4, 0x0f }, 180 }; 181 182 #define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ 183 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ 184 r20, r21, r22, r23, r24, r25, r26, r27) \ 185 .radio_vcocal_countval0 = r00, \ 186 .radio_vcocal_countval1 = r01, \ 187 .radio_rfpll_refmaster_sparextalsize = r02, \ 188 .radio_rfpll_loopfilter_r1 = r03, \ 189 .radio_rfpll_loopfilter_c2 = r04, \ 190 .radio_rfpll_loopfilter_c1 = r05, \ 191 .radio_cp_kpd_idac = r06, \ 192 .radio_rfpll_mmd0 = r07, \ 193 .radio_rfpll_mmd1 = r08, \ 194 .radio_vcobuf_tune = r09, \ 195 .radio_logen_mx2g_tune = r10, \ 196 .radio_logen_mx5g_tune = r11, \ 197 .radio_logen_indbuf2g_tune = r12, \ 198 .radio_logen_indbuf5g_tune = r13, \ 199 .radio_txmix2g_tune_boost_pu_core0 = r14, \ 200 .radio_pad2g_tune_pus_core0 = r15, \ 201 .radio_pga_boost_tune_core0 = r16, \ 202 .radio_txmix5g_boost_tune_core0 = r17, \ 203 .radio_pad5g_tune_misc_pus_core0 = r18, \ 204 .radio_lna2g_tune_core0 = r19, \ 205 .radio_lna5g_tune_core0 = r20, \ 206 .radio_txmix2g_tune_boost_pu_core1 = r21, \ 207 .radio_pad2g_tune_pus_core1 = r22, \ 208 .radio_pga_boost_tune_core1 = r23, \ 209 .radio_txmix5g_boost_tune_core1 = r24, \ 210 .radio_pad5g_tune_misc_pus_core1 = r25, \ 211 .radio_lna2g_tune_core1 = r26, \ 212 .radio_lna5g_tune_core1 = r27 213 214 #define RADIOREGS7_2G(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ 215 r10, r11, r12, r13, r14, r15, r16, r17) \ 216 .radio_vcocal_countval0 = r00, \ 217 .radio_vcocal_countval1 = r01, \ 218 .radio_rfpll_refmaster_sparextalsize = r02, \ 219 .radio_rfpll_loopfilter_r1 = r03, \ 220 .radio_rfpll_loopfilter_c2 = r04, \ 221 .radio_rfpll_loopfilter_c1 = r05, \ 222 .radio_cp_kpd_idac = r06, \ 223 .radio_rfpll_mmd0 = r07, \ 224 .radio_rfpll_mmd1 = r08, \ 225 .radio_vcobuf_tune = r09, \ 226 .radio_logen_mx2g_tune = r10, \ 227 .radio_logen_indbuf2g_tune = r11, \ 228 .radio_txmix2g_tune_boost_pu_core0 = r12, \ 229 .radio_pad2g_tune_pus_core0 = r13, \ 230 .radio_lna2g_tune_core0 = r14, \ 231 .radio_txmix2g_tune_boost_pu_core1 = r15, \ 232 .radio_pad2g_tune_pus_core1 = r16, \ 233 .radio_lna2g_tune_core1 = r17 234 235 #define PHYREGS(r0, r1, r2, r3, r4, r5) \ 236 .phy_regs.phy_bw1a = r0, \ 237 .phy_regs.phy_bw2 = r1, \ 238 .phy_regs.phy_bw3 = r2, \ 239 .phy_regs.phy_bw4 = r3, \ 240 .phy_regs.phy_bw5 = r4, \ 241 .phy_regs.phy_bw6 = r5 242 243 /* Copied from brcmsmac (5.75.11): chan_info_nphyrev8_2057_rev5 */ 244 static const struct bwn_nphy_chantabent_rev7_2g bwn_nphy_chantab_phy_rev8_radio_rev5[] = { 245 { 246 .freq = 2412, 247 RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 248 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 249 0x03, 0xff), 250 PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), 251 }, 252 { 253 .freq = 2417, 254 RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 255 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 256 0x03, 0xff), 257 PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), 258 }, 259 { 260 .freq = 2422, 261 RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 262 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 263 0x03, 0xef), 264 PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), 265 }, 266 { 267 .freq = 2427, 268 RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 269 0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 270 0x03, 0xdf), 271 PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), 272 }, 273 { 274 .freq = 2432, 275 RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 276 0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 277 0x03, 0xcf), 278 PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), 279 }, 280 { 281 .freq = 2437, 282 RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 283 0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 284 0x03, 0xbf), 285 PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), 286 }, 287 { 288 .freq = 2442, 289 RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 290 0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 291 0x03, 0xaf), 292 PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), 293 }, 294 { 295 .freq = 2447, 296 RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 297 0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 298 0x03, 0x9f), 299 PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), 300 }, 301 { 302 .freq = 2452, 303 RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 304 0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 305 0x03, 0x8f), 306 PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), 307 }, 308 { 309 .freq = 2457, 310 RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 311 0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 312 0x03, 0x7f), 313 PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), 314 }, 315 { 316 .freq = 2462, 317 RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 318 0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 319 0x03, 0x6f), 320 PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), 321 }, 322 { 323 .freq = 2467, 324 RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 325 0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 326 0x03, 0x5f), 327 PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), 328 }, 329 { 330 .freq = 2472, 331 RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 332 0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 333 0x03, 0x4f), 334 PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), 335 }, 336 { 337 .freq = 2484, 338 RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 339 0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 340 0x03, 0x3f), 341 PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424), 342 } 343 }; 344 345 /* Extracted from MMIO dump of 6.30.223.248 */ 346 static const struct bwn_nphy_chantabent_rev7_2g bwn_nphy_chantab_phy_rev17_radio_rev14[] = { 347 { 348 .freq = 2412, 349 RADIOREGS7_2G(0x48, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x6c, 350 0x09, 0x0d, 0x09, 0x03, 0x21, 0x53, 0xff, 0x21, 351 0x53, 0xff), 352 PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), 353 }, 354 { 355 .freq = 2417, 356 RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x71, 357 0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21, 358 0x53, 0xff), 359 PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), 360 }, 361 { 362 .freq = 2422, 363 RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x76, 364 0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21, 365 0x53, 0xff), 366 PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), 367 }, 368 { 369 .freq = 2427, 370 RADIOREGS7_2G(0x52, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x7b, 371 0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21, 372 0x53, 0xff), 373 PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), 374 }, 375 { 376 .freq = 2432, 377 RADIOREGS7_2G(0x55, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x80, 378 0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21, 379 0x53, 0xff), 380 PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), 381 }, 382 { 383 .freq = 2437, 384 RADIOREGS7_2G(0x58, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x85, 385 0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21, 386 0x53, 0xff), 387 PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), 388 }, 389 { 390 .freq = 2442, 391 RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8a, 392 0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21, 393 0x43, 0xff), 394 PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), 395 }, 396 { 397 .freq = 2447, 398 RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8f, 399 0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21, 400 0x43, 0xff), 401 PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), 402 }, 403 { 404 .freq = 2452, 405 RADIOREGS7_2G(0x62, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x94, 406 0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21, 407 0x43, 0xff), 408 PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), 409 }, 410 { 411 .freq = 2457, 412 RADIOREGS7_2G(0x66, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x99, 413 0x09, 0x0b, 0x07, 0x03, 0x21, 0x43, 0xff, 0x21, 414 0x43, 0xff), 415 PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), 416 }, 417 { 418 .freq = 2462, 419 RADIOREGS7_2G(0x69, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x9e, 420 0x09, 0x0b, 0x07, 0x03, 0x01, 0x43, 0xff, 0x01, 421 0x43, 0xff), 422 PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), 423 }, 424 }; 425 426 /* Extracted from MMIO dump of 6.30.223.141 */ 427 static const struct bwn_nphy_chantabent_rev7 bwn_nphy_chantab_phy_rev16_radio_rev9[] = { 428 { 429 .freq = 2412, 430 RADIOREGS7(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 431 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63, 432 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 433 0x00, 0x00, 0xf0, 0x00), 434 PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), 435 }, 436 { 437 .freq = 2417, 438 RADIOREGS7(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 439 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63, 440 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 441 0x00, 0x00, 0xf0, 0x00), 442 PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), 443 }, 444 { 445 .freq = 2422, 446 RADIOREGS7(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 447 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63, 448 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 449 0x00, 0x00, 0xf0, 0x00), 450 PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), 451 }, 452 { 453 .freq = 2427, 454 RADIOREGS7(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 455 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63, 456 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 457 0x00, 0x00, 0xf0, 0x00), 458 PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), 459 }, 460 { 461 .freq = 2432, 462 RADIOREGS7(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 463 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63, 464 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 465 0x00, 0x00, 0xf0, 0x00), 466 PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), 467 }, 468 { 469 .freq = 2437, 470 RADIOREGS7(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 471 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63, 472 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 473 0x00, 0x00, 0xf0, 0x00), 474 PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), 475 }, 476 { 477 .freq = 2442, 478 RADIOREGS7(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 479 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63, 480 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 481 0x00, 0x00, 0xf0, 0x00), 482 PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), 483 }, 484 { 485 .freq = 2447, 486 RADIOREGS7(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 487 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63, 488 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 489 0x00, 0x00, 0xf0, 0x00), 490 PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), 491 }, 492 { 493 .freq = 2452, 494 RADIOREGS7(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 495 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63, 496 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 497 0x00, 0x00, 0xf0, 0x00), 498 PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), 499 }, 500 { 501 .freq = 2457, 502 RADIOREGS7(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 503 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63, 504 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 505 0x00, 0x00, 0xf0, 0x00), 506 PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), 507 }, 508 { 509 .freq = 2462, 510 RADIOREGS7(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 511 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63, 512 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00, 513 0x00, 0x00, 0xf0, 0x00), 514 PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), 515 }, 516 { 517 .freq = 5180, 518 RADIOREGS7(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06, 519 0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00, 520 0x9f, 0x2f, 0xa3, 0x00, 0xfc, 0x00, 0x00, 0x4f, 521 0x3a, 0x83, 0x00, 0xfc), 522 PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb), 523 }, 524 { 525 .freq = 5200, 526 RADIOREGS7(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08, 527 0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00, 528 0x7f, 0x2f, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x4c, 529 0x4a, 0x83, 0x00, 0xf8), 530 PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9), 531 }, 532 { 533 .freq = 5220, 534 RADIOREGS7(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a, 535 0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00, 536 0x6d, 0x3d, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x2d, 537 0x2a, 0x73, 0x00, 0xf8), 538 PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7), 539 }, 540 { 541 .freq = 5240, 542 RADIOREGS7(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c, 543 0x02, 0x0d, 0x00, 0x0d, 0x00, 0x8d, 0x00, 0x00, 544 0x4d, 0x1c, 0x73, 0x00, 0xf8, 0x00, 0x00, 0x4d, 545 0x2b, 0x73, 0x00, 0xf8), 546 PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5), 547 }, 548 { 549 .freq = 5745, 550 RADIOREGS7(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d, 551 0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00, 552 0x08, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x06, 553 0x02, 0x03, 0x00, 0x30), 554 PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9), 555 }, 556 { 557 .freq = 5765, 558 RADIOREGS7(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81, 559 0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00, 560 0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 561 0x02, 0x03, 0x00, 0x00), 562 PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8), 563 }, 564 { 565 .freq = 5785, 566 RADIOREGS7(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85, 567 0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00, 568 0x08, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 569 0x21, 0x03, 0x00, 0x00), 570 PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6), 571 }, 572 { 573 .freq = 5805, 574 RADIOREGS7(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89, 575 0x04, 0x07, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 576 0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 577 0x00, 0x03, 0x00, 0x00), 578 PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4), 579 }, 580 { 581 .freq = 5825, 582 RADIOREGS7(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d, 583 0x04, 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 584 0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 585 0x00, 0x03, 0x00, 0x00), 586 PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3), 587 }, 588 }; 589 590 void r2057_upload_inittabs(struct bwn_mac *mac) 591 { 592 struct bwn_phy *phy = &mac->mac_phy; 593 uint16_t *table = NULL; 594 uint16_t size, i; 595 596 switch (phy->rev) { 597 case 7: 598 table = r2057_rev4_init[0]; 599 size = nitems(r2057_rev4_init); 600 break; 601 case 8: 602 if (phy->rf_rev == 5) { 603 table = r2057_rev5_init[0]; 604 size = nitems(r2057_rev5_init); 605 } else if (phy->rf_rev == 7) { 606 table = r2057_rev7_init[0]; 607 size = nitems(r2057_rev7_init); 608 } 609 break; 610 case 9: 611 if (phy->rf_rev == 5) { 612 table = r2057_rev5a_init[0]; 613 size = nitems(r2057_rev5a_init); 614 } 615 break; 616 case 16: 617 if (phy->rf_rev == 9) { 618 table = r2057_rev9_init[0]; 619 size = nitems(r2057_rev9_init); 620 } 621 break; 622 case 17: 623 if (phy->rf_rev == 14) { 624 table = r2057_rev14_init[0]; 625 size = nitems(r2057_rev14_init); 626 } 627 break; 628 } 629 630 if (! table) { 631 device_printf(mac->mac_sc->sc_dev, 632 "%s: couldn't find a suitable table (phy ref=%d, rf_ref=%d)\n", 633 __func__, 634 phy->rev, 635 phy->rf_rev); 636 } 637 638 if (table) { 639 for (i = 0; i < size; i++, table += 2) 640 BWN_RF_WRITE(mac, table[0], table[1]); 641 } 642 } 643 644 void r2057_get_chantabent_rev7(struct bwn_mac *mac, uint16_t freq, 645 const struct bwn_nphy_chantabent_rev7 **tabent_r7, 646 const struct bwn_nphy_chantabent_rev7_2g **tabent_r7_2g) 647 { 648 struct bwn_phy *phy = &mac->mac_phy; 649 const struct bwn_nphy_chantabent_rev7 *e_r7 = NULL; 650 const struct bwn_nphy_chantabent_rev7_2g *e_r7_2g = NULL; 651 unsigned int len, i; 652 653 *tabent_r7 = NULL; 654 *tabent_r7_2g = NULL; 655 656 switch (phy->rev) { 657 case 8: 658 if (phy->rf_rev == 5) { 659 e_r7_2g = bwn_nphy_chantab_phy_rev8_radio_rev5; 660 len = nitems(bwn_nphy_chantab_phy_rev8_radio_rev5); 661 } 662 break; 663 case 16: 664 if (phy->rf_rev == 9) { 665 e_r7 = bwn_nphy_chantab_phy_rev16_radio_rev9; 666 len = nitems(bwn_nphy_chantab_phy_rev16_radio_rev9); 667 } 668 break; 669 case 17: 670 if (phy->rf_rev == 14) { 671 e_r7_2g = bwn_nphy_chantab_phy_rev17_radio_rev14; 672 len = nitems(bwn_nphy_chantab_phy_rev17_radio_rev14); 673 } 674 break; 675 default: 676 break; 677 } 678 679 if (e_r7) { 680 for (i = 0; i < len; i++, e_r7++) { 681 if (e_r7->freq == freq) { 682 *tabent_r7 = e_r7; 683 return; 684 } 685 } 686 } else if (e_r7_2g) { 687 for (i = 0; i < len; i++, e_r7_2g++) { 688 if (e_r7_2g->freq == freq) { 689 *tabent_r7_2g = e_r7_2g; 690 return; 691 } 692 } 693 } else { 694 device_printf(mac->mac_sc->sc_dev, 695 "%s: couldn't find a suitable chantab\n", 696 __func__); 697 } 698 } 699