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/pci/r92ce_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_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
    5  * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
    6  * Copyright (c) 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 <machine/bus.h>
   41 #include <machine/resource.h>
   42 #include <sys/rman.h>
   43 
   44 #include <net/if.h>
   45 #include <net/ethernet.h>
   46 #include <net/if_media.h>
   47 
   48 #include <net80211/ieee80211_var.h>
   49 #include <net80211/ieee80211_radiotap.h>
   50 
   51 #include <dev/rtwn/if_rtwnvar.h>
   52 
   53 #include <dev/rtwn/pci/rtwn_pci_var.h>
   54 
   55 #include <dev/rtwn/rtl8192c/r92c_var.h>
   56 
   57 #include <dev/rtwn/rtl8192c/pci/r92ce.h>
   58 #include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
   59 
   60 void
   61 r92ce_init_intr(struct rtwn_softc *sc)
   62 {
   63         /* Disable interrupts. */
   64         rtwn_write_4(sc, R92C_HISR, 0x00000000);
   65         rtwn_write_4(sc, R92C_HIMR, 0x00000000);
   66 }
   67 
   68 void
   69 r92ce_init_edca(struct rtwn_softc *sc)
   70 {
   71         /* SIFS */
   72         rtwn_write_2(sc, R92C_SPEC_SIFS, 0x1010);
   73         rtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x1010);
   74         rtwn_write_2(sc, R92C_SIFS_CCK, 0x1010);
   75         rtwn_write_2(sc, R92C_SIFS_OFDM, 0x0e0e);
   76         /* TXOP */
   77         rtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
   78         rtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
   79         rtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4322);
   80         rtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3222);
   81 }
   82 
   83 void
   84 r92ce_init_bb(struct rtwn_softc *sc)
   85 {
   86 
   87         /* Enable BB and RF. */
   88         rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0,
   89             R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
   90             R92C_SYS_FUNC_EN_DIO_RF);
   91 
   92         rtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
   93 
   94         rtwn_write_1(sc, R92C_RF_CTRL,
   95             R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
   96 
   97         rtwn_write_1(sc, R92C_SYS_FUNC_EN,
   98             R92C_SYS_FUNC_EN_DIO_PCIE | R92C_SYS_FUNC_EN_PCIEA |
   99             R92C_SYS_FUNC_EN_PPLL | R92C_SYS_FUNC_EN_BB_GLB_RST |
  100             R92C_SYS_FUNC_EN_BBRSTB);
  101 
  102         rtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
  103 
  104         rtwn_setbits_4(sc, R92C_LEDCFG0, 0, 0x00800000);
  105 
  106         r92c_init_bb_common(sc);
  107 }
  108 
  109 int
  110 r92ce_power_on(struct rtwn_softc *sc)
  111 {
  112         struct r92c_softc *rs = sc->sc_priv;
  113         uint32_t reg;
  114         int ntries;
  115 
  116         /* Wait for autoload done bit. */
  117         for (ntries = 0; ntries < 1000; ntries++) {
  118                 if (rtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
  119                         break;
  120                 DELAY(5);
  121         }
  122         if (ntries == 1000) {
  123                 device_printf(sc->sc_dev,
  124                     "timeout waiting for chip autoload\n");
  125                 return (ETIMEDOUT);
  126         }
  127 
  128         /* Unlock ISO/CLK/Power control register. */
  129         rtwn_write_1(sc, R92C_RSV_CTRL, 0);
  130 
  131         if (rs->board_type != R92C_BOARD_TYPE_DONGLE) {
  132                 /* bt coex */
  133                 rtwn_setbits_4(sc, R92C_APS_FSMCO, 0,
  134                     R92C_APS_FSMCO_SOP_ABG |
  135                     R92C_APS_FSMCO_SOP_AMB |
  136                     R92C_APS_FSMCO_XOP_BTCK);
  137         }
  138 
  139         /* Move SPS into PWM mode. */
  140         rtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
  141 
  142         /* Set low byte to 0x0f, leave others unchanged. */
  143         rtwn_write_1(sc, R92C_AFE_XTAL_CTRL, 0x0f);
  144 
  145         /* TODO: check if we need this for 8188CE */
  146         if (rs->board_type != R92C_BOARD_TYPE_DONGLE) {
  147                 /* bt coex */
  148                 /* XXX magic from linux */
  149                 rtwn_setbits_4(sc, R92C_AFE_XTAL_CTRL, 0x024800, 0);
  150         }
  151 
  152         rtwn_setbits_2(sc, R92C_SYS_ISO_CTRL, 0xff00,
  153             R92C_SYS_ISO_CTRL_PWC_EV12V | R92C_SYS_ISO_CTRL_DIOR);
  154 
  155         DELAY(200);
  156 
  157         /* TODO: linux does additional btcoex stuff here */
  158 
  159         /* Auto enable WLAN. */
  160         rtwn_setbits_2(sc, R92C_APS_FSMCO, 0, R92C_APS_FSMCO_APFM_ONMAC);
  161         for (ntries = 0; ntries < 1000; ntries++) {
  162                 if (!(rtwn_read_2(sc, R92C_APS_FSMCO) &
  163                     R92C_APS_FSMCO_APFM_ONMAC))
  164                         break;
  165                 DELAY(5);
  166         }
  167         if (ntries == 1000) {
  168                 device_printf(sc->sc_dev, "timeout waiting for MAC auto ON\n");
  169                 return (ETIMEDOUT);
  170         }
  171 
  172         /* Enable radio, GPIO and LED functions. */
  173         rtwn_write_2(sc, R92C_APS_FSMCO,
  174             R92C_APS_FSMCO_AFSM_PCIE |
  175             R92C_APS_FSMCO_PDN_EN |
  176             R92C_APS_FSMCO_PFM_ALDN);
  177         /* Release RF digital isolation. */
  178         rtwn_setbits_2(sc, R92C_SYS_ISO_CTRL, R92C_SYS_ISO_CTRL_DIOR, 0);
  179 
  180         if (rs->chip & R92C_CHIP_92C)
  181                 rtwn_write_1(sc, R92C_PCIE_CTRL_REG + 3, 0x77);
  182         else
  183                 rtwn_write_1(sc, R92C_PCIE_CTRL_REG + 3, 0x22);
  184 
  185         rtwn_write_4(sc, R92C_INT_MIG, 0);
  186 
  187         if (rs->board_type != R92C_BOARD_TYPE_DONGLE) {
  188                 /* bt coex */
  189                 /* XXX magic from linux */
  190                 rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0x02, 0);
  191         }
  192 
  193         rtwn_setbits_1(sc, R92C_GPIO_MUXCFG, R92C_GPIO_MUXCFG_RFKILL, 0);
  194 
  195         reg = rtwn_read_1(sc, R92C_GPIO_IO_SEL);
  196         if (!(reg & R92C_GPIO_IO_SEL_RFKILL)) {
  197                 device_printf(sc->sc_dev,
  198                     "radio is disabled by hardware switch\n");
  199                 /* XXX how driver will know when radio will be enabled? */
  200                 return (EPERM);
  201         }
  202 
  203         /* Initialize MAC. */
  204         rtwn_setbits_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF, 0);
  205         for (ntries = 0; ntries < 200; ntries++) {
  206                 if (!(rtwn_read_1(sc, R92C_APSD_CTRL) &
  207                     R92C_APSD_CTRL_OFF_STATUS))
  208                         break;
  209                 DELAY(500);
  210         }
  211         if (ntries == 200) {
  212                 device_printf(sc->sc_dev,
  213                     "timeout waiting for MAC initialization\n");
  214                 return (ETIMEDOUT);
  215         }
  216 
  217         /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
  218         rtwn_setbits_2(sc, R92C_CR, 0,
  219             R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
  220             R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
  221             R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
  222             ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0));
  223 
  224         rtwn_write_4(sc, R92C_MCUTST_1, 0x0);
  225 
  226         return (0);
  227 }
  228 
  229 void
  230 r92ce_power_off(struct rtwn_softc *sc)
  231 {
  232 #ifndef RTWN_WITHOUT_UCODE
  233         struct r92c_softc *rs = sc->sc_priv;
  234 
  235         /* Deinit C2H event handler. */
  236         callout_stop(&rs->rs_c2h_report);
  237         rs->rs_c2h_paused = 0;
  238         rs->rs_c2h_pending = 0;
  239         rs->rs_c2h_timeout = hz;
  240 #endif
  241 
  242         /* Stop hardware. */
  243         /* Disable interrupts. */
  244         rtwn_write_4(sc, R92C_HISR, 0);
  245         rtwn_write_4(sc, R92C_HIMR, 0);
  246 
  247         /* Stop hardware. */
  248         rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
  249 
  250         /* Turn off RF. */
  251         rtwn_write_1(sc, R92C_RF_CTRL, 0);
  252 
  253         /* Reset BB state machine */
  254         rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, 0, R92C_SYS_FUNC_EN_BB_GLB_RST);
  255         rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BB_GLB_RST, 0);
  256 
  257         /* Disable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
  258         rtwn_setbits_2(sc, R92C_CR,
  259             R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
  260             R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
  261             R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
  262             R92C_CR_ENSEC,
  263             0);
  264 
  265         /* If firmware in ram code, do reset. */
  266 #ifndef RTWN_WITHOUT_UCODE
  267         if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL)
  268                 r92ce_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
  269 #endif
  270 
  271         /* TODO: linux does additional btcoex stuff here */
  272         rtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0x80); /* linux magic number */
  273         rtwn_write_1(sc, R92C_SPS0_CTRL, 0x23); /* ditto */
  274         rtwn_write_1(sc, R92C_AFE_XTAL_CTRL, 0x0e); /* different with btcoex */
  275         rtwn_write_1(sc, R92C_RSV_CTRL, 0x0e);
  276         rtwn_write_1(sc, R92C_APS_FSMCO, R92C_APS_FSMCO_PDN_EN);
  277 }
  278 
  279 void
  280 r92ce_init_ampdu(struct rtwn_softc *sc)
  281 {
  282 
  283         /* Setup AMPDU aggregation. */
  284         rtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631);  /* MCS7~0 */
  285         rtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
  286 }
  287 
  288 void
  289 r92ce_post_init(struct rtwn_softc *sc)
  290 {
  291         rtwn_write_2(sc, R92C_FWHW_TXQ_CTRL,
  292             0x1f00 | R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW);
  293 
  294         rtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
  295 
  296         /* Perform LO and IQ calibrations. */
  297         r92ce_iq_calib(sc);
  298         /* Perform LC calibration. */
  299         r92c_lc_calib(sc);
  300 
  301         r92c_pa_bias_init(sc);
  302 
  303         /* Fix for lower temperature. */
  304         rtwn_write_1(sc, 0x15, 0xe9);
  305 
  306 #ifndef RTWN_WITHOUT_UCODE
  307         if (sc->sc_flags & RTWN_FW_LOADED) {
  308                 struct r92c_softc *rs = sc->sc_priv;
  309 
  310                 if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
  311                         /* XXX TODO: fix (see comment in r92cu_init.c) */
  312                         sc->sc_ratectl = RTWN_RATECTL_NET80211;
  313                 } else
  314                         sc->sc_ratectl = sc->sc_ratectl_sysctl;
  315 
  316                 /* Start C2H event handling. */
  317                 callout_reset(&rs->rs_c2h_report, rs->rs_c2h_timeout,
  318                     r92c_handle_c2h_report, sc);
  319         } else
  320 #endif
  321                 sc->sc_ratectl = RTWN_RATECTL_NONE;
  322 }

Cache object: 4bb81903e9d9e64109c11e1a164e539c


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