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/pci/rtwn_pci_attach.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) 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 <sys/param.h>
   25 #include <sys/sysctl.h>
   26 #include <sys/lock.h>
   27 #include <sys/mutex.h>
   28 #include <sys/mbuf.h>
   29 #include <sys/kernel.h>
   30 #include <sys/socket.h>
   31 #include <sys/systm.h>
   32 #include <sys/malloc.h>
   33 #include <sys/module.h>
   34 #include <sys/bus.h>
   35 #include <sys/endian.h>
   36 #include <sys/linker.h>
   37 #include <sys/kdb.h>
   38 
   39 #include <machine/bus.h>
   40 #include <machine/resource.h>
   41 #include <sys/rman.h>
   42 
   43 #include <dev/pci/pcireg.h>
   44 #include <dev/pci/pcivar.h>
   45 
   46 #include <net/if.h>
   47 #include <net/ethernet.h>
   48 #include <net/if_media.h>
   49 
   50 #include <net80211/ieee80211_var.h>
   51 
   52 #include <dev/rtwn/if_rtwnreg.h>
   53 #include <dev/rtwn/if_rtwnvar.h>
   54 #include <dev/rtwn/if_rtwn_nop.h>
   55 #include <dev/rtwn/if_rtwn_debug.h>
   56 
   57 #include <dev/rtwn/pci/rtwn_pci_var.h>
   58 
   59 #include <dev/rtwn/pci/rtwn_pci_attach.h>
   60 #include <dev/rtwn/pci/rtwn_pci_reg.h>
   61 #include <dev/rtwn/pci/rtwn_pci_rx.h>
   62 #include <dev/rtwn/pci/rtwn_pci_tx.h>
   63 
   64 #include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
   65 
   66 static device_probe_t   rtwn_pci_probe;
   67 static device_attach_t  rtwn_pci_attach;
   68 static device_detach_t  rtwn_pci_detach;
   69 static device_shutdown_t rtwn_pci_shutdown;
   70 static device_suspend_t rtwn_pci_suspend;
   71 static device_resume_t  rtwn_pci_resume;
   72 
   73 static int      rtwn_pci_alloc_rx_list(struct rtwn_softc *);
   74 static void     rtwn_pci_reset_rx_list(struct rtwn_softc *);
   75 static void     rtwn_pci_free_rx_list(struct rtwn_softc *);
   76 static int      rtwn_pci_alloc_tx_list(struct rtwn_softc *, int);
   77 static void     rtwn_pci_reset_tx_ring_stopped(struct rtwn_softc *, int);
   78 static void     rtwn_pci_reset_beacon_ring(struct rtwn_softc *, int);
   79 static void     rtwn_pci_reset_tx_list(struct rtwn_softc *,
   80                     struct ieee80211vap *, int);
   81 static void     rtwn_pci_free_tx_list(struct rtwn_softc *, int);
   82 static void     rtwn_pci_reset_lists(struct rtwn_softc *,
   83                     struct ieee80211vap *);
   84 static int      rtwn_pci_fw_write_block(struct rtwn_softc *,
   85                     const uint8_t *, uint16_t, int);
   86 static uint16_t rtwn_pci_get_qmap(struct rtwn_softc *);
   87 static void     rtwn_pci_set_desc_addr(struct rtwn_softc *);
   88 static void     rtwn_pci_beacon_update_begin(struct rtwn_softc *,
   89                     struct ieee80211vap *);
   90 static void     rtwn_pci_beacon_update_end(struct rtwn_softc *,
   91                     struct ieee80211vap *);
   92 static void     rtwn_pci_attach_methods(struct rtwn_softc *);
   93 
   94 static const struct rtwn_pci_ident *
   95 rtwn_pci_probe_sub(device_t dev)
   96 {
   97         int i, vendor_id, device_id;
   98 
   99         vendor_id = pci_get_vendor(dev);
  100         device_id = pci_get_device(dev);
  101 
  102         for (i = 0; i < nitems(rtwn_pci_ident_table); i++) {
  103                 if (vendor_id == rtwn_pci_ident_table[i].vendor &&
  104                     device_id == rtwn_pci_ident_table[i].device)
  105                         return (&rtwn_pci_ident_table[i]);
  106         }
  107 
  108         return (NULL);
  109 }
  110 
  111 static int
  112 rtwn_pci_probe(device_t dev)
  113 {
  114         const struct rtwn_pci_ident *ident;
  115 
  116         ident = rtwn_pci_probe_sub(dev);
  117         if (ident != NULL) {
  118                 device_set_desc(dev, ident->name);
  119                 return (BUS_PROBE_DEFAULT);
  120         }
  121         return (ENXIO);
  122 }
  123 
  124 static int
  125 rtwn_pci_alloc_rx_list(struct rtwn_softc *sc)
  126 {
  127         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  128         struct rtwn_rx_ring *rx_ring = &pc->rx_ring;
  129         struct rtwn_rx_data *rx_data;
  130         bus_size_t size;
  131         int i, error;
  132 
  133         /* Allocate Rx descriptors. */
  134         size = sizeof(struct rtwn_rx_stat_pci) * RTWN_PCI_RX_LIST_COUNT;
  135         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
  136             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
  137             size, 1, size, 0, NULL, NULL, &rx_ring->desc_dmat);
  138         if (error != 0) {
  139                 device_printf(sc->sc_dev, "could not create rx desc DMA tag\n");
  140                 goto fail;
  141         }
  142 
  143         error = bus_dmamem_alloc(rx_ring->desc_dmat, (void **)&rx_ring->desc,
  144             BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
  145             &rx_ring->desc_map);
  146         if (error != 0) {
  147                 device_printf(sc->sc_dev, "could not allocate rx desc\n");
  148                 goto fail;
  149         }
  150         error = bus_dmamap_load(rx_ring->desc_dmat, rx_ring->desc_map,
  151             rx_ring->desc, size, rtwn_pci_dma_map_addr, &rx_ring->paddr, 0);
  152         if (error != 0) {
  153                 device_printf(sc->sc_dev, "could not load rx desc DMA map\n");
  154                 goto fail;
  155         }
  156         bus_dmamap_sync(rx_ring->desc_dmat, rx_ring->desc_map,
  157             BUS_DMASYNC_PREWRITE);
  158 
  159         /* Create RX buffer DMA tag. */
  160         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
  161             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
  162             MJUMPAGESIZE, 1, MJUMPAGESIZE, 0, NULL, NULL, &rx_ring->data_dmat);
  163         if (error != 0) {
  164                 device_printf(sc->sc_dev, "could not create rx buf DMA tag\n");
  165                 goto fail;
  166         }
  167 
  168         /* Allocate Rx buffers. */
  169         for (i = 0; i < RTWN_PCI_RX_LIST_COUNT; i++) {
  170                 rx_data = &rx_ring->rx_data[i];
  171                 error = bus_dmamap_create(rx_ring->data_dmat, 0, &rx_data->map);
  172                 if (error != 0) {
  173                         device_printf(sc->sc_dev,
  174                             "could not create rx buf DMA map\n");
  175                         goto fail;
  176                 }
  177 
  178                 rx_data->m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
  179                     MJUMPAGESIZE);
  180                 if (rx_data->m == NULL) {
  181                         device_printf(sc->sc_dev,
  182                             "could not allocate rx mbuf\n");
  183                         error = ENOMEM;
  184                         goto fail;
  185                 }
  186 
  187                 error = bus_dmamap_load(rx_ring->data_dmat, rx_data->map,
  188                     mtod(rx_data->m, void *), MJUMPAGESIZE,
  189                     rtwn_pci_dma_map_addr, &rx_data->paddr, BUS_DMA_NOWAIT);
  190                 if (error != 0) {
  191                         device_printf(sc->sc_dev,
  192                             "could not load rx buf DMA map");
  193                         goto fail;
  194                 }
  195 
  196                 rtwn_pci_setup_rx_desc(pc, &rx_ring->desc[i], rx_data->paddr,
  197                     MJUMPAGESIZE, i);
  198         }
  199         rx_ring->cur = 0;
  200 
  201         return (0);
  202 
  203 fail:
  204         rtwn_pci_free_rx_list(sc);
  205         return (error);
  206 }
  207 
  208 static void
  209 rtwn_pci_reset_rx_list(struct rtwn_softc *sc)
  210 {
  211         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  212         struct rtwn_rx_ring *rx_ring = &pc->rx_ring;
  213         struct rtwn_rx_data *rx_data;
  214         int i;
  215 
  216         for (i = 0; i < RTWN_PCI_RX_LIST_COUNT; i++) {
  217                 rx_data = &rx_ring->rx_data[i];
  218                 rtwn_pci_setup_rx_desc(pc, &rx_ring->desc[i],
  219                     rx_data->paddr, MJUMPAGESIZE, i);
  220         }
  221         rx_ring->cur = 0;
  222 }
  223 
  224 static void
  225 rtwn_pci_free_rx_list(struct rtwn_softc *sc)
  226 {
  227         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  228         struct rtwn_rx_ring *rx_ring = &pc->rx_ring;
  229         struct rtwn_rx_data *rx_data;
  230         int i;
  231 
  232         if (rx_ring->desc_dmat != NULL) {
  233                 if (rx_ring->desc != NULL) {
  234                         bus_dmamap_sync(rx_ring->desc_dmat,
  235                             rx_ring->desc_map,
  236                             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  237                         bus_dmamap_unload(rx_ring->desc_dmat,
  238                             rx_ring->desc_map);
  239                         bus_dmamem_free(rx_ring->desc_dmat, rx_ring->desc,
  240                             rx_ring->desc_map);
  241                         rx_ring->desc = NULL;
  242                 }
  243                 bus_dma_tag_destroy(rx_ring->desc_dmat);
  244                 rx_ring->desc_dmat = NULL;
  245         }
  246 
  247         for (i = 0; i < RTWN_PCI_RX_LIST_COUNT; i++) {
  248                 rx_data = &rx_ring->rx_data[i];
  249 
  250                 if (rx_data->m != NULL) {
  251                         bus_dmamap_sync(rx_ring->data_dmat,
  252                             rx_data->map, BUS_DMASYNC_POSTREAD);
  253                         bus_dmamap_unload(rx_ring->data_dmat, rx_data->map);
  254                         m_freem(rx_data->m);
  255                         rx_data->m = NULL;
  256                 }
  257                 bus_dmamap_destroy(rx_ring->data_dmat, rx_data->map);
  258                 rx_data->map = NULL;
  259         }
  260         if (rx_ring->data_dmat != NULL) {
  261                 bus_dma_tag_destroy(rx_ring->data_dmat);
  262                 rx_ring->data_dmat = NULL;
  263         }
  264 }
  265 
  266 static int
  267 rtwn_pci_alloc_tx_list(struct rtwn_softc *sc, int qid)
  268 {
  269         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  270         struct rtwn_tx_ring *tx_ring = &pc->tx_ring[qid];
  271         bus_size_t size;
  272         int i, error;
  273 
  274         size = sc->txdesc_len * RTWN_PCI_TX_LIST_COUNT;
  275         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), PAGE_SIZE, 0,
  276             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
  277             size, 1, size, 0, NULL, NULL, &tx_ring->desc_dmat);
  278         if (error != 0) {
  279                 device_printf(sc->sc_dev, "could not create tx ring DMA tag\n");
  280                 goto fail;
  281         }
  282 
  283         error = bus_dmamem_alloc(tx_ring->desc_dmat, &tx_ring->desc,
  284             BUS_DMA_NOWAIT | BUS_DMA_ZERO, &tx_ring->desc_map);
  285         if (error != 0) {
  286                 device_printf(sc->sc_dev, "can't map tx ring DMA memory\n");
  287                 goto fail;
  288         }
  289         error = bus_dmamap_load(tx_ring->desc_dmat, tx_ring->desc_map,
  290             tx_ring->desc, size, rtwn_pci_dma_map_addr, &tx_ring->paddr,
  291             BUS_DMA_NOWAIT);
  292         if (error != 0) {
  293                 device_printf(sc->sc_dev, "could not load desc DMA map\n");
  294                 goto fail;
  295         }
  296         bus_dmamap_sync(tx_ring->desc_dmat, tx_ring->desc_map,
  297             BUS_DMASYNC_PREWRITE);
  298 
  299         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
  300             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
  301             MJUMPAGESIZE, 1, MJUMPAGESIZE, 0, NULL, NULL, &tx_ring->data_dmat);
  302         if (error != 0) {
  303                 device_printf(sc->sc_dev, "could not create tx buf DMA tag\n");
  304                 goto fail;
  305         }
  306 
  307         for (i = 0; i < RTWN_PCI_TX_LIST_COUNT; i++) {
  308                 struct rtwn_tx_data *tx_data = &tx_ring->tx_data[i];
  309                 void *tx_desc = (uint8_t *)tx_ring->desc + sc->txdesc_len * i;
  310                 uint32_t next_desc_addr = tx_ring->paddr +
  311                     sc->txdesc_len * ((i + 1) % RTWN_PCI_TX_LIST_COUNT);
  312 
  313                 rtwn_pci_setup_tx_desc(pc, tx_desc, next_desc_addr);
  314 
  315                 error = bus_dmamap_create(tx_ring->data_dmat, 0, &tx_data->map);
  316                 if (error != 0) {
  317                         device_printf(sc->sc_dev,
  318                             "could not create tx buf DMA map\n");
  319                         return (error);
  320                 }
  321                 tx_data->m = NULL;
  322                 tx_data->ni = NULL;
  323         }
  324         return (0);
  325 
  326 fail:
  327         rtwn_pci_free_tx_list(sc, qid);
  328         return (error);
  329 }
  330 
  331 static void
  332 rtwn_pci_reset_tx_ring_stopped(struct rtwn_softc *sc, int qid)
  333 {
  334         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  335         struct rtwn_tx_ring *ring = &pc->tx_ring[qid];
  336         int i;
  337 
  338         for (i = 0; i < RTWN_PCI_TX_LIST_COUNT; i++) {
  339                 struct rtwn_tx_data *data = &ring->tx_data[i];
  340                 void *desc = (uint8_t *)ring->desc + sc->txdesc_len * i;
  341 
  342                 rtwn_pci_copy_tx_desc(pc, desc, NULL);
  343 
  344                 if (data->m != NULL) {
  345                         bus_dmamap_sync(ring->data_dmat, data->map,
  346                             BUS_DMASYNC_POSTWRITE);
  347                         bus_dmamap_unload(ring->data_dmat, data->map);
  348                         m_freem(data->m);
  349                         data->m = NULL;
  350                 }
  351                 if (data->ni != NULL) {
  352                         ieee80211_free_node(data->ni);
  353                         data->ni = NULL;
  354                 }
  355         }
  356 
  357         bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
  358             BUS_DMASYNC_POSTWRITE);
  359 
  360         sc->qfullmsk &= ~(1 << qid);
  361         ring->queued = 0;
  362         ring->last = ring->cur = 0;
  363 }
  364 
  365 /*
  366  * Clear entry 0 (or 1) in the beacon queue (other are not used).
  367  */
  368 static void
  369 rtwn_pci_reset_beacon_ring(struct rtwn_softc *sc, int id)
  370 {
  371         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  372         struct rtwn_tx_ring *ring = &pc->tx_ring[RTWN_PCI_BEACON_QUEUE];
  373         struct rtwn_tx_data *data = &ring->tx_data[id];
  374         struct rtwn_tx_desc_common *txd = (struct rtwn_tx_desc_common *)
  375             ((uint8_t *)ring->desc + id * sc->txdesc_len);
  376 
  377         bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_POSTREAD);
  378         if (txd->flags0 & RTWN_FLAGS0_OWN) {
  379                 /* Clear OWN bit. */
  380                 txd->flags0 &= ~RTWN_FLAGS0_OWN;
  381                 bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
  382                     BUS_DMASYNC_PREWRITE);
  383 
  384                 /* Unload mbuf. */
  385                 bus_dmamap_sync(ring->data_dmat, data->map,
  386                     BUS_DMASYNC_POSTWRITE);
  387                 bus_dmamap_unload(ring->data_dmat, data->map);
  388         }
  389 }
  390 
  391 /*
  392  * Drop stale entries from Tx ring before the vap will be deleted.
  393  * In case if vap is NULL just free everything and reset cur / last pointers.
  394  */
  395 static void
  396 rtwn_pci_reset_tx_list(struct rtwn_softc *sc, struct ieee80211vap *vap,
  397     int qid)
  398 {
  399         int i;
  400 
  401         if (vap == NULL) {
  402                 if (qid != RTWN_PCI_BEACON_QUEUE) {
  403                         /*
  404                          * Device was stopped; just clear all entries.
  405                          */
  406                         rtwn_pci_reset_tx_ring_stopped(sc, qid);
  407                 } else {
  408                         for (i = 0; i < RTWN_PORT_COUNT; i++)
  409                                 rtwn_pci_reset_beacon_ring(sc, i);
  410                 }
  411         } else if (qid == RTWN_PCI_BEACON_QUEUE &&
  412                    (vap->iv_opmode == IEEE80211_M_HOSTAP ||
  413                     vap->iv_opmode == IEEE80211_M_IBSS)) {
  414                 struct rtwn_vap *uvp = RTWN_VAP(vap);
  415 
  416                 rtwn_pci_reset_beacon_ring(sc, uvp->id);
  417         } else {
  418                 struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  419                 struct rtwn_tx_ring *ring = &pc->tx_ring[qid];
  420 
  421                 for (i = 0; i < RTWN_PCI_TX_LIST_COUNT; i++) {
  422                         struct rtwn_tx_data *data = &ring->tx_data[i];
  423                         if (data->ni != NULL && data->ni->ni_vap == vap) {
  424                                 /*
  425                                  * NB: if some vap is still running
  426                                  * rtwn_pci_tx_done() will free the mbuf;
  427                                  * otherwise, rtwn_stop() will reset all rings
  428                                  * after device shutdown.
  429                                  */
  430                                 ieee80211_free_node(data->ni);
  431                                 data->ni = NULL;
  432                         }
  433                 }
  434         }
  435 }
  436 
  437 static void
  438 rtwn_pci_free_tx_list(struct rtwn_softc *sc, int qid)
  439 {
  440         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  441         struct rtwn_tx_ring *tx_ring = &pc->tx_ring[qid];
  442         struct rtwn_tx_data *tx_data;
  443         int i;
  444 
  445         if (tx_ring->desc_dmat != NULL) {
  446                 if (tx_ring->desc != NULL) {
  447                         bus_dmamap_sync(tx_ring->desc_dmat,
  448                             tx_ring->desc_map, BUS_DMASYNC_POSTWRITE);
  449                         bus_dmamap_unload(tx_ring->desc_dmat,
  450                             tx_ring->desc_map);
  451                         bus_dmamem_free(tx_ring->desc_dmat, tx_ring->desc,
  452                             tx_ring->desc_map);
  453                 }
  454                 bus_dma_tag_destroy(tx_ring->desc_dmat);
  455         }
  456 
  457         for (i = 0; i < RTWN_PCI_TX_LIST_COUNT; i++) {
  458                 tx_data = &tx_ring->tx_data[i];
  459 
  460                 if (tx_data->m != NULL) {
  461                         bus_dmamap_sync(tx_ring->data_dmat, tx_data->map,
  462                             BUS_DMASYNC_POSTWRITE);
  463                         bus_dmamap_unload(tx_ring->data_dmat, tx_data->map);
  464                         m_freem(tx_data->m);
  465                         tx_data->m = NULL;
  466                 }
  467         }
  468         if (tx_ring->data_dmat != NULL) {
  469                 bus_dma_tag_destroy(tx_ring->data_dmat);
  470                 tx_ring->data_dmat = NULL;
  471         }
  472 
  473         sc->qfullmsk &= ~(1 << qid);
  474         tx_ring->queued = 0;
  475         tx_ring->last = tx_ring->cur = 0;
  476 }
  477 
  478 static void
  479 rtwn_pci_reset_lists(struct rtwn_softc *sc, struct ieee80211vap *vap)
  480 {
  481         int i;
  482 
  483         for (i = 0; i < RTWN_PCI_NTXQUEUES; i++)
  484                 rtwn_pci_reset_tx_list(sc, vap, i);
  485 
  486         if (vap == NULL) {
  487                 sc->qfullmsk = 0;
  488                 rtwn_pci_reset_rx_list(sc);
  489         }
  490 }
  491 
  492 static int
  493 rtwn_pci_fw_write_block(struct rtwn_softc *sc, const uint8_t *buf,
  494     uint16_t reg, int mlen)
  495 {
  496         int i;
  497 
  498         for (i = 0; i < mlen; i++)
  499                 rtwn_pci_write_1(sc, reg++, buf[i]);
  500 
  501         /* NB: cannot fail */
  502         return (0);
  503 }
  504 
  505 static uint16_t
  506 rtwn_pci_get_qmap(struct rtwn_softc *sc)
  507 {
  508         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  509 
  510         KASSERT(pc->pc_qmap != 0, ("%s: qmap is not set!\n", __func__));
  511 
  512         return (pc->pc_qmap);
  513 }
  514 
  515 static void
  516 rtwn_pci_set_desc_addr(struct rtwn_softc *sc)
  517 {
  518         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
  519 
  520         RTWN_DPRINTF(sc, RTWN_DEBUG_RESET, "%s: addresses:\n"
  521             "bk: %08jX, be: %08jX, vi: %08jX, vo: %08jX\n"
  522             "bcn: %08jX, mgt: %08jX, high: %08jX, rx: %08jX\n",
  523             __func__, (uintmax_t)pc->tx_ring[RTWN_PCI_BK_QUEUE].paddr,
  524             (uintmax_t)pc->tx_ring[RTWN_PCI_BE_QUEUE].paddr,
  525             (uintmax_t)pc->tx_ring[RTWN_PCI_VI_QUEUE].paddr,
  526             (uintmax_t)pc->tx_ring[RTWN_PCI_VO_QUEUE].paddr,
  527             (uintmax_t)pc->tx_ring[RTWN_PCI_BEACON_QUEUE].paddr,
  528             (uintmax_t)pc->tx_ring[RTWN_PCI_MGNT_QUEUE].paddr,
  529             (uintmax_t)pc->tx_ring[RTWN_PCI_HIGH_QUEUE].paddr,
  530             (uintmax_t)pc->rx_ring.paddr);
  531 
  532         /* Set Tx Configuration Register. */
  533         rtwn_pci_write_4(sc, R92C_TCR, pc->tcr);
  534 
  535         /* Configure Tx DMA. */
  536         rtwn_pci_write_4(sc, R92C_BKQ_DESA,
  537             pc->tx_ring[RTWN_PCI_BK_QUEUE].paddr);
  538         rtwn_pci_write_4(sc, R92C_BEQ_DESA,
  539             pc->tx_ring[RTWN_PCI_BE_QUEUE].paddr);
  540         rtwn_pci_write_4(sc, R92C_VIQ_DESA,
  541             pc->tx_ring[RTWN_PCI_VI_QUEUE].paddr);
  542         rtwn_pci_write_4(sc, R92C_VOQ_DESA,
  543             pc->tx_ring[RTWN_PCI_VO_QUEUE].paddr);
  544         rtwn_pci_write_4(sc, R92C_BCNQ_DESA,
  545             pc->tx_ring[RTWN_PCI_BEACON_QUEUE].paddr);
  546         rtwn_pci_write_4(sc, R92C_MGQ_DESA,
  547             pc->tx_ring[RTWN_PCI_MGNT_QUEUE].paddr);
  548         rtwn_pci_write_4(sc, R92C_HQ_DESA,
  549             pc->tx_ring[RTWN_PCI_HIGH_QUEUE].paddr);
  550 
  551         /* Configure Rx DMA. */
  552         rtwn_pci_write_4(sc, R92C_RX_DESA, pc->rx_ring.paddr);
  553 }
  554 
  555 static void
  556 rtwn_pci_beacon_update_begin(struct rtwn_softc *sc, struct ieee80211vap *vap)
  557 {
  558         struct rtwn_vap *rvp = RTWN_VAP(vap);
  559 
  560         RTWN_ASSERT_LOCKED(sc);
  561 
  562         rtwn_beacon_enable(sc, rvp->id, 0);
  563 }
  564 
  565 static void
  566 rtwn_pci_beacon_update_end(struct rtwn_softc *sc, struct ieee80211vap *vap)
  567 {
  568         struct rtwn_vap *rvp = RTWN_VAP(vap);
  569 
  570         RTWN_ASSERT_LOCKED(sc);
  571 
  572         if (rvp->curr_mode != R92C_MSR_NOLINK)
  573                 rtwn_beacon_enable(sc, rvp->id, 1);
  574 }
  575 
  576 static void
  577 rtwn_pci_attach_methods(struct rtwn_softc *sc)
  578 {
  579         sc->sc_write_1          = rtwn_pci_write_1;
  580         sc->sc_write_2          = rtwn_pci_write_2;
  581         sc->sc_write_4          = rtwn_pci_write_4;
  582         sc->sc_read_1           = rtwn_pci_read_1;
  583         sc->sc_read_2           = rtwn_pci_read_2;
  584         sc->sc_read_4           = rtwn_pci_read_4;
  585         sc->sc_delay            = rtwn_pci_delay;
  586         sc->sc_tx_start         = rtwn_pci_tx_start;
  587         sc->sc_reset_lists      = rtwn_pci_reset_lists;
  588         sc->sc_abort_xfers      = rtwn_nop_softc;
  589         sc->sc_fw_write_block   = rtwn_pci_fw_write_block;
  590         sc->sc_get_qmap         = rtwn_pci_get_qmap;
  591         sc->sc_set_desc_addr    = rtwn_pci_set_desc_addr;
  592         sc->sc_drop_incorrect_tx = rtwn_nop_softc;
  593         sc->sc_beacon_update_begin = rtwn_pci_beacon_update_begin;
  594         sc->sc_beacon_update_end = rtwn_pci_beacon_update_end;
  595         sc->sc_beacon_unload    = rtwn_pci_reset_beacon_ring;
  596 
  597         sc->bcn_check_interval  = 25000;
  598 }
  599 
  600 static int
  601 rtwn_pci_attach(device_t dev)
  602 {
  603         const struct rtwn_pci_ident *ident;
  604         struct rtwn_pci_softc *pc = device_get_softc(dev);
  605         struct rtwn_softc *sc = &pc->pc_sc;
  606         struct ieee80211com *ic = &sc->sc_ic;
  607         uint32_t lcsr;
  608         int cap_off, i, error, rid;
  609 
  610         ident = rtwn_pci_probe_sub(dev);
  611         if (ident == NULL)
  612                 return (ENXIO);
  613 
  614         /*
  615          * Get the offset of the PCI Express Capability Structure in PCI
  616          * Configuration Space.
  617          */
  618         error = pci_find_cap(dev, PCIY_EXPRESS, &cap_off);
  619         if (error != 0) {
  620                 device_printf(dev, "PCIe capability structure not found!\n");
  621                 return (error);
  622         }
  623 
  624         /* Enable bus-mastering. */
  625         pci_enable_busmaster(dev);
  626 
  627         rid = PCIR_BAR(2);
  628         pc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
  629             RF_ACTIVE);
  630         if (pc->mem == NULL) {
  631                 device_printf(dev, "can't map mem space\n");
  632                 return (ENOMEM);
  633         }
  634         pc->pc_st = rman_get_bustag(pc->mem);
  635         pc->pc_sh = rman_get_bushandle(pc->mem);
  636 
  637         /* Install interrupt handler. */
  638         rid = 1;
  639         if (pci_alloc_msi(dev, &rid) == 0)
  640                 rid = 1;
  641         else
  642                 rid = 0;
  643         pc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE |
  644             (rid != 0 ? 0 : RF_SHAREABLE));
  645         if (pc->irq == NULL) {
  646                 device_printf(dev, "can't map interrupt\n");
  647                 goto detach;
  648         }
  649 
  650         /* Disable PCIe Active State Power Management (ASPM). */
  651         lcsr = pci_read_config(dev, cap_off + PCIER_LINK_CTL, 4);
  652         lcsr &= ~PCIEM_LINK_CTL_ASPMC;
  653         pci_write_config(dev, cap_off + PCIER_LINK_CTL, lcsr, 4);
  654 
  655         sc->sc_dev = dev;
  656         ic->ic_name = device_get_nameunit(dev);
  657 
  658         /* Need to be initialized early. */
  659         rtwn_sysctlattach(sc);
  660         mtx_init(&sc->sc_mtx, ic->ic_name, MTX_NETWORK_LOCK, MTX_DEF);
  661 
  662         rtwn_pci_attach_methods(sc);
  663         rtwn_pci_attach_private(pc, ident->chip);
  664 
  665         /* Allocate Tx/Rx buffers. */
  666         error = rtwn_pci_alloc_rx_list(sc);
  667         if (error != 0) {
  668                 device_printf(dev,
  669                     "could not allocate Rx buffers, error %d\n",
  670                     error);
  671                 goto detach;
  672         }
  673         for (i = 0; i < RTWN_PCI_NTXQUEUES; i++) {
  674                 error = rtwn_pci_alloc_tx_list(sc, i);
  675                 if (error != 0) {
  676                         device_printf(dev,
  677                             "could not allocate Tx buffers, error %d\n",
  678                             error);
  679                         goto detach;
  680                 }
  681         }
  682 
  683         /* Generic attach. */
  684         error = rtwn_attach(sc);
  685         if (error != 0)
  686                 goto detach;
  687 
  688         /*
  689          * Hook our interrupt after all initialization is complete.
  690          */
  691         error = bus_setup_intr(dev, pc->irq, INTR_TYPE_NET | INTR_MPSAFE,
  692             NULL, rtwn_pci_intr, sc, &pc->pc_ih);
  693         if (error != 0) {
  694                 device_printf(dev, "can't establish interrupt, error %d\n",
  695                     error);
  696                 goto detach;
  697         }
  698 
  699         return (0);
  700 
  701 detach:
  702         rtwn_pci_detach(dev);           /* failure */
  703         return (ENXIO);
  704 }
  705 
  706 static int
  707 rtwn_pci_detach(device_t dev)
  708 {
  709         struct rtwn_pci_softc *pc = device_get_softc(dev);
  710         struct rtwn_softc *sc = &pc->pc_sc;
  711         int i;
  712 
  713         /* Generic detach. */
  714         rtwn_detach(sc);
  715 
  716         /* Uninstall interrupt handler. */
  717         if (pc->irq != NULL) {
  718                 bus_teardown_intr(dev, pc->irq, pc->pc_ih);
  719                 bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(pc->irq),
  720                     pc->irq);
  721                 pci_release_msi(dev);
  722         }
  723 
  724         /* Free Tx/Rx buffers. */
  725         for (i = 0; i < RTWN_PCI_NTXQUEUES; i++)
  726                 rtwn_pci_free_tx_list(sc, i);
  727         rtwn_pci_free_rx_list(sc);
  728 
  729         if (pc->mem != NULL)
  730                 bus_release_resource(dev, SYS_RES_MEMORY,
  731                     rman_get_rid(pc->mem), pc->mem);
  732 
  733         rtwn_detach_private(sc);
  734         mtx_destroy(&sc->sc_mtx);
  735 
  736         return (0);
  737 }
  738 
  739 static int
  740 rtwn_pci_shutdown(device_t self)
  741 {
  742         struct rtwn_pci_softc *pc = device_get_softc(self);
  743 
  744         ieee80211_stop_all(&pc->pc_sc.sc_ic);
  745         return (0);
  746 }
  747 
  748 static int
  749 rtwn_pci_suspend(device_t self)
  750 {
  751         struct rtwn_pci_softc *pc = device_get_softc(self);
  752 
  753         rtwn_suspend(&pc->pc_sc);
  754 
  755         return (0);
  756 }
  757 
  758 static int
  759 rtwn_pci_resume(device_t self)
  760 {
  761         struct rtwn_pci_softc *pc = device_get_softc(self);
  762 
  763         rtwn_resume(&pc->pc_sc);
  764 
  765         return (0);
  766 }
  767 
  768 static device_method_t rtwn_pci_methods[] = {
  769         /* Device interface */
  770         DEVMETHOD(device_probe,         rtwn_pci_probe),
  771         DEVMETHOD(device_attach,        rtwn_pci_attach),
  772         DEVMETHOD(device_detach,        rtwn_pci_detach),
  773         DEVMETHOD(device_shutdown,      rtwn_pci_shutdown),
  774         DEVMETHOD(device_suspend,       rtwn_pci_suspend),
  775         DEVMETHOD(device_resume,        rtwn_pci_resume),
  776 
  777         DEVMETHOD_END
  778 };
  779 
  780 static driver_t rtwn_pci_driver = {
  781         "rtwn",
  782         rtwn_pci_methods,
  783         sizeof(struct rtwn_pci_softc)
  784 };
  785 
  786 DRIVER_MODULE(rtwn_pci, pci, rtwn_pci_driver, NULL, NULL);
  787 MODULE_VERSION(rtwn_pci, 1);
  788 MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, rtwn, rtwn_pci_ident_table,
  789     nitems(rtwn_pci_ident_table));
  790 MODULE_DEPEND(rtwn_pci, pci, 1, 1, 1);
  791 MODULE_DEPEND(rtwn_pci, wlan, 1, 1, 1);
  792 MODULE_DEPEND(rtwn_pci, rtwn, 2, 2, 2);

Cache object: f0cb3c3beafbbee08b4981107681dec1


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