The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/bwn/if_bwn_phy_g.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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/bwn/if_bwnreg.h>
   76 #include <dev/bwn/if_bwnvar.h>
   77 
   78 #include <dev/bwn/if_bwn_debug.h>
   79 #include <dev/bwn/if_bwn_misc.h>
   80 #include <dev/bwn/if_bwn_phy_g.h>
   81 
   82 #include "bhnd_nvram_map.h"
   83 
   84 static void     bwn_phy_g_init_sub(struct bwn_mac *);
   85 static uint8_t  bwn_has_hwpctl(struct bwn_mac *);
   86 static void     bwn_phy_init_b5(struct bwn_mac *);
   87 static void     bwn_phy_init_b6(struct bwn_mac *);
   88 static void     bwn_phy_init_a(struct bwn_mac *);
   89 static void     bwn_loopback_calcgain(struct bwn_mac *);
   90 static uint16_t bwn_rf_init_bcm2050(struct bwn_mac *);
   91 static void     bwn_lo_g_init(struct bwn_mac *);
   92 static void     bwn_lo_g_adjust(struct bwn_mac *);
   93 static void     bwn_lo_get_powervector(struct bwn_mac *);
   94 static struct bwn_lo_calib *bwn_lo_calibset(struct bwn_mac *,
   95                     const struct bwn_bbatt *, const struct bwn_rfatt *);
   96 static void     bwn_lo_write(struct bwn_mac *, struct bwn_loctl *);
   97 static void     bwn_phy_hwpctl_init(struct bwn_mac *);
   98 static void     bwn_phy_g_switch_chan(struct bwn_mac *, int, uint8_t);
   99 static void     bwn_phy_g_set_txpwr_sub(struct bwn_mac *,
  100                     const struct bwn_bbatt *, const struct bwn_rfatt *,
  101                     uint8_t);
  102 static void     bwn_phy_g_set_bbatt(struct bwn_mac *, uint16_t);
  103 static uint16_t bwn_rf_2050_rfoverval(struct bwn_mac *, uint16_t, uint32_t);
  104 static void     bwn_spu_workaround(struct bwn_mac *, uint8_t);
  105 static void     bwn_wa_init(struct bwn_mac *);
  106 static void     bwn_ofdmtab_write_2(struct bwn_mac *, uint16_t, uint16_t,
  107                     uint16_t);
  108 static void     bwn_ofdmtab_write_4(struct bwn_mac *, uint16_t, uint16_t,
  109                     uint32_t);
  110 static void     bwn_gtab_write(struct bwn_mac *, uint16_t, uint16_t,
  111                     uint16_t);
  112 static int16_t  bwn_nrssi_read(struct bwn_mac *, uint16_t);
  113 static void     bwn_nrssi_offset(struct bwn_mac *);
  114 static void     bwn_nrssi_threshold(struct bwn_mac *);
  115 static void     bwn_nrssi_slope_11g(struct bwn_mac *);
  116 static void     bwn_set_all_gains(struct bwn_mac *, int16_t, int16_t,
  117                     int16_t);
  118 static void     bwn_set_original_gains(struct bwn_mac *);
  119 static void     bwn_hwpctl_early_init(struct bwn_mac *);
  120 static void     bwn_hwpctl_init_gphy(struct bwn_mac *);
  121 static uint16_t bwn_phy_g_chan2freq(uint8_t);
  122 static void     bwn_phy_g_dc_lookup_init(struct bwn_mac *, uint8_t);
  123 
  124 /* Stuff we need */
  125 
  126 static uint16_t bwn_phy_g_txctl(struct bwn_mac *mac);
  127 static int      bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset);
  128 static void     bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp);
  129 static void     bwn_phy_lock(struct bwn_mac *mac);
  130 static void     bwn_phy_unlock(struct bwn_mac *mac);
  131 static void     bwn_rf_lock(struct bwn_mac *mac);
  132 static void     bwn_rf_unlock(struct bwn_mac *mac);
  133 
  134 static const uint16_t bwn_tab_noise_g1[] = BWN_TAB_NOISE_G1;
  135 static const uint16_t bwn_tab_noise_g2[] = BWN_TAB_NOISE_G2;
  136 static const uint16_t bwn_tab_noisescale_g1[] = BWN_TAB_NOISESCALE_G1;
  137 static const uint16_t bwn_tab_noisescale_g2[] = BWN_TAB_NOISESCALE_G2;
  138 static const uint16_t bwn_tab_noisescale_g3[] = BWN_TAB_NOISESCALE_G3;
  139 const uint8_t bwn_bitrev_table[256] = BWN_BITREV_TABLE;
  140 
  141 static uint8_t
  142 bwn_has_hwpctl(struct bwn_mac *mac)
  143 {
  144 
  145         if (mac->mac_phy.hwpctl == 0 || mac->mac_phy.use_hwpctl == NULL)
  146                 return (0);
  147         return (mac->mac_phy.use_hwpctl(mac));
  148 }
  149 
  150 int
  151 bwn_phy_g_attach(struct bwn_mac *mac)
  152 {
  153         struct bwn_softc *sc = mac->mac_sc;
  154         struct bwn_phy *phy = &mac->mac_phy;
  155         struct bwn_phy_g *pg = &phy->phy_g;
  156         unsigned int i;
  157         int16_t pab0, pab1, pab2;
  158         static int8_t bwn_phy_g_tssi2dbm_table[] = BWN_PHY_G_TSSI2DBM_TABLE;
  159         int8_t bg;
  160         int error;
  161 
  162         /* Fetch SPROM configuration */
  163 #define BWN_PHY_G_READVAR(_dev, _type, _name, _result)          \
  164 do {                                                                    \
  165         error = bhnd_nvram_getvar_ ##_type((_dev), (_name), (_result)); \
  166         if (error) {                                                    \
  167                 device_printf((_dev), "NVRAM variable %s unreadable: "  \
  168                     "%d\n", (_name), error);                            \
  169                 return (error);                                         \
  170         }                                                               \
  171 } while(0)
  172 
  173         BWN_PHY_G_READVAR(sc->sc_dev, int8, BHND_NVAR_PA0ITSSIT, &bg);
  174         BWN_PHY_G_READVAR(sc->sc_dev, int16, BHND_NVAR_PA0B0, &pab0);
  175         BWN_PHY_G_READVAR(sc->sc_dev, int16, BHND_NVAR_PA0B1, &pab1);
  176         BWN_PHY_G_READVAR(sc->sc_dev, int16, BHND_NVAR_PA0B2, &pab2);
  177         BWN_PHY_G_READVAR(sc->sc_dev, int16, BHND_NVAR_PA0MAXPWR,
  178             &pg->pg_pa0maxpwr);
  179 
  180 #undef  BWN_PHY_G_READVAR
  181 
  182         pg->pg_flags = 0;
  183         if (pab0 == 0 || pab1 == 0 || pab2 == 0 || pab0 == -1 || pab1 == -1 ||
  184             pab2 == -1) {
  185                 pg->pg_idletssi = 52;
  186                 pg->pg_tssi2dbm = bwn_phy_g_tssi2dbm_table;
  187                 return (0);
  188         }
  189 
  190         pg->pg_idletssi = (bg == 0 || bg == -1) ? 62 : bg;
  191         pg->pg_tssi2dbm = (uint8_t *)malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
  192         if (pg->pg_tssi2dbm == NULL) {
  193                 device_printf(sc->sc_dev, "failed to allocate buffer\n");
  194                 return (ENOMEM);
  195         }
  196         for (i = 0; i < 64; i++) {
  197                 int32_t m1, m2, f, q, delta;
  198                 int8_t j = 0;
  199 
  200                 m1 = BWN_TSSI2DBM(16 * pab0 + i * pab1, 32);
  201                 m2 = MAX(BWN_TSSI2DBM(32768 + i * pab2, 256), 1);
  202                 f = 256;
  203 
  204                 do {
  205                         if (j > 15) {
  206                                 device_printf(sc->sc_dev,
  207                                     "failed to generate tssi2dBm\n");
  208                                 free(pg->pg_tssi2dbm, M_DEVBUF);
  209                                 return (ENOMEM);
  210                         }
  211                         q = BWN_TSSI2DBM(f * 4096 - BWN_TSSI2DBM(m2 * f, 16) *
  212                             f, 2048);
  213                         delta = abs(q - f);
  214                         f = q;
  215                         j++;
  216                 } while (delta >= 2);
  217 
  218                 pg->pg_tssi2dbm[i] = MIN(MAX(BWN_TSSI2DBM(m1 * f, 8192), -127),
  219                     127);
  220         }
  221 
  222         pg->pg_flags |= BWN_PHY_G_FLAG_TSSITABLE_ALLOC;
  223         return (0);
  224 }
  225 
  226 void
  227 bwn_phy_g_detach(struct bwn_mac *mac)
  228 {
  229         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
  230 
  231         if (pg->pg_flags & BWN_PHY_G_FLAG_TSSITABLE_ALLOC) {
  232                 free(pg->pg_tssi2dbm, M_DEVBUF);
  233                 pg->pg_tssi2dbm = NULL;
  234         }
  235         pg->pg_flags = 0;
  236 }
  237 
  238 void
  239 bwn_phy_g_init_pre(struct bwn_mac *mac)
  240 {
  241         struct bwn_phy *phy = &mac->mac_phy;
  242         struct bwn_phy_g *pg = &phy->phy_g;
  243         void *tssi2dbm;
  244         int idletssi;
  245         unsigned int i;
  246 
  247         tssi2dbm = pg->pg_tssi2dbm;
  248         idletssi = pg->pg_idletssi;
  249 
  250         memset(pg, 0, sizeof(*pg));
  251 
  252         pg->pg_tssi2dbm = tssi2dbm;
  253         pg->pg_idletssi = idletssi;
  254 
  255         memset(pg->pg_minlowsig, 0xff, sizeof(pg->pg_minlowsig));
  256 
  257         for (i = 0; i < N(pg->pg_nrssi); i++)
  258                 pg->pg_nrssi[i] = -1000;
  259         for (i = 0; i < N(pg->pg_nrssi_lt); i++)
  260                 pg->pg_nrssi_lt[i] = i;
  261         pg->pg_lofcal = 0xffff;
  262         pg->pg_initval = 0xffff;
  263         pg->pg_immode = BWN_IMMODE_NONE;
  264         pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_UNKNOWN;
  265         pg->pg_avgtssi = 0xff;
  266 
  267         pg->pg_loctl.tx_bias = 0xff;
  268         TAILQ_INIT(&pg->pg_loctl.calib_list);
  269 }
  270 
  271 int
  272 bwn_phy_g_prepare_hw(struct bwn_mac *mac)
  273 {
  274         struct bwn_phy *phy = &mac->mac_phy;
  275         struct bwn_phy_g *pg = &phy->phy_g;
  276         struct bwn_softc *sc = mac->mac_sc;
  277         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
  278         static const struct bwn_rfatt rfatt0[] = {
  279                 { 3, 0 }, { 1, 0 }, { 5, 0 }, { 7, 0 }, { 9, 0 }, { 2, 0 },
  280                 { 0, 0 }, { 4, 0 }, { 6, 0 }, { 8, 0 }, { 1, 1 }, { 2, 1 },
  281                 { 3, 1 }, { 4, 1 }
  282         };
  283         static const struct bwn_rfatt rfatt1[] = {
  284                 { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 10, 1 }, { 12, 1 },
  285                 { 14, 1 }
  286         };
  287         static const struct bwn_rfatt rfatt2[] = {
  288                 { 0, 1 }, { 2, 1 }, { 4, 1 }, { 6, 1 }, { 8, 1 }, { 9, 1 },
  289                 { 9, 1 }
  290         };
  291         static const struct bwn_bbatt bbatt_0[] = {
  292                 { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }
  293         };
  294 
  295         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
  296 
  297         if (phy->rf_ver == 0x2050 && phy->rf_rev < 6)
  298                 pg->pg_bbatt.att = 0;
  299         else
  300                 pg->pg_bbatt.att = 2;
  301 
  302         /* prepare Radio Attenuation */
  303         pg->pg_rfatt.padmix = 0;
  304 
  305         if (sc->sc_board_info.board_vendor == PCI_VENDOR_BROADCOM &&
  306             sc->sc_board_info.board_type == BHND_BOARD_BCM94309G) {
  307                 if (sc->sc_board_info.board_rev < 0x43) {
  308                         pg->pg_rfatt.att = 2;
  309                         goto done;
  310                 } else if (sc->sc_board_info.board_rev < 0x51) {
  311                         pg->pg_rfatt.att = 3;
  312                         goto done;
  313                 }
  314         }
  315 
  316         if (phy->type == BWN_PHYTYPE_A) {
  317                 pg->pg_rfatt.att = 0x60;
  318                 goto done;
  319         }
  320 
  321         switch (phy->rf_ver) {
  322         case 0x2050:
  323                 switch (phy->rf_rev) {
  324                 case 0:
  325                         pg->pg_rfatt.att = 5;
  326                         goto done;
  327                 case 1:
  328                         if (phy->type == BWN_PHYTYPE_G) {
  329                                 if (sc->sc_board_info.board_vendor ==
  330                                     PCI_VENDOR_BROADCOM &&
  331                                     sc->sc_board_info.board_type ==
  332                                     BHND_BOARD_BCM94309G &&
  333                                     sc->sc_board_info.board_rev >= 30)
  334                                         pg->pg_rfatt.att = 3;
  335                                 else if (sc->sc_board_info.board_vendor ==
  336                                     PCI_VENDOR_BROADCOM &&
  337                                     sc->sc_board_info.board_type ==
  338                                     BHND_BOARD_BU4306)
  339                                         pg->pg_rfatt.att = 3;
  340                                 else
  341                                         pg->pg_rfatt.att = 1;
  342                         } else {
  343                                 if (sc->sc_board_info.board_vendor ==
  344                                     PCI_VENDOR_BROADCOM &&
  345                                     sc->sc_board_info.board_type ==
  346                                     BHND_BOARD_BCM94309G &&
  347                                     sc->sc_board_info.board_rev >= 30)
  348                                         pg->pg_rfatt.att = 7;
  349                                 else
  350                                         pg->pg_rfatt.att = 6;
  351                         }
  352                         goto done;
  353                 case 2:
  354                         if (phy->type == BWN_PHYTYPE_G) {
  355                                 if (sc->sc_board_info.board_vendor ==
  356                                     PCI_VENDOR_BROADCOM &&
  357                                     sc->sc_board_info.board_type ==
  358                                     BHND_BOARD_BCM94309G &&
  359                                     sc->sc_board_info.board_rev >= 30)
  360                                         pg->pg_rfatt.att = 3;
  361                                 else if (sc->sc_board_info.board_vendor ==
  362                                     PCI_VENDOR_BROADCOM &&
  363                                     sc->sc_board_info.board_type ==
  364                                     BHND_BOARD_BU4306)
  365                                         pg->pg_rfatt.att = 5;
  366                                 else if (sc->sc_cid.chip_id ==
  367                                     BHND_CHIPID_BCM4320)
  368                                         pg->pg_rfatt.att = 4;
  369                                 else
  370                                         pg->pg_rfatt.att = 3;
  371                         } else
  372                                 pg->pg_rfatt.att = 6;
  373                         goto done;
  374                 case 3:
  375                         pg->pg_rfatt.att = 5;
  376                         goto done;
  377                 case 4:
  378                 case 5:
  379                         pg->pg_rfatt.att = 1;
  380                         goto done;
  381                 case 6:
  382                 case 7:
  383                         pg->pg_rfatt.att = 5;
  384                         goto done;
  385                 case 8:
  386                         pg->pg_rfatt.att = 0xa;
  387                         pg->pg_rfatt.padmix = 1;
  388                         goto done;
  389                 case 9:
  390                 default:
  391                         pg->pg_rfatt.att = 5;
  392                         goto done;
  393                 }
  394                 break;
  395         case 0x2053:
  396                 switch (phy->rf_rev) {
  397                 case 1:
  398                         pg->pg_rfatt.att = 6;
  399                         goto done;
  400                 }
  401                 break;
  402         }
  403         pg->pg_rfatt.att = 5;
  404 done:
  405         pg->pg_txctl = (bwn_phy_g_txctl(mac) << 4);
  406 
  407         if (!bwn_has_hwpctl(mac)) {
  408                 lo->rfatt.array = rfatt0;
  409                 lo->rfatt.len = N(rfatt0);
  410                 lo->rfatt.min = 0;
  411                 lo->rfatt.max = 9;
  412                 goto genbbatt;
  413         }
  414         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
  415                 lo->rfatt.array = rfatt1;
  416                 lo->rfatt.len = N(rfatt1);
  417                 lo->rfatt.min = 0;
  418                 lo->rfatt.max = 14;
  419                 goto genbbatt;
  420         }
  421         lo->rfatt.array = rfatt2;
  422         lo->rfatt.len = N(rfatt2);
  423         lo->rfatt.min = 0;
  424         lo->rfatt.max = 9;
  425 genbbatt:
  426         lo->bbatt.array = bbatt_0;
  427         lo->bbatt.len = N(bbatt_0);
  428         lo->bbatt.min = 0;
  429         lo->bbatt.max = 8;
  430 
  431         BWN_READ_4(mac, BWN_MACCTL);
  432         if (phy->rev == 1) {
  433                 phy->gmode = 0;
  434                 bwn_reset_core(mac, 0);
  435                 bwn_phy_g_init_sub(mac);
  436                 phy->gmode = 1;
  437                 bwn_reset_core(mac, 1);
  438         }
  439         return (0);
  440 }
  441 
  442 static uint16_t
  443 bwn_phy_g_txctl(struct bwn_mac *mac)
  444 {
  445         struct bwn_phy *phy = &mac->mac_phy;
  446 
  447         if (phy->rf_ver != 0x2050)
  448                 return (0);
  449         if (phy->rf_rev == 1)
  450                 return (BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX);
  451         if (phy->rf_rev < 6)
  452                 return (BWN_TXCTL_PA2DB);
  453         if (phy->rf_rev == 8)
  454                 return (BWN_TXCTL_TXMIX);
  455         return (0);
  456 }
  457 
  458 int
  459 bwn_phy_g_init(struct bwn_mac *mac)
  460 {
  461 
  462         bwn_phy_g_init_sub(mac);
  463         return (0);
  464 }
  465 
  466 void
  467 bwn_phy_g_exit(struct bwn_mac *mac)
  468 {
  469         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
  470         struct bwn_lo_calib *cal, *tmp;
  471 
  472         if (lo == NULL)
  473                 return;
  474         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
  475                 TAILQ_REMOVE(&lo->calib_list, cal, list);
  476                 free(cal, M_DEVBUF);
  477         }
  478 }
  479 
  480 uint16_t
  481 bwn_phy_g_read(struct bwn_mac *mac, uint16_t reg)
  482 {
  483 
  484         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
  485         return (BWN_READ_2(mac, BWN_PHYDATA));
  486 }
  487 
  488 void
  489 bwn_phy_g_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
  490 {
  491 
  492         BWN_WRITE_2(mac, BWN_PHYCTL, reg);
  493         BWN_WRITE_2(mac, BWN_PHYDATA, value);
  494 }
  495 
  496 uint16_t
  497 bwn_phy_g_rf_read(struct bwn_mac *mac, uint16_t reg)
  498 {
  499 
  500         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
  501         BWN_WRITE_2(mac, BWN_RFCTL, reg | 0x80);
  502         return (BWN_READ_2(mac, BWN_RFDATALO));
  503 }
  504 
  505 void
  506 bwn_phy_g_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
  507 {
  508 
  509         KASSERT(reg != 1, ("%s:%d: fail", __func__, __LINE__));
  510         BWN_WRITE_2(mac, BWN_RFCTL, reg);
  511         BWN_WRITE_2(mac, BWN_RFDATALO, value);
  512 }
  513 
  514 int
  515 bwn_phy_g_hwpctl(struct bwn_mac *mac)
  516 {
  517 
  518         return (mac->mac_phy.rev >= 6);
  519 }
  520 
  521 void
  522 bwn_phy_g_rf_onoff(struct bwn_mac *mac, int on)
  523 {
  524         struct bwn_phy *phy = &mac->mac_phy;
  525         struct bwn_phy_g *pg = &phy->phy_g;
  526         unsigned int channel;
  527         uint16_t rfover, rfoverval;
  528 
  529         if (on) {
  530                 if (phy->rf_on)
  531                         return;
  532 
  533                 BWN_PHY_WRITE(mac, 0x15, 0x8000);
  534                 BWN_PHY_WRITE(mac, 0x15, 0xcc00);
  535                 BWN_PHY_WRITE(mac, 0x15, (phy->gmode ? 0xc0 : 0x0));
  536                 if (pg->pg_flags & BWN_PHY_G_FLAG_RADIOCTX_VALID) {
  537                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
  538                             pg->pg_radioctx_over);
  539                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
  540                             pg->pg_radioctx_overval);
  541                         pg->pg_flags &= ~BWN_PHY_G_FLAG_RADIOCTX_VALID;
  542                 }
  543                 channel = phy->chan;
  544                 bwn_phy_g_switch_chan(mac, 6, 1);
  545                 bwn_phy_g_switch_chan(mac, channel, 0);
  546                 return;
  547         }
  548 
  549         rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
  550         rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
  551         pg->pg_radioctx_over = rfover;
  552         pg->pg_radioctx_overval = rfoverval;
  553         pg->pg_flags |= BWN_PHY_G_FLAG_RADIOCTX_VALID;
  554         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover | 0x008c);
  555         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval & 0xff73);
  556 }
  557 
  558 int
  559 bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan)
  560 {
  561 
  562         if ((newchan < 1) || (newchan > 14))
  563                 return (EINVAL);
  564         bwn_phy_g_switch_chan(mac, newchan, 0);
  565 
  566         return (0);
  567 }
  568 
  569 uint32_t
  570 bwn_phy_g_get_default_chan(struct bwn_mac *mac)
  571 {
  572 
  573         return (1);
  574 }
  575 
  576 void
  577 bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna)
  578 {
  579         struct bwn_phy *phy = &mac->mac_phy;
  580         uint64_t hf;
  581         int autodiv = 0;
  582         uint16_t tmp;
  583 
  584         if (antenna == BWN_ANTAUTO0 || antenna == BWN_ANTAUTO1)
  585                 autodiv = 1;
  586 
  587         hf = bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER;
  588         bwn_hf_write(mac, hf);
  589 
  590         BWN_PHY_WRITE(mac, BWN_PHY_BBANDCFG,
  591             (BWN_PHY_READ(mac, BWN_PHY_BBANDCFG) & ~BWN_PHY_BBANDCFG_RXANT) |
  592             ((autodiv ? BWN_ANTAUTO1 : antenna)
  593                 << BWN_PHY_BBANDCFG_RXANT_SHIFT));
  594 
  595         if (autodiv) {
  596                 tmp = BWN_PHY_READ(mac, BWN_PHY_ANTDWELL);
  597                 if (antenna == BWN_ANTAUTO1)
  598                         tmp &= ~BWN_PHY_ANTDWELL_AUTODIV1;
  599                 else
  600                         tmp |= BWN_PHY_ANTDWELL_AUTODIV1;
  601                 BWN_PHY_WRITE(mac, BWN_PHY_ANTDWELL, tmp);
  602         }
  603         tmp = BWN_PHY_READ(mac, BWN_PHY_ANTWRSETT);
  604         if (autodiv)
  605                 tmp |= BWN_PHY_ANTWRSETT_ARXDIV;
  606         else
  607                 tmp &= ~BWN_PHY_ANTWRSETT_ARXDIV;
  608         BWN_PHY_WRITE(mac, BWN_PHY_ANTWRSETT, tmp);
  609         if (phy->rev >= 2) {
  610                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM61,
  611                     BWN_PHY_READ(mac, BWN_PHY_OFDM61) | BWN_PHY_OFDM61_10);
  612                 BWN_PHY_WRITE(mac, BWN_PHY_DIVSRCHGAINBACK,
  613                     (BWN_PHY_READ(mac, BWN_PHY_DIVSRCHGAINBACK) & 0xff00) |
  614                     0x15);
  615                 if (phy->rev == 2)
  616                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED, 8);
  617                 else
  618                         BWN_PHY_WRITE(mac, BWN_PHY_ADIVRELATED,
  619                             (BWN_PHY_READ(mac, BWN_PHY_ADIVRELATED) & 0xff00) |
  620                             8);
  621         }
  622         if (phy->rev >= 6)
  623                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM9B, 0xdc);
  624 
  625         hf |= BWN_HF_UCODE_ANTDIV_HELPER;
  626         bwn_hf_write(mac, hf);
  627 }
  628 
  629 int
  630 bwn_phy_g_im(struct bwn_mac *mac, int mode)
  631 {
  632         struct bwn_phy *phy = &mac->mac_phy;
  633         struct bwn_phy_g *pg = &phy->phy_g;
  634 
  635         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
  636         KASSERT(mode == BWN_IMMODE_NONE, ("%s: fail", __func__));
  637 
  638         if (phy->rev == 0 || !phy->gmode)
  639                 return (ENODEV);
  640 
  641         pg->pg_aci_wlan_automatic = 0;
  642         return (0);
  643 }
  644 
  645 bwn_txpwr_result_t
  646 bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi)
  647 {
  648         struct bwn_phy *phy = &mac->mac_phy;
  649         struct bwn_phy_g *pg = &phy->phy_g;
  650         struct bwn_softc *sc = mac->mac_sc;
  651         unsigned int tssi;
  652         int cck, ofdm;
  653         int power;
  654         int rfatt, bbatt;
  655         unsigned int max;
  656 
  657         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
  658 
  659         cck = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_CCK);
  660         ofdm = bwn_phy_shm_tssi_read(mac, BWN_SHARED_TSSI_OFDM_G);
  661         if (cck < 0 && ofdm < 0) {
  662                 if (ignore_tssi == 0)
  663                         return (BWN_TXPWR_RES_DONE);
  664                 cck = 0;
  665                 ofdm = 0;
  666         }
  667         tssi = (cck < 0) ? ofdm : ((ofdm < 0) ? cck : (cck + ofdm) / 2);
  668         if (pg->pg_avgtssi != 0xff)
  669                 tssi = (tssi + pg->pg_avgtssi) / 2;
  670         pg->pg_avgtssi = tssi;
  671         KASSERT(tssi < BWN_TSSI_MAX, ("%s:%d: fail", __func__, __LINE__));
  672 
  673         max = pg->pg_pa0maxpwr;
  674         if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL)
  675                 max -= 3;
  676         if (max >= 120) {
  677                 device_printf(sc->sc_dev, "invalid max TX-power value\n");
  678                 max = 80;
  679                 pg->pg_pa0maxpwr = max;
  680         }
  681 
  682         power = MIN(MAX((phy->txpower < 0) ? 0 : (phy->txpower << 2), 0), max) -
  683             (pg->pg_tssi2dbm[MIN(MAX(pg->pg_idletssi - pg->pg_curtssi +
  684              tssi, 0x00), 0x3f)]);
  685         if (power == 0)
  686                 return (BWN_TXPWR_RES_DONE);
  687 
  688         rfatt = -((power + 7) / 8);
  689         bbatt = (-(power / 2)) - (4 * rfatt);
  690         if ((rfatt == 0) && (bbatt == 0))
  691                 return (BWN_TXPWR_RES_DONE);
  692         pg->pg_bbatt_delta = bbatt;
  693         pg->pg_rfatt_delta = rfatt;
  694         return (BWN_TXPWR_RES_NEED_ADJUST);
  695 }
  696 
  697 void
  698 bwn_phy_g_set_txpwr(struct bwn_mac *mac)
  699 {
  700         struct bwn_phy *phy = &mac->mac_phy;
  701         struct bwn_phy_g *pg = &phy->phy_g;
  702         struct bwn_softc *sc = mac->mac_sc;
  703         int rfatt, bbatt;
  704         uint8_t txctl;
  705 
  706         bwn_mac_suspend(mac);
  707 
  708         BWN_ASSERT_LOCKED(sc);
  709 
  710         bbatt = pg->pg_bbatt.att;
  711         bbatt += pg->pg_bbatt_delta;
  712         rfatt = pg->pg_rfatt.att;
  713         rfatt += pg->pg_rfatt_delta;
  714 
  715         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
  716         txctl = pg->pg_txctl;
  717         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 2)) {
  718                 if (rfatt <= 1) {
  719                         if (txctl == 0) {
  720                                 txctl = BWN_TXCTL_PA2DB | BWN_TXCTL_TXMIX;
  721                                 rfatt += 2;
  722                                 bbatt += 2;
  723                         } else if (sc->sc_board_info.board_flags &
  724                             BHND_BFL_PACTRL) {
  725                                 bbatt += 4 * (rfatt - 2);
  726                                 rfatt = 2;
  727                         }
  728                 } else if (rfatt > 4 && txctl) {
  729                         txctl = 0;
  730                         if (bbatt < 3) {
  731                                 rfatt -= 3;
  732                                 bbatt += 2;
  733                         } else {
  734                                 rfatt -= 2;
  735                                 bbatt -= 2;
  736                         }
  737                 }
  738         }
  739         pg->pg_txctl = txctl;
  740         bwn_phy_g_setatt(mac, &bbatt, &rfatt);
  741         pg->pg_rfatt.att = rfatt;
  742         pg->pg_bbatt.att = bbatt;
  743 
  744         DPRINTF(sc, BWN_DEBUG_TXPOW, "%s: adjust TX power\n", __func__);
  745 
  746         bwn_phy_lock(mac);
  747         bwn_rf_lock(mac);
  748         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
  749             pg->pg_txctl);
  750         bwn_rf_unlock(mac);
  751         bwn_phy_unlock(mac);
  752 
  753         bwn_mac_enable(mac);
  754 }
  755 
  756 void
  757 bwn_phy_g_task_15s(struct bwn_mac *mac)
  758 {
  759         struct bwn_phy *phy = &mac->mac_phy;
  760         struct bwn_phy_g *pg = &phy->phy_g;
  761         struct bwn_softc *sc = mac->mac_sc;
  762         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
  763         unsigned long expire, now;
  764         struct bwn_lo_calib *cal, *tmp;
  765         uint8_t expired = 0;
  766 
  767         bwn_mac_suspend(mac);
  768 
  769         if (lo == NULL)
  770                 goto fail;
  771 
  772         BWN_GETTIME(now);
  773         if (bwn_has_hwpctl(mac)) {
  774                 expire = now - BWN_LO_PWRVEC_EXPIRE;
  775                 if (ieee80211_time_before(lo->pwr_vec_read_time, expire)) {
  776                         bwn_lo_get_powervector(mac);
  777                         bwn_phy_g_dc_lookup_init(mac, 0);
  778                 }
  779                 goto fail;
  780         }
  781 
  782         expire = now - BWN_LO_CALIB_EXPIRE;
  783         TAILQ_FOREACH_SAFE(cal, &lo->calib_list, list, tmp) {
  784                 if (!ieee80211_time_before(cal->calib_time, expire))
  785                         continue;
  786                 if (BWN_BBATTCMP(&cal->bbatt, &pg->pg_bbatt) &&
  787                     BWN_RFATTCMP(&cal->rfatt, &pg->pg_rfatt)) {
  788                         KASSERT(!expired, ("%s:%d: fail", __func__, __LINE__));
  789                         expired = 1;
  790                 }
  791 
  792                 DPRINTF(sc, BWN_DEBUG_LO, "expired BB %u RF %u %u I %d Q %d\n",
  793                     cal->bbatt.att, cal->rfatt.att, cal->rfatt.padmix,
  794                     cal->ctl.i, cal->ctl.q);
  795 
  796                 TAILQ_REMOVE(&lo->calib_list, cal, list);
  797                 free(cal, M_DEVBUF);
  798         }
  799         if (expired || TAILQ_EMPTY(&lo->calib_list)) {
  800                 cal = bwn_lo_calibset(mac, &pg->pg_bbatt,
  801                     &pg->pg_rfatt);
  802                 if (cal == NULL) {
  803                         device_printf(sc->sc_dev,
  804                             "failed to recalibrate LO\n");
  805                         goto fail;
  806                 }
  807                 TAILQ_INSERT_TAIL(&lo->calib_list, cal, list);
  808                 bwn_lo_write(mac, &cal->ctl);
  809         }
  810 
  811 fail:
  812         bwn_mac_enable(mac);
  813 }
  814 
  815 void
  816 bwn_phy_g_task_60s(struct bwn_mac *mac)
  817 {
  818         struct bwn_phy *phy = &mac->mac_phy;
  819         struct bwn_softc *sc = mac->mac_sc;
  820         uint8_t old = phy->chan;
  821 
  822         if (!(sc->sc_board_info.board_flags & BHND_BFL_ADCDIV))
  823                 return;
  824 
  825         bwn_mac_suspend(mac);
  826         bwn_nrssi_slope_11g(mac);
  827         if ((phy->rf_ver == 0x2050) && (phy->rf_rev == 8)) {
  828                 bwn_switch_channel(mac, (old >= 8) ? 1 : 13);
  829                 bwn_switch_channel(mac, old);
  830         }
  831         bwn_mac_enable(mac);
  832 }
  833 
  834 void
  835 bwn_phy_switch_analog(struct bwn_mac *mac, int on)
  836 {
  837 
  838         BWN_WRITE_2(mac, BWN_PHY0, on ? 0 : 0xf4);
  839 }
  840 
  841 static void
  842 bwn_phy_g_init_sub(struct bwn_mac *mac)
  843 {
  844         struct bwn_phy *phy = &mac->mac_phy;
  845         struct bwn_phy_g *pg = &phy->phy_g;
  846         struct bwn_softc *sc = mac->mac_sc;
  847         uint16_t i, tmp;
  848 
  849         if (phy->rev == 1)
  850                 bwn_phy_init_b5(mac);
  851         else
  852                 bwn_phy_init_b6(mac);
  853 
  854         if (phy->rev >= 2 || phy->gmode)
  855                 bwn_phy_init_a(mac);
  856 
  857         if (phy->rev >= 2) {
  858                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, 0);
  859                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, 0);
  860         }
  861         if (phy->rev == 2) {
  862                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
  863                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
  864         }
  865         if (phy->rev > 5) {
  866                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x400);
  867                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xc0);
  868         }
  869         if (phy->gmode || phy->rev >= 2) {
  870                 tmp = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
  871                 tmp &= BWN_PHYVER_VERSION;
  872                 if (tmp == 3 || tmp == 5) {
  873                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc2), 0x1816);
  874                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc3), 0x8006);
  875                 }
  876                 if (tmp == 5) {
  877                         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xcc), 0x00ff,
  878                             0x1f00);
  879                 }
  880         }
  881         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
  882                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x7e), 0x78);
  883         if (phy->rf_rev == 8) {
  884                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x80);
  885                 BWN_PHY_SET(mac, BWN_PHY_OFDM(0x3e), 0x4);
  886         }
  887         if (BWN_HAS_LOOPBACK(phy))
  888                 bwn_loopback_calcgain(mac);
  889 
  890         if (phy->rf_rev != 8) {
  891                 if (pg->pg_initval == 0xffff)
  892                         pg->pg_initval = bwn_rf_init_bcm2050(mac);
  893                 else
  894                         BWN_RF_WRITE(mac, 0x0078, pg->pg_initval);
  895         }
  896         bwn_lo_g_init(mac);
  897         if (BWN_HAS_TXMAG(phy)) {
  898                 BWN_RF_WRITE(mac, 0x52,
  899                     (BWN_RF_READ(mac, 0x52) & 0xff00)
  900                     | pg->pg_loctl.tx_bias |
  901                     pg->pg_loctl.tx_magn);
  902         } else {
  903                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, pg->pg_loctl.tx_bias);
  904         }
  905         if (phy->rev >= 6) {
  906                 BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x36), 0x0fff,
  907                     (pg->pg_loctl.tx_bias << 12));
  908         }
  909         if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL)
  910                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8075);
  911         else
  912                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x807f);
  913         if (phy->rev < 2)
  914                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x101);
  915         else
  916                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x202);
  917         if (phy->gmode || phy->rev >= 2) {
  918                 bwn_lo_g_adjust(mac);
  919                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
  920         }
  921 
  922         if (!(sc->sc_board_info.board_flags & BHND_BFL_ADCDIV)) {
  923                 for (i = 0; i < 64; i++) {
  924                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, i);
  925                         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_DATA,
  926                             (uint16_t)MIN(MAX(bwn_nrssi_read(mac, i) - 0xffff,
  927                             -32), 31));
  928                 }
  929                 bwn_nrssi_threshold(mac);
  930         } else if (phy->gmode || phy->rev >= 2) {
  931                 if (pg->pg_nrssi[0] == -1000) {
  932                         KASSERT(pg->pg_nrssi[1] == -1000,
  933                             ("%s:%d: fail", __func__, __LINE__));
  934                         bwn_nrssi_slope_11g(mac);
  935                 } else
  936                         bwn_nrssi_threshold(mac);
  937         }
  938         if (phy->rf_rev == 8)
  939                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x05), 0x3230);
  940         bwn_phy_hwpctl_init(mac);
  941         if ((sc->sc_cid.chip_id == BHND_CHIPID_BCM4306
  942              && sc->sc_cid.chip_pkg == 2) || 0) {
  943                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0xbfff);
  944                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xc3), 0x7fff);
  945         }
  946 }
  947 
  948 static void
  949 bwn_phy_init_b5(struct bwn_mac *mac)
  950 {
  951         struct bwn_phy *phy = &mac->mac_phy;
  952         struct bwn_phy_g *pg = &phy->phy_g;
  953         struct bwn_softc *sc = mac->mac_sc;
  954         uint16_t offset, value;
  955         uint8_t old_channel;
  956 
  957         if (phy->analog == 1)
  958                 BWN_RF_SET(mac, 0x007a, 0x0050);
  959         if ((sc->sc_board_info.board_vendor != PCI_VENDOR_BROADCOM) &&
  960             (sc->sc_board_info.board_type != BHND_BOARD_BU4306)) {
  961                 value = 0x2120;
  962                 for (offset = 0x00a8; offset < 0x00c7; offset++) {
  963                         BWN_PHY_WRITE(mac, offset, value);
  964                         value += 0x202;
  965                 }
  966         }
  967         BWN_PHY_SETMASK(mac, 0x0035, 0xf0ff, 0x0700);
  968         if (phy->rf_ver == 0x2050)
  969                 BWN_PHY_WRITE(mac, 0x0038, 0x0667);
  970 
  971         if (phy->gmode || phy->rev >= 2) {
  972                 if (phy->rf_ver == 0x2050) {
  973                         BWN_RF_SET(mac, 0x007a, 0x0020);
  974                         BWN_RF_SET(mac, 0x0051, 0x0004);
  975                 }
  976                 BWN_WRITE_2(mac, BWN_PHY_RADIO, 0x0000);
  977 
  978                 BWN_PHY_SET(mac, 0x0802, 0x0100);
  979                 BWN_PHY_SET(mac, 0x042b, 0x2000);
  980 
  981                 BWN_PHY_WRITE(mac, 0x001c, 0x186a);
  982 
  983                 BWN_PHY_SETMASK(mac, 0x0013, 0x00ff, 0x1900);
  984                 BWN_PHY_SETMASK(mac, 0x0035, 0xffc0, 0x0064);
  985                 BWN_PHY_SETMASK(mac, 0x005d, 0xff80, 0x000a);
  986         }
  987 
  988         if (mac->mac_flags & BWN_MAC_FLAG_BADFRAME_PREEMP)
  989                 BWN_PHY_SET(mac, BWN_PHY_RADIO_BITFIELD, (1 << 11));
  990 
  991         if (phy->analog == 1) {
  992                 BWN_PHY_WRITE(mac, 0x0026, 0xce00);
  993                 BWN_PHY_WRITE(mac, 0x0021, 0x3763);
  994                 BWN_PHY_WRITE(mac, 0x0022, 0x1bc3);
  995                 BWN_PHY_WRITE(mac, 0x0023, 0x06f9);
  996                 BWN_PHY_WRITE(mac, 0x0024, 0x037e);
  997         } else
  998                 BWN_PHY_WRITE(mac, 0x0026, 0xcc00);
  999         BWN_PHY_WRITE(mac, 0x0030, 0x00c6);
 1000         BWN_WRITE_2(mac, 0x03ec, 0x3f22);
 1001 
 1002         if (phy->analog == 1)
 1003                 BWN_PHY_WRITE(mac, 0x0020, 0x3e1c);
 1004         else
 1005                 BWN_PHY_WRITE(mac, 0x0020, 0x301c);
 1006 
 1007         if (phy->analog == 0)
 1008                 BWN_WRITE_2(mac, 0x03e4, 0x3000);
 1009 
 1010         old_channel = phy->chan;
 1011         bwn_phy_g_switch_chan(mac, 7, 0);
 1012 
 1013         if (phy->rf_ver != 0x2050) {
 1014                 BWN_RF_WRITE(mac, 0x0075, 0x0080);
 1015                 BWN_RF_WRITE(mac, 0x0079, 0x0081);
 1016         }
 1017 
 1018         BWN_RF_WRITE(mac, 0x0050, 0x0020);
 1019         BWN_RF_WRITE(mac, 0x0050, 0x0023);
 1020 
 1021         if (phy->rf_ver == 0x2050) {
 1022                 BWN_RF_WRITE(mac, 0x0050, 0x0020);
 1023                 BWN_RF_WRITE(mac, 0x005a, 0x0070);
 1024         }
 1025 
 1026         BWN_RF_WRITE(mac, 0x005b, 0x007b);
 1027         BWN_RF_WRITE(mac, 0x005c, 0x00b0);
 1028         BWN_RF_SET(mac, 0x007a, 0x0007);
 1029 
 1030         bwn_phy_g_switch_chan(mac, old_channel, 0);
 1031         BWN_PHY_WRITE(mac, 0x0014, 0x0080);
 1032         BWN_PHY_WRITE(mac, 0x0032, 0x00ca);
 1033         BWN_PHY_WRITE(mac, 0x002a, 0x88a3);
 1034 
 1035         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
 1036             pg->pg_txctl);
 1037 
 1038         if (phy->rf_ver == 0x2050)
 1039                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
 1040 
 1041         BWN_WRITE_2(mac, 0x03e4, (BWN_READ_2(mac, 0x03e4) & 0xffc0) | 0x0004);
 1042 }
 1043 
 1044 static void
 1045 bwn_loopback_calcgain(struct bwn_mac *mac)
 1046 {
 1047         struct bwn_phy *phy = &mac->mac_phy;
 1048         struct bwn_phy_g *pg = &phy->phy_g;
 1049         struct bwn_softc *sc = mac->mac_sc;
 1050         uint16_t backup_phy[16] = { 0 };
 1051         uint16_t backup_radio[3];
 1052         uint16_t backup_bband;
 1053         uint16_t i, j, loop_i_max;
 1054         uint16_t trsw_rx;
 1055         uint16_t loop1_outer_done, loop1_inner_done;
 1056 
 1057         backup_phy[0] = BWN_PHY_READ(mac, BWN_PHY_CRS0);
 1058         backup_phy[1] = BWN_PHY_READ(mac, BWN_PHY_CCKBBANDCFG);
 1059         backup_phy[2] = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
 1060         backup_phy[3] = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
 1061         if (phy->rev != 1) {
 1062                 backup_phy[4] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
 1063                 backup_phy[5] = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
 1064         }
 1065         backup_phy[6] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
 1066         backup_phy[7] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
 1067         backup_phy[8] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
 1068         backup_phy[9] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x0a));
 1069         backup_phy[10] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x03));
 1070         backup_phy[11] = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
 1071         backup_phy[12] = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
 1072         backup_phy[13] = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2b));
 1073         backup_phy[14] = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
 1074         backup_phy[15] = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
 1075         backup_bband = pg->pg_bbatt.att;
 1076         backup_radio[0] = BWN_RF_READ(mac, 0x52);
 1077         backup_radio[1] = BWN_RF_READ(mac, 0x43);
 1078         backup_radio[2] = BWN_RF_READ(mac, 0x7a);
 1079 
 1080         BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x3fff);
 1081         BWN_PHY_SET(mac, BWN_PHY_CCKBBANDCFG, 0x8000);
 1082         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0002);
 1083         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffd);
 1084         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0001);
 1085         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xfffe);
 1086         if (phy->rev != 1) {
 1087                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0001);
 1088                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffe);
 1089                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0002);
 1090                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffd);
 1091         }
 1092         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x000c);
 1093         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x000c);
 1094         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0030);
 1095         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xffcf, 0x10);
 1096 
 1097         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0780);
 1098         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
 1099         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
 1100 
 1101         BWN_PHY_SET(mac, BWN_PHY_CCK(0x0a), 0x2000);
 1102         if (phy->rev != 1) {
 1103                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0004);
 1104                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffb);
 1105         }
 1106         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xff9f, 0x40);
 1107 
 1108         if (phy->rf_rev == 8)
 1109                 BWN_RF_WRITE(mac, 0x43, 0x000f);
 1110         else {
 1111                 BWN_RF_WRITE(mac, 0x52, 0);
 1112                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x9);
 1113         }
 1114         bwn_phy_g_set_bbatt(mac, 11);
 1115 
 1116         if (phy->rev >= 3)
 1117                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
 1118         else
 1119                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
 1120         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
 1121 
 1122         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xffc0, 0x01);
 1123         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x2b), 0xc0ff, 0x800);
 1124 
 1125         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0100);
 1126         BWN_PHY_MASK(mac, BWN_PHY_RFOVERVAL, 0xcfff);
 1127 
 1128         if (sc->sc_board_info.board_flags & BHND_BFL_EXTLNA) {
 1129                 if (phy->rev >= 7) {
 1130                         BWN_PHY_SET(mac, BWN_PHY_RFOVER, 0x0800);
 1131                         BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x8000);
 1132                 }
 1133         }
 1134         BWN_RF_MASK(mac, 0x7a, 0x00f7);
 1135 
 1136         j = 0;
 1137         loop_i_max = (phy->rf_rev == 8) ? 15 : 9;
 1138         for (i = 0; i < loop_i_max; i++) {
 1139                 for (j = 0; j < 16; j++) {
 1140                         BWN_RF_WRITE(mac, 0x43, i);
 1141                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff,
 1142                             (j << 8));
 1143                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
 1144                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
 1145                         DELAY(20);
 1146                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
 1147                                 goto done0;
 1148                 }
 1149         }
 1150 done0:
 1151         loop1_outer_done = i;
 1152         loop1_inner_done = j;
 1153         if (j >= 8) {
 1154                 BWN_PHY_SET(mac, BWN_PHY_RFOVERVAL, 0x30);
 1155                 trsw_rx = 0x1b;
 1156                 for (j = j - 8; j < 16; j++) {
 1157                         BWN_PHY_SETMASK(mac, BWN_PHY_RFOVERVAL, 0xf0ff, j << 8);
 1158                         BWN_PHY_SETMASK(mac, BWN_PHY_PGACTL, 0x0fff, 0xa000);
 1159                         BWN_PHY_SET(mac, BWN_PHY_PGACTL, 0xf000);
 1160                         DELAY(20);
 1161                         trsw_rx -= 3;
 1162                         if (BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE) >= 0xdfc)
 1163                                 goto done1;
 1164                 }
 1165         } else
 1166                 trsw_rx = 0x18;
 1167 done1:
 1168 
 1169         if (phy->rev != 1) {
 1170                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, backup_phy[4]);
 1171                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL, backup_phy[5]);
 1172         }
 1173         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), backup_phy[6]);
 1174         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), backup_phy[7]);
 1175         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), backup_phy[8]);
 1176         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x0a), backup_phy[9]);
 1177         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x03), backup_phy[10]);
 1178         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, backup_phy[11]);
 1179         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, backup_phy[12]);
 1180         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), backup_phy[13]);
 1181         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, backup_phy[14]);
 1182 
 1183         bwn_phy_g_set_bbatt(mac, backup_bband);
 1184 
 1185         BWN_RF_WRITE(mac, 0x52, backup_radio[0]);
 1186         BWN_RF_WRITE(mac, 0x43, backup_radio[1]);
 1187         BWN_RF_WRITE(mac, 0x7a, backup_radio[2]);
 1188 
 1189         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2] | 0x0003);
 1190         DELAY(10);
 1191         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, backup_phy[2]);
 1192         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, backup_phy[3]);
 1193         BWN_PHY_WRITE(mac, BWN_PHY_CRS0, backup_phy[0]);
 1194         BWN_PHY_WRITE(mac, BWN_PHY_CCKBBANDCFG, backup_phy[1]);
 1195 
 1196         pg->pg_max_lb_gain =
 1197             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
 1198         pg->pg_trsw_rx_gain = trsw_rx * 2;
 1199 }
 1200 
 1201 static uint16_t
 1202 bwn_rf_init_bcm2050(struct bwn_mac *mac)
 1203 {
 1204         struct bwn_phy *phy = &mac->mac_phy;
 1205         uint32_t tmp1 = 0, tmp2 = 0;
 1206         uint16_t rcc, i, j, pgactl, cck0, cck1, cck2, cck3, rfover, rfoverval,
 1207             analogover, analogoverval, crs0, classctl, lomask, loctl, syncctl,
 1208             radio0, radio1, radio2, reg0, reg1, reg2, radio78, reg, index;
 1209         static const uint8_t rcc_table[] = {
 1210                 0x02, 0x03, 0x01, 0x0f,
 1211                 0x06, 0x07, 0x05, 0x0f,
 1212                 0x0a, 0x0b, 0x09, 0x0f,
 1213                 0x0e, 0x0f, 0x0d, 0x0f,
 1214         };
 1215 
 1216         loctl = lomask = reg0 = classctl = crs0 = analogoverval = analogover =
 1217             rfoverval = rfover = cck3 = 0;
 1218         radio0 = BWN_RF_READ(mac, 0x43);
 1219         radio1 = BWN_RF_READ(mac, 0x51);
 1220         radio2 = BWN_RF_READ(mac, 0x52);
 1221         pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
 1222         cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x5a));
 1223         cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x59));
 1224         cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x58));
 1225 
 1226         if (phy->type == BWN_PHYTYPE_B) {
 1227                 cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
 1228                 reg0 = BWN_READ_2(mac, 0x3ec);
 1229 
 1230                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0xff);
 1231                 BWN_WRITE_2(mac, 0x3ec, 0x3f3f);
 1232         } else if (phy->gmode || phy->rev >= 2) {
 1233                 rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
 1234                 rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
 1235                 analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
 1236                 analogoverval = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
 1237                 crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
 1238                 classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
 1239 
 1240                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
 1241                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
 1242                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
 1243                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
 1244                 if (BWN_HAS_LOOPBACK(phy)) {
 1245                         lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
 1246                         loctl = BWN_PHY_READ(mac, BWN_PHY_LO_CTL);
 1247                         if (phy->rev >= 3)
 1248                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc020);
 1249                         else
 1250                                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8020);
 1251                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, 0);
 1252                 }
 1253 
 1254                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1255                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
 1256                         BWN_LPD(0, 1, 1)));
 1257                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER,
 1258                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVER, 0));
 1259         }
 1260         BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2) | 0x8000);
 1261 
 1262         syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
 1263         BWN_PHY_MASK(mac, BWN_PHY_SYNCCTL, 0xff7f);
 1264         reg1 = BWN_READ_2(mac, 0x3e6);
 1265         reg2 = BWN_READ_2(mac, 0x3f4);
 1266 
 1267         if (phy->analog == 0)
 1268                 BWN_WRITE_2(mac, 0x03e6, 0x0122);
 1269         else {
 1270                 if (phy->analog >= 2)
 1271                         BWN_PHY_SETMASK(mac, BWN_PHY_CCK(0x03), 0xffbf, 0x40);
 1272                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
 1273                     (BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000));
 1274         }
 1275 
 1276         reg = BWN_RF_READ(mac, 0x60);
 1277         index = (reg & 0x001e) >> 1;
 1278         rcc = (((rcc_table[index] << 1) | (reg & 0x0001)) | 0x0020);
 1279 
 1280         if (phy->type == BWN_PHYTYPE_B)
 1281                 BWN_RF_WRITE(mac, 0x78, 0x26);
 1282         if (phy->gmode || phy->rev >= 2) {
 1283                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1284                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
 1285                         BWN_LPD(0, 1, 1)));
 1286         }
 1287         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfaf);
 1288         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1403);
 1289         if (phy->gmode || phy->rev >= 2) {
 1290                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1291                     bwn_rf_2050_rfoverval(mac, BWN_PHY_RFOVERVAL,
 1292                         BWN_LPD(0, 0, 1)));
 1293         }
 1294         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xbfa0);
 1295         BWN_RF_SET(mac, 0x51, 0x0004);
 1296         if (phy->rf_rev == 8)
 1297                 BWN_RF_WRITE(mac, 0x43, 0x1f);
 1298         else {
 1299                 BWN_RF_WRITE(mac, 0x52, 0);
 1300                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, 0x0009);
 1301         }
 1302         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
 1303 
 1304         for (i = 0; i < 16; i++) {
 1305                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0480);
 1306                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
 1307                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
 1308                 if (phy->gmode || phy->rev >= 2) {
 1309                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1310                             bwn_rf_2050_rfoverval(mac,
 1311                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
 1312                 }
 1313                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
 1314                 DELAY(10);
 1315                 if (phy->gmode || phy->rev >= 2) {
 1316                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1317                             bwn_rf_2050_rfoverval(mac,
 1318                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
 1319                 }
 1320                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
 1321                 DELAY(10);
 1322                 if (phy->gmode || phy->rev >= 2) {
 1323                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1324                             bwn_rf_2050_rfoverval(mac,
 1325                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
 1326                 }
 1327                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
 1328                 DELAY(20);
 1329                 tmp1 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
 1330                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
 1331                 if (phy->gmode || phy->rev >= 2) {
 1332                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1333                             bwn_rf_2050_rfoverval(mac,
 1334                                 BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
 1335                 }
 1336                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
 1337         }
 1338         DELAY(10);
 1339 
 1340         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
 1341         tmp1++;
 1342         tmp1 >>= 9;
 1343 
 1344         for (i = 0; i < 16; i++) {
 1345                 radio78 = (BWN_BITREV4(i) << 1) | 0x0020;
 1346                 BWN_RF_WRITE(mac, 0x78, radio78);
 1347                 DELAY(10);
 1348                 for (j = 0; j < 16; j++) {
 1349                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), 0x0d80);
 1350                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), 0xc810);
 1351                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0x000d);
 1352                         if (phy->gmode || phy->rev >= 2) {
 1353                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1354                                     bwn_rf_2050_rfoverval(mac,
 1355                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
 1356                         }
 1357                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
 1358                         DELAY(10);
 1359                         if (phy->gmode || phy->rev >= 2) {
 1360                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1361                                     bwn_rf_2050_rfoverval(mac,
 1362                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
 1363                         }
 1364                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xefb0);
 1365                         DELAY(10);
 1366                         if (phy->gmode || phy->rev >= 2) {
 1367                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1368                                     bwn_rf_2050_rfoverval(mac,
 1369                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 0)));
 1370                         }
 1371                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xfff0);
 1372                         DELAY(10);
 1373                         tmp2 += BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
 1374                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), 0);
 1375                         if (phy->gmode || phy->rev >= 2) {
 1376                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL,
 1377                                     bwn_rf_2050_rfoverval(mac,
 1378                                         BWN_PHY_RFOVERVAL, BWN_LPD(1, 0, 1)));
 1379                         }
 1380                         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xafb0);
 1381                 }
 1382                 tmp2++;
 1383                 tmp2 >>= 8;
 1384                 if (tmp1 < tmp2)
 1385                         break;
 1386         }
 1387 
 1388         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pgactl);
 1389         BWN_RF_WRITE(mac, 0x51, radio1);
 1390         BWN_RF_WRITE(mac, 0x52, radio2);
 1391         BWN_RF_WRITE(mac, 0x43, radio0);
 1392         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x5a), cck0);
 1393         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x59), cck1);
 1394         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x58), cck2);
 1395         BWN_WRITE_2(mac, 0x3e6, reg1);
 1396         if (phy->analog != 0)
 1397                 BWN_WRITE_2(mac, 0x3f4, reg2);
 1398         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, syncctl);
 1399         bwn_spu_workaround(mac, phy->chan);
 1400         if (phy->type == BWN_PHYTYPE_B) {
 1401                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), cck3);
 1402                 BWN_WRITE_2(mac, 0x3ec, reg0);
 1403         } else if (phy->gmode) {
 1404                 BWN_WRITE_2(mac, BWN_PHY_RADIO,
 1405                             BWN_READ_2(mac, BWN_PHY_RADIO)
 1406                             & 0x7fff);
 1407                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, rfover);
 1408                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfoverval);
 1409                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, analogover);
 1410                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
 1411                               analogoverval);
 1412                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, crs0);
 1413                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, classctl);
 1414                 if (BWN_HAS_LOOPBACK(phy)) {
 1415                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, lomask);
 1416                         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, loctl);
 1417                 }
 1418         }
 1419 
 1420         return ((i > 15) ? radio78 : rcc);
 1421 }
 1422 
 1423 static void
 1424 bwn_phy_init_b6(struct bwn_mac *mac)
 1425 {
 1426         struct bwn_phy *phy = &mac->mac_phy;
 1427         struct bwn_phy_g *pg = &phy->phy_g;
 1428         struct bwn_softc *sc = mac->mac_sc;
 1429         uint16_t offset, val;
 1430         uint8_t old_channel;
 1431 
 1432         KASSERT(!(phy->rf_rev == 6 || phy->rf_rev == 7),
 1433             ("%s:%d: fail", __func__, __LINE__));
 1434 
 1435         BWN_PHY_WRITE(mac, 0x003e, 0x817a);
 1436         BWN_RF_WRITE(mac, 0x007a, BWN_RF_READ(mac, 0x007a) | 0x0058);
 1437         if (phy->rf_rev == 4 || phy->rf_rev == 5) {
 1438                 BWN_RF_WRITE(mac, 0x51, 0x37);
 1439                 BWN_RF_WRITE(mac, 0x52, 0x70);
 1440                 BWN_RF_WRITE(mac, 0x53, 0xb3);
 1441                 BWN_RF_WRITE(mac, 0x54, 0x9b);
 1442                 BWN_RF_WRITE(mac, 0x5a, 0x88);
 1443                 BWN_RF_WRITE(mac, 0x5b, 0x88);
 1444                 BWN_RF_WRITE(mac, 0x5d, 0x88);
 1445                 BWN_RF_WRITE(mac, 0x5e, 0x88);
 1446                 BWN_RF_WRITE(mac, 0x7d, 0x88);
 1447                 bwn_hf_write(mac,
 1448                     bwn_hf_read(mac) | BWN_HF_TSSI_RESET_PSM_WORKAROUN);
 1449         }
 1450         if (phy->rf_rev == 8) {
 1451                 BWN_RF_WRITE(mac, 0x51, 0);
 1452                 BWN_RF_WRITE(mac, 0x52, 0x40);
 1453                 BWN_RF_WRITE(mac, 0x53, 0xb7);
 1454                 BWN_RF_WRITE(mac, 0x54, 0x98);
 1455                 BWN_RF_WRITE(mac, 0x5a, 0x88);
 1456                 BWN_RF_WRITE(mac, 0x5b, 0x6b);
 1457                 BWN_RF_WRITE(mac, 0x5c, 0x0f);
 1458                 if (sc->sc_board_info.board_flags & BHND_BFL_ALTIQ) {
 1459                         BWN_RF_WRITE(mac, 0x5d, 0xfa);
 1460                         BWN_RF_WRITE(mac, 0x5e, 0xd8);
 1461                 } else {
 1462                         BWN_RF_WRITE(mac, 0x5d, 0xf5);
 1463                         BWN_RF_WRITE(mac, 0x5e, 0xb8);
 1464                 }
 1465                 BWN_RF_WRITE(mac, 0x0073, 0x0003);
 1466                 BWN_RF_WRITE(mac, 0x007d, 0x00a8);
 1467                 BWN_RF_WRITE(mac, 0x007c, 0x0001);
 1468                 BWN_RF_WRITE(mac, 0x007e, 0x0008);
 1469         }
 1470         for (val = 0x1e1f, offset = 0x0088; offset < 0x0098; offset++) {
 1471                 BWN_PHY_WRITE(mac, offset, val);
 1472                 val -= 0x0202;
 1473         }
 1474         for (val = 0x3e3f, offset = 0x0098; offset < 0x00a8; offset++) {
 1475                 BWN_PHY_WRITE(mac, offset, val);
 1476                 val -= 0x0202;
 1477         }
 1478         for (val = 0x2120, offset = 0x00a8; offset < 0x00c8; offset++) {
 1479                 BWN_PHY_WRITE(mac, offset, (val & 0x3f3f));
 1480                 val += 0x0202;
 1481         }
 1482         if (phy->type == BWN_PHYTYPE_G) {
 1483                 BWN_RF_SET(mac, 0x007a, 0x0020);
 1484                 BWN_RF_SET(mac, 0x0051, 0x0004);
 1485                 BWN_PHY_SET(mac, 0x0802, 0x0100);
 1486                 BWN_PHY_SET(mac, 0x042b, 0x2000);
 1487                 BWN_PHY_WRITE(mac, 0x5b, 0);
 1488                 BWN_PHY_WRITE(mac, 0x5c, 0);
 1489         }
 1490 
 1491         old_channel = phy->chan;
 1492         bwn_phy_g_switch_chan(mac, (old_channel >= 8) ? 1 : 13, 0);
 1493 
 1494         BWN_RF_WRITE(mac, 0x0050, 0x0020);
 1495         BWN_RF_WRITE(mac, 0x0050, 0x0023);
 1496         DELAY(40);
 1497         if (phy->rf_rev < 6 || phy->rf_rev == 8) {
 1498                 BWN_RF_WRITE(mac, 0x7c, BWN_RF_READ(mac, 0x7c) | 0x0002);
 1499                 BWN_RF_WRITE(mac, 0x50, 0x20);
 1500         }
 1501         if (phy->rf_rev <= 2) {
 1502                 BWN_RF_WRITE(mac, 0x7c, 0x20);
 1503                 BWN_RF_WRITE(mac, 0x5a, 0x70);
 1504                 BWN_RF_WRITE(mac, 0x5b, 0x7b);
 1505                 BWN_RF_WRITE(mac, 0x5c, 0xb0);
 1506         }
 1507         BWN_RF_SETMASK(mac, 0x007a, 0x00f8, 0x0007);
 1508 
 1509         bwn_phy_g_switch_chan(mac, old_channel, 0);
 1510 
 1511         BWN_PHY_WRITE(mac, 0x0014, 0x0200);
 1512         if (phy->rf_rev >= 6)
 1513                 BWN_PHY_WRITE(mac, 0x2a, 0x88c2);
 1514         else
 1515                 BWN_PHY_WRITE(mac, 0x2a, 0x8ac0);
 1516         BWN_PHY_WRITE(mac, 0x0038, 0x0668);
 1517         bwn_phy_g_set_txpwr_sub(mac, &pg->pg_bbatt, &pg->pg_rfatt,
 1518             pg->pg_txctl);
 1519         if (phy->rf_rev <= 5)
 1520                 BWN_PHY_SETMASK(mac, 0x5d, 0xff80, 0x0003);
 1521         if (phy->rf_rev <= 2)
 1522                 BWN_RF_WRITE(mac, 0x005d, 0x000d);
 1523 
 1524         if (phy->analog == 4) {
 1525                 BWN_WRITE_2(mac, 0x3e4, 9);
 1526                 BWN_PHY_MASK(mac, 0x61, 0x0fff);
 1527         } else
 1528                 BWN_PHY_SETMASK(mac, 0x0002, 0xffc0, 0x0004);
 1529         if (phy->type == BWN_PHYTYPE_B)
 1530                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
 1531         else if (phy->type == BWN_PHYTYPE_G)
 1532                 BWN_WRITE_2(mac, 0x03e6, 0x0);
 1533 }
 1534 
 1535 static void
 1536 bwn_phy_init_a(struct bwn_mac *mac)
 1537 {
 1538         struct bwn_phy *phy = &mac->mac_phy;
 1539         struct bwn_softc *sc = mac->mac_sc;
 1540 
 1541         KASSERT(phy->type == BWN_PHYTYPE_A || phy->type == BWN_PHYTYPE_G,
 1542             ("%s:%d: fail", __func__, __LINE__));
 1543 
 1544         if (phy->rev >= 6) {
 1545                 if (phy->type == BWN_PHYTYPE_A)
 1546                         BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x1000);
 1547                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) & BWN_PHY_ENCORE_EN)
 1548                         BWN_PHY_SET(mac, BWN_PHY_ENCORE, 0x0010);
 1549                 else
 1550                         BWN_PHY_MASK(mac, BWN_PHY_ENCORE, ~0x1010);
 1551         }
 1552 
 1553         bwn_wa_init(mac);
 1554 
 1555         if (phy->type == BWN_PHYTYPE_G &&
 1556             (sc->sc_board_info.board_flags & BHND_BFL_PACTRL))
 1557                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x6e), 0xe000, 0x3cf);
 1558 }
 1559 
 1560 static void
 1561 bwn_wa_write_noisescale(struct bwn_mac *mac, const uint16_t *nst)
 1562 {
 1563         int i;
 1564 
 1565         for (i = 0; i < BWN_TAB_NOISESCALE_SIZE; i++)
 1566                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_NOISESCALE, i, nst[i]);
 1567 }
 1568 
 1569 static void
 1570 bwn_wa_agc(struct bwn_mac *mac)
 1571 {
 1572         struct bwn_phy *phy = &mac->mac_phy;
 1573 
 1574         if (phy->rev == 1) {
 1575                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 0, 254);
 1576                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 1, 13);
 1577                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 2, 19);
 1578                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1_R1, 3, 25);
 1579                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 0, 0x2710);
 1580                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 1, 0x9b83);
 1581                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 2, 0x9b83);
 1582                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, 3, 0x0f8d);
 1583                 BWN_PHY_WRITE(mac, BWN_PHY_LMS, 4);
 1584         } else {
 1585                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 0, 254);
 1586                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 1, 13);
 1587                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 2, 19);
 1588                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC1, 3, 25);
 1589         }
 1590 
 1591         BWN_PHY_SETMASK(mac, BWN_PHY_CCKSHIFTBITS_WA, (uint16_t)~0xff00,
 1592             0x5700);
 1593         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x007f, 0x000f);
 1594         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1a), ~0x3f80, 0x2b80);
 1595         BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, 0xf0ff, 0x0300);
 1596         BWN_RF_SET(mac, 0x7a, 0x0008);
 1597         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x000f, 0x0008);
 1598         BWN_PHY_SETMASK(mac, BWN_PHY_P1P2GAIN, ~0x0f00, 0x0600);
 1599         BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x0f00, 0x0700);
 1600         BWN_PHY_SETMASK(mac, BWN_PHY_N1P1GAIN, ~0x0f00, 0x0100);
 1601         if (phy->rev == 1)
 1602                 BWN_PHY_SETMASK(mac, BWN_PHY_N1N2GAIN, ~0x000f, 0x0007);
 1603         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x00ff, 0x001c);
 1604         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x88), ~0x3f00, 0x0200);
 1605         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), ~0x00ff, 0x001c);
 1606         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x00ff, 0x0020);
 1607         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x89), ~0x3f00, 0x0200);
 1608         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x82), ~0x00ff, 0x002e);
 1609         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x96), (uint16_t)~0xff00, 0x1a00);
 1610         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), ~0x00ff, 0x0028);
 1611         BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x81), (uint16_t)~0xff00, 0x2c00);
 1612         if (phy->rev == 1) {
 1613                 BWN_PHY_WRITE(mac, BWN_PHY_PEAK_COUNT, 0x092b);
 1614                 BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e, 0x0002);
 1615         } else {
 1616                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x1b), ~0x001e);
 1617                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x1f), 0x287a);
 1618                 BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL, ~0x000f, 0x0004);
 1619                 if (phy->rev >= 6) {
 1620                         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x22), 0x287a);
 1621                         BWN_PHY_SETMASK(mac, BWN_PHY_LPFGAINCTL,
 1622                             (uint16_t)~0xf000, 0x3000);
 1623                 }
 1624         }
 1625         BWN_PHY_SETMASK(mac, BWN_PHY_DIVSRCHIDX, 0x8080, 0x7874);
 1626         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8e), 0x1c00);
 1627         if (phy->rev == 1) {
 1628                 BWN_PHY_SETMASK(mac, BWN_PHY_DIVP1P2GAIN, ~0x0f00, 0x0600);
 1629                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8b), 0x005e);
 1630                 BWN_PHY_SETMASK(mac, BWN_PHY_ANTWRSETT, ~0x00ff, 0x001e);
 1631                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x8d), 0x0002);
 1632                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 0, 0);
 1633                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 1, 7);
 1634                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 2, 16);
 1635                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3_R1, 3, 28);
 1636         } else {
 1637                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 0, 0);
 1638                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 1, 7);
 1639                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 2, 16);
 1640                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC3, 3, 28);
 1641         }
 1642         if (phy->rev >= 6) {
 1643                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x0003);
 1644                 BWN_PHY_MASK(mac, BWN_PHY_OFDM(0x26), ~0x1000);
 1645         }
 1646         BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM);
 1647 }
 1648 
 1649 static void
 1650 bwn_wa_grev1(struct bwn_mac *mac)
 1651 {
 1652         struct bwn_phy *phy = &mac->mac_phy;
 1653         int i;
 1654         static const uint16_t bwn_tab_finefreqg[] = BWN_TAB_FINEFREQ_G;
 1655         static const uint32_t bwn_tab_retard[] = BWN_TAB_RETARD;
 1656         static const uint32_t bwn_tab_rotor[] = BWN_TAB_ROTOR;
 1657 
 1658         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
 1659 
 1660         /* init CRSTHRES and ANTDWELL */
 1661         if (phy->rev == 1) {
 1662                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
 1663         } else if (phy->rev == 2) {
 1664                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
 1665                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
 1666                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
 1667         } else {
 1668                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
 1669                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
 1670                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
 1671                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
 1672         }
 1673         BWN_PHY_SETMASK(mac, BWN_PHY_CRS0, ~0x03c0, 0xd000);
 1674         BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0x2c), 0x005a);
 1675         BWN_PHY_WRITE(mac, BWN_PHY_CCKSHIFTBITS, 0x0026);
 1676 
 1677         /* XXX support PHY-A??? */
 1678         for (i = 0; i < N(bwn_tab_finefreqg); i++)
 1679                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DACRFPABB, i,
 1680                     bwn_tab_finefreqg[i]);
 1681 
 1682         /* XXX support PHY-A??? */
 1683         if (phy->rev == 1)
 1684                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
 1685                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
 1686                             bwn_tab_noise_g1[i]);
 1687         else
 1688                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
 1689                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
 1690                             bwn_tab_noise_g2[i]);
 1691 
 1692         for (i = 0; i < N(bwn_tab_rotor); i++)
 1693                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ROTOR, i,
 1694                     bwn_tab_rotor[i]);
 1695 
 1696         /* XXX support PHY-A??? */
 1697         if (phy->rev >= 6) {
 1698                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
 1699                     BWN_PHY_ENCORE_EN)
 1700                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
 1701                 else
 1702                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
 1703         } else
 1704                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
 1705 
 1706         for (i = 0; i < N(bwn_tab_retard); i++)
 1707                 bwn_ofdmtab_write_4(mac, BWN_OFDMTAB_ADVRETARD, i,
 1708                     bwn_tab_retard[i]);
 1709 
 1710         if (phy->rev == 1) {
 1711                 for (i = 0; i < 16; i++)
 1712                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1,
 1713                             i, 0x0020);
 1714         } else {
 1715                 for (i = 0; i < 32; i++)
 1716                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
 1717         }
 1718 
 1719         bwn_wa_agc(mac);
 1720 }
 1721 
 1722 static void
 1723 bwn_wa_grev26789(struct bwn_mac *mac)
 1724 {
 1725         struct bwn_phy *phy = &mac->mac_phy;
 1726         int i;
 1727         static const uint16_t bwn_tab_sigmasqr2[] = BWN_TAB_SIGMASQR2;
 1728         uint16_t ofdmrev;
 1729 
 1730         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
 1731 
 1732         bwn_gtab_write(mac, BWN_GTAB_ORIGTR, 0, 0xc480);
 1733 
 1734         /* init CRSTHRES and ANTDWELL */
 1735         if (phy->rev == 1)
 1736                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1_R1, 0x4f19);
 1737         else if (phy->rev == 2) {
 1738                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x1861);
 1739                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0271);
 1740                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
 1741         } else {
 1742                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES1, 0x0098);
 1743                 BWN_PHY_WRITE(mac, BWN_PHY_CRSTHRES2, 0x0070);
 1744                 BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xc9), 0x0080);
 1745                 BWN_PHY_SET(mac, BWN_PHY_ANTDWELL, 0x0800);
 1746         }
 1747 
 1748         for (i = 0; i < 64; i++)
 1749                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_RSSI, i, i);
 1750 
 1751         /* XXX support PHY-A??? */
 1752         if (phy->rev == 1)
 1753                 for (i = 0; i < N(bwn_tab_noise_g1); i++)
 1754                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
 1755                             bwn_tab_noise_g1[i]);
 1756         else
 1757                 for (i = 0; i < N(bwn_tab_noise_g2); i++)
 1758                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_AGC2, i,
 1759                             bwn_tab_noise_g2[i]);
 1760 
 1761         /* XXX support PHY-A??? */
 1762         if (phy->rev >= 6) {
 1763                 if (BWN_PHY_READ(mac, BWN_PHY_ENCORE) &
 1764                     BWN_PHY_ENCORE_EN)
 1765                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g3);
 1766                 else
 1767                         bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g2);
 1768         } else
 1769                 bwn_wa_write_noisescale(mac, bwn_tab_noisescale_g1);
 1770 
 1771         for (i = 0; i < N(bwn_tab_sigmasqr2); i++)
 1772                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_MINSIGSQ, i,
 1773                     bwn_tab_sigmasqr2[i]);
 1774 
 1775         if (phy->rev == 1) {
 1776                 for (i = 0; i < 16; i++)
 1777                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI_R1, i,
 1778                             0x0020);
 1779         } else {
 1780                 for (i = 0; i < 32; i++)
 1781                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_WRSSI, i, 0x0820);
 1782         }
 1783 
 1784         bwn_wa_agc(mac);
 1785 
 1786         ofdmrev = BWN_PHY_READ(mac, BWN_PHY_VERSION_OFDM) & BWN_PHYVER_VERSION;
 1787         if (ofdmrev > 2) {
 1788                 if (phy->type == BWN_PHYTYPE_A)
 1789                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1808);
 1790                 else
 1791                         BWN_PHY_WRITE(mac, BWN_PHY_PWRDOWN, 0x1000);
 1792         } else {
 1793                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 3, 0x1044);
 1794                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 4, 0x7201);
 1795                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_DAC, 6, 0x0040);
 1796         }
 1797 
 1798         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 2, 15);
 1799         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_0F, 3, 20);
 1800 }
 1801 
 1802 static void
 1803 bwn_wa_init(struct bwn_mac *mac)
 1804 {
 1805         struct bwn_phy *phy = &mac->mac_phy;
 1806         struct bwn_softc *sc = mac->mac_sc;
 1807 
 1808         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s fail", __func__));
 1809 
 1810         switch (phy->rev) {
 1811         case 1:
 1812                 bwn_wa_grev1(mac);
 1813                 break;
 1814         case 2:
 1815         case 6:
 1816         case 7:
 1817         case 8:
 1818         case 9:
 1819                 bwn_wa_grev26789(mac);
 1820                 break;
 1821         default:
 1822                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
 1823         }
 1824 
 1825         if (sc->sc_board_info.board_vendor != PCI_VENDOR_BROADCOM ||
 1826             sc->sc_board_info.board_type != BHND_BOARD_BU4306 ||
 1827             sc->sc_board_info.board_rev != 0x17) {
 1828                 if (phy->rev < 2) {
 1829                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 1,
 1830                             0x0002);
 1831                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX_R1, 2,
 1832                             0x0001);
 1833                 } else {
 1834                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 1, 0x0002);
 1835                         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX, 2, 0x0001);
 1836                         if ((sc->sc_board_info.board_flags &
 1837                              BHND_BFL_EXTLNA) &&
 1838                             (phy->rev >= 7)) {
 1839                                 BWN_PHY_MASK(mac, BWN_PHY_EXTG(0x11), 0xf7ff);
 1840                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
 1841                                     0x0020, 0x0001);
 1842                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
 1843                                     0x0021, 0x0001);
 1844                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
 1845                                     0x0022, 0x0001);
 1846                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
 1847                                     0x0023, 0x0000);
 1848                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
 1849                                     0x0000, 0x0000);
 1850                                 bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_GAINX,
 1851                                     0x0003, 0x0002);
 1852                         }
 1853                 }
 1854         }
 1855         if (sc->sc_board_info.board_flags & BHND_BFL_FEM) {
 1856                 BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, 0x3120);
 1857                 BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, 0xc480);
 1858         }
 1859 
 1860         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 0, 0);
 1861         bwn_ofdmtab_write_2(mac, BWN_OFDMTAB_UNKNOWN_11, 1, 0);
 1862 }
 1863 
 1864 static void
 1865 bwn_ofdmtab_write_2(struct bwn_mac *mac, uint16_t table, uint16_t offset,
 1866     uint16_t value)
 1867 {
 1868         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
 1869         uint16_t addr;
 1870 
 1871         addr = table + offset;
 1872         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
 1873             (addr - 1 != pg->pg_ofdmtab_addr)) {
 1874                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
 1875                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
 1876         }
 1877         pg->pg_ofdmtab_addr = addr;
 1878         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
 1879 }
 1880 
 1881 static void
 1882 bwn_ofdmtab_write_4(struct bwn_mac *mac, uint16_t table, uint16_t offset,
 1883     uint32_t value)
 1884 {
 1885         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
 1886         uint16_t addr;
 1887 
 1888         addr = table + offset;
 1889         if ((pg->pg_ofdmtab_dir != BWN_OFDMTAB_DIR_WRITE) ||
 1890             (addr - 1 != pg->pg_ofdmtab_addr)) {
 1891                 BWN_PHY_WRITE(mac, BWN_PHY_OTABLECTL, addr);
 1892                 pg->pg_ofdmtab_dir = BWN_OFDMTAB_DIR_WRITE;
 1893         }
 1894         pg->pg_ofdmtab_addr = addr;
 1895 
 1896         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEI, value);
 1897         BWN_PHY_WRITE(mac, BWN_PHY_OTABLEQ, (value >> 16));
 1898 }
 1899 
 1900 static void
 1901 bwn_gtab_write(struct bwn_mac *mac, uint16_t table, uint16_t offset,
 1902     uint16_t value)
 1903 {
 1904 
 1905         BWN_PHY_WRITE(mac, BWN_PHY_GTABCTL, table + offset);
 1906         BWN_PHY_WRITE(mac, BWN_PHY_GTABDATA, value);
 1907 }
 1908 
 1909 static void
 1910 bwn_lo_write(struct bwn_mac *mac, struct bwn_loctl *ctl)
 1911 {
 1912         uint16_t value;
 1913 
 1914         KASSERT(mac->mac_phy.type == BWN_PHYTYPE_G,
 1915             ("%s:%d: fail", __func__, __LINE__));
 1916 
 1917         value = (uint8_t) (ctl->q);
 1918         value |= ((uint8_t) (ctl->i)) << 8;
 1919         BWN_PHY_WRITE(mac, BWN_PHY_LO_CTL, value);
 1920 }
 1921 
 1922 static uint16_t
 1923 bwn_lo_calcfeed(struct bwn_mac *mac,
 1924     uint16_t lna, uint16_t pga, uint16_t trsw_rx)
 1925 {
 1926         struct bwn_phy *phy = &mac->mac_phy;
 1927         struct bwn_softc *sc = mac->mac_sc;
 1928         uint16_t rfover;
 1929         uint16_t feedthrough;
 1930 
 1931         if (phy->gmode) {
 1932                 lna <<= BWN_PHY_RFOVERVAL_LNA_SHIFT;
 1933                 pga <<= BWN_PHY_RFOVERVAL_PGA_SHIFT;
 1934 
 1935                 KASSERT((lna & ~BWN_PHY_RFOVERVAL_LNA) == 0,
 1936                     ("%s:%d: fail", __func__, __LINE__));
 1937                 KASSERT((pga & ~BWN_PHY_RFOVERVAL_PGA) == 0,
 1938                     ("%s:%d: fail", __func__, __LINE__));
 1939 
 1940                 trsw_rx &= (BWN_PHY_RFOVERVAL_TRSWRX | BWN_PHY_RFOVERVAL_BW);
 1941 
 1942                 rfover = BWN_PHY_RFOVERVAL_UNK | pga | lna | trsw_rx;
 1943                 if ((sc->sc_board_info.board_flags & BHND_BFL_EXTLNA) &&
 1944                     phy->rev > 6)
 1945                         rfover |= BWN_PHY_RFOVERVAL_EXTLNA;
 1946 
 1947                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
 1948                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
 1949                 DELAY(10);
 1950                 rfover |= BWN_PHY_RFOVERVAL_BW_LBW;
 1951                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
 1952                 DELAY(10);
 1953                 rfover |= BWN_PHY_RFOVERVAL_BW_LPF;
 1954                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, rfover);
 1955                 DELAY(10);
 1956                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xf300);
 1957         } else {
 1958                 pga |= BWN_PHY_PGACTL_UNKNOWN;
 1959                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
 1960                 DELAY(10);
 1961                 pga |= BWN_PHY_PGACTL_LOWBANDW;
 1962                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
 1963                 DELAY(10);
 1964                 pga |= BWN_PHY_PGACTL_LPF;
 1965                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, pga);
 1966         }
 1967         DELAY(21);
 1968         feedthrough = BWN_PHY_READ(mac, BWN_PHY_LO_LEAKAGE);
 1969 
 1970         return (feedthrough);
 1971 }
 1972 
 1973 static uint16_t
 1974 bwn_lo_txctl_regtable(struct bwn_mac *mac,
 1975     uint16_t *value, uint16_t *pad_mix_gain)
 1976 {
 1977         struct bwn_phy *phy = &mac->mac_phy;
 1978         uint16_t reg, v, padmix;
 1979 
 1980         if (phy->type == BWN_PHYTYPE_B) {
 1981                 v = 0x30;
 1982                 if (phy->rf_rev <= 5) {
 1983                         reg = 0x43;
 1984                         padmix = 0;
 1985                 } else {
 1986                         reg = 0x52;
 1987                         padmix = 5;
 1988                 }
 1989         } else {
 1990                 if (phy->rev >= 2 && phy->rf_rev == 8) {
 1991                         reg = 0x43;
 1992                         v = 0x10;
 1993                         padmix = 2;
 1994                 } else {
 1995                         reg = 0x52;
 1996                         v = 0x30;
 1997                         padmix = 5;
 1998                 }
 1999         }
 2000         if (value)
 2001                 *value = v;
 2002         if (pad_mix_gain)
 2003                 *pad_mix_gain = padmix;
 2004 
 2005         return (reg);
 2006 }
 2007 
 2008 static void
 2009 bwn_lo_measure_txctl_values(struct bwn_mac *mac)
 2010 {
 2011         struct bwn_phy *phy = &mac->mac_phy;
 2012         struct bwn_phy_g *pg = &phy->phy_g;
 2013         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
 2014         uint16_t reg, mask;
 2015         uint16_t trsw_rx, pga;
 2016         uint16_t rf_pctl_reg;
 2017 
 2018         static const uint8_t tx_bias_values[] = {
 2019                 0x09, 0x08, 0x0a, 0x01, 0x00,
 2020                 0x02, 0x05, 0x04, 0x06,
 2021         };
 2022         static const uint8_t tx_magn_values[] = {
 2023                 0x70, 0x40,
 2024         };
 2025 
 2026         if (!BWN_HAS_LOOPBACK(phy)) {
 2027                 rf_pctl_reg = 6;
 2028                 trsw_rx = 2;
 2029                 pga = 0;
 2030         } else {
 2031                 int lb_gain;
 2032 
 2033                 trsw_rx = 0;
 2034                 lb_gain = pg->pg_max_lb_gain / 2;
 2035                 if (lb_gain > 10) {
 2036                         rf_pctl_reg = 0;
 2037                         pga = abs(10 - lb_gain) / 6;
 2038                         pga = MIN(MAX(pga, 0), 15);
 2039                 } else {
 2040                         int cmp_val;
 2041                         int tmp;
 2042 
 2043                         pga = 0;
 2044                         cmp_val = 0x24;
 2045                         if ((phy->rev >= 2) &&
 2046                             (phy->rf_ver == 0x2050) && (phy->rf_rev == 8))
 2047                                 cmp_val = 0x3c;
 2048                         tmp = lb_gain;
 2049                         if ((10 - lb_gain) < cmp_val)
 2050                                 tmp = (10 - lb_gain);
 2051                         if (tmp < 0)
 2052                                 tmp += 6;
 2053                         else
 2054                                 tmp += 3;
 2055                         cmp_val /= 4;
 2056                         tmp /= 4;
 2057                         if (tmp >= cmp_val)
 2058                                 rf_pctl_reg = cmp_val;
 2059                         else
 2060                                 rf_pctl_reg = tmp;
 2061                 }
 2062         }
 2063         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rf_pctl_reg);
 2064         bwn_phy_g_set_bbatt(mac, 2);
 2065 
 2066         reg = bwn_lo_txctl_regtable(mac, &mask, NULL);
 2067         mask = ~mask;
 2068         BWN_RF_MASK(mac, reg, mask);
 2069 
 2070         if (BWN_HAS_TXMAG(phy)) {
 2071                 int i, j;
 2072                 int feedthrough;
 2073                 int min_feedth = 0xffff;
 2074                 uint8_t tx_magn, tx_bias;
 2075 
 2076                 for (i = 0; i < N(tx_magn_values); i++) {
 2077                         tx_magn = tx_magn_values[i];
 2078                         BWN_RF_SETMASK(mac, 0x52, 0xff0f, tx_magn);
 2079                         for (j = 0; j < N(tx_bias_values); j++) {
 2080                                 tx_bias = tx_bias_values[j];
 2081                                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, tx_bias);
 2082                                 feedthrough = bwn_lo_calcfeed(mac, 0, pga,
 2083                                     trsw_rx);
 2084                                 if (feedthrough < min_feedth) {
 2085                                         lo->tx_bias = tx_bias;
 2086                                         lo->tx_magn = tx_magn;
 2087                                         min_feedth = feedthrough;
 2088                                 }
 2089                                 if (lo->tx_bias == 0)
 2090                                         break;
 2091                         }
 2092                         BWN_RF_WRITE(mac, 0x52,
 2093                                           (BWN_RF_READ(mac, 0x52)
 2094                                            & 0xff00) | lo->tx_bias | lo->
 2095                                           tx_magn);
 2096                 }
 2097         } else {
 2098                 lo->tx_magn = 0;
 2099                 lo->tx_bias = 0;
 2100                 BWN_RF_MASK(mac, 0x52, 0xfff0);
 2101         }
 2102 
 2103         BWN_GETTIME(lo->txctl_measured_time);
 2104 }
 2105 
 2106 static void
 2107 bwn_lo_get_powervector(struct bwn_mac *mac)
 2108 {
 2109         struct bwn_phy *phy = &mac->mac_phy;
 2110         struct bwn_phy_g *pg = &phy->phy_g;
 2111         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
 2112         int i;
 2113         uint64_t tmp;
 2114         uint64_t power_vector = 0;
 2115 
 2116         for (i = 0; i < 8; i += 2) {
 2117                 tmp = bwn_shm_read_2(mac, BWN_SHARED, 0x310 + i);
 2118                 power_vector |= (tmp << (i * 8));
 2119                 bwn_shm_write_2(mac, BWN_SHARED, 0x310 + i, 0);
 2120         }
 2121         if (power_vector)
 2122                 lo->power_vector = power_vector;
 2123 
 2124         BWN_GETTIME(lo->pwr_vec_read_time);
 2125 }
 2126 
 2127 static void
 2128 bwn_lo_measure_gain_values(struct bwn_mac *mac, int16_t max_rx_gain,
 2129     int use_trsw_rx)
 2130 {
 2131         struct bwn_phy *phy = &mac->mac_phy;
 2132         struct bwn_phy_g *pg = &phy->phy_g;
 2133         uint16_t tmp;
 2134 
 2135         if (max_rx_gain < 0)
 2136                 max_rx_gain = 0;
 2137 
 2138         if (BWN_HAS_LOOPBACK(phy)) {
 2139                 int trsw_rx_gain;
 2140 
 2141                 if (use_trsw_rx) {
 2142                         trsw_rx_gain = pg->pg_trsw_rx_gain / 2;
 2143                         if (max_rx_gain >= trsw_rx_gain) {
 2144                                 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
 2145                         }
 2146                 } else
 2147                         trsw_rx_gain = max_rx_gain;
 2148                 if (trsw_rx_gain < 9) {
 2149                         pg->pg_lna_lod_gain = 0;
 2150                 } else {
 2151                         pg->pg_lna_lod_gain = 1;
 2152                         trsw_rx_gain -= 8;
 2153                 }
 2154                 trsw_rx_gain = MIN(MAX(trsw_rx_gain, 0), 0x2d);
 2155                 pg->pg_pga_gain = trsw_rx_gain / 3;
 2156                 if (pg->pg_pga_gain >= 5) {
 2157                         pg->pg_pga_gain -= 5;
 2158                         pg->pg_lna_gain = 2;
 2159                 } else
 2160                         pg->pg_lna_gain = 0;
 2161         } else {
 2162                 pg->pg_lna_gain = 0;
 2163                 pg->pg_trsw_rx_gain = 0x20;
 2164                 if (max_rx_gain >= 0x14) {
 2165                         pg->pg_lna_lod_gain = 1;
 2166                         pg->pg_pga_gain = 2;
 2167                 } else if (max_rx_gain >= 0x12) {
 2168                         pg->pg_lna_lod_gain = 1;
 2169                         pg->pg_pga_gain = 1;
 2170                 } else if (max_rx_gain >= 0xf) {
 2171                         pg->pg_lna_lod_gain = 1;
 2172                         pg->pg_pga_gain = 0;
 2173                 } else {
 2174                         pg->pg_lna_lod_gain = 0;
 2175                         pg->pg_pga_gain = 0;
 2176                 }
 2177         }
 2178 
 2179         tmp = BWN_RF_READ(mac, 0x7a);
 2180         if (pg->pg_lna_lod_gain == 0)
 2181                 tmp &= ~0x0008;
 2182         else
 2183                 tmp |= 0x0008;
 2184         BWN_RF_WRITE(mac, 0x7a, tmp);
 2185 }
 2186 
 2187 static void
 2188 bwn_lo_save(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
 2189 {
 2190         struct bwn_phy *phy = &mac->mac_phy;
 2191         struct bwn_phy_g *pg = &phy->phy_g;
 2192         struct bwn_softc *sc = mac->mac_sc;
 2193         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
 2194         struct timespec ts;
 2195         uint16_t tmp;
 2196 
 2197         if (bwn_has_hwpctl(mac)) {
 2198                 sav->phy_lomask = BWN_PHY_READ(mac, BWN_PHY_LO_MASK);
 2199                 sav->phy_extg = BWN_PHY_READ(mac, BWN_PHY_EXTG(0x01));
 2200                 sav->phy_dacctl_hwpctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
 2201                 sav->phy_cck4 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x14));
 2202                 sav->phy_hpwr_tssictl = BWN_PHY_READ(mac, BWN_PHY_HPWR_TSSICTL);
 2203 
 2204                 BWN_PHY_SET(mac, BWN_PHY_HPWR_TSSICTL, 0x100);
 2205                 BWN_PHY_SET(mac, BWN_PHY_EXTG(0x01), 0x40);
 2206                 BWN_PHY_SET(mac, BWN_PHY_DACCTL, 0x40);
 2207                 BWN_PHY_SET(mac, BWN_PHY_CCK(0x14), 0x200);
 2208         }
 2209         if (phy->type == BWN_PHYTYPE_B &&
 2210             phy->rf_ver == 0x2050 && phy->rf_rev < 6) {
 2211                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x16), 0x410);
 2212                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x17), 0x820);
 2213         }
 2214         if (phy->rev >= 2) {
 2215                 sav->phy_analogover = BWN_PHY_READ(mac, BWN_PHY_ANALOGOVER);
 2216                 sav->phy_analogoverval =
 2217                     BWN_PHY_READ(mac, BWN_PHY_ANALOGOVERVAL);
 2218                 sav->phy_rfover = BWN_PHY_READ(mac, BWN_PHY_RFOVER);
 2219                 sav->phy_rfoverval = BWN_PHY_READ(mac, BWN_PHY_RFOVERVAL);
 2220                 sav->phy_classctl = BWN_PHY_READ(mac, BWN_PHY_CLASSCTL);
 2221                 sav->phy_cck3 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x3e));
 2222                 sav->phy_crs0 = BWN_PHY_READ(mac, BWN_PHY_CRS0);
 2223 
 2224                 BWN_PHY_MASK(mac, BWN_PHY_CLASSCTL, 0xfffc);
 2225                 BWN_PHY_MASK(mac, BWN_PHY_CRS0, 0x7fff);
 2226                 BWN_PHY_SET(mac, BWN_PHY_ANALOGOVER, 0x0003);
 2227                 BWN_PHY_MASK(mac, BWN_PHY_ANALOGOVERVAL, 0xfffc);
 2228                 if (phy->type == BWN_PHYTYPE_G) {
 2229                         if ((phy->rev >= 7) &&
 2230                             (sc->sc_board_info.board_flags &
 2231                              BHND_BFL_EXTLNA)) {
 2232                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x933);
 2233                         } else {
 2234                                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0x133);
 2235                         }
 2236                 } else {
 2237                         BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, 0);
 2238                 }
 2239                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), 0);
 2240         }
 2241         sav->reg0 = BWN_READ_2(mac, 0x3f4);
 2242         sav->reg1 = BWN_READ_2(mac, 0x3e2);
 2243         sav->rf0 = BWN_RF_READ(mac, 0x43);
 2244         sav->rf1 = BWN_RF_READ(mac, 0x7a);
 2245         sav->phy_pgactl = BWN_PHY_READ(mac, BWN_PHY_PGACTL);
 2246         sav->phy_cck2 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x2a));
 2247         sav->phy_syncctl = BWN_PHY_READ(mac, BWN_PHY_SYNCCTL);
 2248         sav->phy_dacctl = BWN_PHY_READ(mac, BWN_PHY_DACCTL);
 2249 
 2250         if (!BWN_HAS_TXMAG(phy)) {
 2251                 sav->rf2 = BWN_RF_READ(mac, 0x52);
 2252                 sav->rf2 &= 0x00f0;
 2253         }
 2254         if (phy->type == BWN_PHYTYPE_B) {
 2255                 sav->phy_cck0 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x30));
 2256                 sav->phy_cck1 = BWN_PHY_READ(mac, BWN_PHY_CCK(0x06));
 2257                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), 0x00ff);
 2258                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), 0x3f3f);
 2259         } else {
 2260                 BWN_WRITE_2(mac, 0x3e2, BWN_READ_2(mac, 0x3e2)
 2261                             | 0x8000);
 2262         }
 2263         BWN_WRITE_2(mac, 0x3f4, BWN_READ_2(mac, 0x3f4)
 2264                     & 0xf000);
 2265 
 2266         tmp =
 2267             (phy->type == BWN_PHYTYPE_G) ? BWN_PHY_LO_MASK : BWN_PHY_CCK(0x2e);
 2268         BWN_PHY_WRITE(mac, tmp, 0x007f);
 2269 
 2270         tmp = sav->phy_syncctl;
 2271         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, tmp & 0xff7f);
 2272         tmp = sav->rf1;
 2273         BWN_RF_WRITE(mac, 0x007a, tmp & 0xfff0);
 2274 
 2275         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), 0x8a3);
 2276         if (phy->type == BWN_PHYTYPE_G ||
 2277             (phy->type == BWN_PHYTYPE_B &&
 2278              phy->rf_ver == 0x2050 && phy->rf_rev >= 6)) {
 2279                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x1003);
 2280         } else
 2281                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2b), 0x0802);
 2282         if (phy->rev >= 2)
 2283                 bwn_dummy_transmission(mac, 0, 1);
 2284         bwn_phy_g_switch_chan(mac, 6, 0);
 2285         BWN_RF_READ(mac, 0x51);
 2286         if (phy->type == BWN_PHYTYPE_G)
 2287                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0);
 2288 
 2289         nanouptime(&ts);
 2290         if (ieee80211_time_before(lo->txctl_measured_time,
 2291             (ts.tv_nsec / 1000000 + ts.tv_sec * 1000) - BWN_LO_TXCTL_EXPIRE))
 2292                 bwn_lo_measure_txctl_values(mac);
 2293 
 2294         if (phy->type == BWN_PHYTYPE_G && phy->rev >= 3)
 2295                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0xc078);
 2296         else {
 2297                 if (phy->type == BWN_PHYTYPE_B)
 2298                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
 2299                 else
 2300                         BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, 0x8078);
 2301         }
 2302 }
 2303 
 2304 static void
 2305 bwn_lo_restore(struct bwn_mac *mac, struct bwn_lo_g_value *sav)
 2306 {
 2307         struct bwn_phy *phy = &mac->mac_phy;
 2308         struct bwn_phy_g *pg = &phy->phy_g;
 2309         uint16_t tmp;
 2310 
 2311         if (phy->rev >= 2) {
 2312                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, 0xe300);
 2313                 tmp = (pg->pg_pga_gain << 8);
 2314                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa0);
 2315                 DELAY(5);
 2316                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa2);
 2317                 DELAY(2);
 2318                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, tmp | 0xa3);
 2319         } else {
 2320                 tmp = (pg->pg_pga_gain | 0xefa0);
 2321                 BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, tmp);
 2322         }
 2323         if (phy->type == BWN_PHYTYPE_G) {
 2324                 if (phy->rev >= 3)
 2325                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0xc078);
 2326                 else
 2327                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2e), 0x8078);
 2328                 if (phy->rev >= 2)
 2329                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0202);
 2330                 else
 2331                         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2f), 0x0101);
 2332         }
 2333         BWN_WRITE_2(mac, 0x3f4, sav->reg0);
 2334         BWN_PHY_WRITE(mac, BWN_PHY_PGACTL, sav->phy_pgactl);
 2335         BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x2a), sav->phy_cck2);
 2336         BWN_PHY_WRITE(mac, BWN_PHY_SYNCCTL, sav->phy_syncctl);
 2337         BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl);
 2338         BWN_RF_WRITE(mac, 0x43, sav->rf0);
 2339         BWN_RF_WRITE(mac, 0x7a, sav->rf1);
 2340         if (!BWN_HAS_TXMAG(phy)) {
 2341                 tmp = sav->rf2;
 2342                 BWN_RF_SETMASK(mac, 0x52, 0xff0f, tmp);
 2343         }
 2344         BWN_WRITE_2(mac, 0x3e2, sav->reg1);
 2345         if (phy->type == BWN_PHYTYPE_B &&
 2346             phy->rf_ver == 0x2050 && phy->rf_rev <= 5) {
 2347                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x30), sav->phy_cck0);
 2348                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x06), sav->phy_cck1);
 2349         }
 2350         if (phy->rev >= 2) {
 2351                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVER, sav->phy_analogover);
 2352                 BWN_PHY_WRITE(mac, BWN_PHY_ANALOGOVERVAL,
 2353                               sav->phy_analogoverval);
 2354                 BWN_PHY_WRITE(mac, BWN_PHY_CLASSCTL, sav->phy_classctl);
 2355                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVER, sav->phy_rfover);
 2356                 BWN_PHY_WRITE(mac, BWN_PHY_RFOVERVAL, sav->phy_rfoverval);
 2357                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x3e), sav->phy_cck3);
 2358                 BWN_PHY_WRITE(mac, BWN_PHY_CRS0, sav->phy_crs0);
 2359         }
 2360         if (bwn_has_hwpctl(mac)) {
 2361                 tmp = (sav->phy_lomask & 0xbfff);
 2362                 BWN_PHY_WRITE(mac, BWN_PHY_LO_MASK, tmp);
 2363                 BWN_PHY_WRITE(mac, BWN_PHY_EXTG(0x01), sav->phy_extg);
 2364                 BWN_PHY_WRITE(mac, BWN_PHY_DACCTL, sav->phy_dacctl_hwpctl);
 2365                 BWN_PHY_WRITE(mac, BWN_PHY_CCK(0x14), sav->phy_cck4);
 2366                 BWN_PHY_WRITE(mac, BWN_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
 2367         }
 2368         bwn_phy_g_switch_chan(mac, sav->old_channel, 1);
 2369 }
 2370 
 2371 static int
 2372 bwn_lo_probe_loctl(struct bwn_mac *mac,
 2373     struct bwn_loctl *probe, struct bwn_lo_g_sm *d)
 2374 {
 2375         struct bwn_phy *phy = &mac->mac_phy;
 2376         struct bwn_phy_g *pg = &phy->phy_g;
 2377         struct bwn_loctl orig, test;
 2378         struct bwn_loctl prev = { -100, -100 };
 2379         static const struct bwn_loctl modifiers[] = {
 2380                 {  1,  1,}, {  1,  0,}, {  1, -1,}, {  0, -1,},
 2381                 { -1, -1,}, { -1,  0,}, { -1,  1,}, {  0,  1,}
 2382         };
 2383         int begin, end, lower = 0, i;
 2384         uint16_t feedth;
 2385 
 2386         if (d->curstate == 0) {
 2387                 begin = 1;
 2388                 end = 8;
 2389         } else if (d->curstate % 2 == 0) {
 2390                 begin = d->curstate - 1;
 2391                 end = d->curstate + 1;
 2392         } else {
 2393                 begin = d->curstate - 2;
 2394                 end = d->curstate + 2;
 2395         }
 2396         if (begin < 1)
 2397                 begin += 8;
 2398         if (end > 8)
 2399                 end -= 8;
 2400 
 2401         memcpy(&orig, probe, sizeof(struct bwn_loctl));
 2402         i = begin;
 2403         d->curstate = i;
 2404         while (1) {
 2405                 KASSERT(i >= 1 && i <= 8, ("%s:%d: fail", __func__, __LINE__));
 2406                 memcpy(&test, &orig, sizeof(struct bwn_loctl));
 2407                 test.i += modifiers[i - 1].i * d->multipler;
 2408                 test.q += modifiers[i - 1].q * d->multipler;
 2409                 if ((test.i != prev.i || test.q != prev.q) &&
 2410                     (abs(test.i) <= 16 && abs(test.q) <= 16)) {
 2411                         bwn_lo_write(mac, &test);
 2412                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
 2413                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
 2414                         if (feedth < d->feedth) {
 2415                                 memcpy(probe, &test,
 2416                                     sizeof(struct bwn_loctl));
 2417                                 lower = 1;
 2418                                 d->feedth = feedth;
 2419                                 if (d->nmeasure < 2 && !BWN_HAS_LOOPBACK(phy))
 2420                                         break;
 2421                         }
 2422                 }
 2423                 memcpy(&prev, &test, sizeof(prev));
 2424                 if (i == end)
 2425                         break;
 2426                 if (i == 8)
 2427                         i = 1;
 2428                 else
 2429                         i++;
 2430                 d->curstate = i;
 2431         }
 2432 
 2433         return (lower);
 2434 }
 2435 
 2436 static void
 2437 bwn_lo_probe_sm(struct bwn_mac *mac, struct bwn_loctl *loctl, int *rxgain)
 2438 {
 2439         struct bwn_phy *phy = &mac->mac_phy;
 2440         struct bwn_phy_g *pg = &phy->phy_g;
 2441         struct bwn_lo_g_sm d;
 2442         struct bwn_loctl probe;
 2443         int lower, repeat, cnt = 0;
 2444         uint16_t feedth;
 2445 
 2446         d.nmeasure = 0;
 2447         d.multipler = 1;
 2448         if (BWN_HAS_LOOPBACK(phy))
 2449                 d.multipler = 3;
 2450 
 2451         memcpy(&d.loctl, loctl, sizeof(struct bwn_loctl));
 2452         repeat = (BWN_HAS_LOOPBACK(phy)) ? 4 : 1;
 2453 
 2454         do {
 2455                 bwn_lo_write(mac, &d.loctl);
 2456                 feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
 2457                     pg->pg_pga_gain, pg->pg_trsw_rx_gain);
 2458                 if (feedth < 0x258) {
 2459                         if (feedth >= 0x12c)
 2460                                 *rxgain += 6;
 2461                         else
 2462                                 *rxgain += 3;
 2463                         feedth = bwn_lo_calcfeed(mac, pg->pg_lna_gain,
 2464                             pg->pg_pga_gain, pg->pg_trsw_rx_gain);
 2465                 }
 2466                 d.feedth = feedth;
 2467                 d.curstate = 0;
 2468                 do {
 2469                         KASSERT(d.curstate >= 0 && d.curstate <= 8,
 2470                             ("%s:%d: fail", __func__, __LINE__));
 2471                         memcpy(&probe, &d.loctl,
 2472                                sizeof(struct bwn_loctl));
 2473                         lower = bwn_lo_probe_loctl(mac, &probe, &d);
 2474                         if (!lower)
 2475                                 break;
 2476                         if ((probe.i == d.loctl.i) && (probe.q == d.loctl.q))
 2477                                 break;
 2478                         memcpy(&d.loctl, &probe, sizeof(struct bwn_loctl));
 2479                         d.nmeasure++;
 2480                 } while (d.nmeasure < 24);
 2481                 memcpy(loctl, &d.loctl, sizeof(struct bwn_loctl));
 2482 
 2483                 if (BWN_HAS_LOOPBACK(phy)) {
 2484                         if (d.feedth > 0x1194)
 2485                                 *rxgain -= 6;
 2486                         else if (d.feedth < 0x5dc)
 2487                                 *rxgain += 3;
 2488                         if (cnt == 0) {
 2489                                 if (d.feedth <= 0x5dc) {
 2490                                         d.multipler = 1;
 2491                                         cnt++;
 2492                                 } else
 2493                                         d.multipler = 2;
 2494                         } else if (cnt == 2)
 2495                                 d.multipler = 1;
 2496                 }
 2497                 bwn_lo_measure_gain_values(mac, *rxgain, BWN_HAS_LOOPBACK(phy));
 2498         } while (++cnt < repeat);
 2499 }
 2500 
 2501 static struct bwn_lo_calib *
 2502 bwn_lo_calibset(struct bwn_mac *mac,
 2503     const struct bwn_bbatt *bbatt, const struct bwn_rfatt *rfatt)
 2504 {
 2505         struct bwn_phy *phy = &mac->mac_phy;
 2506         struct bwn_phy_g *pg = &phy->phy_g;
 2507         struct bwn_loctl loctl = { 0, 0 };
 2508         struct bwn_lo_calib *cal;
 2509         struct bwn_lo_g_value sval = { 0 };
 2510         int rxgain;
 2511         uint16_t pad, reg, value;
 2512 
 2513         sval.old_channel = phy->chan;
 2514         bwn_mac_suspend(mac);
 2515         bwn_lo_save(mac, &sval);
 2516 
 2517         reg = bwn_lo_txctl_regtable(mac, &value, &pad);
 2518         BWN_RF_SETMASK(mac, 0x43, 0xfff0, rfatt->att);
 2519         BWN_RF_SETMASK(mac, reg, ~value, (rfatt->padmix ? value :0));
 2520 
 2521         rxgain = (rfatt->att * 2) + (bbatt->att / 2);
 2522         if (rfatt->padmix)
 2523                 rxgain -= pad;
 2524         if (BWN_HAS_LOOPBACK(phy))
 2525                 rxgain += pg->pg_max_lb_gain;
 2526         bwn_lo_measure_gain_values(mac, rxgain, BWN_HAS_LOOPBACK(phy));
 2527         bwn_phy_g_set_bbatt(mac, bbatt->att);
 2528         bwn_lo_probe_sm(mac, &loctl, &rxgain);
 2529 
 2530         bwn_lo_restore(mac, &sval);
 2531         bwn_mac_enable(mac);
 2532 
 2533         cal = malloc(sizeof(*cal), M_DEVBUF, M_NOWAIT | M_ZERO);
 2534         if (!cal) {
 2535                 device_printf(mac->mac_sc->sc_dev, "out of memory\n");
 2536                 return (NULL);
 2537         }
 2538         memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
 2539         memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
 2540         memcpy(&cal->ctl, &loctl, sizeof(loctl));
 2541 
 2542         BWN_GETTIME(cal->calib_time);
 2543 
 2544         return (cal);
 2545 }
 2546 
 2547 static struct bwn_lo_calib *
 2548 bwn_lo_get_calib(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
 2549     const struct bwn_rfatt *rfatt)
 2550 {
 2551         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
 2552         struct bwn_lo_calib *c;
 2553 
 2554         TAILQ_FOREACH(c, &lo->calib_list, list) {
 2555                 if (!BWN_BBATTCMP(&c->bbatt, bbatt))
 2556                         continue;
 2557                 if (!BWN_RFATTCMP(&c->rfatt, rfatt))
 2558                         continue;
 2559                 return (c);
 2560         }
 2561 
 2562         c = bwn_lo_calibset(mac, bbatt, rfatt);
 2563         if (!c)
 2564                 return (NULL);
 2565         TAILQ_INSERT_TAIL(&lo->calib_list, c, list);
 2566 
 2567         return (c);
 2568 }
 2569 
 2570 static void
 2571 bwn_phy_g_dc_lookup_init(struct bwn_mac *mac, uint8_t update)
 2572 {
 2573         struct bwn_phy *phy = &mac->mac_phy;
 2574         struct bwn_phy_g *pg = &phy->phy_g;
 2575         struct bwn_softc *sc = mac->mac_sc;
 2576         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
 2577         const struct bwn_rfatt *rfatt;
 2578         const struct bwn_bbatt *bbatt;
 2579         uint64_t pvector;
 2580         int i;
 2581         int rf_offset, bb_offset;
 2582         uint8_t changed = 0;
 2583 
 2584         KASSERT(BWN_DC_LT_SIZE == 32, ("%s:%d: fail", __func__, __LINE__));
 2585         KASSERT(lo->rfatt.len * lo->bbatt.len <= 64,
 2586             ("%s:%d: fail", __func__, __LINE__));
 2587 
 2588         pvector = lo->power_vector;
 2589         if (!update && !pvector)
 2590                 return;
 2591 
 2592         bwn_mac_suspend(mac);
 2593 
 2594         for (i = 0; i < BWN_DC_LT_SIZE * 2; i++) {
 2595                 struct bwn_lo_calib *cal;
 2596                 int idx;
 2597                 uint16_t val;
 2598 
 2599                 if (!update && !(pvector & (((uint64_t)1ULL) << i)))
 2600                         continue;
 2601                 bb_offset = i / lo->rfatt.len;
 2602                 rf_offset = i % lo->rfatt.len;
 2603                 bbatt = &(lo->bbatt.array[bb_offset]);
 2604                 rfatt = &(lo->rfatt.array[rf_offset]);
 2605 
 2606                 cal = bwn_lo_calibset(mac, bbatt, rfatt);
 2607                 if (!cal) {
 2608                         device_printf(sc->sc_dev, "LO: Could not "
 2609                             "calibrate DC table entry\n");
 2610                         continue;
 2611                 }
 2612                 val = (uint8_t)(cal->ctl.q);
 2613                 val |= ((uint8_t)(cal->ctl.i)) << 4;
 2614                 free(cal, M_DEVBUF);
 2615 
 2616                 idx = i / 2;
 2617                 if (i % 2)
 2618                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00ff)
 2619                             | ((val & 0x00ff) << 8);
 2620                 else
 2621                         lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xff00)
 2622                             | (val & 0x00ff);
 2623                 changed = 1;
 2624         }
 2625         if (changed) {
 2626                 for (i = 0; i < BWN_DC_LT_SIZE; i++)
 2627                         BWN_PHY_WRITE(mac, 0x3a0 + i, lo->dc_lt[i]);
 2628         }
 2629         bwn_mac_enable(mac);
 2630 }
 2631 
 2632 static void
 2633 bwn_lo_fixup_rfatt(struct bwn_rfatt *rf)
 2634 {
 2635 
 2636         if (!rf->padmix)
 2637                 return;
 2638         if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
 2639                 rf->att = 4;
 2640 }
 2641 
 2642 static void
 2643 bwn_lo_g_adjust(struct bwn_mac *mac)
 2644 {
 2645         struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
 2646         struct bwn_lo_calib *cal;
 2647         struct bwn_rfatt rf;
 2648 
 2649         memcpy(&rf, &pg->pg_rfatt, sizeof(rf));
 2650         bwn_lo_fixup_rfatt(&rf);
 2651 
 2652         cal = bwn_lo_get_calib(mac, &pg->pg_bbatt, &rf);
 2653         if (!cal)
 2654                 return;
 2655         bwn_lo_write(mac, &cal->ctl);
 2656 }
 2657 
 2658 static void
 2659 bwn_lo_g_init(struct bwn_mac *mac)
 2660 {
 2661 
 2662         if (!bwn_has_hwpctl(mac))
 2663                 return;
 2664 
 2665         bwn_lo_get_powervector(mac);
 2666         bwn_phy_g_dc_lookup_init(mac, 1);
 2667 }
 2668 
 2669 static int16_t
 2670 bwn_nrssi_read(struct bwn_mac *mac, uint16_t offset)
 2671 {
 2672 
 2673         BWN_PHY_WRITE(mac, BWN_PHY_NRSSI_CTRL, offset);
 2674         return ((int16_t)BWN_PHY_READ(mac, BWN_PHY_NRSSI_DATA));
 2675 }
 2676 
 2677 static void
 2678 bwn_nrssi_threshold(struct bwn_mac *mac)
 2679 {
 2680         struct bwn_phy *phy = &mac->mac_phy;
 2681         struct bwn_phy_g *pg = &phy->phy_g;
 2682         struct bwn_softc *sc = mac->mac_sc;
 2683         int32_t a, b;
 2684         int16_t tmp16;
 2685         uint16_t tmpu16;
 2686 
 2687         KASSERT(phy->type == BWN_PHYTYPE_G, ("%s: fail", __func__));
 2688 
 2689         if (phy->gmode && (sc->sc_board_info.board_flags & BHND_BFL_ADCDIV)) {
 2690                 if (!pg->pg_aci_wlan_automatic && pg->pg_aci_enable) {
 2691                         a = 0x13;
 2692                         b = 0x12;
 2693                 } else {
 2694                         a = 0xe;
 2695                         b = 0x11;
 2696                 }
 2697 
 2698                 a = a * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
 2699                 a += (pg->pg_nrssi[0] << 6);
 2700                 a += (a < 32) ? 31 : 32;
 2701                 a = a >> 6;
 2702                 a = MIN(MAX(a, -31), 31);
 2703 
 2704                 b = b * (pg->pg_nrssi[1] - pg->pg_nrssi[0]);
 2705                 b += (pg->pg_nrssi[0] << 6);
 2706                 if (b < 32)
 2707                         b += 31;
 2708                 else
 2709                         b += 32;
 2710                 b = b >> 6;
 2711                 b = MIN(MAX(b, -31), 31);
 2712 
 2713                 tmpu16 = BWN_PHY_READ(mac, 0x048a) & 0xf000;
 2714                 tmpu16 |= ((uint32_t)b & 0x0000003f);
 2715                 tmpu16 |= (((uint32_t)a & 0x0000003f) << 6);
 2716                 BWN_PHY_WRITE(mac, 0x048a, tmpu16);
 2717                 return;
 2718         }
 2719 
 2720         tmp16 = bwn_nrssi_read(mac, 0x20);
 2721         if (tmp16 >= 0x20)
 2722                 tmp16 -= 0x40;
 2723         BWN_PHY_SETMASK(mac, 0x048a, 0xf000, (tmp16 < 3) ? 0x09eb : 0x0aed);
 2724 }
 2725 
 2726 static void
 2727 bwn_nrssi_slope_11g(struct bwn_mac *mac)
 2728 {
 2729 #define SAVE_RF_MAX             3
 2730 #define SAVE_PHY_COMM_MAX       4
 2731 #define SAVE_PHY3_MAX           8
 2732         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
 2733                 { 0x7a, 0x52, 0x43 };
 2734         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
 2735                 { 0x15, 0x5a, 0x59, 0x58 };
 2736         static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
 2737                 0x002e, 0x002f, 0x080f, BWN_PHY_G_LOCTL,
 2738                 0x0801, 0x0060, 0x0014, 0x0478
 2739         };
 2740         struct bwn_phy *phy = &mac->mac_phy;
 2741         struct bwn_phy_g *pg = &phy->phy_g;
 2742         int32_t i, tmp32, phy3_idx = 0;
 2743         uint16_t delta, tmp;
 2744         uint16_t save_rf[SAVE_RF_MAX];
 2745         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
 2746         uint16_t save_phy3[SAVE_PHY3_MAX];
 2747         uint16_t ant_div, phy0, chan_ex;
 2748         int16_t nrssi0, nrssi1;
 2749 
 2750         KASSERT(phy->type == BWN_PHYTYPE_G,
 2751             ("%s:%d: fail", __func__, __LINE__));
 2752 
 2753         if (phy->rf_rev >= 9)
 2754                 return;
 2755         if (phy->rf_rev == 8)
 2756                 bwn_nrssi_offset(mac);
 2757 
 2758         BWN_PHY_MASK(mac, BWN_PHY_G_CRS, 0x7fff);
 2759         BWN_PHY_MASK(mac, 0x0802, 0xfffc);
 2760 
 2761         /*
 2762          * Save RF/PHY registers for later restoration
 2763          */
 2764         ant_div = BWN_READ_2(mac, 0x03e2);
 2765         BWN_WRITE_2(mac, 0x03e2, BWN_READ_2(mac, 0x03e2) | 0x8000);
 2766         for (i = 0; i < SAVE_RF_MAX; ++i)
 2767                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
 2768         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
 2769                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
 2770 
 2771         phy0 = BWN_READ_2(mac, BWN_PHY0);
 2772         chan_ex = BWN_READ_2(mac, BWN_CHANNEL_EXT);
 2773         if (phy->rev >= 3) {
 2774                 for (i = 0; i < SAVE_PHY3_MAX; ++i)
 2775                         save_phy3[i] = BWN_PHY_READ(mac, save_phy3_regs[i]);
 2776                 BWN_PHY_WRITE(mac, 0x002e, 0);
 2777                 BWN_PHY_WRITE(mac, BWN_PHY_G_LOCTL, 0);
 2778                 switch (phy->rev) {
 2779                 case 4:
 2780                 case 6:
 2781                 case 7:
 2782                         BWN_PHY_SET(mac, 0x0478, 0x0100);
 2783                         BWN_PHY_SET(mac, 0x0801, 0x0040);
 2784                         break;
 2785                 case 3:
 2786                 case 5:
 2787                         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
 2788                         break;
 2789                 }
 2790                 BWN_PHY_SET(mac, 0x0060, 0x0040);
 2791                 BWN_PHY_SET(mac, 0x0014, 0x0200);
 2792         }
 2793         /*
 2794          * Calculate nrssi0
 2795          */
 2796         BWN_RF_SET(mac, 0x007a, 0x0070);
 2797         bwn_set_all_gains(mac, 0, 8, 0);
 2798         BWN_RF_MASK(mac, 0x007a, 0x00f7);
 2799         if (phy->rev >= 2) {
 2800                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0030);
 2801                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0010);
 2802         }
 2803         BWN_RF_SET(mac, 0x007a, 0x0080);
 2804         DELAY(20);
 2805 
 2806         nrssi0 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
 2807         if (nrssi0 >= 0x0020)
 2808                 nrssi0 -= 0x0040;
 2809 
 2810         /*
 2811          * Calculate nrssi1
 2812          */
 2813         BWN_RF_MASK(mac, 0x007a, 0x007f);
 2814         if (phy->rev >= 2)
 2815                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
 2816 
 2817         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
 2818             BWN_READ_2(mac, BWN_CHANNEL_EXT) | 0x2000);
 2819         BWN_RF_SET(mac, 0x007a, 0x000f);
 2820         BWN_PHY_WRITE(mac, 0x0015, 0xf330);
 2821         if (phy->rev >= 2) {
 2822                 BWN_PHY_SETMASK(mac, 0x0812, 0xffcf, 0x0020);
 2823                 BWN_PHY_SETMASK(mac, 0x0811, 0xffcf, 0x0020);
 2824         }
 2825 
 2826         bwn_set_all_gains(mac, 3, 0, 1);
 2827         if (phy->rf_rev == 8) {
 2828                 BWN_RF_WRITE(mac, 0x0043, 0x001f);
 2829         } else {
 2830                 tmp = BWN_RF_READ(mac, 0x0052) & 0xff0f;
 2831                 BWN_RF_WRITE(mac, 0x0052, tmp | 0x0060);
 2832                 tmp = BWN_RF_READ(mac, 0x0043) & 0xfff0;
 2833                 BWN_RF_WRITE(mac, 0x0043, tmp | 0x0009);
 2834         }
 2835         BWN_PHY_WRITE(mac, 0x005a, 0x0480);
 2836         BWN_PHY_WRITE(mac, 0x0059, 0x0810);
 2837         BWN_PHY_WRITE(mac, 0x0058, 0x000d);
 2838         DELAY(20);
 2839         nrssi1 = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
 2840 
 2841         /*
 2842          * Install calculated narrow RSSI values
 2843          */
 2844         if (nrssi1 >= 0x0020)
 2845                 nrssi1 -= 0x0040;
 2846         if (nrssi0 == nrssi1)
 2847                 pg->pg_nrssi_slope = 0x00010000;
 2848         else
 2849                 pg->pg_nrssi_slope = 0x00400000 / (nrssi0 - nrssi1);
 2850         if (nrssi0 >= -4) {
 2851                 pg->pg_nrssi[0] = nrssi1;
 2852                 pg->pg_nrssi[1] = nrssi0;
 2853         }
 2854 
 2855         /*
 2856          * Restore saved RF/PHY registers
 2857          */
 2858         if (phy->rev >= 3) {
 2859                 for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
 2860                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
 2861                             save_phy3[phy3_idx]);
 2862                 }
 2863         }
 2864         if (phy->rev >= 2) {
 2865                 BWN_PHY_MASK(mac, 0x0812, 0xffcf);
 2866                 BWN_PHY_MASK(mac, 0x0811, 0xffcf);
 2867         }
 2868 
 2869         for (i = 0; i < SAVE_RF_MAX; ++i)
 2870                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
 2871 
 2872         BWN_WRITE_2(mac, 0x03e2, ant_div);
 2873         BWN_WRITE_2(mac, 0x03e6, phy0);
 2874         BWN_WRITE_2(mac, BWN_CHANNEL_EXT, chan_ex);
 2875 
 2876         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
 2877                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
 2878 
 2879         bwn_spu_workaround(mac, phy->chan);
 2880         BWN_PHY_SET(mac, 0x0802, (0x0001 | 0x0002));
 2881         bwn_set_original_gains(mac);
 2882         BWN_PHY_SET(mac, BWN_PHY_G_CRS, 0x8000);
 2883         if (phy->rev >= 3) {
 2884                 for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
 2885                         BWN_PHY_WRITE(mac, save_phy3_regs[phy3_idx],
 2886                             save_phy3[phy3_idx]);
 2887                 }
 2888         }
 2889 
 2890         delta = 0x1f - pg->pg_nrssi[0];
 2891         for (i = 0; i < 64; i++) {
 2892                 tmp32 = (((i - delta) * pg->pg_nrssi_slope) / 0x10000) + 0x3a;
 2893                 tmp32 = MIN(MAX(tmp32, 0), 0x3f);
 2894                 pg->pg_nrssi_lt[i] = tmp32;
 2895         }
 2896 
 2897         bwn_nrssi_threshold(mac);
 2898 #undef SAVE_RF_MAX
 2899 #undef SAVE_PHY_COMM_MAX
 2900 #undef SAVE_PHY3_MAX
 2901 }
 2902 
 2903 static void
 2904 bwn_nrssi_offset(struct bwn_mac *mac)
 2905 {
 2906 #define SAVE_RF_MAX             2
 2907 #define SAVE_PHY_COMM_MAX       10
 2908 #define SAVE_PHY6_MAX           8
 2909         static const uint16_t save_rf_regs[SAVE_RF_MAX] =
 2910                 { 0x7a, 0x43 };
 2911         static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
 2912                 0x0001, 0x0811, 0x0812, 0x0814,
 2913                 0x0815, 0x005a, 0x0059, 0x0058,
 2914                 0x000a, 0x0003
 2915         };
 2916         static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
 2917                 0x002e, 0x002f, 0x080f, 0x0810,
 2918                 0x0801, 0x0060, 0x0014, 0x0478
 2919         };
 2920         struct bwn_phy *phy = &mac->mac_phy;
 2921         int i, phy6_idx = 0;
 2922         uint16_t save_rf[SAVE_RF_MAX];
 2923         uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
 2924         uint16_t save_phy6[SAVE_PHY6_MAX];
 2925         int16_t nrssi;
 2926         uint16_t saved = 0xffff;
 2927 
 2928         for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
 2929                 save_phy_comm[i] = BWN_PHY_READ(mac, save_phy_comm_regs[i]);
 2930         for (i = 0; i < SAVE_RF_MAX; ++i)
 2931                 save_rf[i] = BWN_RF_READ(mac, save_rf_regs[i]);
 2932 
 2933         BWN_PHY_MASK(mac, 0x0429, 0x7fff);
 2934         BWN_PHY_SETMASK(mac, 0x0001, 0x3fff, 0x4000);
 2935         BWN_PHY_SET(mac, 0x0811, 0x000c);
 2936         BWN_PHY_SETMASK(mac, 0x0812, 0xfff3, 0x0004);
 2937         BWN_PHY_MASK(mac, 0x0802, ~(0x1 | 0x2));
 2938         if (phy->rev >= 6) {
 2939                 for (i = 0; i < SAVE_PHY6_MAX; ++i)
 2940                         save_phy6[i] = BWN_PHY_READ(mac, save_phy6_regs[i]);
 2941 
 2942                 BWN_PHY_WRITE(mac, 0x002e, 0);
 2943                 BWN_PHY_WRITE(mac, 0x002f, 0);
 2944                 BWN_PHY_WRITE(mac, 0x080f, 0);
 2945                 BWN_PHY_WRITE(mac, 0x0810, 0);
 2946                 BWN_PHY_SET(mac, 0x0478, 0x0100);
 2947                 BWN_PHY_SET(mac, 0x0801, 0x0040);
 2948                 BWN_PHY_SET(mac, 0x0060, 0x0040);
 2949                 BWN_PHY_SET(mac, 0x0014, 0x0200);
 2950         }
 2951         BWN_RF_SET(mac, 0x007a, 0x0070);
 2952         BWN_RF_SET(mac, 0x007a, 0x0080);
 2953         DELAY(30);
 2954 
 2955         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
 2956         if (nrssi >= 0x20)
 2957                 nrssi -= 0x40;
 2958         if (nrssi == 31) {
 2959                 for (i = 7; i >= 4; i--) {
 2960                         BWN_RF_WRITE(mac, 0x007b, i);
 2961                         DELAY(20);
 2962                         nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) &
 2963                             0x003f);
 2964                         if (nrssi >= 0x20)
 2965                                 nrssi -= 0x40;
 2966                         if (nrssi < 31 && saved == 0xffff)
 2967                                 saved = i;
 2968                 }
 2969                 if (saved == 0xffff)
 2970                         saved = 4;
 2971         } else {
 2972                 BWN_RF_MASK(mac, 0x007a, 0x007f);
 2973                 if (phy->rev != 1) {
 2974                         BWN_PHY_SET(mac, 0x0814, 0x0001);
 2975                         BWN_PHY_MASK(mac, 0x0815, 0xfffe);
 2976                 }
 2977                 BWN_PHY_SET(mac, 0x0811, 0x000c);
 2978                 BWN_PHY_SET(mac, 0x0812, 0x000c);
 2979                 BWN_PHY_SET(mac, 0x0811, 0x0030);
 2980                 BWN_PHY_SET(mac, 0x0812, 0x0030);
 2981                 BWN_PHY_WRITE(mac, 0x005a, 0x0480);
 2982                 BWN_PHY_WRITE(mac, 0x0059, 0x0810);
 2983                 BWN_PHY_WRITE(mac, 0x0058, 0x000d);
 2984                 if (phy->rev == 0)
 2985                         BWN_PHY_WRITE(mac, 0x0003, 0x0122);
 2986                 else
 2987                         BWN_PHY_SET(mac, 0x000a, 0x2000);
 2988                 if (phy->rev != 1) {
 2989                         BWN_PHY_SET(mac, 0x0814, 0x0004);
 2990                         BWN_PHY_MASK(mac, 0x0815, 0xfffb);
 2991                 }
 2992                 BWN_PHY_SETMASK(mac, 0x0003, 0xff9f, 0x0040);
 2993                 BWN_RF_SET(mac, 0x007a, 0x000f);
 2994                 bwn_set_all_gains(mac, 3, 0, 1);
 2995                 BWN_RF_SETMASK(mac, 0x0043, 0x00f0, 0x000f);
 2996                 DELAY(30);
 2997                 nrssi = (int16_t) ((BWN_PHY_READ(mac, 0x047f) >> 8) & 0x003f);
 2998                 if (nrssi >= 0x20)
 2999                         nrssi -= 0x40;
 3000                 if (nrssi == -32) {
 3001                         for (i = 0; i < 4; i++) {
 3002                                 BWN_RF_WRITE(mac, 0x007b, i);
 3003                                 DELAY(20);
 3004                                 nrssi = (int16_t)((BWN_PHY_READ(mac,
 3005                                     0x047f) >> 8) & 0x003f);
 3006                                 if (nrssi >= 0x20)
 3007                                         nrssi -= 0x40;
 3008                                 if (nrssi > -31 && saved == 0xffff)
 3009                                         saved = i;
 3010                         }
 3011                         if (saved == 0xffff)
 3012                                 saved = 3;
 3013                 } else
 3014                         saved = 0;
 3015         }
 3016         BWN_RF_WRITE(mac, 0x007b, saved);
 3017 
 3018         /*
 3019          * Restore saved RF/PHY registers
 3020          */
 3021         if (phy->rev >= 6) {
 3022                 for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
 3023                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
 3024                             save_phy6[phy6_idx]);
 3025                 }
 3026         }
 3027         if (phy->rev != 1) {
 3028                 for (i = 3; i < 5; i++)
 3029                         BWN_PHY_WRITE(mac, save_phy_comm_regs[i],
 3030                             save_phy_comm[i]);
 3031         }
 3032         for (i = 5; i < SAVE_PHY_COMM_MAX; i++)
 3033                 BWN_PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
 3034 
 3035         for (i = SAVE_RF_MAX - 1; i >= 0; --i)
 3036                 BWN_RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
 3037 
 3038         BWN_PHY_WRITE(mac, 0x0802, BWN_PHY_READ(mac, 0x0802) | 0x1 | 0x2);
 3039         BWN_PHY_SET(mac, 0x0429, 0x8000);
 3040         bwn_set_original_gains(mac);
 3041         if (phy->rev >= 6) {
 3042                 for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
 3043                         BWN_PHY_WRITE(mac, save_phy6_regs[phy6_idx],
 3044                             save_phy6[phy6_idx]);
 3045                 }
 3046         }
 3047 
 3048         BWN_PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
 3049         BWN_PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
 3050         BWN_PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
 3051 }
 3052 
 3053 static void
 3054 bwn_set_all_gains(struct bwn_mac *mac, int16_t first, int16_t second,
 3055     int16_t third)
 3056 {
 3057         struct bwn_phy *phy = &mac->mac_phy;
 3058         uint16_t i;
 3059         uint16_t start = 0x08, end = 0x18;
 3060         uint16_t tmp;
 3061         uint16_t table;
 3062 
 3063         if (phy->rev <= 1) {
 3064                 start = 0x10;
 3065                 end = 0x20;
 3066         }
 3067 
 3068         table = BWN_OFDMTAB_GAINX;
 3069         if (phy->rev <= 1)
 3070                 table = BWN_OFDMTAB_GAINX_R1;
 3071         for (i = 0; i < 4; i++)
 3072                 bwn_ofdmtab_write_2(mac, table, i, first);
 3073 
 3074         for (i = start; i < end; i++)
 3075                 bwn_ofdmtab_write_2(mac, table, i, second);
 3076 
 3077         if (third != -1) {
 3078                 tmp = ((uint16_t) third << 14) | ((uint16_t) third << 6);
 3079                 BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, tmp);
 3080                 BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, tmp);
 3081                 BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, tmp);
 3082         }
 3083         bwn_dummy_transmission(mac, 0, 1);
 3084 }
 3085 
 3086 static void
 3087 bwn_set_original_gains(struct bwn_mac *mac)
 3088 {
 3089         struct bwn_phy *phy = &mac->mac_phy;
 3090         uint16_t i, tmp;
 3091         uint16_t table;
 3092         uint16_t start = 0x0008, end = 0x0018;
 3093 
 3094         if (phy->rev <= 1) {
 3095                 start = 0x0010;
 3096                 end = 0x0020;
 3097         }
 3098 
 3099         table = BWN_OFDMTAB_GAINX;
 3100         if (phy->rev <= 1)
 3101                 table = BWN_OFDMTAB_GAINX_R1;
 3102         for (i = 0; i < 4; i++) {
 3103                 tmp = (i & 0xfffc);
 3104                 tmp |= (i & 0x0001) << 1;
 3105                 tmp |= (i & 0x0002) >> 1;
 3106 
 3107                 bwn_ofdmtab_write_2(mac, table, i, tmp);
 3108         }
 3109 
 3110         for (i = start; i < end; i++)
 3111                 bwn_ofdmtab_write_2(mac, table, i, i - start);
 3112 
 3113         BWN_PHY_SETMASK(mac, 0x04a0, 0xbfbf, 0x4040);
 3114         BWN_PHY_SETMASK(mac, 0x04a1, 0xbfbf, 0x4040);
 3115         BWN_PHY_SETMASK(mac, 0x04a2, 0xbfbf, 0x4000);
 3116         bwn_dummy_transmission(mac, 0, 1);
 3117 }
 3118 
 3119 static void
 3120 bwn_phy_hwpctl_init(struct bwn_mac *mac)
 3121 {
 3122         struct bwn_phy *phy = &mac->mac_phy;
 3123         struct bwn_phy_g *pg = &phy->phy_g;
 3124         struct bwn_rfatt old_rfatt, rfatt;
 3125         struct bwn_bbatt old_bbatt, bbatt;
 3126         struct bwn_softc *sc = mac->mac_sc;
 3127         uint8_t old_txctl = 0;
 3128 
 3129         KASSERT(phy->type == BWN_PHYTYPE_G,
 3130             ("%s:%d: fail", __func__, __LINE__));
 3131 
 3132         if ((sc->sc_board_info.board_vendor == PCI_VENDOR_BROADCOM) &&
 3133             (sc->sc_board_info.board_type == BHND_BOARD_BU4306))
 3134                 return;
 3135 
 3136         BWN_PHY_WRITE(mac, 0x0028, 0x8018);
 3137 
 3138         BWN_WRITE_2(mac, BWN_PHY0, BWN_READ_2(mac, BWN_PHY0) & 0xffdf);
 3139 
 3140         if (!phy->gmode)
 3141                 return;
 3142         bwn_hwpctl_early_init(mac);
 3143         if (pg->pg_curtssi == 0) {
 3144                 if (phy->rf_ver == 0x2050 && phy->analog == 0) {
 3145                         BWN_RF_SETMASK(mac, 0x0076, 0x00f7, 0x0084);
 3146                 } else {
 3147                         memcpy(&old_rfatt, &pg->pg_rfatt, sizeof(old_rfatt));
 3148                         memcpy(&old_bbatt, &pg->pg_bbatt, sizeof(old_bbatt));
 3149                         old_txctl = pg->pg_txctl;
 3150 
 3151                         bbatt.att = 11;
 3152                         if (phy->rf_rev == 8) {
 3153                                 rfatt.att = 15;
 3154                                 rfatt.padmix = 1;
 3155                         } else {
 3156                                 rfatt.att = 9;
 3157                                 rfatt.padmix = 0;
 3158                         }
 3159                         bwn_phy_g_set_txpwr_sub(mac, &bbatt, &rfatt, 0);
 3160                 }
 3161                 bwn_dummy_transmission(mac, 0, 1);
 3162                 pg->pg_curtssi = BWN_PHY_READ(mac, BWN_PHY_TSSI);
 3163                 if (phy->rf_ver == 0x2050 && phy->analog == 0)
 3164                         BWN_RF_MASK(mac, 0x0076, 0xff7b);
 3165                 else
 3166                         bwn_phy_g_set_txpwr_sub(mac, &old_bbatt,
 3167                             &old_rfatt, old_txctl);
 3168         }
 3169         bwn_hwpctl_init_gphy(mac);
 3170 
 3171         /* clear TSSI */
 3172         bwn_shm_write_2(mac, BWN_SHARED, 0x0058, 0x7f7f);
 3173         bwn_shm_write_2(mac, BWN_SHARED, 0x005a, 0x7f7f);
 3174         bwn_shm_write_2(mac, BWN_SHARED, 0x0070, 0x7f7f);
 3175         bwn_shm_write_2(mac, BWN_SHARED, 0x0072, 0x7f7f);
 3176 }
 3177 
 3178 static void
 3179 bwn_hwpctl_early_init(struct bwn_mac *mac)
 3180 {
 3181         struct bwn_phy *phy = &mac->mac_phy;
 3182 
 3183         if (!bwn_has_hwpctl(mac)) {
 3184                 BWN_PHY_WRITE(mac, 0x047a, 0xc111);
 3185                 return;
 3186         }
 3187 
 3188         BWN_PHY_MASK(mac, 0x0036, 0xfeff);
 3189         BWN_PHY_WRITE(mac, 0x002f, 0x0202);
 3190         BWN_PHY_SET(mac, 0x047c, 0x0002);
 3191         BWN_PHY_SET(mac, 0x047a, 0xf000);
 3192         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8) {
 3193                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
 3194                 BWN_PHY_SET(mac, 0x005d, 0x8000);
 3195                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
 3196                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
 3197                 BWN_PHY_SET(mac, 0x0036, 0x0400);
 3198         } else {
 3199                 BWN_PHY_SET(mac, 0x0036, 0x0200);
 3200                 BWN_PHY_SET(mac, 0x0036, 0x0400);
 3201                 BWN_PHY_MASK(mac, 0x005d, 0x7fff);
 3202                 BWN_PHY_MASK(mac, 0x004f, 0xfffe);
 3203                 BWN_PHY_SETMASK(mac, 0x004e, 0xffc0, 0x0010);
 3204                 BWN_PHY_WRITE(mac, 0x002e, 0xc07f);
 3205                 BWN_PHY_SETMASK(mac, 0x047a, 0xff0f, 0x0010);
 3206         }
 3207 }
 3208 
 3209 static void
 3210 bwn_hwpctl_init_gphy(struct bwn_mac *mac)
 3211 {
 3212         struct bwn_phy *phy = &mac->mac_phy;
 3213         struct bwn_phy_g *pg = &phy->phy_g;
 3214         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
 3215         int i;
 3216         uint16_t nr_written = 0, tmp, value;
 3217         uint8_t rf, bb;
 3218 
 3219         if (!bwn_has_hwpctl(mac)) {
 3220                 bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_HW_POWERCTL);
 3221                 return;
 3222         }
 3223 
 3224         BWN_PHY_SETMASK(mac, 0x0036, 0xffc0,
 3225             (pg->pg_idletssi - pg->pg_curtssi));
 3226         BWN_PHY_SETMASK(mac, 0x0478, 0xff00,
 3227             (pg->pg_idletssi - pg->pg_curtssi));
 3228 
 3229         for (i = 0; i < 32; i++)
 3230                 bwn_ofdmtab_write_2(mac, 0x3c20, i, pg->pg_tssi2dbm[i]);
 3231         for (i = 32; i < 64; i++)
 3232                 bwn_ofdmtab_write_2(mac, 0x3c00, i - 32, pg->pg_tssi2dbm[i]);
 3233         for (i = 0; i < 64; i += 2) {
 3234                 value = (uint16_t) pg->pg_tssi2dbm[i];
 3235                 value |= ((uint16_t) pg->pg_tssi2dbm[i + 1]) << 8;
 3236                 BWN_PHY_WRITE(mac, 0x380 + (i / 2), value);
 3237         }
 3238 
 3239         for (rf = 0; rf < lo->rfatt.len; rf++) {
 3240                 for (bb = 0; bb < lo->bbatt.len; bb++) {
 3241                         if (nr_written >= 0x40)
 3242                                 return;
 3243                         tmp = lo->bbatt.array[bb].att;
 3244                         tmp <<= 8;
 3245                         if (phy->rf_rev == 8)
 3246                                 tmp |= 0x50;
 3247                         else
 3248                                 tmp |= 0x40;
 3249                         tmp |= lo->rfatt.array[rf].att;
 3250                         BWN_PHY_WRITE(mac, 0x3c0 + nr_written, tmp);
 3251                         nr_written++;
 3252                 }
 3253         }
 3254 
 3255         BWN_PHY_MASK(mac, 0x0060, 0xffbf);
 3256         BWN_PHY_WRITE(mac, 0x0014, 0x0000);
 3257 
 3258         KASSERT(phy->rev >= 6, ("%s:%d: fail", __func__, __LINE__));
 3259         BWN_PHY_SET(mac, 0x0478, 0x0800);
 3260         BWN_PHY_MASK(mac, 0x0478, 0xfeff);
 3261         BWN_PHY_MASK(mac, 0x0801, 0xffbf);
 3262 
 3263         bwn_phy_g_dc_lookup_init(mac, 1);
 3264         bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_HW_POWERCTL);
 3265 }
 3266 
 3267 static void
 3268 bwn_phy_g_switch_chan(struct bwn_mac *mac, int channel, uint8_t spu)
 3269 {
 3270         struct bwn_softc        *sc = mac->mac_sc;
 3271         int                      error;
 3272 
 3273         if (spu != 0)
 3274                 bwn_spu_workaround(mac, channel);
 3275 
 3276         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
 3277 
 3278         if (channel == 14) {
 3279                 uint8_t cc;
 3280 
 3281                 error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_CC, &cc);
 3282                 if (error) {
 3283                         device_printf(sc->sc_dev, "error reading country code "
 3284                             "from NVRAM, assuming channel 14 unavailable: %d\n",
 3285                             error);
 3286                         cc = BWN_SPROM1_CC_WORLDWIDE;
 3287                 }
 3288 
 3289                 if (cc == BWN_SPROM1_CC_JP)
 3290                         bwn_hf_write(mac,
 3291                             bwn_hf_read(mac) & ~BWN_HF_JAPAN_CHAN14_OFF);
 3292                 else
 3293                         bwn_hf_write(mac,
 3294                             bwn_hf_read(mac) | BWN_HF_JAPAN_CHAN14_OFF);
 3295                 BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
 3296                     BWN_READ_2(mac, BWN_CHANNEL_EXT) | (1 << 11));
 3297                 return;
 3298         }
 3299 
 3300         BWN_WRITE_2(mac, BWN_CHANNEL_EXT,
 3301             BWN_READ_2(mac, BWN_CHANNEL_EXT) & 0xf7bf);
 3302 }
 3303 
 3304 static uint16_t
 3305 bwn_phy_g_chan2freq(uint8_t channel)
 3306 {
 3307         static const uint8_t bwn_phy_g_rf_channels[] = BWN_PHY_G_RF_CHANNELS;
 3308 
 3309         KASSERT(channel >= 1 && channel <= 14,
 3310             ("%s:%d: fail", __func__, __LINE__));
 3311 
 3312         return (bwn_phy_g_rf_channels[channel - 1]);
 3313 }
 3314 
 3315 static void
 3316 bwn_phy_g_set_txpwr_sub(struct bwn_mac *mac, const struct bwn_bbatt *bbatt,
 3317     const struct bwn_rfatt *rfatt, uint8_t txctl)
 3318 {
 3319         struct bwn_phy *phy = &mac->mac_phy;
 3320         struct bwn_phy_g *pg = &phy->phy_g;
 3321         struct bwn_txpwr_loctl *lo = &pg->pg_loctl;
 3322         uint16_t bb, rf;
 3323         uint16_t tx_bias, tx_magn;
 3324 
 3325         bb = bbatt->att;
 3326         rf = rfatt->att;
 3327         tx_bias = lo->tx_bias;
 3328         tx_magn = lo->tx_magn;
 3329         if (tx_bias == 0xff)
 3330                 tx_bias = 0;
 3331 
 3332         pg->pg_txctl = txctl;
 3333         memmove(&pg->pg_rfatt, rfatt, sizeof(*rfatt));
 3334         pg->pg_rfatt.padmix = (txctl & BWN_TXCTL_TXMIX) ? 1 : 0;
 3335         memmove(&pg->pg_bbatt, bbatt, sizeof(*bbatt));
 3336         bwn_phy_g_set_bbatt(mac, bb);
 3337         bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RADIO_ATT, rf);
 3338         if (phy->rf_ver == 0x2050 && phy->rf_rev == 8)
 3339                 BWN_RF_WRITE(mac, 0x43, (rf & 0x000f) | (txctl & 0x0070));
 3340         else {
 3341                 BWN_RF_SETMASK(mac, 0x43, 0xfff0, (rf & 0x000f));
 3342                 BWN_RF_SETMASK(mac, 0x52, ~0x0070, (txctl & 0x0070));
 3343         }
 3344         if (BWN_HAS_TXMAG(phy))
 3345                 BWN_RF_WRITE(mac, 0x52, tx_magn | tx_bias);
 3346         else
 3347                 BWN_RF_SETMASK(mac, 0x52, 0xfff0, (tx_bias & 0x000f));
 3348         bwn_lo_g_adjust(mac);
 3349 }
 3350 
 3351 static void
 3352 bwn_phy_g_set_bbatt(struct bwn_mac *mac,
 3353     uint16_t bbatt)
 3354 {
 3355         struct bwn_phy *phy = &mac->mac_phy;
 3356 
 3357         if (phy->analog == 0) {
 3358                 BWN_WRITE_2(mac, BWN_PHY0,
 3359                     (BWN_READ_2(mac, BWN_PHY0) & 0xfff0) | bbatt);
 3360                 return;
 3361         }
 3362         if (phy->analog > 1) {
 3363                 BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xffc3, bbatt << 2);
 3364                 return;
 3365         }
 3366         BWN_PHY_SETMASK(mac, BWN_PHY_DACCTL, 0xff87, bbatt << 3);
 3367 }
 3368 
 3369 static uint16_t
 3370 bwn_rf_2050_rfoverval(struct bwn_mac *mac, uint16_t reg, uint32_t lpd)
 3371 {
 3372         struct bwn_phy *phy = &mac->mac_phy;
 3373         struct bwn_phy_g *pg = &phy->phy_g;
 3374         struct bwn_softc *sc = mac->mac_sc;
 3375         int max_lb_gain;
 3376         uint16_t extlna;
 3377         uint16_t i;
 3378 
 3379         if (phy->gmode == 0)
 3380                 return (0);
 3381 
 3382         if (BWN_HAS_LOOPBACK(phy)) {
 3383                 max_lb_gain = pg->pg_max_lb_gain;
 3384                 max_lb_gain += (phy->rf_rev == 8) ? 0x3e : 0x26;
 3385                 if (max_lb_gain >= 0x46) {
 3386                         extlna = 0x3000;
 3387                         max_lb_gain -= 0x46;
 3388                 } else if (max_lb_gain >= 0x3a) {
 3389                         extlna = 0x1000;
 3390                         max_lb_gain -= 0x3a;
 3391                 } else if (max_lb_gain >= 0x2e) {
 3392                         extlna = 0x2000;
 3393                         max_lb_gain -= 0x2e;
 3394                 } else {
 3395                         extlna = 0;
 3396                         max_lb_gain -= 0x10;
 3397                 }
 3398 
 3399                 for (i = 0; i < 16; i++) {
 3400                         max_lb_gain -= (i * 6);
 3401                         if (max_lb_gain < 6)
 3402                                 break;
 3403                 }
 3404 
 3405                 if ((phy->rev < 7) ||
 3406                     !(sc->sc_board_info.board_flags & BHND_BFL_EXTLNA)) {
 3407                         if (reg == BWN_PHY_RFOVER) {
 3408                                 return (0x1b3);
 3409                         } else if (reg == BWN_PHY_RFOVERVAL) {
 3410                                 extlna |= (i << 8);
 3411                                 switch (lpd) {
 3412                                 case BWN_LPD(0, 1, 1):
 3413                                         return (0x0f92);
 3414                                 case BWN_LPD(0, 0, 1):
 3415                                 case BWN_LPD(1, 0, 1):
 3416                                         return (0x0092 | extlna);
 3417                                 case BWN_LPD(1, 0, 0):
 3418                                         return (0x0093 | extlna);
 3419                                 }
 3420                                 KASSERT(0 == 1,
 3421                                     ("%s:%d: fail", __func__, __LINE__));
 3422                         }
 3423                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
 3424                 } else {
 3425                         if (reg == BWN_PHY_RFOVER)
 3426                                 return (0x9b3);
 3427                         if (reg == BWN_PHY_RFOVERVAL) {
 3428                                 if (extlna)
 3429                                         extlna |= 0x8000;
 3430                                 extlna |= (i << 8);
 3431                                 switch (lpd) {
 3432                                 case BWN_LPD(0, 1, 1):
 3433                                         return (0x8f92);
 3434                                 case BWN_LPD(0, 0, 1):
 3435                                         return (0x8092 | extlna);
 3436                                 case BWN_LPD(1, 0, 1):
 3437                                         return (0x2092 | extlna);
 3438                                 case BWN_LPD(1, 0, 0):
 3439                                         return (0x2093 | extlna);
 3440                                 }
 3441                                 KASSERT(0 == 1,
 3442                                     ("%s:%d: fail", __func__, __LINE__));
 3443                         }
 3444                         KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
 3445                 }
 3446                 return (0);
 3447         }
 3448 
 3449         if ((phy->rev < 7) ||
 3450             !(sc->sc_board_info.board_flags & BHND_BFL_EXTLNA)) {
 3451                 if (reg == BWN_PHY_RFOVER) {
 3452                         return (0x1b3);
 3453                 } else if (reg == BWN_PHY_RFOVERVAL) {
 3454                         switch (lpd) {
 3455                         case BWN_LPD(0, 1, 1):
 3456                                 return (0x0fb2);
 3457                         case BWN_LPD(0, 0, 1):
 3458                                 return (0x00b2);
 3459                         case BWN_LPD(1, 0, 1):
 3460                                 return (0x30b2);
 3461                         case BWN_LPD(1, 0, 0):
 3462                                 return (0x30b3);
 3463                         }
 3464                         KASSERT(0 == 1,
 3465                             ("%s:%d: fail", __func__, __LINE__));
 3466                 }
 3467                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
 3468         } else {
 3469                 if (reg == BWN_PHY_RFOVER) {
 3470                         return (0x9b3);
 3471                 } else if (reg == BWN_PHY_RFOVERVAL) {
 3472                         switch (lpd) {
 3473                         case BWN_LPD(0, 1, 1):
 3474                                 return (0x8fb2);
 3475                         case BWN_LPD(0, 0, 1):
 3476                                 return (0x80b2);
 3477                         case BWN_LPD(1, 0, 1):
 3478                                 return (0x20b2);
 3479                         case BWN_LPD(1, 0, 0):
 3480                                 return (0x20b3);
 3481                         }
 3482                         KASSERT(0 == 1,
 3483                             ("%s:%d: fail", __func__, __LINE__));
 3484                 }
 3485                 KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
 3486         }
 3487         return (0);
 3488 }
 3489 
 3490 static void
 3491 bwn_spu_workaround(struct bwn_mac *mac, uint8_t channel)
 3492 {
 3493 
 3494         if (mac->mac_phy.rf_ver != 0x2050 || mac->mac_phy.rf_rev >= 6)
 3495                 return;
 3496         BWN_WRITE_2(mac, BWN_CHANNEL, (channel <= 10) ?
 3497             bwn_phy_g_chan2freq(channel + 4) : bwn_phy_g_chan2freq(1));
 3498         DELAY(1000);
 3499         BWN_WRITE_2(mac, BWN_CHANNEL, bwn_phy_g_chan2freq(channel));
 3500 }
 3501 
 3502 static int
 3503 bwn_phy_shm_tssi_read(struct bwn_mac *mac, uint16_t shm_offset)
 3504 {
 3505         const uint8_t ofdm = (shm_offset != BWN_SHARED_TSSI_CCK);
 3506         unsigned int a, b, c, d;
 3507         unsigned int avg;
 3508         uint32_t tmp;
 3509 
 3510         tmp = bwn_shm_read_4(mac, BWN_SHARED, shm_offset);
 3511         a = tmp & 0xff;
 3512         b = (tmp >> 8) & 0xff;
 3513         c = (tmp >> 16) & 0xff;
 3514         d = (tmp >> 24) & 0xff;
 3515         if (a == 0 || a == BWN_TSSI_MAX || b == 0 || b == BWN_TSSI_MAX ||
 3516             c == 0 || c == BWN_TSSI_MAX || d == 0 || d == BWN_TSSI_MAX)
 3517                 return (ENOENT);
 3518         bwn_shm_write_4(mac, BWN_SHARED, shm_offset,
 3519             BWN_TSSI_MAX | (BWN_TSSI_MAX << 8) |
 3520             (BWN_TSSI_MAX << 16) | (BWN_TSSI_MAX << 24));
 3521 
 3522         if (ofdm) {
 3523                 a = (a + 32) & 0x3f;
 3524                 b = (b + 32) & 0x3f;
 3525                 c = (c + 32) & 0x3f;
 3526                 d = (d + 32) & 0x3f;
 3527         }
 3528 
 3529         avg = (a + b + c + d + 2) / 4;
 3530         if (ofdm) {
 3531                 if (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO)
 3532                     & BWN_HF_4DB_CCK_POWERBOOST)
 3533                         avg = (avg >= 13) ? (avg - 13) : 0;
 3534         }
 3535         return (avg);
 3536 }
 3537 
 3538 static void
 3539 bwn_phy_g_setatt(struct bwn_mac *mac, int *bbattp, int *rfattp)
 3540 {
 3541         struct bwn_txpwr_loctl *lo = &mac->mac_phy.phy_g.pg_loctl;
 3542         int rfatt = *rfattp;
 3543         int bbatt = *bbattp;
 3544 
 3545         while (1) {
 3546                 if (rfatt > lo->rfatt.max && bbatt > lo->bbatt.max - 4)
 3547                         break;
 3548                 if (rfatt < lo->rfatt.min && bbatt < lo->bbatt.min + 4)
 3549                         break;
 3550                 if (bbatt > lo->bbatt.max && rfatt > lo->rfatt.max - 1)
 3551                         break;
 3552                 if (bbatt < lo->bbatt.min && rfatt < lo->rfatt.min + 1)
 3553                         break;
 3554                 if (bbatt > lo->bbatt.max) {
 3555                         bbatt -= 4;
 3556                         rfatt += 1;
 3557                         continue;
 3558                 }
 3559                 if (bbatt < lo->bbatt.min) {
 3560                         bbatt += 4;
 3561                         rfatt -= 1;
 3562                         continue;
 3563                 }
 3564                 if (rfatt > lo->rfatt.max) {
 3565                         rfatt -= 1;
 3566                         bbatt += 4;
 3567                         continue;
 3568                 }
 3569                 if (rfatt < lo->rfatt.min) {
 3570                         rfatt += 1;
 3571                         bbatt -= 4;
 3572                         continue;
 3573                 }
 3574                 break;
 3575         }
 3576 
 3577         *rfattp = MIN(MAX(rfatt, lo->rfatt.min), lo->rfatt.max);
 3578         *bbattp = MIN(MAX(bbatt, lo->bbatt.min), lo->bbatt.max);
 3579 }
 3580 
 3581 static void
 3582 bwn_phy_lock(struct bwn_mac *mac)
 3583 {
 3584         struct bwn_softc *sc = mac->mac_sc;
 3585         struct ieee80211com *ic = &sc->sc_ic;
 3586 
 3587         KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 3,
 3588             ("%s: unsupported rev %d", __func__, bhnd_get_hwrev(sc->sc_dev)));
 3589 
 3590         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
 3591                 bwn_psctl(mac, BWN_PS_AWAKE);
 3592 }
 3593 
 3594 static void
 3595 bwn_phy_unlock(struct bwn_mac *mac)
 3596 {
 3597         struct bwn_softc *sc = mac->mac_sc;
 3598         struct ieee80211com *ic = &sc->sc_ic;
 3599 
 3600         KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 3,
 3601             ("%s: unsupported rev %d", __func__, bhnd_get_hwrev(sc->sc_dev)));
 3602 
 3603         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
 3604                 bwn_psctl(mac, 0);
 3605 }
 3606 
 3607 static void
 3608 bwn_rf_lock(struct bwn_mac *mac)
 3609 {
 3610 
 3611         BWN_WRITE_4(mac, BWN_MACCTL,
 3612             BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_RADIO_LOCK);
 3613         BWN_READ_4(mac, BWN_MACCTL);
 3614         DELAY(10);
 3615 }
 3616 
 3617 static void
 3618 bwn_rf_unlock(struct bwn_mac *mac)
 3619 {
 3620 
 3621         BWN_READ_2(mac, BWN_PHYVER);
 3622         BWN_WRITE_4(mac, BWN_MACCTL,
 3623             BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_RADIO_LOCK);
 3624 }

Cache object: cd6e2c39913111a327ee8fd33c3bcce7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.