1 /*- 2 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include "opt_bwn.h" 34 #include "opt_wlan.h" 35 36 /* 37 * The Broadcom Wireless LAN controller driver. 38 */ 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/kernel.h> 43 #include <sys/malloc.h> 44 #include <sys/module.h> 45 #include <sys/endian.h> 46 #include <sys/errno.h> 47 #include <sys/firmware.h> 48 #include <sys/lock.h> 49 #include <sys/mutex.h> 50 #include <machine/bus.h> 51 #include <machine/resource.h> 52 #include <sys/bus.h> 53 #include <sys/rman.h> 54 #include <sys/socket.h> 55 #include <sys/sockio.h> 56 57 #include <net/ethernet.h> 58 #include <net/if.h> 59 #include <net/if_var.h> 60 #include <net/if_arp.h> 61 #include <net/if_dl.h> 62 #include <net/if_llc.h> 63 #include <net/if_media.h> 64 #include <net/if_types.h> 65 66 #include <dev/pci/pcivar.h> 67 #include <dev/pci/pcireg.h> 68 69 #include <net80211/ieee80211_var.h> 70 #include <net80211/ieee80211_radiotap.h> 71 #include <net80211/ieee80211_regdomain.h> 72 #include <net80211/ieee80211_phy.h> 73 #include <net80211/ieee80211_ratectl.h> 74 75 #include <dev/bhnd/bhnd.h> 76 #include <dev/bhnd/bhnd_ids.h> 77 78 #include <dev/bhnd/cores/pmu/bhnd_pmu.h> 79 80 #include <dev/bwn/if_bwnreg.h> 81 #include <dev/bwn/if_bwnvar.h> 82 83 #include <dev/bwn/if_bwn_debug.h> 84 #include <dev/bwn/if_bwn_misc.h> 85 #include <dev/bwn/if_bwn_util.h> 86 #include <dev/bwn/if_bwn_phy_common.h> 87 #include <dev/bwn/if_bwn_phy_lp.h> 88 89 #include "bhnd_nvram_map.h" 90 91 static int bwn_phy_lp_readsprom(struct bwn_mac *); 92 static void bwn_phy_lp_bbinit(struct bwn_mac *); 93 static void bwn_phy_lp_txpctl_init(struct bwn_mac *); 94 static void bwn_phy_lp_calib(struct bwn_mac *); 95 static int bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t); 96 static int bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t); 97 static void bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t); 98 static void bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t); 99 static void bwn_phy_lp_digflt_save(struct bwn_mac *); 100 static void bwn_phy_lp_get_txpctlmode(struct bwn_mac *); 101 static void bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t); 102 static void bwn_phy_lp_bugfix(struct bwn_mac *); 103 static void bwn_phy_lp_digflt_restore(struct bwn_mac *); 104 static void bwn_phy_lp_tblinit(struct bwn_mac *); 105 static void bwn_phy_lp_bbinit_r2(struct bwn_mac *); 106 static void bwn_phy_lp_bbinit_r01(struct bwn_mac *); 107 static int bwn_phy_lp_b2062_init(struct bwn_mac *); 108 static int bwn_phy_lp_b2063_init(struct bwn_mac *); 109 static int bwn_phy_lp_rxcal_r2(struct bwn_mac *); 110 static int bwn_phy_lp_rccal_r12(struct bwn_mac *); 111 static void bwn_phy_lp_set_rccap(struct bwn_mac *); 112 static uint32_t bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t); 113 static void bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *); 114 static void bwn_phy_lp_b2062_vco_calib(struct bwn_mac *); 115 static void bwn_tab_write_multi(struct bwn_mac *, uint32_t, int, 116 const void *); 117 static void bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *); 118 static struct bwn_txgain 119 bwn_phy_lp_get_txgain(struct bwn_mac *); 120 static uint8_t bwn_phy_lp_get_bbmult(struct bwn_mac *); 121 static void bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *); 122 static void bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t); 123 static void bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t); 124 static void bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t); 125 static void bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t); 126 static int bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t); 127 static void bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t); 128 static void bwn_phy_lp_tblinit_r01(struct bwn_mac *); 129 static void bwn_phy_lp_tblinit_r2(struct bwn_mac *); 130 static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *); 131 static void bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t); 132 static void bwn_phy_lp_b2062_tblinit(struct bwn_mac *); 133 static void bwn_phy_lp_b2063_tblinit(struct bwn_mac *); 134 static int bwn_phy_lp_loopback(struct bwn_mac *); 135 static void bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t); 136 static void bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int, 137 int); 138 static uint8_t bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t, 139 struct bwn_phy_lp_iq_est *); 140 static void bwn_phy_lp_ddfs_turnoff(struct bwn_mac *); 141 static uint32_t bwn_tab_read(struct bwn_mac *, uint32_t); 142 static void bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t); 143 static void bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t); 144 static void bwn_phy_lp_set_txgain_override(struct bwn_mac *); 145 static uint16_t bwn_phy_lp_get_pa_gain(struct bwn_mac *); 146 static uint8_t bwn_nbits(int32_t); 147 static void bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int, 148 struct bwn_txgain_entry *); 149 static void bwn_phy_lp_gaintbl_write(struct bwn_mac *, int, 150 struct bwn_txgain_entry); 151 static void bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int, 152 struct bwn_txgain_entry); 153 static void bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int, 154 struct bwn_txgain_entry); 155 156 static const uint8_t bwn_b2063_chantable_data[33][12] = { 157 { 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 158 { 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 159 { 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 160 { 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 161 { 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 }, 162 { 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 }, 163 { 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 }, 164 { 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 }, 165 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 }, 166 { 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 }, 167 { 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 }, 168 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 }, 169 { 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 }, 170 { 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 }, 171 { 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 172 { 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 }, 173 { 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 }, 174 { 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 }, 175 { 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 }, 176 { 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 177 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 }, 178 { 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 179 { 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 180 { 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 }, 181 { 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 }, 182 { 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 183 { 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 }, 184 { 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 185 { 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 186 { 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 }, 187 { 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 188 { 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }, 189 { 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 } 190 }; 191 192 static const struct bwn_b206x_chan bwn_b2063_chantable[] = { 193 { 1, 2412, bwn_b2063_chantable_data[0] }, 194 { 2, 2417, bwn_b2063_chantable_data[0] }, 195 { 3, 2422, bwn_b2063_chantable_data[0] }, 196 { 4, 2427, bwn_b2063_chantable_data[1] }, 197 { 5, 2432, bwn_b2063_chantable_data[1] }, 198 { 6, 2437, bwn_b2063_chantable_data[1] }, 199 { 7, 2442, bwn_b2063_chantable_data[1] }, 200 { 8, 2447, bwn_b2063_chantable_data[1] }, 201 { 9, 2452, bwn_b2063_chantable_data[2] }, 202 { 10, 2457, bwn_b2063_chantable_data[2] }, 203 { 11, 2462, bwn_b2063_chantable_data[3] }, 204 { 12, 2467, bwn_b2063_chantable_data[3] }, 205 { 13, 2472, bwn_b2063_chantable_data[3] }, 206 { 14, 2484, bwn_b2063_chantable_data[4] }, 207 { 34, 5170, bwn_b2063_chantable_data[5] }, 208 { 36, 5180, bwn_b2063_chantable_data[6] }, 209 { 38, 5190, bwn_b2063_chantable_data[7] }, 210 { 40, 5200, bwn_b2063_chantable_data[8] }, 211 { 42, 5210, bwn_b2063_chantable_data[9] }, 212 { 44, 5220, bwn_b2063_chantable_data[10] }, 213 { 46, 5230, bwn_b2063_chantable_data[11] }, 214 { 48, 5240, bwn_b2063_chantable_data[12] }, 215 { 52, 5260, bwn_b2063_chantable_data[13] }, 216 { 56, 5280, bwn_b2063_chantable_data[14] }, 217 { 60, 5300, bwn_b2063_chantable_data[14] }, 218 { 64, 5320, bwn_b2063_chantable_data[15] }, 219 { 100, 5500, bwn_b2063_chantable_data[16] }, 220 { 104, 5520, bwn_b2063_chantable_data[17] }, 221 { 108, 5540, bwn_b2063_chantable_data[18] }, 222 { 112, 5560, bwn_b2063_chantable_data[19] }, 223 { 116, 5580, bwn_b2063_chantable_data[20] }, 224 { 120, 5600, bwn_b2063_chantable_data[21] }, 225 { 124, 5620, bwn_b2063_chantable_data[21] }, 226 { 128, 5640, bwn_b2063_chantable_data[22] }, 227 { 132, 5660, bwn_b2063_chantable_data[22] }, 228 { 136, 5680, bwn_b2063_chantable_data[22] }, 229 { 140, 5700, bwn_b2063_chantable_data[23] }, 230 { 149, 5745, bwn_b2063_chantable_data[23] }, 231 { 153, 5765, bwn_b2063_chantable_data[23] }, 232 { 157, 5785, bwn_b2063_chantable_data[23] }, 233 { 161, 5805, bwn_b2063_chantable_data[23] }, 234 { 165, 5825, bwn_b2063_chantable_data[23] }, 235 { 184, 4920, bwn_b2063_chantable_data[24] }, 236 { 188, 4940, bwn_b2063_chantable_data[25] }, 237 { 192, 4960, bwn_b2063_chantable_data[26] }, 238 { 196, 4980, bwn_b2063_chantable_data[27] }, 239 { 200, 5000, bwn_b2063_chantable_data[28] }, 240 { 204, 5020, bwn_b2063_chantable_data[29] }, 241 { 208, 5040, bwn_b2063_chantable_data[30] }, 242 { 212, 5060, bwn_b2063_chantable_data[31] }, 243 { 216, 5080, bwn_b2063_chantable_data[32] } 244 }; 245 246 static const uint8_t bwn_b2062_chantable_data[22][12] = { 247 { 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 }, 248 { 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 249 { 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 250 { 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 251 { 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 252 { 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 253 { 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 254 { 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 255 { 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 256 { 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 257 { 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 258 { 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 259 { 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 }, 260 { 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 261 { 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 262 { 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 263 { 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 264 { 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 265 { 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 266 { 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 }, 267 { 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }, 268 { 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 } 269 }; 270 271 static const struct bwn_b206x_chan bwn_b2062_chantable[] = { 272 { 1, 2412, bwn_b2062_chantable_data[0] }, 273 { 2, 2417, bwn_b2062_chantable_data[0] }, 274 { 3, 2422, bwn_b2062_chantable_data[0] }, 275 { 4, 2427, bwn_b2062_chantable_data[0] }, 276 { 5, 2432, bwn_b2062_chantable_data[0] }, 277 { 6, 2437, bwn_b2062_chantable_data[0] }, 278 { 7, 2442, bwn_b2062_chantable_data[0] }, 279 { 8, 2447, bwn_b2062_chantable_data[0] }, 280 { 9, 2452, bwn_b2062_chantable_data[0] }, 281 { 10, 2457, bwn_b2062_chantable_data[0] }, 282 { 11, 2462, bwn_b2062_chantable_data[0] }, 283 { 12, 2467, bwn_b2062_chantable_data[0] }, 284 { 13, 2472, bwn_b2062_chantable_data[0] }, 285 { 14, 2484, bwn_b2062_chantable_data[0] }, 286 { 34, 5170, bwn_b2062_chantable_data[1] }, 287 { 38, 5190, bwn_b2062_chantable_data[2] }, 288 { 42, 5210, bwn_b2062_chantable_data[2] }, 289 { 46, 5230, bwn_b2062_chantable_data[3] }, 290 { 36, 5180, bwn_b2062_chantable_data[4] }, 291 { 40, 5200, bwn_b2062_chantable_data[5] }, 292 { 44, 5220, bwn_b2062_chantable_data[6] }, 293 { 48, 5240, bwn_b2062_chantable_data[3] }, 294 { 52, 5260, bwn_b2062_chantable_data[3] }, 295 { 56, 5280, bwn_b2062_chantable_data[3] }, 296 { 60, 5300, bwn_b2062_chantable_data[7] }, 297 { 64, 5320, bwn_b2062_chantable_data[8] }, 298 { 100, 5500, bwn_b2062_chantable_data[9] }, 299 { 104, 5520, bwn_b2062_chantable_data[10] }, 300 { 108, 5540, bwn_b2062_chantable_data[10] }, 301 { 112, 5560, bwn_b2062_chantable_data[10] }, 302 { 116, 5580, bwn_b2062_chantable_data[11] }, 303 { 120, 5600, bwn_b2062_chantable_data[12] }, 304 { 124, 5620, bwn_b2062_chantable_data[12] }, 305 { 128, 5640, bwn_b2062_chantable_data[12] }, 306 { 132, 5660, bwn_b2062_chantable_data[12] }, 307 { 136, 5680, bwn_b2062_chantable_data[12] }, 308 { 140, 5700, bwn_b2062_chantable_data[12] }, 309 { 149, 5745, bwn_b2062_chantable_data[12] }, 310 { 153, 5765, bwn_b2062_chantable_data[12] }, 311 { 157, 5785, bwn_b2062_chantable_data[12] }, 312 { 161, 5805, bwn_b2062_chantable_data[12] }, 313 { 165, 5825, bwn_b2062_chantable_data[12] }, 314 { 184, 4920, bwn_b2062_chantable_data[13] }, 315 { 188, 4940, bwn_b2062_chantable_data[14] }, 316 { 192, 4960, bwn_b2062_chantable_data[15] }, 317 { 196, 4980, bwn_b2062_chantable_data[16] }, 318 { 200, 5000, bwn_b2062_chantable_data[17] }, 319 { 204, 5020, bwn_b2062_chantable_data[18] }, 320 { 208, 5040, bwn_b2062_chantable_data[19] }, 321 { 212, 5060, bwn_b2062_chantable_data[20] }, 322 { 216, 5080, bwn_b2062_chantable_data[21] } 323 }; 324 325 /* for LP PHY */ 326 static const struct bwn_rxcompco bwn_rxcompco_5354[] = { 327 { 1, -66, 15 }, { 2, -66, 15 }, { 3, -66, 15 }, { 4, -66, 15 }, 328 { 5, -66, 15 }, { 6, -66, 15 }, { 7, -66, 14 }, { 8, -66, 14 }, 329 { 9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 }, 330 { 13, -66, 13 }, { 14, -66, 13 }, 331 }; 332 333 /* for LP PHY */ 334 static const struct bwn_rxcompco bwn_rxcompco_r12[] = { 335 { 1, -64, 13 }, { 2, -64, 13 }, { 3, -64, 13 }, { 4, -64, 13 }, 336 { 5, -64, 12 }, { 6, -64, 12 }, { 7, -64, 12 }, { 8, -64, 12 }, 337 { 9, -64, 12 }, { 10, -64, 11 }, { 11, -64, 11 }, { 12, -64, 11 }, 338 { 13, -64, 11 }, { 14, -64, 10 }, { 34, -62, 24 }, { 38, -62, 24 }, 339 { 42, -62, 24 }, { 46, -62, 23 }, { 36, -62, 24 }, { 40, -62, 24 }, 340 { 44, -62, 23 }, { 48, -62, 23 }, { 52, -62, 23 }, { 56, -62, 22 }, 341 { 60, -62, 22 }, { 64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 }, 342 { 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 }, 343 { 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 }, 344 { 140, -62, 10 }, { 149, -61, 9 }, { 153, -61, 9 }, { 157, -61, 9 }, 345 { 161, -61, 8 }, { 165, -61, 8 }, { 184, -62, 25 }, { 188, -62, 25 }, 346 { 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 }, 347 { 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 }, 348 }; 349 350 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 }; 351 352 static const uint8_t bwn_tab_sigsq_tbl[] = { 353 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd, 354 0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 355 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00, 356 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 357 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 358 0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 359 }; 360 361 static const uint8_t bwn_tab_pllfrac_tbl[] = { 362 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 363 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 364 }; 365 366 static const uint16_t bwn_tabl_iqlocal_tbl[] = { 367 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 368 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 369 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 370 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600, 371 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 372 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000, 373 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 374 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 375 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 376 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000, 377 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 378 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 379 }; 380 381 void 382 bwn_phy_lp_init_pre(struct bwn_mac *mac) 383 { 384 struct bwn_phy *phy = &mac->mac_phy; 385 struct bwn_phy_lp *plp = &phy->phy_lp; 386 387 plp->plp_antenna = BWN_ANT_DEFAULT; 388 } 389 390 int 391 bwn_phy_lp_init(struct bwn_mac *mac) 392 { 393 static const struct bwn_stxtable tables[] = { 394 { 2, 6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 }, 395 { 1, 8, 0x50, 0, 0x7f }, { 0, 8, 0x44, 0, 0xff }, 396 { 1, 0, 0x4a, 0, 0xff }, { 0, 4, 0x4d, 0, 0xff }, 397 { 1, 4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f }, 398 { 1, 0, 0x4f, 4, 0x0f }, { 3, 0, 0x49, 0, 0x0f }, 399 { 4, 3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 }, 400 { 4, 0, 0x46, 1, 0x07 }, { 3, 8, 0x48, 4, 0x07 }, 401 { 3, 11, 0x48, 0, 0x0f }, { 3, 4, 0x49, 4, 0x0f }, 402 { 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 }, 403 { 6, 0, 0x52, 7, 0x01 }, { 5, 3, 0x41, 5, 0x07 }, 404 { 5, 6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 }, 405 { 4, 15, 0x42, 0, 0x01 }, { 5, 0, 0x42, 1, 0x07 }, 406 { 4, 11, 0x43, 4, 0x0f }, { 4, 7, 0x43, 0, 0x0f }, 407 { 4, 6, 0x45, 1, 0x01 }, { 2, 7, 0x40, 4, 0x0f }, 408 { 2, 11, 0x40, 0, 0x0f } 409 }; 410 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 411 struct bwn_softc *sc = mac->mac_sc; 412 const struct bwn_stxtable *st; 413 struct ieee80211com *ic = &sc->sc_ic; 414 int i, error; 415 uint16_t tmp; 416 417 /* All LP-PHY devices have a PMU */ 418 if (sc->sc_pmu == NULL) { 419 device_printf(sc->sc_dev, "no PMU; cannot configure PAREF " 420 "LDO\n"); 421 return (ENXIO); 422 } 423 424 if ((error = bwn_phy_lp_readsprom(mac))) 425 return (error); 426 427 bwn_phy_lp_bbinit(mac); 428 429 /* initialize RF */ 430 BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2); 431 DELAY(1); 432 BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd); 433 DELAY(1); 434 435 if (mac->mac_phy.rf_ver == 0x2062) { 436 if ((error = bwn_phy_lp_b2062_init(mac))) 437 return (error); 438 } else { 439 if ((error = bwn_phy_lp_b2063_init(mac))) 440 return (error); 441 442 /* synchronize stx table. */ 443 for (i = 0; i < N(tables); i++) { 444 st = &tables[i]; 445 tmp = BWN_RF_READ(mac, st->st_rfaddr); 446 tmp >>= st->st_rfshift; 447 tmp <<= st->st_physhift; 448 BWN_PHY_SETMASK(mac, 449 BWN_PHY_OFDM(0xf2 + st->st_phyoffset), 450 ~(st->st_mask << st->st_physhift), tmp); 451 } 452 453 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80); 454 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0); 455 } 456 457 /* calibrate RC */ 458 if (mac->mac_phy.rev >= 2) { 459 if ((error = bwn_phy_lp_rxcal_r2(mac))) 460 return (error); 461 } else if (!plp->plp_rccap) { 462 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 463 if ((error = bwn_phy_lp_rccal_r12(mac))) 464 return (error); 465 } 466 } else 467 bwn_phy_lp_set_rccap(mac); 468 469 error = bwn_phy_lp_switch_channel(mac, 7); 470 if (error) 471 device_printf(sc->sc_dev, 472 "failed to change channel 7 (%d)\n", error); 473 bwn_phy_lp_txpctl_init(mac); 474 bwn_phy_lp_calib(mac); 475 return (0); 476 } 477 478 uint16_t 479 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg) 480 { 481 482 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 483 return (BWN_READ_2(mac, BWN_PHYDATA)); 484 } 485 486 void 487 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 488 { 489 490 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 491 BWN_WRITE_2(mac, BWN_PHYDATA, value); 492 } 493 494 void 495 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, 496 uint16_t set) 497 { 498 499 BWN_WRITE_2(mac, BWN_PHYCTL, reg); 500 BWN_WRITE_2(mac, BWN_PHYDATA, 501 (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set); 502 } 503 504 uint16_t 505 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg) 506 { 507 508 KASSERT(reg != 1, ("unaccessible register %d", reg)); 509 if (mac->mac_phy.rev < 2 && reg != 0x4001) 510 reg |= 0x100; 511 if (mac->mac_phy.rev >= 2) 512 reg |= 0x200; 513 BWN_WRITE_2(mac, BWN_RFCTL, reg); 514 return BWN_READ_2(mac, BWN_RFDATALO); 515 } 516 517 void 518 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value) 519 { 520 521 KASSERT(reg != 1, ("unaccessible register %d", reg)); 522 BWN_WRITE_2(mac, BWN_RFCTL, reg); 523 BWN_WRITE_2(mac, BWN_RFDATALO, value); 524 } 525 526 void 527 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on) 528 { 529 530 if (on) { 531 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff); 532 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 533 (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7); 534 return; 535 } 536 537 if (mac->mac_phy.rev >= 2) { 538 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff); 539 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 540 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff); 541 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff); 542 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808); 543 return; 544 } 545 546 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff); 547 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00); 548 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff); 549 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018); 550 } 551 552 int 553 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan) 554 { 555 struct bwn_phy *phy = &mac->mac_phy; 556 struct bwn_phy_lp *plp = &phy->phy_lp; 557 int error; 558 559 if (phy->rf_ver == 0x2063) { 560 error = bwn_phy_lp_b2063_switch_channel(mac, chan); 561 if (error) 562 return (error); 563 } else { 564 error = bwn_phy_lp_b2062_switch_channel(mac, chan); 565 if (error) 566 return (error); 567 bwn_phy_lp_set_anafilter(mac, chan); 568 bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0)); 569 } 570 571 plp->plp_chan = chan; 572 BWN_WRITE_2(mac, BWN_CHANNEL, chan); 573 return (0); 574 } 575 576 uint32_t 577 bwn_phy_lp_get_default_chan(struct bwn_mac *mac) 578 { 579 struct bwn_softc *sc = mac->mac_sc; 580 struct ieee80211com *ic = &sc->sc_ic; 581 582 return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); 583 } 584 585 void 586 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna) 587 { 588 struct bwn_phy *phy = &mac->mac_phy; 589 struct bwn_phy_lp *plp = &phy->phy_lp; 590 591 if (phy->rev >= 2 || antenna > BWN_ANTAUTO1) 592 return; 593 594 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER); 595 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2); 596 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1); 597 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER); 598 plp->plp_antenna = antenna; 599 } 600 601 void 602 bwn_phy_lp_task_60s(struct bwn_mac *mac) 603 { 604 605 bwn_phy_lp_calib(mac); 606 } 607 608 static int 609 bwn_phy_lp_readsprom(struct bwn_mac *mac) 610 { 611 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 612 struct bwn_softc *sc = mac->mac_sc; 613 struct ieee80211com *ic = &sc->sc_ic; 614 615 #define BWN_PHY_LP_READVAR(_dev, _type, _name, _result) \ 616 do { \ 617 int error; \ 618 \ 619 error = bhnd_nvram_getvar_ ##_type((_dev), (_name), (_result)); \ 620 if (error) { \ 621 device_printf((_dev), "NVRAM variable %s unreadable: " \ 622 "%d\n", (_name), error); \ 623 return (error); \ 624 } \ 625 } while(0) 626 627 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 628 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_TRI2G, 629 &plp->plp_txisoband_m); 630 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_BXA2G, 631 &plp->plp_bxarch); 632 BWN_PHY_LP_READVAR(sc->sc_dev, int8, BHND_NVAR_RXPO2G, 633 &plp->plp_rxpwroffset); 634 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_RSSISMF2G, 635 &plp->plp_rssivf); 636 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_RSSISMC2G, 637 &plp->plp_rssivc); 638 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_RSSISAV2G, 639 &plp->plp_rssigs); 640 641 return (0); 642 } 643 644 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_TRI5GL, 645 &plp->plp_txisoband_l); 646 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_TRI5G, 647 &plp->plp_txisoband_m); 648 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_TRI5GH, 649 &plp->plp_txisoband_h); 650 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_BXA5G, 651 &plp->plp_bxarch); 652 BWN_PHY_LP_READVAR(sc->sc_dev, int8, BHND_NVAR_RXPO5G, 653 &plp->plp_rxpwroffset); 654 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_RSSISMF5G, 655 &plp->plp_rssivf); 656 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_RSSISMC5G, 657 &plp->plp_rssivc); 658 BWN_PHY_LP_READVAR(sc->sc_dev, uint8, BHND_NVAR_RSSISAV5G, 659 &plp->plp_rssigs); 660 661 #undef BWN_PHY_LP_READVAR 662 663 return (0); 664 } 665 666 static void 667 bwn_phy_lp_bbinit(struct bwn_mac *mac) 668 { 669 670 bwn_phy_lp_tblinit(mac); 671 if (mac->mac_phy.rev >= 2) 672 bwn_phy_lp_bbinit_r2(mac); 673 else 674 bwn_phy_lp_bbinit_r01(mac); 675 } 676 677 static void 678 bwn_phy_lp_txpctl_init(struct bwn_mac *mac) 679 { 680 struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; 681 struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; 682 struct bwn_softc *sc = mac->mac_sc; 683 struct ieee80211com *ic = &sc->sc_ic; 684 685 bwn_phy_lp_set_txgain(mac, 686 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); 687 bwn_phy_lp_set_bbmult(mac, 150); 688 } 689 690 static void 691 bwn_phy_lp_calib(struct bwn_mac *mac) 692 { 693 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 694 struct bwn_softc *sc = mac->mac_sc; 695 struct ieee80211com *ic = &sc->sc_ic; 696 const struct bwn_rxcompco *rc = NULL; 697 struct bwn_txgain ogain; 698 int i, omode, oafeovr, orf, obbmult; 699 uint8_t mode, fc = 0; 700 701 if (plp->plp_chanfullcal != plp->plp_chan) { 702 plp->plp_chanfullcal = plp->plp_chan; 703 fc = 1; 704 } 705 706 bwn_mac_suspend(mac); 707 708 /* BlueTooth Coexistance Override */ 709 BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3); 710 BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff); 711 712 if (mac->mac_phy.rev >= 2) 713 bwn_phy_lp_digflt_save(mac); 714 bwn_phy_lp_get_txpctlmode(mac); 715 mode = plp->plp_txpctlmode; 716 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 717 if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF) 718 bwn_phy_lp_bugfix(mac); 719 if (mac->mac_phy.rev >= 2 && fc == 1) { 720 bwn_phy_lp_get_txpctlmode(mac); 721 omode = plp->plp_txpctlmode; 722 oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40; 723 if (oafeovr) 724 ogain = bwn_phy_lp_get_txgain(mac); 725 orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff; 726 obbmult = bwn_phy_lp_get_bbmult(mac); 727 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 728 if (oafeovr) 729 bwn_phy_lp_set_txgain(mac, &ogain); 730 bwn_phy_lp_set_bbmult(mac, obbmult); 731 bwn_phy_lp_set_txpctlmode(mac, omode); 732 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf); 733 } 734 bwn_phy_lp_set_txpctlmode(mac, mode); 735 if (mac->mac_phy.rev >= 2) 736 bwn_phy_lp_digflt_restore(mac); 737 738 /* do RX IQ Calculation; assumes that noise is true. */ 739 if (sc->sc_cid.chip_id == BHND_CHIPID_BCM5354) { 740 for (i = 0; i < N(bwn_rxcompco_5354); i++) { 741 if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan) 742 rc = &bwn_rxcompco_5354[i]; 743 } 744 } else if (mac->mac_phy.rev >= 2) 745 rc = &bwn_rxcompco_r2; 746 else { 747 for (i = 0; i < N(bwn_rxcompco_r12); i++) { 748 if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan) 749 rc = &bwn_rxcompco_r12[i]; 750 } 751 } 752 if (rc == NULL) 753 goto fail; 754 755 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1); 756 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8); 757 758 bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */); 759 760 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 761 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 762 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0); 763 } else { 764 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 765 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0); 766 } 767 768 bwn_phy_lp_set_rxgain(mac, 0x2d5d); 769 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 770 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 771 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 772 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 773 bwn_phy_lp_set_deaf(mac, 0); 774 /* XXX no checking return value? */ 775 (void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0); 776 bwn_phy_lp_clear_deaf(mac, 0); 777 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc); 778 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7); 779 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf); 780 781 /* disable RX GAIN override. */ 782 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe); 783 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef); 784 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf); 785 if (mac->mac_phy.rev >= 2) { 786 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 787 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 788 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff); 789 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7); 790 } 791 } else { 792 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff); 793 } 794 795 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe); 796 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff); 797 fail: 798 bwn_mac_enable(mac); 799 } 800 801 void 802 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on) 803 { 804 805 if (on) { 806 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8); 807 return; 808 } 809 810 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007); 811 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007); 812 } 813 814 static int 815 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan) 816 { 817 static const struct bwn_b206x_chan *bc = NULL; 818 struct bwn_softc *sc = mac->mac_sc; 819 uint32_t count, freqref, freqvco, val[3], timeout, timeoutref, 820 tmp[6]; 821 uint16_t old, scale, tmp16; 822 u_int freqxtal; 823 int error, i, div; 824 825 for (i = 0; i < N(bwn_b2063_chantable); i++) { 826 if (bwn_b2063_chantable[i].bc_chan == chan) { 827 bc = &bwn_b2063_chantable[i]; 828 break; 829 } 830 } 831 if (bc == NULL) 832 return (EINVAL); 833 834 error = bhnd_get_clock_freq(sc->sc_dev, BHND_CLOCK_ALP, &freqxtal); 835 if (error) { 836 device_printf(sc->sc_dev, "failed to fetch clock frequency: %d", 837 error); 838 return (error); 839 } 840 841 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]); 842 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]); 843 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]); 844 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]); 845 BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]); 846 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]); 847 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]); 848 BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]); 849 BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]); 850 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]); 851 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]); 852 BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]); 853 854 old = BWN_RF_READ(mac, BWN_B2063_COM15); 855 BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e); 856 857 freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2); 858 freqref = freqxtal * 3; 859 div = (freqxtal <= 26000000 ? 1 : 2); 860 timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1; 861 timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) + 862 999999) / 1000000) + 1; 863 864 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2); 865 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6, 866 0xfff8, timeout >> 2); 867 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 868 0xff9f,timeout << 5); 869 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref); 870 871 val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16); 872 val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16); 873 val[2] = bwn_phy_lp_roundup(freqvco, 3, 16); 874 875 count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) * 876 (timeoutref + 1)) - 1; 877 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7, 878 0xf0, count >> 8); 879 BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff); 880 881 tmp[0] = ((val[2] * 62500) / freqref) << 4; 882 tmp[1] = ((val[2] * 62500) % freqref) << 4; 883 while (tmp[1] >= freqref) { 884 tmp[0]++; 885 tmp[1] -= freqref; 886 } 887 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4); 888 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4); 889 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16); 890 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff); 891 BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff); 892 893 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9); 894 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88); 895 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28); 896 BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63); 897 898 tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27; 899 tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16); 900 901 if (howmany(tmp[3], tmp[2]) > 60) { 902 scale = 1; 903 tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8; 904 } else { 905 scale = 0; 906 tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8; 907 } 908 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]); 909 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6); 910 911 tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) * 912 (scale + 1); 913 if (tmp[5] > 150) 914 tmp[5] = 0; 915 916 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]); 917 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5); 918 919 BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4); 920 if (freqxtal > 26000000) 921 BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2); 922 else 923 BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd); 924 925 if (val[0] == 45) 926 BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2); 927 else 928 BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd); 929 930 BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3); 931 DELAY(1); 932 BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc); 933 934 /* VCO Calibration */ 935 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40); 936 tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8; 937 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16); 938 DELAY(1); 939 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4); 940 DELAY(1); 941 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6); 942 DELAY(1); 943 BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7); 944 DELAY(300); 945 BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40); 946 947 BWN_RF_WRITE(mac, BWN_B2063_COM15, old); 948 return (0); 949 } 950 951 static int 952 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan) 953 { 954 struct bwn_softc *sc = mac->mac_sc; 955 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 956 const struct bwn_b206x_chan *bc = NULL; 957 uint32_t tmp[9]; 958 u_int freqxtal; 959 int error, i; 960 961 for (i = 0; i < N(bwn_b2062_chantable); i++) { 962 if (bwn_b2062_chantable[i].bc_chan == chan) { 963 bc = &bwn_b2062_chantable[i]; 964 break; 965 } 966 } 967 968 if (bc == NULL) 969 return (EINVAL); 970 971 error = bhnd_get_clock_freq(sc->sc_dev, BHND_CLOCK_ALP, &freqxtal); 972 if (error) { 973 device_printf(sc->sc_dev, "failed to fetch clock frequency: %d", 974 error); 975 return (error); 976 } 977 978 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04); 979 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]); 980 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]); 981 BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]); 982 BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]); 983 BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]); 984 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]); 985 BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]); 986 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]); 987 BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]); 988 989 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc); 990 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07); 991 bwn_phy_lp_b2062_reset_pllbias(mac); 992 tmp[0] = freqxtal / 1000; 993 tmp[1] = plp->plp_div * 1000; 994 tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0); 995 if (ieee80211_ieee2mhz(chan, 0) < 4000) 996 tmp[2] *= 2; 997 tmp[3] = 48 * tmp[0]; 998 tmp[5] = tmp[2] / tmp[3]; 999 tmp[6] = tmp[2] % tmp[3]; 1000 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]); 1001 tmp[4] = tmp[6] * 0x100; 1002 tmp[5] = tmp[4] / tmp[3]; 1003 tmp[6] = tmp[4] % tmp[3]; 1004 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]); 1005 tmp[4] = tmp[6] * 0x100; 1006 tmp[5] = tmp[4] / tmp[3]; 1007 tmp[6] = tmp[4] % tmp[3]; 1008 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]); 1009 tmp[4] = tmp[6] * 0x100; 1010 tmp[5] = tmp[4] / tmp[3]; 1011 tmp[6] = tmp[4] % tmp[3]; 1012 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29, 1013 tmp[5] + ((2 * tmp[6]) / tmp[3])); 1014 tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19); 1015 tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]); 1016 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16); 1017 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff); 1018 1019 bwn_phy_lp_b2062_vco_calib(mac); 1020 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 1021 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc); 1022 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0); 1023 bwn_phy_lp_b2062_reset_pllbias(mac); 1024 bwn_phy_lp_b2062_vco_calib(mac); 1025 if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) { 1026 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 1027 return (EIO); 1028 } 1029 } 1030 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04); 1031 return (0); 1032 } 1033 1034 static void 1035 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel) 1036 { 1037 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1038 uint16_t tmp = (channel == 14); 1039 1040 if (mac->mac_phy.rev < 2) { 1041 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9); 1042 if ((mac->mac_phy.rev == 1) && (plp->plp_rccap)) 1043 bwn_phy_lp_set_rccap(mac); 1044 return; 1045 } 1046 1047 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f); 1048 } 1049 1050 static void 1051 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) 1052 { 1053 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1054 struct bwn_softc *sc = mac->mac_sc; 1055 struct ieee80211com *ic = &sc->sc_ic; 1056 uint16_t iso, tmp[3]; 1057 1058 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 1059 1060 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 1061 iso = plp->plp_txisoband_m; 1062 else if (freq <= 5320) 1063 iso = plp->plp_txisoband_l; 1064 else if (freq <= 5700) 1065 iso = plp->plp_txisoband_m; 1066 else 1067 iso = plp->plp_txisoband_h; 1068 1069 tmp[0] = ((iso - 26) / 12) << 12; 1070 tmp[1] = tmp[0] + 0x1000; 1071 tmp[2] = tmp[0] + 0x2000; 1072 1073 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp); 1074 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp); 1075 } 1076 1077 static void 1078 bwn_phy_lp_digflt_save(struct bwn_mac *mac) 1079 { 1080 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1081 int i; 1082 static const uint16_t addr[] = { 1083 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 1084 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 1085 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 1086 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 1087 BWN_PHY_OFDM(0xcf), 1088 }; 1089 static const uint16_t val[] = { 1090 0xde5e, 0xe832, 0xe331, 0x4d26, 1091 0x0026, 0x1420, 0x0020, 0xfe08, 1092 0x0008, 1093 }; 1094 1095 for (i = 0; i < N(addr); i++) { 1096 plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]); 1097 BWN_PHY_WRITE(mac, addr[i], val[i]); 1098 } 1099 } 1100 1101 static void 1102 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac) 1103 { 1104 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1105 struct bwn_softc *sc = mac->mac_sc; 1106 uint16_t ctl; 1107 1108 ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD); 1109 switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) { 1110 case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF: 1111 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF; 1112 break; 1113 case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW: 1114 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW; 1115 break; 1116 case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW: 1117 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW; 1118 break; 1119 default: 1120 plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN; 1121 device_printf(sc->sc_dev, "unknown command mode\n"); 1122 break; 1123 } 1124 } 1125 1126 static void 1127 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode) 1128 { 1129 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1130 uint16_t ctl; 1131 uint8_t old; 1132 1133 bwn_phy_lp_get_txpctlmode(mac); 1134 old = plp->plp_txpctlmode; 1135 if (old == mode) 1136 return; 1137 plp->plp_txpctlmode = mode; 1138 1139 if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) { 1140 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80, 1141 plp->plp_tssiidx); 1142 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM, 1143 0x8fff, ((uint16_t)plp->plp_tssinpt << 16)); 1144 1145 /* disable TX GAIN override */ 1146 if (mac->mac_phy.rev < 2) 1147 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff); 1148 else { 1149 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f); 1150 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff); 1151 } 1152 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf); 1153 1154 plp->plp_txpwridx = -1; 1155 } 1156 if (mac->mac_phy.rev >= 2) { 1157 if (mode == BWN_PHYLP_TXPCTL_ON_HW) 1158 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2); 1159 else 1160 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd); 1161 } 1162 1163 /* writes TX Power Control mode */ 1164 switch (plp->plp_txpctlmode) { 1165 case BWN_PHYLP_TXPCTL_OFF: 1166 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF; 1167 break; 1168 case BWN_PHYLP_TXPCTL_ON_HW: 1169 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW; 1170 break; 1171 case BWN_PHYLP_TXPCTL_ON_SW: 1172 ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW; 1173 break; 1174 default: 1175 ctl = 0; 1176 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 1177 } 1178 BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 1179 (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl); 1180 } 1181 1182 static void 1183 bwn_phy_lp_bugfix(struct bwn_mac *mac) 1184 { 1185 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1186 struct bwn_softc *sc = mac->mac_sc; 1187 const unsigned int size = 256; 1188 struct bwn_txgain tg; 1189 uint32_t rxcomp, txgain, coeff, rfpwr, *tabs; 1190 uint16_t tssinpt, tssiidx, value[2]; 1191 uint8_t mode; 1192 int8_t txpwridx; 1193 1194 tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF, 1195 M_NOWAIT | M_ZERO); 1196 if (tabs == NULL) { 1197 device_printf(sc->sc_dev, "failed to allocate buffer.\n"); 1198 return; 1199 } 1200 1201 bwn_phy_lp_get_txpctlmode(mac); 1202 mode = plp->plp_txpctlmode; 1203 txpwridx = plp->plp_txpwridx; 1204 tssinpt = plp->plp_tssinpt; 1205 tssiidx = plp->plp_tssiidx; 1206 1207 bwn_tab_read_multi(mac, 1208 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 1209 BWN_TAB_4(7, 0x140), size, tabs); 1210 1211 bwn_phy_lp_tblinit(mac); 1212 bwn_phy_lp_bbinit(mac); 1213 bwn_phy_lp_txpctl_init(mac); 1214 bwn_phy_lp_rf_onoff(mac, 1); 1215 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 1216 1217 bwn_tab_write_multi(mac, 1218 (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) : 1219 BWN_TAB_4(7, 0x140), size, tabs); 1220 1221 BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan); 1222 plp->plp_tssinpt = tssinpt; 1223 plp->plp_tssiidx = tssiidx; 1224 bwn_phy_lp_set_anafilter(mac, plp->plp_chan); 1225 if (txpwridx != -1) { 1226 /* set TX power by index */ 1227 plp->plp_txpwridx = txpwridx; 1228 bwn_phy_lp_get_txpctlmode(mac); 1229 if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF) 1230 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW); 1231 if (mac->mac_phy.rev >= 2) { 1232 rxcomp = bwn_tab_read(mac, 1233 BWN_TAB_4(7, txpwridx + 320)); 1234 txgain = bwn_tab_read(mac, 1235 BWN_TAB_4(7, txpwridx + 192)); 1236 tg.tg_pad = (txgain >> 16) & 0xff; 1237 tg.tg_gm = txgain & 0xff; 1238 tg.tg_pga = (txgain >> 8) & 0xff; 1239 tg.tg_dac = (rxcomp >> 28) & 0xff; 1240 bwn_phy_lp_set_txgain(mac, &tg); 1241 } else { 1242 rxcomp = bwn_tab_read(mac, 1243 BWN_TAB_4(10, txpwridx + 320)); 1244 txgain = bwn_tab_read(mac, 1245 BWN_TAB_4(10, txpwridx + 192)); 1246 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 1247 0xf800, (txgain >> 4) & 0x7fff); 1248 bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7); 1249 bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f); 1250 } 1251 bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff); 1252 1253 /* set TX IQCC */ 1254 value[0] = (rxcomp >> 10) & 0x3ff; 1255 value[1] = rxcomp & 0x3ff; 1256 bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value); 1257 1258 coeff = bwn_tab_read(mac, 1259 (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) : 1260 BWN_TAB_4(10, txpwridx + 448)); 1261 bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff); 1262 if (mac->mac_phy.rev >= 2) { 1263 rfpwr = bwn_tab_read(mac, 1264 BWN_TAB_4(7, txpwridx + 576)); 1265 BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, 1266 rfpwr & 0xffff); 1267 } 1268 bwn_phy_lp_set_txgain_override(mac); 1269 } 1270 if (plp->plp_rccap) 1271 bwn_phy_lp_set_rccap(mac); 1272 bwn_phy_lp_set_antenna(mac, plp->plp_antenna); 1273 bwn_phy_lp_set_txpctlmode(mac, mode); 1274 free(tabs, M_DEVBUF); 1275 } 1276 1277 static void 1278 bwn_phy_lp_digflt_restore(struct bwn_mac *mac) 1279 { 1280 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1281 int i; 1282 static const uint16_t addr[] = { 1283 BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2), 1284 BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4), 1285 BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6), 1286 BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8), 1287 BWN_PHY_OFDM(0xcf), 1288 }; 1289 1290 for (i = 0; i < N(addr); i++) 1291 BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]); 1292 } 1293 1294 static void 1295 bwn_phy_lp_tblinit(struct bwn_mac *mac) 1296 { 1297 uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0); 1298 1299 if (mac->mac_phy.rev < 2) { 1300 bwn_phy_lp_tblinit_r01(mac); 1301 bwn_phy_lp_tblinit_txgain(mac); 1302 bwn_phy_lp_set_gaintbl(mac, freq); 1303 return; 1304 } 1305 1306 bwn_phy_lp_tblinit_r2(mac); 1307 bwn_phy_lp_tblinit_txgain(mac); 1308 } 1309 1310 struct bwn_wpair { 1311 uint16_t reg; 1312 uint16_t value; 1313 }; 1314 1315 struct bwn_smpair { 1316 uint16_t offset; 1317 uint16_t mask; 1318 uint16_t set; 1319 }; 1320 1321 static void 1322 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) 1323 { 1324 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1325 struct bwn_softc *sc = mac->mac_sc; 1326 struct ieee80211com *ic = &sc->sc_ic; 1327 static const struct bwn_wpair v1[] = { 1328 { BWN_PHY_AFE_DAC_CTL, 0x50 }, 1329 { BWN_PHY_AFE_CTL, 0x8800 }, 1330 { BWN_PHY_AFE_CTL_OVR, 0 }, 1331 { BWN_PHY_AFE_CTL_OVRVAL, 0 }, 1332 { BWN_PHY_RF_OVERRIDE_0, 0 }, 1333 { BWN_PHY_RF_OVERRIDE_2, 0 }, 1334 { BWN_PHY_OFDM(0xf9), 0 }, 1335 { BWN_PHY_TR_LOOKUP_1, 0 } 1336 }; 1337 static const struct bwn_smpair v2[] = { 1338 { BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 }, 1339 { BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 }, 1340 { BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f }, 1341 { BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 }, 1342 { BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 } 1343 }; 1344 static const struct bwn_smpair v3[] = { 1345 { BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f }, 1346 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 1347 { BWN_PHY_OFDM(0x100), 0xff00, 0x19 }, 1348 { BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 }, 1349 { BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 }, 1350 { BWN_PHY_OFDM(0xff), 0xffe0, 0xc }, 1351 { BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 }, 1352 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 }, 1353 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 }, 1354 { BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 }, 1355 1356 }; 1357 int i; 1358 1359 for (i = 0; i < N(v1); i++) 1360 BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value); 1361 BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10); 1362 for (i = 0; i < N(v2); i++) 1363 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set); 1364 1365 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000); 1366 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000); 1367 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1); 1368 if (sc->sc_board_info.board_rev >= 0x18) { 1369 bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec); 1370 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14); 1371 } else { 1372 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10); 1373 } 1374 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4); 1375 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100); 1376 BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48); 1377 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46); 1378 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10); 1379 BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9); 1380 BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf); 1381 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500); 1382 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0); 1383 BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300); 1384 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00); 1385 if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4325 && 1386 sc->sc_cid.chip_pkg == 0) { 1387 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 1388 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa); 1389 } else { 1390 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00); 1391 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd); 1392 } 1393 for (i = 0; i < N(v3); i++) 1394 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set); 1395 if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4325 && 1396 sc->sc_cid.chip_pkg == 0) { 1397 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0); 1398 bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40); 1399 } 1400 1401 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 1402 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40); 1403 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00); 1404 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6); 1405 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00); 1406 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1); 1407 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 1408 } else 1409 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40); 1410 1411 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3); 1412 BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00); 1413 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset); 1414 BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44); 1415 BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80); 1416 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954); 1417 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1, 1418 0x2000 | ((uint16_t)plp->plp_rssigs << 10) | 1419 ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf); 1420 1421 if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4325 && 1422 sc->sc_cid.chip_pkg == 0) { 1423 BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c); 1424 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800); 1425 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400); 1426 } 1427 1428 bwn_phy_lp_digflt_save(mac); 1429 } 1430 1431 static void 1432 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) 1433 { 1434 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1435 struct bwn_softc *sc = mac->mac_sc; 1436 struct ieee80211com *ic = &sc->sc_ic; 1437 static const struct bwn_smpair v1[] = { 1438 { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, 1439 { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, 1440 { BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 }, 1441 { BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 }, 1442 { BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a }, 1443 { BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 }, 1444 { BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 } 1445 }; 1446 static const struct bwn_smpair v2[] = { 1447 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 1448 { BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 }, 1449 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 1450 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 1451 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a }, 1452 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 }, 1453 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a }, 1454 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 }, 1455 { BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a }, 1456 { BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 }, 1457 { BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a }, 1458 { BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 }, 1459 { BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a }, 1460 { BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 }, 1461 { BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a }, 1462 { BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 } 1463 }; 1464 static const struct bwn_smpair v3[] = { 1465 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 }, 1466 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 }, 1467 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 }, 1468 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 }, 1469 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 1470 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 }, 1471 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 1472 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 } 1473 }; 1474 static const struct bwn_smpair v4[] = { 1475 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 }, 1476 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 }, 1477 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 }, 1478 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 }, 1479 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 }, 1480 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 }, 1481 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 }, 1482 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 } 1483 }; 1484 static const struct bwn_smpair v5[] = { 1485 { BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a }, 1486 { BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 }, 1487 { BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a }, 1488 { BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 }, 1489 { BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 }, 1490 { BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 }, 1491 { BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 }, 1492 { BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 } 1493 }; 1494 int error, i; 1495 uint16_t tmp, tmp2; 1496 1497 BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff); 1498 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0); 1499 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0); 1500 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0); 1501 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0); 1502 BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004); 1503 BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078); 1504 BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800); 1505 BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016); 1506 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004); 1507 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400); 1508 BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400); 1509 BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100); 1510 BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006); 1511 BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe); 1512 for (i = 0; i < N(v1); i++) 1513 BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set); 1514 BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 1515 0xff00, plp->plp_rxpwroffset); 1516 if ((sc->sc_board_info.board_flags & BHND_BFL_FEM) && 1517 ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) || 1518 (sc->sc_board_info.board_flags & BHND_BFL_PAREF))) { 1519 error = bhnd_pmu_set_voltage_raw(sc->sc_pmu, 1520 BHND_REGULATOR_PAREF_LDO, 0x28); 1521 if (error) 1522 device_printf(sc->sc_dev, "failed to set PAREF LDO " 1523 "voltage: %d\n", error); 1524 1525 error = bhnd_pmu_enable_regulator(sc->sc_pmu, 1526 BHND_REGULATOR_PAREF_LDO); 1527 if (error) 1528 device_printf(sc->sc_dev, "failed to enable PAREF LDO " 1529 "regulator: %d\n", error); 1530 1531 if (mac->mac_phy.rev == 0) 1532 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 1533 0xffcf, 0x0010); 1534 bwn_tab_write(mac, BWN_TAB_2(11, 7), 60); 1535 } else { 1536 error = bhnd_pmu_disable_regulator(sc->sc_pmu, 1537 BHND_REGULATOR_PAREF_LDO); 1538 if (error) 1539 device_printf(sc->sc_dev, "failed to disable PAREF LDO " 1540 "regulator: %d\n", error); 1541 1542 BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020); 1543 bwn_tab_write(mac, BWN_TAB_2(11, 7), 100); 1544 } 1545 tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000; 1546 BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp); 1547 if (sc->sc_board_info.board_flags & BHND_BFL_RSSIINV) 1548 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa); 1549 else 1550 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa); 1551 bwn_tab_write(mac, BWN_TAB_2(11, 1), 24); 1552 BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL, 1553 0xfff9, (plp->plp_bxarch << 1)); 1554 if (mac->mac_phy.rev == 1 && 1555 (sc->sc_board_info.board_flags & BHND_BFL_FEM_BT)) { 1556 for (i = 0; i < N(v2); i++) 1557 BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, 1558 v2[i].set); 1559 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) || 1560 (sc->sc_board_info.board_type == 0x048a) || 1561 ((mac->mac_phy.rev == 0) && 1562 (sc->sc_board_info.board_flags & BHND_BFL_FEM))) { 1563 for (i = 0; i < N(v3); i++) 1564 BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, 1565 v3[i].set); 1566 } else if (mac->mac_phy.rev == 1 || 1567 (sc->sc_board_info.board_flags & BHND_BFL_FEM)) { 1568 for (i = 0; i < N(v4); i++) 1569 BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask, 1570 v4[i].set); 1571 } else { 1572 for (i = 0; i < N(v5); i++) 1573 BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask, 1574 v5[i].set); 1575 } 1576 if (mac->mac_phy.rev == 1 && 1577 (sc->sc_board_info.board_flags & BHND_BFL_PAREF)) { 1578 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1); 1579 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2); 1580 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3); 1581 BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4); 1582 } 1583 if ((sc->sc_board_info.board_flags & BHND_BFL_FEM_BT) && 1584 (sc->sc_cid.chip_id == BHND_CHIPID_BCM5354) && 1585 (sc->sc_cid.chip_pkg == BHND_PKGID_BCM4712SMALL)) { 1586 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006); 1587 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005); 1588 BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff); 1589 bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W); 1590 } 1591 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 1592 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000); 1593 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040); 1594 BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400); 1595 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00); 1596 BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007); 1597 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003); 1598 BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020); 1599 BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff); 1600 } else { 1601 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff); 1602 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf); 1603 } 1604 if (mac->mac_phy.rev == 1) { 1605 tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH); 1606 tmp2 = (tmp & 0x03e0) >> 5; 1607 tmp2 |= tmp2 << 5; 1608 BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2); 1609 tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH); 1610 tmp2 = (tmp & 0x1f00) >> 8; 1611 tmp2 |= tmp2 << 5; 1612 BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2); 1613 tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB); 1614 tmp2 = tmp & 0x00ff; 1615 tmp2 |= tmp << 8; 1616 BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2); 1617 } 1618 } 1619 1620 struct bwn_b2062_freq { 1621 uint16_t freq; 1622 uint8_t value[6]; 1623 }; 1624 1625 static int 1626 bwn_phy_lp_b2062_init(struct bwn_mac *mac) 1627 { 1628 #define CALC_CTL7(freq, div) \ 1629 (((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff) 1630 #define CALC_CTL18(freq, div) \ 1631 ((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff) 1632 #define CALC_CTL19(freq, div) \ 1633 ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) 1634 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1635 struct bwn_softc *sc = mac->mac_sc; 1636 struct ieee80211com *ic = &sc->sc_ic; 1637 static const struct bwn_b2062_freq freqdata_tab[] = { 1638 { 12000, { 6, 6, 6, 6, 10, 6 } }, 1639 { 13000, { 4, 4, 4, 4, 11, 7 } }, 1640 { 14400, { 3, 3, 3, 3, 12, 7 } }, 1641 { 16200, { 3, 3, 3, 3, 13, 8 } }, 1642 { 18000, { 2, 2, 2, 2, 14, 8 } }, 1643 { 19200, { 1, 1, 1, 1, 14, 9 } } 1644 }; 1645 static const struct bwn_wpair v1[] = { 1646 { BWN_B2062_N_TXCTL3, 0 }, 1647 { BWN_B2062_N_TXCTL4, 0 }, 1648 { BWN_B2062_N_TXCTL5, 0 }, 1649 { BWN_B2062_N_TXCTL6, 0 }, 1650 { BWN_B2062_N_PDNCTL0, 0x40 }, 1651 { BWN_B2062_N_PDNCTL0, 0 }, 1652 { BWN_B2062_N_CALIB_TS, 0x10 }, 1653 { BWN_B2062_N_CALIB_TS, 0 } 1654 }; 1655 const struct bwn_b2062_freq *f = NULL; 1656 uint32_t ref; 1657 u_int xtalfreq; 1658 unsigned int i; 1659 int error; 1660 1661 error = bhnd_get_clock_freq(sc->sc_dev, BHND_CLOCK_ALP, &xtalfreq); 1662 if (error) { 1663 device_printf(sc->sc_dev, "failed to fetch clock frequency: %d", 1664 error); 1665 return (error); 1666 } 1667 1668 bwn_phy_lp_b2062_tblinit(mac); 1669 1670 for (i = 0; i < N(v1); i++) 1671 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 1672 if (mac->mac_phy.rev > 0) 1673 BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1, 1674 (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80); 1675 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 1676 BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1); 1677 else 1678 BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1); 1679 1680 if (xtalfreq <= 30000000) { 1681 plp->plp_div = 1; 1682 BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb); 1683 } else { 1684 plp->plp_div = 2; 1685 BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4); 1686 } 1687 1688 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7, 1689 CALC_CTL7(xtalfreq, plp->plp_div)); 1690 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18, 1691 CALC_CTL18(xtalfreq, plp->plp_div)); 1692 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19, 1693 CALC_CTL19(xtalfreq, plp->plp_div)); 1694 1695 ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div); 1696 ref &= 0xffff; 1697 for (i = 0; i < N(freqdata_tab); i++) { 1698 if (ref < freqdata_tab[i].freq) { 1699 f = &freqdata_tab[i]; 1700 break; 1701 } 1702 } 1703 if (f == NULL) 1704 f = &freqdata_tab[N(freqdata_tab) - 1]; 1705 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8, 1706 ((uint16_t)(f->value[1]) << 4) | f->value[0]); 1707 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9, 1708 ((uint16_t)(f->value[3]) << 4) | f->value[2]); 1709 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]); 1710 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]); 1711 1712 return (0); 1713 #undef CALC_CTL7 1714 #undef CALC_CTL18 1715 #undef CALC_CTL19 1716 } 1717 1718 static int 1719 bwn_phy_lp_b2063_init(struct bwn_mac *mac) 1720 { 1721 1722 bwn_phy_lp_b2063_tblinit(mac); 1723 BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0); 1724 BWN_RF_SET(mac, BWN_B2063_COM8, 0x38); 1725 BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56); 1726 BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2); 1727 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0); 1728 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20); 1729 BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40); 1730 if (mac->mac_phy.rev == 2) { 1731 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0); 1732 BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0); 1733 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18); 1734 } else { 1735 BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20); 1736 BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20); 1737 } 1738 1739 return (0); 1740 } 1741 1742 static int 1743 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac) 1744 { 1745 struct bwn_softc *sc = mac->mac_sc; 1746 static const struct bwn_wpair v1[] = { 1747 { BWN_B2063_RX_BB_SP8, 0x0 }, 1748 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 1749 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 1750 { BWN_B2063_RC_CALIB_CTL2, 0x15 }, 1751 { BWN_B2063_RC_CALIB_CTL3, 0x70 }, 1752 { BWN_B2063_RC_CALIB_CTL4, 0x52 }, 1753 { BWN_B2063_RC_CALIB_CTL5, 0x1 }, 1754 { BWN_B2063_RC_CALIB_CTL1, 0x7d } 1755 }; 1756 static const struct bwn_wpair v2[] = { 1757 { BWN_B2063_TX_BB_SP3, 0x0 }, 1758 { BWN_B2063_RC_CALIB_CTL1, 0x7e }, 1759 { BWN_B2063_RC_CALIB_CTL1, 0x7c }, 1760 { BWN_B2063_RC_CALIB_CTL2, 0x55 }, 1761 { BWN_B2063_RC_CALIB_CTL3, 0x76 } 1762 }; 1763 u_int freqxtal; 1764 int error, i; 1765 uint8_t tmp; 1766 1767 error = bhnd_get_clock_freq(sc->sc_dev, BHND_CLOCK_ALP, &freqxtal); 1768 if (error) { 1769 device_printf(sc->sc_dev, "failed to fetch clock frequency: %d", 1770 error); 1771 return (error); 1772 } 1773 1774 tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff; 1775 1776 for (i = 0; i < 2; i++) 1777 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 1778 BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7); 1779 for (i = 2; i < N(v1); i++) 1780 BWN_RF_WRITE(mac, v1[i].reg, v1[i].value); 1781 for (i = 0; i < 10000; i++) { 1782 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 1783 break; 1784 DELAY(1000); 1785 } 1786 1787 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 1788 BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp); 1789 1790 tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff; 1791 1792 for (i = 0; i < N(v2); i++) 1793 BWN_RF_WRITE(mac, v2[i].reg, v2[i].value); 1794 if (freqxtal == 24000000) { 1795 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc); 1796 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0); 1797 } else { 1798 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13); 1799 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1); 1800 } 1801 BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d); 1802 for (i = 0; i < 10000; i++) { 1803 if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2) 1804 break; 1805 DELAY(1000); 1806 } 1807 if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)) 1808 BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp); 1809 BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e); 1810 1811 return (0); 1812 } 1813 1814 static int 1815 bwn_phy_lp_rccal_r12(struct bwn_mac *mac) 1816 { 1817 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1818 struct bwn_softc *sc = mac->mac_sc; 1819 struct bwn_phy_lp_iq_est ie; 1820 struct bwn_txgain tx_gains; 1821 static const uint32_t pwrtbl[21] = { 1822 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 1823 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 1824 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 1825 0x0004c, 0x0002c, 0x0001a, 1826 }; 1827 uint32_t npwr, ipwr, sqpwr, tmp; 1828 int loopback, i, j, sum, error; 1829 uint16_t save[7]; 1830 uint8_t txo, bbmult, txpctlmode; 1831 1832 error = bwn_phy_lp_switch_channel(mac, 7); 1833 if (error) 1834 device_printf(sc->sc_dev, 1835 "failed to change channel to 7 (%d)\n", error); 1836 txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0; 1837 bbmult = bwn_phy_lp_get_bbmult(mac); 1838 if (txo) 1839 tx_gains = bwn_phy_lp_get_txgain(mac); 1840 1841 save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0); 1842 save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0); 1843 save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR); 1844 save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL); 1845 save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2); 1846 save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL); 1847 save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL); 1848 1849 bwn_phy_lp_get_txpctlmode(mac); 1850 txpctlmode = plp->plp_txpctlmode; 1851 bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF); 1852 1853 /* disable CRS */ 1854 bwn_phy_lp_set_deaf(mac, 1); 1855 bwn_phy_lp_set_trsw_over(mac, 0, 1); 1856 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb); 1857 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4); 1858 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7); 1859 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 1860 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10); 1861 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 1862 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf); 1863 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20); 1864 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf); 1865 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 1866 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7); 1867 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38); 1868 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f); 1869 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100); 1870 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff); 1871 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0); 1872 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1); 1873 BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20); 1874 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff); 1875 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff); 1876 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0); 1877 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af); 1878 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff); 1879 1880 loopback = bwn_phy_lp_loopback(mac); 1881 if (loopback == -1) 1882 goto done; 1883 bwn_phy_lp_set_rxgain_idx(mac, loopback); 1884 BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40); 1885 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1); 1886 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8); 1887 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0); 1888 1889 tmp = 0; 1890 memset(&ie, 0, sizeof(ie)); 1891 for (i = 128; i <= 159; i++) { 1892 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i); 1893 sum = 0; 1894 for (j = 5; j <= 25; j++) { 1895 bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0); 1896 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 1897 goto done; 1898 sqpwr = ie.ie_ipwr + ie.ie_qpwr; 1899 ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1; 1900 npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0, 1901 12); 1902 sum += ((ipwr - npwr) * (ipwr - npwr)); 1903 if ((i == 128) || (sum < tmp)) { 1904 plp->plp_rccap = i; 1905 tmp = sum; 1906 } 1907 } 1908 } 1909 bwn_phy_lp_ddfs_turnoff(mac); 1910 done: 1911 /* restore CRS */ 1912 bwn_phy_lp_clear_deaf(mac, 1); 1913 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80); 1914 BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00); 1915 1916 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]); 1917 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]); 1918 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]); 1919 BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]); 1920 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]); 1921 BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]); 1922 BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]); 1923 1924 bwn_phy_lp_set_bbmult(mac, bbmult); 1925 if (txo) 1926 bwn_phy_lp_set_txgain(mac, &tx_gains); 1927 bwn_phy_lp_set_txpctlmode(mac, txpctlmode); 1928 if (plp->plp_rccap) 1929 bwn_phy_lp_set_rccap(mac); 1930 1931 return (0); 1932 } 1933 1934 static void 1935 bwn_phy_lp_set_rccap(struct bwn_mac *mac) 1936 { 1937 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 1938 uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1; 1939 1940 if (mac->mac_phy.rev == 1) 1941 rc_cap = MIN(rc_cap + 5, 15); 1942 1943 BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, 1944 MAX(plp->plp_rccap - 4, 0x80)); 1945 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80); 1946 BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16, 1947 ((plp->plp_rccap & 0x1f) >> 2) | 0x80); 1948 } 1949 1950 static uint32_t 1951 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre) 1952 { 1953 uint32_t i, q, r; 1954 1955 if (div == 0) 1956 return (0); 1957 1958 for (i = 0, q = value / div, r = value % div; i < pre; i++) { 1959 q <<= 1; 1960 if (r << 1 >= div) { 1961 q++; 1962 r = (r << 1) - div; 1963 } 1964 } 1965 if (r << 1 >= div) 1966 q++; 1967 return (q); 1968 } 1969 1970 static void 1971 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac) 1972 { 1973 struct bwn_softc *sc = mac->mac_sc; 1974 1975 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff); 1976 DELAY(20); 1977 if (sc->sc_cid.chip_id == BHND_CHIPID_BCM5354) { 1978 BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4); 1979 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4); 1980 } else { 1981 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0); 1982 } 1983 DELAY(5); 1984 } 1985 1986 static void 1987 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac) 1988 { 1989 1990 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42); 1991 BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62); 1992 DELAY(200); 1993 } 1994 1995 static void 1996 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) 1997 { 1998 #define FLAG_A 0x01 1999 #define FLAG_G 0x02 2000 struct bwn_softc *sc = mac->mac_sc; 2001 struct ieee80211com *ic = &sc->sc_ic; 2002 static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { 2003 { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 2004 { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, 2005 { BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, }, 2006 { BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, }, 2007 { BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, }, 2008 { BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, }, 2009 { BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, }, 2010 { BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, }, 2011 { BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, }, 2012 { BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, }, 2013 { BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, }, 2014 { BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, }, 2015 { BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, }, 2016 { BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, }, 2017 { BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, }, 2018 { BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, }, 2019 { BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, }, 2020 { BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, 2021 { BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, }, 2022 { BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, }, 2023 { BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, }, 2024 { BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, }, 2025 { BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, }, 2026 { BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, }, 2027 { BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, }, 2028 { BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, }, 2029 { BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, }, 2030 { BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, }, 2031 { BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, }, 2032 { BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, }, 2033 { BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, }, 2034 { BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, }, 2035 { BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, }, 2036 { BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, }, 2037 { BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, }, 2038 { BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, }, 2039 { BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, }, 2040 { BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, }, 2041 { BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, }, 2042 { BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, }, 2043 { BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, }, 2044 { BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, }, 2045 { BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, }, 2046 { BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, }, 2047 { BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, }, 2048 { BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, }, 2049 { BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, }, 2050 }; 2051 const struct bwn_b206x_rfinit_entry *br; 2052 unsigned int i; 2053 2054 for (i = 0; i < N(bwn_b2062_init_tab); i++) { 2055 br = &bwn_b2062_init_tab[i]; 2056 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 2057 if (br->br_flags & FLAG_G) 2058 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 2059 } else { 2060 if (br->br_flags & FLAG_A) 2061 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 2062 } 2063 } 2064 #undef FLAG_A 2065 #undef FLAG_B 2066 } 2067 2068 static void 2069 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) 2070 { 2071 #define FLAG_A 0x01 2072 #define FLAG_G 0x02 2073 struct bwn_softc *sc = mac->mac_sc; 2074 struct ieee80211com *ic = &sc->sc_ic; 2075 static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { 2076 { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, 2077 { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, 2078 { BWN_B2063_COM16, 0x0, 0x0, FLAG_G, }, 2079 { BWN_B2063_COM17, 0x0, 0x0, FLAG_G, }, 2080 { BWN_B2063_COM18, 0x0, 0x0, FLAG_G, }, 2081 { BWN_B2063_COM19, 0x0, 0x0, FLAG_G, }, 2082 { BWN_B2063_COM20, 0x0, 0x0, FLAG_G, }, 2083 { BWN_B2063_COM21, 0x0, 0x0, FLAG_G, }, 2084 { BWN_B2063_COM22, 0x0, 0x0, FLAG_G, }, 2085 { BWN_B2063_COM23, 0x0, 0x0, FLAG_G, }, 2086 { BWN_B2063_COM24, 0x0, 0x0, FLAG_G, }, 2087 { BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, }, 2088 { BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, }, 2089 { BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, }, 2090 { BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, }, 2091 { BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, }, 2092 { BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, }, 2093 { BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, }, 2094 { BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, }, 2095 { BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, }, 2096 { BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, }, 2097 { BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, }, 2098 { BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, }, 2099 { BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, }, 2100 { BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, }, 2101 { BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, }, 2102 { BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, }, 2103 { BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, }, 2104 { BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, }, 2105 { BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, }, 2106 { BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, }, 2107 { BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, }, 2108 { BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, }, 2109 { BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, }, 2110 { BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, }, 2111 { BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, }, 2112 { BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, }, 2113 { BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, }, 2114 { BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, }, 2115 { BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, }, 2116 { BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, }, 2117 { BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, }, 2118 }; 2119 const struct bwn_b206x_rfinit_entry *br; 2120 unsigned int i; 2121 2122 for (i = 0; i < N(bwn_b2063_init_tab); i++) { 2123 br = &bwn_b2063_init_tab[i]; 2124 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 2125 if (br->br_flags & FLAG_G) 2126 BWN_RF_WRITE(mac, br->br_offset, br->br_valueg); 2127 } else { 2128 if (br->br_flags & FLAG_A) 2129 BWN_RF_WRITE(mac, br->br_offset, br->br_valuea); 2130 } 2131 } 2132 #undef FLAG_A 2133 #undef FLAG_B 2134 } 2135 2136 static void 2137 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset, 2138 int count, void *_data) 2139 { 2140 unsigned int i; 2141 uint32_t offset, type; 2142 uint8_t *data = _data; 2143 2144 type = BWN_TAB_GETTYPE(typenoffset); 2145 offset = BWN_TAB_GETOFFSET(typenoffset); 2146 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 2147 2148 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 2149 2150 for (i = 0; i < count; i++) { 2151 switch (type) { 2152 case BWN_TAB_8BIT: 2153 *data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 2154 data++; 2155 break; 2156 case BWN_TAB_16BIT: 2157 *((uint16_t *)data) = BWN_PHY_READ(mac, 2158 BWN_PHY_TABLEDATALO); 2159 data += 2; 2160 break; 2161 case BWN_TAB_32BIT: 2162 *((uint32_t *)data) = BWN_PHY_READ(mac, 2163 BWN_PHY_TABLEDATAHI); 2164 *((uint32_t *)data) <<= 16; 2165 *((uint32_t *)data) |= BWN_PHY_READ(mac, 2166 BWN_PHY_TABLEDATALO); 2167 data += 4; 2168 break; 2169 default: 2170 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 2171 } 2172 } 2173 } 2174 2175 static void 2176 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset, 2177 int count, const void *_data) 2178 { 2179 uint32_t offset, type, value; 2180 const uint8_t *data = _data; 2181 unsigned int i; 2182 2183 type = BWN_TAB_GETTYPE(typenoffset); 2184 offset = BWN_TAB_GETOFFSET(typenoffset); 2185 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 2186 2187 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 2188 2189 for (i = 0; i < count; i++) { 2190 switch (type) { 2191 case BWN_TAB_8BIT: 2192 value = *data; 2193 data++; 2194 KASSERT(!(value & ~0xff), 2195 ("%s:%d: fail", __func__, __LINE__)); 2196 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 2197 break; 2198 case BWN_TAB_16BIT: 2199 value = *((const uint16_t *)data); 2200 data += 2; 2201 KASSERT(!(value & ~0xffff), 2202 ("%s:%d: fail", __func__, __LINE__)); 2203 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 2204 break; 2205 case BWN_TAB_32BIT: 2206 value = *((const uint32_t *)data); 2207 data += 4; 2208 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 2209 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 2210 break; 2211 default: 2212 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 2213 } 2214 } 2215 } 2216 2217 static struct bwn_txgain 2218 bwn_phy_lp_get_txgain(struct bwn_mac *mac) 2219 { 2220 struct bwn_txgain tg; 2221 uint16_t tmp; 2222 2223 tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7; 2224 if (mac->mac_phy.rev < 2) { 2225 tmp = BWN_PHY_READ(mac, 2226 BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff; 2227 tg.tg_gm = tmp & 0x0007; 2228 tg.tg_pga = (tmp & 0x0078) >> 3; 2229 tg.tg_pad = (tmp & 0x780) >> 7; 2230 return (tg); 2231 } 2232 2233 tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL); 2234 tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff; 2235 tg.tg_gm = tmp & 0xff; 2236 tg.tg_pga = (tmp >> 8) & 0xff; 2237 return (tg); 2238 } 2239 2240 static uint8_t 2241 bwn_phy_lp_get_bbmult(struct bwn_mac *mac) 2242 { 2243 2244 return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8; 2245 } 2246 2247 static void 2248 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg) 2249 { 2250 uint16_t pa; 2251 2252 if (mac->mac_phy.rev < 2) { 2253 BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800, 2254 (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm); 2255 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 2256 bwn_phy_lp_set_txgain_override(mac); 2257 return; 2258 } 2259 2260 pa = bwn_phy_lp_get_pa_gain(mac); 2261 BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 2262 (tg->tg_pga << 8) | tg->tg_gm); 2263 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000, 2264 tg->tg_pad | (pa << 6)); 2265 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm); 2266 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000, 2267 tg->tg_pad | (pa << 8)); 2268 bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac); 2269 bwn_phy_lp_set_txgain_override(mac); 2270 } 2271 2272 static void 2273 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult) 2274 { 2275 2276 bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8); 2277 } 2278 2279 static void 2280 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx) 2281 { 2282 uint16_t trsw = (tx << 1) | rx; 2283 2284 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw); 2285 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3); 2286 } 2287 2288 static void 2289 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) 2290 { 2291 struct bwn_softc *sc = mac->mac_sc; 2292 struct ieee80211com *ic = &sc->sc_ic; 2293 uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; 2294 2295 if (mac->mac_phy.rev < 2) { 2296 trsw = gain & 0x1; 2297 lna = (gain & 0xfffc) | ((gain & 0xc) >> 2); 2298 ext_lna = (gain & 2) >> 1; 2299 2300 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 2301 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 2302 0xfbff, ext_lna << 10); 2303 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 2304 0xf7ff, ext_lna << 11); 2305 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna); 2306 } else { 2307 low_gain = gain & 0xffff; 2308 high_gain = (gain >> 16) & 0xf; 2309 ext_lna = (gain >> 21) & 0x1; 2310 trsw = ~(gain >> 20) & 0x1; 2311 2312 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw); 2313 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 2314 0xfdff, ext_lna << 9); 2315 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 2316 0xfbff, ext_lna << 10); 2317 BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain); 2318 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain); 2319 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 2320 tmp = (gain >> 2) & 0x3; 2321 BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 2322 0xe7ff, tmp<<11); 2323 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7, 2324 tmp << 3); 2325 } 2326 } 2327 2328 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1); 2329 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10); 2330 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40); 2331 if (mac->mac_phy.rev >= 2) { 2332 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 2333 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { 2334 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400); 2335 BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8); 2336 } 2337 return; 2338 } 2339 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200); 2340 } 2341 2342 static void 2343 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user) 2344 { 2345 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 2346 2347 if (user) 2348 plp->plp_crsusr_off = 1; 2349 else 2350 plp->plp_crssys_off = 1; 2351 2352 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80); 2353 } 2354 2355 static void 2356 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) 2357 { 2358 struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; 2359 struct bwn_softc *sc = mac->mac_sc; 2360 struct ieee80211com *ic = &sc->sc_ic; 2361 2362 if (user) 2363 plp->plp_crsusr_off = 0; 2364 else 2365 plp->plp_crssys_off = 0; 2366 2367 if (plp->plp_crsusr_off || plp->plp_crssys_off) 2368 return; 2369 2370 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 2371 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60); 2372 else 2373 BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20); 2374 } 2375 2376 static int 2377 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample) 2378 { 2379 #define CALC_COEFF(_v, _x, _y, _z) do { \ 2380 int _t; \ 2381 _t = _x - 20; \ 2382 if (_t >= 0) { \ 2383 _v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \ 2384 } else { \ 2385 _v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \ 2386 } \ 2387 } while (0) 2388 #define CALC_COEFF2(_v, _x, _y, _z) do { \ 2389 int _t; \ 2390 _t = _x - 11; \ 2391 if (_t >= 0) \ 2392 _v = (_y << (31 - _x)) / (_z >> _t); \ 2393 else \ 2394 _v = (_y << (31 - _x)) / (_z << -_t); \ 2395 } while (0) 2396 struct bwn_phy_lp_iq_est ie; 2397 uint16_t v0, v1; 2398 int tmp[2], ret; 2399 2400 v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S); 2401 v0 = v1 >> 8; 2402 v1 |= 0xff; 2403 2404 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0); 2405 BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff); 2406 2407 ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie); 2408 if (ret == 0) 2409 goto done; 2410 2411 if (ie.ie_ipwr + ie.ie_qpwr < 2) { 2412 ret = 0; 2413 goto done; 2414 } 2415 2416 CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr); 2417 CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr); 2418 2419 tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0])); 2420 v0 = tmp[0] >> 3; 2421 v1 = tmp[1] >> 4; 2422 done: 2423 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1); 2424 BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8); 2425 return ret; 2426 #undef CALC_COEFF 2427 #undef CALC_COEFF2 2428 } 2429 2430 static void 2431 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac) 2432 { 2433 static const uint16_t noisescale[] = { 2434 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 2435 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 2436 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 2437 0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2438 0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36, 2439 }; 2440 static const uint16_t crsgainnft[] = { 2441 0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 2442 0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 2443 0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 2444 0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 2445 0x013d, 2446 }; 2447 static const uint16_t filterctl[] = { 2448 0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 2449 0xff53, 0x0127, 2450 }; 2451 static const uint32_t psctl[] = { 2452 0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 2453 0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0, 2454 0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105, 2455 0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0, 2456 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202, 2457 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0, 2458 0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 2459 0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0, 2460 }; 2461 static const uint16_t ofdmcckgain_r0[] = { 2462 0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 2463 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 2464 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 2465 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 2466 0x755d, 2467 }; 2468 static const uint16_t ofdmcckgain_r1[] = { 2469 0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 2470 0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 2471 0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 2472 0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 2473 0x755d, 2474 }; 2475 static const uint16_t gaindelta[] = { 2476 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2477 0x0000, 2478 }; 2479 static const uint32_t txpwrctl[] = { 2480 0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 2481 0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047, 2482 0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042, 2483 0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d, 2484 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038, 2485 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033, 2486 0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 2487 0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 2488 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 2489 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f, 2490 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a, 2491 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 2492 0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 2493 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2494 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2495 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2496 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2497 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2498 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2499 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2500 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2501 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2502 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2503 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2504 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2505 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2506 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2507 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2508 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2509 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2510 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2511 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2512 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2513 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2514 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2515 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2516 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2517 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2518 0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1, 2519 0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3, 2520 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2, 2521 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20, 2522 0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 2523 0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661, 2524 0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60, 2525 0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62, 2526 0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661, 2527 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663, 2528 0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 2529 0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 2530 0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663, 2531 0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1, 2532 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0, 2533 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2, 2534 0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 2535 0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 2536 0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562, 2537 0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60, 2538 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63, 2539 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1, 2540 0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 2541 0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 2542 0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1, 2543 0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3, 2544 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2545 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2546 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2547 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2548 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2549 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2550 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2551 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2552 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2553 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2554 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2555 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2556 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2557 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2558 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2559 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2560 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2561 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2562 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2563 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2564 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2565 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2566 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2567 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000, 2568 0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 2569 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc, 2570 0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 2571 0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 2572 0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb, 2573 0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00, 2574 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd, 2575 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500, 2576 0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 2577 0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503, 2578 0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501, 2579 0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303, 2580 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01, 2581 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe, 2582 0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 2583 0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 2584 0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc, 2585 0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd, 2586 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9, 2587 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05, 2588 0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 2589 0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 2590 0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206, 2591 0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe, 2592 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9, 2593 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08, 2594 0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 2595 0x00000702, 2596 }; 2597 2598 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 2599 2600 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 2601 bwn_tab_sigsq_tbl); 2602 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 2603 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft); 2604 bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl); 2605 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl); 2606 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 2607 bwn_tab_pllfrac_tbl); 2608 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 2609 bwn_tabl_iqlocal_tbl); 2610 if (mac->mac_phy.rev == 0) { 2611 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0), 2612 ofdmcckgain_r0); 2613 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0), 2614 ofdmcckgain_r0); 2615 } else { 2616 bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1), 2617 ofdmcckgain_r1); 2618 bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1), 2619 ofdmcckgain_r1); 2620 } 2621 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta); 2622 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl); 2623 } 2624 2625 static void 2626 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac) 2627 { 2628 struct bwn_softc *sc = mac->mac_sc; 2629 int i; 2630 static const uint16_t noisescale[] = { 2631 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 2632 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 2633 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 2634 0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 2635 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 2636 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 2637 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4 2638 }; 2639 static const uint32_t filterctl[] = { 2640 0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 2641 0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f 2642 }; 2643 static const uint32_t psctl[] = { 2644 0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 2645 0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042, 2646 0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006, 2647 0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002 2648 }; 2649 static const uint32_t gainidx[] = { 2650 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2651 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2652 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2653 0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000, 2654 0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207, 2655 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 2656 0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 2657 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 2658 0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 2659 0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 2660 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 2661 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 2662 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 2663 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 2664 0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000, 2665 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2666 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2667 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2668 0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 2669 0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001, 2670 0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683, 2671 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000, 2672 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 2673 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 2674 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 2675 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 2676 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6, 2677 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a, 2678 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 2679 0x0000001a, 0x64ca55ad, 0x0000001a 2680 }; 2681 static const uint16_t auxgainidx[] = { 2682 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2683 0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 2684 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 2685 0x0004, 0x0016 2686 }; 2687 static const uint16_t swctl[] = { 2688 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 2689 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 2690 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 2691 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 2692 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 2693 0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 2694 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 2695 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 2696 }; 2697 static const uint8_t hf[] = { 2698 0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48, 2699 0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17 2700 }; 2701 static const uint32_t gainval[] = { 2702 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 2703 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 2704 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 2705 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 2706 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 2707 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 2708 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2709 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2710 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 2711 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 2712 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 2713 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 2714 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 2715 0x000000f1, 0x00000000, 0x00000000 2716 }; 2717 static const uint16_t gain[] = { 2718 0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 2719 0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 2720 0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 2721 0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 2722 0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f, 2723 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000, 2724 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2725 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2726 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2727 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2728 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2729 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 2730 }; 2731 static const uint32_t papdeps[] = { 2732 0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 2733 0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 2734 0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3, 2735 0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77, 2736 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41, 2737 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16, 2738 0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 2739 0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 2740 0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047, 2741 0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7, 2742 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3, 2743 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356, 2744 0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506 2745 }; 2746 static const uint32_t papdmult[] = { 2747 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 2748 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 2749 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 2750 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 2751 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 2752 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 2753 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 2754 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 2755 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 2756 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 2757 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 2758 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 2759 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 2760 }; 2761 static const uint32_t gainidx_a0[] = { 2762 0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 2763 0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 2764 0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa, 2765 0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3, 2766 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f, 2767 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193, 2768 0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 2769 0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 2770 0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd, 2771 0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc, 2772 0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5, 2773 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd, 2774 0x00036963, 0x000339f2, 0x00030a89, 0x0002db28 2775 }; 2776 static const uint16_t auxgainidx_a0[] = { 2777 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2778 0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 2779 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2780 0x0002, 0x0014 2781 }; 2782 static const uint32_t gainval_a0[] = { 2783 0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 2784 0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004, 2785 0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012, 2786 0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000, 2787 0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000, 2788 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000, 2789 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2790 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2791 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, 2792 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 2793 0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012, 2794 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000, 2795 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 2796 0x000000f7, 0x00000000, 0x00000000 2797 }; 2798 static const uint16_t gain_a0[] = { 2799 0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 2800 0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 2801 0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 2802 0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 2803 0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b, 2804 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000, 2805 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2806 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2807 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2808 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2809 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2810 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 2811 }; 2812 2813 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 2814 2815 for (i = 0; i < 704; i++) 2816 bwn_tab_write(mac, BWN_TAB_4(7, i), 0); 2817 2818 bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl), 2819 bwn_tab_sigsq_tbl); 2820 bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale); 2821 bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl); 2822 bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl); 2823 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx); 2824 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx); 2825 bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl); 2826 bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf); 2827 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval); 2828 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain); 2829 bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl), 2830 bwn_tab_pllfrac_tbl); 2831 bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl), 2832 bwn_tabl_iqlocal_tbl); 2833 bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps); 2834 bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult); 2835 2836 if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4325 && 2837 sc->sc_cid.chip_pkg == 0) { 2838 bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0), 2839 gainidx_a0); 2840 bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0), 2841 auxgainidx_a0); 2842 bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0), 2843 gainval_a0); 2844 bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0); 2845 } 2846 } 2847 2848 static void 2849 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) 2850 { 2851 struct bwn_softc *sc = mac->mac_sc; 2852 struct ieee80211com *ic = &sc->sc_ic; 2853 static struct bwn_txgain_entry txgain_r2[] = { 2854 { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, 2855 { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, 2856 { 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 }, 2857 { 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 }, 2858 { 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 }, 2859 { 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 }, 2860 { 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 }, 2861 { 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 }, 2862 { 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 }, 2863 { 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 }, 2864 { 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 }, 2865 { 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 }, 2866 { 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 }, 2867 { 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 }, 2868 { 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 }, 2869 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 2870 { 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 }, 2871 { 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 }, 2872 { 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 }, 2873 { 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 }, 2874 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 2875 { 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 }, 2876 { 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 }, 2877 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 2878 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 2879 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 2880 { 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 }, 2881 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 2882 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 2883 { 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 }, 2884 { 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 }, 2885 { 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 }, 2886 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 2887 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 2888 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 2889 { 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 }, 2890 { 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 }, 2891 { 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 }, 2892 { 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 }, 2893 { 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 }, 2894 { 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 }, 2895 { 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 }, 2896 { 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 }, 2897 { 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 }, 2898 { 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 }, 2899 { 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 }, 2900 { 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 }, 2901 { 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 }, 2902 { 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 }, 2903 { 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 }, 2904 { 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 }, 2905 { 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 }, 2906 { 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 }, 2907 { 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 }, 2908 { 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 }, 2909 { 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 }, 2910 { 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 }, 2911 { 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 }, 2912 { 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 }, 2913 { 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 }, 2914 { 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 }, 2915 { 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 }, 2916 { 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 }, 2917 { 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 }, 2918 }; 2919 static struct bwn_txgain_entry txgain_2ghz_r2[] = { 2920 { 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 }, 2921 { 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 }, 2922 { 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 }, 2923 { 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 }, 2924 { 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 }, 2925 { 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 }, 2926 { 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 }, 2927 { 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 }, 2928 { 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 }, 2929 { 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 }, 2930 { 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 }, 2931 { 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 }, 2932 { 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 }, 2933 { 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 }, 2934 { 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 }, 2935 { 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 }, 2936 { 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 }, 2937 { 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 }, 2938 { 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 }, 2939 { 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 }, 2940 { 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 }, 2941 { 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 }, 2942 { 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 }, 2943 { 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 }, 2944 { 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 }, 2945 { 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 }, 2946 { 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 }, 2947 { 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 }, 2948 { 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 }, 2949 { 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 }, 2950 { 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 }, 2951 { 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 }, 2952 { 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 }, 2953 { 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 }, 2954 { 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 }, 2955 { 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 }, 2956 { 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 }, 2957 { 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 }, 2958 { 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 }, 2959 { 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 }, 2960 { 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 }, 2961 { 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 }, 2962 { 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 }, 2963 { 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 }, 2964 { 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 }, 2965 { 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 }, 2966 { 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 }, 2967 { 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 }, 2968 { 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 }, 2969 { 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 }, 2970 { 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 }, 2971 { 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 }, 2972 { 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 }, 2973 { 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 }, 2974 { 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 }, 2975 { 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 }, 2976 { 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 }, 2977 { 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 }, 2978 { 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 }, 2979 { 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 }, 2980 { 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 }, 2981 { 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 }, 2982 { 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 }, 2983 { 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 }, 2984 }; 2985 static struct bwn_txgain_entry txgain_5ghz_r2[] = { 2986 { 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 }, 2987 { 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 }, 2988 { 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 }, 2989 { 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 }, 2990 { 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 }, 2991 { 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 }, 2992 { 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 }, 2993 { 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 }, 2994 { 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 }, 2995 { 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 }, 2996 { 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 }, 2997 { 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 }, 2998 { 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 }, 2999 { 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 }, 3000 { 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 }, 3001 { 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 }, 3002 { 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 }, 3003 { 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 }, 3004 { 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 }, 3005 { 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 }, 3006 { 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 }, 3007 { 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 }, 3008 { 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 }, 3009 { 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 }, 3010 { 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 }, 3011 { 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 }, 3012 { 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 }, 3013 { 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 }, 3014 { 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 }, 3015 { 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 }, 3016 { 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 }, 3017 { 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 }, 3018 { 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 }, 3019 { 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 }, 3020 { 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 }, 3021 { 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 }, 3022 { 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 }, 3023 { 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 }, 3024 { 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 }, 3025 { 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 }, 3026 { 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 }, 3027 { 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 }, 3028 { 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 }, 3029 { 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 }, 3030 { 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 }, 3031 { 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 }, 3032 { 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 }, 3033 { 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 }, 3034 { 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 }, 3035 { 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 }, 3036 { 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 }, 3037 { 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 }, 3038 { 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 }, 3039 { 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 }, 3040 { 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 }, 3041 { 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 }, 3042 { 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 }, 3043 { 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 }, 3044 { 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 }, 3045 { 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 }, 3046 { 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 }, 3047 { 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 }, 3048 { 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 }, 3049 { 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 } 3050 }; 3051 static struct bwn_txgain_entry txgain_r0[] = { 3052 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 3053 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 3054 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 3055 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 3056 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 3057 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 3058 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 3059 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 3060 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 3061 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 3062 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 3063 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 3064 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 3065 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 3066 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 3067 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 3068 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 3069 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 3070 { 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 }, 3071 { 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 }, 3072 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 3073 { 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 }, 3074 { 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 }, 3075 { 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 }, 3076 { 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 }, 3077 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 }, 3078 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 }, 3079 { 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 }, 3080 { 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 }, 3081 { 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 }, 3082 { 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 }, 3083 { 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 }, 3084 { 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 }, 3085 { 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 }, 3086 { 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 }, 3087 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 3088 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 3089 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 }, 3090 { 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 }, 3091 { 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 }, 3092 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 }, 3093 { 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 }, 3094 { 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 }, 3095 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 3096 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 3097 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 3098 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 3099 { 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 }, 3100 { 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 }, 3101 { 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 }, 3102 { 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 }, 3103 { 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 }, 3104 { 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 }, 3105 { 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 }, 3106 { 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 }, 3107 { 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 }, 3108 { 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 }, 3109 { 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 }, 3110 { 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 }, 3111 { 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 }, 3112 { 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 }, 3113 { 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 }, 3114 { 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 }, 3115 { 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 } 3116 }; 3117 static struct bwn_txgain_entry txgain_2ghz_r0[] = { 3118 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 3119 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 3120 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 3121 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 3122 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 3123 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 3124 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 3125 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 3126 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 3127 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 3128 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 3129 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 3130 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 3131 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 3132 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 3133 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 3134 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 3135 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 3136 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 3137 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 3138 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 3139 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 3140 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 3141 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 3142 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 3143 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 3144 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 3145 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 3146 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 3147 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 3148 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 3149 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 3150 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 3151 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }, 3152 { 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 }, 3153 { 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 }, 3154 { 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 }, 3155 { 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 }, 3156 { 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 }, 3157 { 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 }, 3158 { 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 }, 3159 { 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 }, 3160 { 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 }, 3161 { 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 }, 3162 { 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 }, 3163 { 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 }, 3164 { 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 }, 3165 { 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 }, 3166 { 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 }, 3167 { 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 }, 3168 { 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 }, 3169 { 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 }, 3170 { 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 }, 3171 { 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 }, 3172 { 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 }, 3173 { 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 }, 3174 { 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 }, 3175 { 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 }, 3176 { 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 }, 3177 { 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 }, 3178 { 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 }, 3179 { 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 }, 3180 { 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 }, 3181 { 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 } 3182 }; 3183 static struct bwn_txgain_entry txgain_5ghz_r0[] = { 3184 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 3185 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 3186 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 3187 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 3188 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 3189 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 3190 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 3191 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 3192 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 3193 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 3194 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 3195 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 3196 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 3197 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 3198 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 3199 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 3200 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 3201 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 3202 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 3203 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 3204 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 3205 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 3206 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 3207 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 3208 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 3209 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 3210 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 3211 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 3212 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 3213 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 3214 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 3215 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 3216 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 3217 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 3218 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 3219 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 3220 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 3221 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 3222 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 3223 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 3224 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 3225 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 3226 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 3227 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 3228 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 3229 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 3230 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 3231 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 3232 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 3233 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 3234 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 3235 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 3236 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 3237 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 3238 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 3239 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 3240 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 3241 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 3242 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 3243 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 3244 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 3245 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 3246 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 3247 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 3248 }; 3249 static struct bwn_txgain_entry txgain_r1[] = { 3250 { 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 }, 3251 { 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 }, 3252 { 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 }, 3253 { 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 }, 3254 { 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 }, 3255 { 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 }, 3256 { 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 }, 3257 { 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 }, 3258 { 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 }, 3259 { 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 }, 3260 { 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 }, 3261 { 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 }, 3262 { 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 }, 3263 { 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 }, 3264 { 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 }, 3265 { 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 }, 3266 { 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 }, 3267 { 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 }, 3268 { 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 }, 3269 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 3270 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 3271 { 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 }, 3272 { 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 }, 3273 { 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 }, 3274 { 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 }, 3275 { 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 }, 3276 { 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 }, 3277 { 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 }, 3278 { 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 }, 3279 { 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 }, 3280 { 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 }, 3281 { 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 }, 3282 { 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 }, 3283 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 3284 { 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 }, 3285 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 3286 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 3287 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 3288 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 3289 { 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 }, 3290 { 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 }, 3291 { 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 }, 3292 { 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 }, 3293 { 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 }, 3294 { 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 }, 3295 { 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 }, 3296 { 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 }, 3297 { 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 }, 3298 { 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 }, 3299 { 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 }, 3300 { 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 }, 3301 { 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 }, 3302 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 3303 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 3304 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 3305 { 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 }, 3306 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 3307 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 3308 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 3309 { 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 }, 3310 { 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 }, 3311 { 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 }, 3312 { 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 }, 3313 { 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 }, 3314 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 3315 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 }, 3316 { 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 }, 3317 { 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 }, 3318 { 7, 11, 6, 0, 71 } 3319 }; 3320 static struct bwn_txgain_entry txgain_2ghz_r1[] = { 3321 { 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 }, 3322 { 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 }, 3323 { 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 }, 3324 { 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 }, 3325 { 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 }, 3326 { 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 }, 3327 { 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 }, 3328 { 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 }, 3329 { 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 }, 3330 { 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 }, 3331 { 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 }, 3332 { 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 }, 3333 { 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 }, 3334 { 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 }, 3335 { 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 }, 3336 { 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 }, 3337 { 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 }, 3338 { 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 }, 3339 { 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 }, 3340 { 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 }, 3341 { 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 }, 3342 { 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 }, 3343 { 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 }, 3344 { 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 }, 3345 { 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 }, 3346 { 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 }, 3347 { 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 }, 3348 { 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 }, 3349 { 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 }, 3350 { 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 }, 3351 { 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 }, 3352 { 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 }, 3353 { 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 }, 3354 { 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 }, 3355 { 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 }, 3356 { 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 }, 3357 { 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 }, 3358 { 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 }, 3359 { 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 }, 3360 { 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 }, 3361 { 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 }, 3362 { 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 }, 3363 { 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 }, 3364 { 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 }, 3365 { 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 }, 3366 { 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 }, 3367 { 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 }, 3368 { 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 }, 3369 { 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 }, 3370 { 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 }, 3371 { 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 }, 3372 { 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 }, 3373 { 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 }, 3374 { 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 }, 3375 { 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 }, 3376 { 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 }, 3377 { 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 }, 3378 { 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 }, 3379 { 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 }, 3380 { 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 }, 3381 { 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 }, 3382 { 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 }, 3383 { 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 }, 3384 { 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 } 3385 }; 3386 static struct bwn_txgain_entry txgain_5ghz_r1[] = { 3387 { 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 }, 3388 { 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 }, 3389 { 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 }, 3390 { 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 }, 3391 { 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 }, 3392 { 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 }, 3393 { 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 }, 3394 { 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 }, 3395 { 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 }, 3396 { 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 }, 3397 { 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 }, 3398 { 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 }, 3399 { 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 }, 3400 { 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 }, 3401 { 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 }, 3402 { 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 }, 3403 { 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 }, 3404 { 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 }, 3405 { 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 }, 3406 { 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 }, 3407 { 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 }, 3408 { 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 }, 3409 { 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 }, 3410 { 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 }, 3411 { 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 }, 3412 { 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 }, 3413 { 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 }, 3414 { 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 }, 3415 { 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 }, 3416 { 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 }, 3417 { 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 }, 3418 { 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 }, 3419 { 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 }, 3420 { 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 }, 3421 { 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 }, 3422 { 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 }, 3423 { 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 }, 3424 { 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 }, 3425 { 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 }, 3426 { 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 }, 3427 { 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 }, 3428 { 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 }, 3429 { 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 }, 3430 { 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 }, 3431 { 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 }, 3432 { 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 }, 3433 { 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 }, 3434 { 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 }, 3435 { 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 }, 3436 { 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 }, 3437 { 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 }, 3438 { 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 }, 3439 { 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 }, 3440 { 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 }, 3441 { 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 }, 3442 { 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 }, 3443 { 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 }, 3444 { 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 }, 3445 { 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 }, 3446 { 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 }, 3447 { 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 }, 3448 { 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 }, 3449 { 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 }, 3450 { 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 } 3451 }; 3452 3453 if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) { 3454 if (sc->sc_board_info.board_flags & BHND_BFL_NOPA) 3455 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2); 3456 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 3457 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 3458 txgain_2ghz_r2); 3459 else 3460 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 3461 txgain_5ghz_r2); 3462 return; 3463 } 3464 3465 if (mac->mac_phy.rev == 0) { 3466 if ((sc->sc_board_info.board_flags & BHND_BFL_NOPA) || 3467 (sc->sc_board_info.board_flags & BHND_BFL_HGPA)) 3468 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0); 3469 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 3470 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 3471 txgain_2ghz_r0); 3472 else 3473 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, 3474 txgain_5ghz_r0); 3475 return; 3476 } 3477 3478 if ((sc->sc_board_info.board_flags & BHND_BFL_NOPA) || 3479 (sc->sc_board_info.board_flags & BHND_BFL_HGPA)) 3480 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1); 3481 else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) 3482 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1); 3483 else 3484 bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1); 3485 } 3486 3487 static void 3488 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value) 3489 { 3490 uint32_t offset, type; 3491 3492 type = BWN_TAB_GETTYPE(typeoffset); 3493 offset = BWN_TAB_GETOFFSET(typeoffset); 3494 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 3495 3496 switch (type) { 3497 case BWN_TAB_8BIT: 3498 KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__)); 3499 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 3500 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 3501 break; 3502 case BWN_TAB_16BIT: 3503 KASSERT(!(value & ~0xffff), 3504 ("%s:%d: fail", __func__, __LINE__)); 3505 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 3506 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 3507 break; 3508 case BWN_TAB_32BIT: 3509 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 3510 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16); 3511 BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value); 3512 break; 3513 default: 3514 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3515 } 3516 } 3517 3518 static int 3519 bwn_phy_lp_loopback(struct bwn_mac *mac) 3520 { 3521 struct bwn_phy_lp_iq_est ie; 3522 int i, index = -1; 3523 uint32_t tmp; 3524 3525 memset(&ie, 0, sizeof(ie)); 3526 3527 bwn_phy_lp_set_trsw_over(mac, 1, 1); 3528 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1); 3529 BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe); 3530 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800); 3531 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800); 3532 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8); 3533 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8); 3534 BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80); 3535 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80); 3536 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80); 3537 for (i = 0; i < 32; i++) { 3538 bwn_phy_lp_set_rxgain_idx(mac, i); 3539 bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0); 3540 if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie))) 3541 continue; 3542 tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000; 3543 if ((tmp > 4000) && (tmp < 10000)) { 3544 index = i; 3545 break; 3546 } 3547 } 3548 bwn_phy_lp_ddfs_turnoff(mac); 3549 return (index); 3550 } 3551 3552 static void 3553 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx) 3554 { 3555 3556 bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx))); 3557 } 3558 3559 static void 3560 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on, 3561 int incr1, int incr2, int scale_idx) 3562 { 3563 3564 bwn_phy_lp_ddfs_turnoff(mac); 3565 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80); 3566 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff); 3567 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1); 3568 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8); 3569 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3); 3570 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4); 3571 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5); 3572 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb); 3573 BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2); 3574 BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20); 3575 } 3576 3577 static uint8_t 3578 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time, 3579 struct bwn_phy_lp_iq_est *ie) 3580 { 3581 int i; 3582 3583 BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7); 3584 BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample); 3585 BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time); 3586 BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff); 3587 BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200); 3588 3589 for (i = 0; i < 500; i++) { 3590 if (!(BWN_PHY_READ(mac, 3591 BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) 3592 break; 3593 DELAY(1000); 3594 } 3595 if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) { 3596 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 3597 return 0; 3598 } 3599 3600 ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR); 3601 ie->ie_iqprod <<= 16; 3602 ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR); 3603 ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR); 3604 ie->ie_ipwr <<= 16; 3605 ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR); 3606 ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR); 3607 ie->ie_qpwr <<= 16; 3608 ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR); 3609 3610 BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8); 3611 return 1; 3612 } 3613 3614 static uint32_t 3615 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset) 3616 { 3617 uint32_t offset, type, value; 3618 3619 type = BWN_TAB_GETTYPE(typeoffset); 3620 offset = BWN_TAB_GETOFFSET(typeoffset); 3621 KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__)); 3622 3623 switch (type) { 3624 case BWN_TAB_8BIT: 3625 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 3626 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff; 3627 break; 3628 case BWN_TAB_16BIT: 3629 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 3630 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 3631 break; 3632 case BWN_TAB_32BIT: 3633 BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset); 3634 value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI); 3635 value <<= 16; 3636 value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO); 3637 break; 3638 default: 3639 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__)); 3640 value = 0; 3641 } 3642 3643 return (value); 3644 } 3645 3646 static void 3647 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac) 3648 { 3649 3650 BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd); 3651 BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf); 3652 } 3653 3654 static void 3655 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac) 3656 { 3657 uint16_t ctl; 3658 3659 ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f; 3660 ctl |= dac << 7; 3661 BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl); 3662 } 3663 3664 static void 3665 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain) 3666 { 3667 3668 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6); 3669 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8); 3670 } 3671 3672 static void 3673 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac) 3674 { 3675 3676 if (mac->mac_phy.rev < 2) 3677 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100); 3678 else { 3679 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80); 3680 BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000); 3681 } 3682 BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40); 3683 } 3684 3685 static uint16_t 3686 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac) 3687 { 3688 3689 return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f; 3690 } 3691 3692 static uint8_t 3693 bwn_nbits(int32_t val) 3694 { 3695 uint32_t tmp; 3696 uint8_t nbits = 0; 3697 3698 for (tmp = abs(val); tmp != 0; tmp >>= 1) 3699 nbits++; 3700 return (nbits); 3701 } 3702 3703 static void 3704 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count, 3705 struct bwn_txgain_entry *table) 3706 { 3707 int i; 3708 3709 for (i = offset; i < count; i++) 3710 bwn_phy_lp_gaintbl_write(mac, i, table[i]); 3711 } 3712 3713 static void 3714 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset, 3715 struct bwn_txgain_entry data) 3716 { 3717 3718 if (mac->mac_phy.rev >= 2) 3719 bwn_phy_lp_gaintbl_write_r2(mac, offset, data); 3720 else 3721 bwn_phy_lp_gaintbl_write_r01(mac, offset, data); 3722 } 3723 3724 static void 3725 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, 3726 struct bwn_txgain_entry te) 3727 { 3728 struct bwn_softc *sc = mac->mac_sc; 3729 struct ieee80211com *ic = &sc->sc_ic; 3730 uint32_t tmp; 3731 3732 KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); 3733 3734 tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm; 3735 if (mac->mac_phy.rev >= 3) { 3736 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 3737 (0x10 << 24) : (0x70 << 24)); 3738 } else { 3739 tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ? 3740 (0x14 << 24) : (0x7f << 24)); 3741 } 3742 bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp); 3743 bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset), 3744 te.te_bbmult << 20 | te.te_dac << 28); 3745 } 3746 3747 static void 3748 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset, 3749 struct bwn_txgain_entry te) 3750 { 3751 3752 KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); 3753 3754 bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset), 3755 (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm << 4) | 3756 te.te_dac); 3757 bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20); 3758 } 3759