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/usb/r92cu_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/usb/rtwn_usb_var.h>
   52 
   53 #include <dev/rtwn/rtl8192c/r92c_var.h>
   54 
   55 #include <dev/rtwn/rtl8192c/usb/r92cu.h>
   56 #include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
   57 
   58 void
   59 r92cu_init_bb(struct rtwn_softc *sc)
   60 {
   61 
   62         /* Enable BB and RF. */
   63         rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0,
   64             R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
   65             R92C_SYS_FUNC_EN_DIO_RF);
   66 
   67         rtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
   68 
   69         rtwn_write_1(sc, R92C_RF_CTRL,
   70             R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
   71         rtwn_write_1(sc, R92C_SYS_FUNC_EN,
   72             R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
   73             R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
   74 
   75         rtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
   76         rtwn_write_1(sc, 0x15, 0xe9);
   77         rtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
   78 
   79         r92c_init_bb_common(sc);
   80 }
   81 
   82 int
   83 r92cu_power_on(struct rtwn_softc *sc)
   84 {
   85 #define RTWN_CHK(res) do {      \
   86         if (res != 0)           \
   87                 return (EIO);   \
   88 } while(0)
   89         uint32_t reg;
   90         int ntries;
   91 
   92         /* Wait for autoload done bit. */
   93         for (ntries = 0; ntries < 5000; ntries++) {
   94                 if (rtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
   95                         break;
   96                 rtwn_delay(sc, 10);
   97         }
   98         if (ntries == 5000) {
   99                 device_printf(sc->sc_dev,
  100                     "timeout waiting for chip autoload\n");
  101                 return (ETIMEDOUT);
  102         }
  103 
  104         /* Unlock ISO/CLK/Power control register. */
  105         RTWN_CHK(rtwn_write_1(sc, R92C_RSV_CTRL, 0));
  106 
  107         /* Move SPS into PWM mode. */
  108         RTWN_CHK(rtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b));
  109 
  110         /* just in case if power_off() was not properly executed. */
  111         rtwn_delay(sc, 100);
  112 
  113         reg = rtwn_read_1(sc, R92C_LDOV12D_CTRL);
  114         if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) {
  115                 RTWN_CHK(rtwn_write_1(sc, R92C_LDOV12D_CTRL,
  116                     reg | R92C_LDOV12D_CTRL_LDV12_EN));
  117 
  118                 rtwn_delay(sc, 100);
  119 
  120                 RTWN_CHK(rtwn_setbits_1(sc, R92C_SYS_ISO_CTRL,
  121                     R92C_SYS_ISO_CTRL_MD2PP, 0));
  122         }
  123 
  124         /* Auto enable WLAN. */
  125         RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0,
  126             R92C_APS_FSMCO_APFM_ONMAC, 1));
  127 
  128         for (ntries = 0; ntries < 5000; ntries++) {
  129                 if (!(rtwn_read_2(sc, R92C_APS_FSMCO) &
  130                     R92C_APS_FSMCO_APFM_ONMAC))
  131                         break;
  132                 rtwn_delay(sc, 10);
  133         }
  134         if (ntries == 5000) {
  135                 device_printf(sc->sc_dev,
  136                     "timeout waiting for MAC auto ON\n");
  137                 return (ETIMEDOUT);
  138         }
  139 
  140         /* Enable radio, GPIO and LED functions. */
  141         RTWN_CHK(rtwn_write_2(sc, R92C_APS_FSMCO,
  142             R92C_APS_FSMCO_AFSM_HSUS |
  143             R92C_APS_FSMCO_PDN_EN |
  144             R92C_APS_FSMCO_PFM_ALDN));
  145 
  146         /* Release RF digital isolation. */
  147         RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_SYS_ISO_CTRL,
  148             R92C_SYS_ISO_CTRL_DIOR, 0, 1));
  149 
  150         /* Initialize MAC. */
  151         RTWN_CHK(rtwn_setbits_1(sc, R92C_APSD_CTRL,
  152             R92C_APSD_CTRL_OFF, 0));
  153         for (ntries = 0; ntries < 1000; ntries++) {
  154                 if (!(rtwn_read_1(sc, R92C_APSD_CTRL) &
  155                     R92C_APSD_CTRL_OFF_STATUS))
  156                         break;
  157                 rtwn_delay(sc, 50);
  158         }
  159         if (ntries == 1000) {
  160                 device_printf(sc->sc_dev,
  161                     "timeout waiting for MAC initialization\n");
  162                 return (ETIMEDOUT);
  163         }
  164 
  165         /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
  166         RTWN_CHK(rtwn_setbits_2(sc, R92C_CR, 0,
  167             R92C_CR_HCI_TXDMA_EN | R92C_CR_TXDMA_EN |
  168             R92C_CR_HCI_RXDMA_EN | R92C_CR_RXDMA_EN |
  169             R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN |
  170             ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) |
  171             R92C_CR_CALTMR_EN));
  172 
  173         RTWN_CHK(rtwn_write_1(sc, 0xfe10, 0x19));
  174 
  175         return (0);
  176 #undef RTWN_CHK
  177 }
  178 
  179 void
  180 r92cu_power_off(struct rtwn_softc *sc)
  181 {
  182 #ifndef RTWN_WITHOUT_UCODE
  183         struct r92c_softc *rs = sc->sc_priv;
  184 #endif
  185         uint32_t reg;
  186         int error;
  187 
  188         /* Deinit C2H event handler. */
  189 #ifndef RTWN_WITHOUT_UCODE
  190         callout_stop(&rs->rs_c2h_report);
  191         rs->rs_c2h_paused = 0;
  192         rs->rs_c2h_pending = 0;
  193         rs->rs_c2h_timeout = hz;
  194 #endif
  195 
  196         /* Block all Tx queues. */
  197         error = rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
  198         if (error == ENXIO)     /* hardware gone */
  199                 return;
  200 
  201         /* Disable RF */
  202         rtwn_rf_write(sc, 0, 0, 0);
  203 
  204         rtwn_write_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF);
  205 
  206         /* Reset BB state machine */
  207         rtwn_write_1(sc, R92C_SYS_FUNC_EN,
  208             R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA |
  209             R92C_SYS_FUNC_EN_BB_GLB_RST);
  210         rtwn_write_1(sc, R92C_SYS_FUNC_EN,
  211             R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA);
  212 
  213         /*
  214          * Reset digital sequence
  215          */
  216 #ifndef RTWN_WITHOUT_UCODE
  217         if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) {
  218                 /* Reset MCU ready status */
  219                 rtwn_write_1(sc, R92C_MCUFWDL, 0);
  220 
  221                 /* If firmware in ram code, do reset */
  222                 r92c_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
  223         }
  224 #endif
  225 
  226         /* Reset MAC and Enable 8051 */
  227         rtwn_write_1(sc, R92C_SYS_FUNC_EN + 1,
  228             (R92C_SYS_FUNC_EN_CPUEN |
  229              R92C_SYS_FUNC_EN_ELDR |
  230              R92C_SYS_FUNC_EN_HWPDN) >> 8);
  231 
  232         /* Reset MCU ready status */
  233         rtwn_write_1(sc, R92C_MCUFWDL, 0);
  234 
  235         /* Disable MAC clock */
  236         rtwn_write_2(sc, R92C_SYS_CLKR,
  237             R92C_SYS_CLKR_ANAD16V_EN |
  238             R92C_SYS_CLKR_ANA8M |
  239             R92C_SYS_CLKR_LOADER_EN |
  240             R92C_SYS_CLKR_80M_SSC_DIS |
  241             R92C_SYS_CLKR_SYS_EN |
  242             R92C_SYS_CLKR_RING_EN |
  243             0x4000);
  244 
  245         /* Disable AFE PLL */
  246         rtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x80);
  247 
  248         /* Gated AFE DIG_CLOCK */
  249         rtwn_write_2(sc, R92C_AFE_XTAL_CTRL, 0x880F);
  250 
  251         /* Isolated digital to PON */
  252         rtwn_write_1(sc, R92C_SYS_ISO_CTRL,
  253             R92C_SYS_ISO_CTRL_MD2PP |
  254             R92C_SYS_ISO_CTRL_PA2PCIE |
  255             R92C_SYS_ISO_CTRL_PD2CORE |
  256             R92C_SYS_ISO_CTRL_IP2MAC |
  257             R92C_SYS_ISO_CTRL_DIOP |
  258             R92C_SYS_ISO_CTRL_DIOE);
  259 
  260         /*
  261          * Pull GPIO PIN to balance level and LED control
  262          */
  263         /* 1. Disable GPIO[7:0] */
  264         rtwn_write_2(sc, R92C_GPIO_IOSEL, 0x0000);
  265 
  266         reg = rtwn_read_4(sc, R92C_GPIO_PIN_CTRL) & ~0x0000ff00;
  267         reg |= ((reg << 8) & 0x0000ff00) | 0x00ff0000;
  268         rtwn_write_4(sc, R92C_GPIO_PIN_CTRL, reg);
  269 
  270         /* Disable GPIO[10:8] */
  271         rtwn_write_1(sc, R92C_MAC_PINMUX_CFG, 0x00);
  272 
  273         reg = rtwn_read_2(sc, R92C_GPIO_IO_SEL) & ~0x00f0;
  274         reg |= (((reg & 0x000f) << 4) | 0x0780);
  275         rtwn_write_2(sc, R92C_GPIO_IO_SEL, reg);
  276 
  277         /* Disable LED0 & 1 */
  278         rtwn_write_2(sc, R92C_LEDCFG0, 0x8080);
  279 
  280         /*
  281          * Reset digital sequence
  282          */
  283         /* Disable ELDR clock */
  284         rtwn_write_2(sc, R92C_SYS_CLKR,
  285             R92C_SYS_CLKR_ANAD16V_EN |
  286             R92C_SYS_CLKR_ANA8M |
  287             R92C_SYS_CLKR_LOADER_EN |
  288             R92C_SYS_CLKR_80M_SSC_DIS |
  289             R92C_SYS_CLKR_SYS_EN |
  290             R92C_SYS_CLKR_RING_EN |
  291             0x4000);
  292 
  293         /* Isolated ELDR to PON */
  294         rtwn_write_1(sc, R92C_SYS_ISO_CTRL + 1,
  295             (R92C_SYS_ISO_CTRL_DIOR |
  296              R92C_SYS_ISO_CTRL_PWC_EV12V) >> 8);
  297 
  298         /*
  299          * Disable analog sequence
  300          */
  301         /* Disable A15 power */
  302         rtwn_write_1(sc, R92C_LDOA15_CTRL, R92C_LDOA15_CTRL_OBUF);
  303         /* Disable digital core power */
  304         rtwn_setbits_1(sc, R92C_LDOV12D_CTRL,
  305             R92C_LDOV12D_CTRL_LDV12_EN, 0);
  306 
  307         /* Enter PFM mode */
  308         rtwn_write_1(sc, R92C_SPS0_CTRL, 0x23);
  309 
  310         /* Set USB suspend */
  311         rtwn_write_2(sc, R92C_APS_FSMCO,
  312             R92C_APS_FSMCO_APDM_HOST |
  313             R92C_APS_FSMCO_AFSM_HSUS |
  314             R92C_APS_FSMCO_PFM_ALDN);
  315 
  316         /* Lock ISO/CLK/Power control register. */
  317         rtwn_write_1(sc, R92C_RSV_CTRL, 0x0E);
  318 }
  319 
  320 void
  321 r92cu_init_intr(struct rtwn_softc *sc)
  322 {
  323         rtwn_write_4(sc, R92C_HISR, 0xffffffff);
  324         rtwn_write_4(sc, R92C_HIMR, 0xffffffff);
  325 }
  326 
  327 void
  328 r92cu_init_tx_agg(struct rtwn_softc *sc)
  329 {
  330         struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
  331         uint32_t reg;
  332 
  333         reg = rtwn_read_4(sc, R92C_TDECTRL);
  334         reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, uc->tx_agg_desc_num);
  335         rtwn_write_4(sc, R92C_TDECTRL, reg);
  336 }
  337 
  338 void
  339 r92cu_init_rx_agg(struct rtwn_softc *sc)
  340 {
  341 
  342         /* Rx aggregation (DMA & USB). */
  343         rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0,
  344             R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
  345         rtwn_setbits_1(sc, R92C_USB_SPECIAL_OPTION, 0,
  346             R92C_USB_SPECIAL_OPTION_AGG_EN);
  347 
  348         /* XXX dehardcode */
  349         rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
  350         rtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
  351         rtwn_write_1(sc, R92C_USB_AGG_TH, 8);
  352         rtwn_write_1(sc, R92C_USB_AGG_TO, 6);
  353 }
  354 
  355 void
  356 r92cu_post_init(struct rtwn_softc *sc)
  357 {
  358 
  359         rtwn_write_4(sc, R92C_POWER_STATUS, 0x5);
  360 
  361         /* Perform LO and IQ calibrations. */
  362         r92c_iq_calib(sc);
  363         /* Perform LC calibration. */
  364         r92c_lc_calib(sc);
  365 
  366         /* Fix USB interference issue. */
  367         rtwn_write_1(sc, 0xfe40, 0xe0);
  368         rtwn_write_1(sc, 0xfe41, 0x8d);
  369         rtwn_write_1(sc, 0xfe42, 0x80);
  370 
  371         r92c_pa_bias_init(sc);
  372 
  373         /* Fix for lower temperature. */
  374         rtwn_write_1(sc, 0x15, 0xe9);
  375 
  376 #ifndef RTWN_WITHOUT_UCODE
  377         if (sc->sc_flags & RTWN_FW_LOADED) {
  378                 struct r92c_softc *rs = sc->sc_priv;
  379 
  380                 if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
  381                         /* XXX firmware RA does not work yet */
  382                         sc->sc_ratectl = RTWN_RATECTL_NET80211;
  383                 } else
  384                         sc->sc_ratectl = sc->sc_ratectl_sysctl;
  385 
  386                 /* Start C2H event handling. */
  387                 callout_reset(&rs->rs_c2h_report, rs->rs_c2h_timeout,
  388                     r92c_handle_c2h_report, sc);
  389         } else
  390 #endif
  391                 sc->sc_ratectl = RTWN_RATECTL_NONE;
  392 }

Cache object: bd722f2304e7157ae0a15c6c1b43dc4b


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