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/rtwn/rtl8192c/r92c_init.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 /*      $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
    5  * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
    6  * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org>
    7  *
    8  * Permission to use, copy, modify, and distribute this software for any
    9  * purpose with or without fee is hereby granted, provided that the above
   10  * copyright notice and this permission notice appear in all copies.
   11  *
   12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   19  */
   20 
   21 #include <sys/cdefs.h>
   22 __FBSDID("$FreeBSD$");
   23 
   24 #include "opt_wlan.h"
   25 
   26 #include <sys/param.h>
   27 #include <sys/lock.h>
   28 #include <sys/mutex.h>
   29 #include <sys/mbuf.h>
   30 #include <sys/kernel.h>
   31 #include <sys/socket.h>
   32 #include <sys/systm.h>
   33 #include <sys/malloc.h>
   34 #include <sys/queue.h>
   35 #include <sys/taskqueue.h>
   36 #include <sys/bus.h>
   37 #include <sys/endian.h>
   38 #include <sys/linker.h>
   39 
   40 #include <net/if.h>
   41 #include <net/ethernet.h>
   42 #include <net/if_media.h>
   43 
   44 #include <net80211/ieee80211_var.h>
   45 #include <net80211/ieee80211_radiotap.h>
   46 
   47 #include <dev/rtwn/if_rtwnreg.h>
   48 #include <dev/rtwn/if_rtwnvar.h>
   49 #include <dev/rtwn/if_rtwn_debug.h>
   50 
   51 #include <dev/rtwn/rtl8192c/r92c.h>
   52 #include <dev/rtwn/rtl8192c/r92c_priv.h>
   53 #include <dev/rtwn/rtl8192c/r92c_reg.h>
   54 #include <dev/rtwn/rtl8192c/r92c_var.h>
   55 
   56 int
   57 r92c_check_condition(struct rtwn_softc *sc, const uint8_t cond[])
   58 {
   59         struct r92c_softc *rs = sc->sc_priv;
   60         uint8_t mask;
   61         int i;
   62 
   63         if (cond[0] == 0)
   64                 return (1);
   65 
   66         RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
   67             "%s: condition byte 0: %02X; chip %02X, board %02X\n",
   68             __func__, cond[0], rs->chip, rs->board_type);
   69 
   70         if (!(rs->chip & R92C_CHIP_92C)) {
   71                 if (rs->board_type == R92C_BOARD_TYPE_HIGHPA)
   72                         mask = R92C_COND_RTL8188RU;
   73                 else if (rs->board_type == R92C_BOARD_TYPE_MINICARD)
   74                         mask = R92C_COND_RTL8188CE;
   75                 else
   76                         mask = R92C_COND_RTL8188CU;
   77         } else {
   78                 if (rs->board_type == R92C_BOARD_TYPE_MINICARD)
   79                         mask = R92C_COND_RTL8192CE;
   80                 else
   81                         mask = R92C_COND_RTL8192CU;
   82         }
   83 
   84         for (i = 0; i < RTWN_MAX_CONDITIONS && cond[i] != 0; i++)
   85                 if ((cond[i] & mask) == mask)
   86                         return (1);
   87 
   88         return (0);
   89 }
   90 
   91 int
   92 r92c_llt_init(struct rtwn_softc *sc)
   93 {
   94         int i, error;
   95 
   96         /* Reserve pages [0; page_count]. */
   97         for (i = 0; i < sc->page_count; i++) {
   98                 if ((error = r92c_llt_write(sc, i, i + 1)) != 0)
   99                         return (error);
  100         }
  101         /* NB: 0xff indicates end-of-list. */
  102         if ((error = r92c_llt_write(sc, i, 0xff)) != 0)
  103                 return (error);
  104         /*
  105          * Use pages [page_count + 1; pktbuf_count - 1]
  106          * as ring buffer.
  107          */
  108         for (++i; i < sc->pktbuf_count - 1; i++) {
  109                 if ((error = r92c_llt_write(sc, i, i + 1)) != 0)
  110                         return (error);
  111         }
  112         /* Make the last page point to the beginning of the ring buffer. */
  113         error = r92c_llt_write(sc, i, sc->page_count + 1);
  114         return (error);
  115 }
  116 
  117 int
  118 r92c_set_page_size(struct rtwn_softc *sc)
  119 {
  120         return (rtwn_write_1(sc, R92C_PBP, SM(R92C_PBP_PSRX, R92C_PBP_128) |
  121             SM(R92C_PBP_PSTX, R92C_PBP_128)) == 0);
  122 }
  123 
  124 void
  125 r92c_init_bb_common(struct rtwn_softc *sc)
  126 {
  127         struct r92c_softc *rs = sc->sc_priv;
  128         int i, j;
  129 
  130         /* Write BB initialization values. */
  131         for (i = 0; i < sc->bb_size; i++) {
  132                 const struct rtwn_bb_prog *bb_prog = &sc->bb_prog[i];
  133 
  134                 while (!rtwn_check_condition(sc, bb_prog->cond)) {
  135                         KASSERT(bb_prog->next != NULL,
  136                             ("%s: wrong condition value (i %d)\n",
  137                             __func__, i));
  138                         bb_prog = bb_prog->next;
  139                 }
  140 
  141                 for (j = 0; j < bb_prog->count; j++) {
  142                         RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
  143                             "BB: reg 0x%03x, val 0x%08x\n",
  144                             bb_prog->reg[j], bb_prog->val[j]);
  145 
  146                         rtwn_bb_write(sc, bb_prog->reg[j], bb_prog->val[j]);
  147                         rtwn_delay(sc, 1);
  148                 }
  149         }
  150 
  151         if (rs->chip & R92C_CHIP_92C_1T2R) {
  152                 /* 8192C 1T only configuration. */
  153                 rtwn_bb_setbits(sc, R92C_FPGA0_TXINFO, 0x03, 0x02);
  154                 rtwn_bb_setbits(sc, R92C_FPGA1_TXINFO, 0x300033, 0x200022);
  155                 rtwn_bb_setbits(sc, R92C_CCK0_AFESETTING, 0xff000000,
  156                     0x45000000);
  157                 rtwn_bb_setbits(sc, R92C_OFDM0_TRXPATHENA, 0xff, 0x23);
  158                 rtwn_bb_setbits(sc, R92C_OFDM0_AGCPARAM1, 0x30, 0x10);
  159 
  160                 rtwn_bb_setbits(sc, 0xe74, 0x0c000000, 0x08000000);
  161                 rtwn_bb_setbits(sc, 0xe78, 0x0c000000, 0x08000000);
  162                 rtwn_bb_setbits(sc, 0xe7c, 0x0c000000, 0x08000000);
  163                 rtwn_bb_setbits(sc, 0xe80, 0x0c000000, 0x08000000);
  164                 rtwn_bb_setbits(sc, 0xe88, 0x0c000000, 0x08000000);
  165         }
  166 
  167         /* Write AGC values. */
  168         for (i = 0; i < sc->agc_size; i++) {
  169                 const struct rtwn_agc_prog *agc_prog = &sc->agc_prog[i];
  170 
  171                 while (!rtwn_check_condition(sc, agc_prog->cond)) {
  172                         KASSERT(agc_prog->next != NULL,
  173                             ("%s: wrong condition value (2) (i %d)\n",
  174                             __func__, i));
  175                         agc_prog = agc_prog->next;
  176                 }
  177 
  178                 for (j = 0; j < agc_prog->count; j++) {
  179                         RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
  180                             "AGC: val 0x%08x\n", agc_prog->val[j]);
  181 
  182                         rtwn_bb_write(sc, R92C_OFDM0_AGCRSSITABLE,
  183                             agc_prog->val[j]);
  184                         rtwn_delay(sc, 1);
  185                 }
  186         }
  187 
  188         if (rtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) & R92C_HSSI_PARAM2_CCK_HIPWR)
  189                 sc->sc_flags |= RTWN_FLAG_CCK_HIPWR;
  190 }
  191 
  192 int
  193 r92c_init_rf_chain(struct rtwn_softc *sc,
  194     const struct rtwn_rf_prog *rf_prog, int chain)
  195 {
  196         int i, j;
  197 
  198         RTWN_DPRINTF(sc, RTWN_DEBUG_RESET, "%s: chain %d\n",
  199             __func__, chain);
  200 
  201         for (i = 0; rf_prog[i].reg != NULL; i++) {
  202                 const struct rtwn_rf_prog *prog = &rf_prog[i];
  203 
  204                 while (!rtwn_check_condition(sc, prog->cond)) {
  205                         KASSERT(prog->next != NULL,
  206                             ("%s: wrong condition value (i %d)\n",
  207                             __func__, i));
  208                         prog = prog->next;
  209                 }
  210 
  211                 for (j = 0; j < prog->count; j++) {
  212                         RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
  213                             "RF: reg 0x%02x, val 0x%05x\n",
  214                             prog->reg[j], prog->val[j]);
  215 
  216                         /*
  217                          * These are fake RF registers offsets that
  218                          * indicate a delay is required.
  219                          */
  220                         /* NB: we are using 'value' to store required delay. */
  221                         if (prog->reg[j] > 0xf8) {
  222                                 rtwn_delay(sc, prog->val[j]);
  223                                 continue;
  224                         }
  225 
  226                         rtwn_rf_write(sc, chain, prog->reg[j], prog->val[j]);
  227                         rtwn_delay(sc, 1);
  228                 }
  229         }
  230 
  231         return (i);
  232 }
  233 
  234 void
  235 r92c_init_rf(struct rtwn_softc *sc)
  236 {
  237         struct r92c_softc *rs = sc->sc_priv;
  238         uint32_t reg, type;
  239         int i, chain, idx, off;
  240 
  241         for (chain = 0, i = 0; chain < sc->nrxchains; chain++, i++) {
  242                 /* Save RF_ENV control type. */
  243                 idx = chain / 2;
  244                 off = (chain % 2) * 16;
  245                 reg = rtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx));
  246                 type = (reg >> off) & 0x10;
  247 
  248                 /* Set RF_ENV enable. */
  249                 rtwn_bb_setbits(sc, R92C_FPGA0_RFIFACEOE(chain),
  250                     0, 0x100000);
  251                 rtwn_delay(sc, 1);
  252                 /* Set RF_ENV output high. */
  253                 rtwn_bb_setbits(sc, R92C_FPGA0_RFIFACEOE(chain),
  254                     0, 0x10);
  255                 rtwn_delay(sc, 1);
  256                 /* Set address and data lengths of RF registers. */
  257                 rtwn_bb_setbits(sc, R92C_HSSI_PARAM2(chain),
  258                     R92C_HSSI_PARAM2_ADDR_LENGTH, 0);
  259                 rtwn_delay(sc, 1);
  260                 rtwn_bb_setbits(sc, R92C_HSSI_PARAM2(chain),
  261                     R92C_HSSI_PARAM2_DATA_LENGTH, 0);
  262                 rtwn_delay(sc, 1);
  263 
  264                 /* Write RF initialization values for this chain. */
  265                 i += r92c_init_rf_chain(sc, &sc->rf_prog[i], chain);
  266 
  267                 /* Restore RF_ENV control type. */
  268                 rtwn_bb_setbits(sc, R92C_FPGA0_RFIFACESW(idx),
  269                     0x10 << off, type << off);
  270 
  271                 /* Cache RF register CHNLBW. */
  272                 rs->rf_chnlbw[chain] = rtwn_rf_read(sc, chain,
  273                     R92C_RF_CHNLBW);
  274         }
  275 
  276         if ((rs->chip & (R92C_CHIP_UMC_A_CUT | R92C_CHIP_92C)) ==
  277             R92C_CHIP_UMC_A_CUT) {
  278                 rtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255);
  279                 rtwn_rf_write(sc, 0, R92C_RF_RX_G2, 0x50a00);
  280         }
  281 
  282         /* Turn CCK and OFDM blocks on. */
  283         rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, 0, R92C_RFMOD_CCK_EN);
  284         rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, 0, R92C_RFMOD_OFDM_EN);
  285 }
  286 
  287 void
  288 r92c_init_edca(struct rtwn_softc *sc)
  289 {
  290         /* SIFS */
  291         rtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a);
  292         rtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a);
  293         rtwn_write_2(sc, R92C_SIFS_CCK, 0x100a);
  294         rtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a);
  295         /* TXOP */
  296         rtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
  297         rtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
  298         rtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324);
  299         rtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226);
  300 }
  301 
  302 void
  303 r92c_init_ampdu(struct rtwn_softc *sc)
  304 {
  305 
  306         /* Setup AMPDU aggregation. */
  307         rtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631);  /* MCS7~0 */
  308         rtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
  309         rtwn_write_2(sc, R92C_MAX_AGGR_NUM, 0x0708);
  310 }
  311 
  312 void
  313 r92c_init_antsel(struct rtwn_softc *sc)
  314 {
  315         uint32_t reg;
  316 
  317         if (sc->ntxchains != 1 || sc->nrxchains != 1)
  318                 return;
  319 
  320         rtwn_setbits_1(sc, R92C_LEDCFG2, 0, 0x80);
  321         rtwn_bb_setbits(sc, R92C_FPGA0_RFPARAM(0), 0, 0x2000);
  322         reg = rtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(0));
  323         sc->sc_ant = MS(reg, R92C_FPGA0_RFIFACEOE0_ANT);        /* XXX */
  324         rtwn_setbits_1(sc, R92C_LEDCFG2, 0x80, 0);
  325 }
  326 
  327 void
  328 r92c_pa_bias_init(struct rtwn_softc *sc)
  329 {
  330         struct r92c_softc *rs = sc->sc_priv;
  331         int i;
  332 
  333         for (i = 0; i < sc->nrxchains; i++) {
  334                 if (rs->pa_setting & (1 << i))
  335                         continue;
  336                 r92c_rf_write(sc, i, R92C_RF_IPA, 0x0f406);
  337                 r92c_rf_write(sc, i, R92C_RF_IPA, 0x4f406);
  338                 r92c_rf_write(sc, i, R92C_RF_IPA, 0x8f406);
  339                 r92c_rf_write(sc, i, R92C_RF_IPA, 0xcf406);
  340         }
  341         if (!(rs->pa_setting & 0x10))
  342                 rtwn_setbits_1(sc, 0x16, 0xf0, 0x90);
  343 }

Cache object: 78db7a930a328e2b981594c9e81b477a


[ 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.