root/dev/pci/if_casvar.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


    1 /*      $OpenBSD: if_casvar.h,v 1.4 2007/04/15 16:31:30 kettenis Exp $  */
    2 
    3 /*
    4  *
    5  * Copyright (C) 2007 Mark Kettenis.
    6  * Copyright (C) 2001 Eduardo Horvath.
    7  * All rights reserved.
    8  *
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR  BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  */
   32 
   33 #ifndef _IF_CASVAR_H
   34 #define _IF_CASVAR_H
   35 
   36 #include <sys/queue.h>
   37 #include <sys/timeout.h>
   38 
   39 /*
   40  * Misc. definitions for Sun Cassini ethernet controllers.
   41  */
   42 
   43 /*
   44  * Preferred page size.  Cassini has a configurable page size, but
   45  * needs at least 8k to handle jumbo frames.  This happens to be the
   46  * default anyway.
   47  */
   48 #define CAS_PAGE_SIZE           8192
   49 
   50 /*
   51  * Transmit descriptor ring size.  This is arbitrary, but allocate
   52  * enough descriptors for 64 pending transmissions and 16 segments
   53  * per packet.
   54  */
   55 #define CAS_NTXSEGS             16
   56 
   57 #define CAS_TXQUEUELEN          64
   58 #define CAS_NTXDESC             (CAS_TXQUEUELEN * CAS_NTXSEGS)
   59 #define CAS_NTXDESC_MASK        (CAS_NTXDESC - 1)
   60 #define CAS_NEXTTX(x)           ((x + 1) & CAS_NTXDESC_MASK)
   61 
   62 struct cas_sxd {
   63         struct mbuf *sd_mbuf;
   64         bus_dmamap_t sd_map;
   65 };
   66 
   67 /*
   68  * Receive descriptor ring size.  We have one Rx buffer per incoming
   69  * packet, so this logic is a little simpler.
   70  */
   71 #define CAS_NRXDESC             128
   72 #define CAS_NRXDESC_MASK        (CAS_NRXDESC - 1)
   73 
   74 /*
   75  * Receive completion ring size.
   76  */
   77 #define CAS_NRXCOMP             256
   78 #define CAS_NRXCOMP_MASK        (CAS_NRXCOMP - 1)
   79 #define CAS_NEXTRX(x)           ((x + 1) & CAS_NRXCOMP_MASK)
   80 
   81 /*
   82  * Control structures are DMA'd to the Cassini chip.  We allocate them in
   83  * a single clump that maps to a single DMA segment to make several things
   84  * easier.
   85  */
   86 struct cas_control_data {
   87         /*
   88          * The transmit descriptors.
   89          */
   90         struct cas_desc ccd_txdescs[CAS_NTXDESC];
   91 
   92         /*
   93          * The receive completions.
   94          */
   95         struct cas_comp ccd_rxcomps[CAS_NRXCOMP];
   96 
   97         /*
   98          * The receive descriptors.
   99          */
  100         struct cas_desc ccd_rxdescs[CAS_NRXDESC];
  101 };
  102 
  103 #define CAS_CDOFF(x)            offsetof(struct cas_control_data, x)
  104 #define CAS_CDTXOFF(x)          CAS_CDOFF(ccd_txdescs[(x)])
  105 #define CAS_CDRXOFF(x)          CAS_CDOFF(ccd_rxdescs[(x)])
  106 #define CAS_CDRXCOFF(x)         CAS_CDOFF(ccd_rxcomps[(x)])
  107 
  108 /*
  109  * Software state for receive jobs.
  110  */
  111 struct cas_rxsoft {
  112         bus_dmamap_t rxs_dmamap;        /* our DMA map */
  113         bus_dma_segment_t rxs_dmaseg;   /* our DMA segment */
  114         caddr_t rxs_kva;
  115 };
  116 
  117 /*
  118  * Software state per device.
  119  */
  120 struct cas_softc {
  121         struct device   sc_dev;         /* generic device information */
  122         struct arpcom   sc_arpcom;      /* ethernet common data */
  123         struct mii_data sc_mii;         /* MII media control */
  124 #define sc_media        sc_mii.mii_media/* shorthand */
  125         struct timeout  sc_tick_ch;     /* tick callout */
  126 
  127         bus_space_tag_t sc_memt;
  128         bus_space_handle_t sc_memh;
  129         void            *sc_ih;
  130 
  131         bus_dma_tag_t   sc_dmatag;      /* bus dma tag */
  132         bus_dmamap_t    sc_dmamap;      /* bus dma handle */
  133         int             sc_burst;       /* DVMA burst size in effect */
  134         int             sc_phys[2];     /* MII instance -> PHY map */
  135 
  136         int             sc_if_flags;
  137 
  138         int             sc_mif_config;  /* Selected MII reg setting */
  139 
  140         /*
  141          * Ring buffer DMA stuff.
  142          */
  143         bus_dma_segment_t sc_cdseg;     /* control data memory */
  144         int             sc_cdnseg;      /* number of segments */
  145         bus_dmamap_t sc_cddmamap;       /* control data DMA map */
  146 #define sc_cddma        sc_cddmamap->dm_segs[0].ds_addr
  147 
  148         /*
  149          * Software state for transmit and receive descriptors.
  150          */
  151         struct cas_sxd sc_txd[CAS_NTXDESC];
  152         u_int32_t sc_tx_cnt, sc_tx_prod, sc_tx_cons;
  153 
  154         struct cas_rxsoft sc_rxsoft[CAS_NRXDESC];
  155 
  156         /*
  157          * Control data structures.
  158          */
  159         struct cas_control_data *sc_control_data;
  160 #define sc_txdescs      sc_control_data->ccd_txdescs
  161 #define sc_rxdescs      sc_control_data->ccd_rxdescs
  162 #define sc_rxcomps      sc_control_data->ccd_rxcomps
  163 
  164         int                     sc_rxptr;               /* next ready RX descriptor/descsoft */
  165         int                     sc_rxfifosize;
  166         int                     sc_rxdptr;
  167 
  168         /* ========== */
  169         int                     sc_inited;
  170         int                     sc_debug;
  171         void                    *sc_sh;         /* shutdownhook cookie */
  172 };
  173 
  174 #define CAS_DMA_READ(v)         letoh64(v)
  175 #define CAS_DMA_WRITE(v)        htole64(v)
  176 
  177 /*
  178  * This macro returns the current media entry for *non-MII* media.
  179  */
  180 #define CAS_CURRENT_MEDIA(sc)                                           \
  181         (IFM_SUBTYPE((sc)->sc_mii.mii_media.ifm_cur->ifm_media) != IFM_AUTO ? \
  182          (sc)->sc_mii.mii_media.ifm_cur : (sc)->sc_nway_active)
  183 
  184 /*
  185  * This macro determines if a change to media-related OPMODE bits requires
  186  * a chip reset.
  187  */
  188 #define CAS_MEDIA_NEEDSRESET(sc, newbits)                               \
  189         (((sc)->sc_opmode & OPMODE_MEDIA_BITS) !=                       \
  190          ((newbits) & OPMODE_MEDIA_BITS))
  191 
  192 #define CAS_CDTXADDR(sc, x)     ((sc)->sc_cddma + CAS_CDTXOFF((x)))
  193 #define CAS_CDRXADDR(sc, x)     ((sc)->sc_cddma + CAS_CDRXOFF((x)))
  194 #define CAS_CDRXCADDR(sc, x)    ((sc)->sc_cddma + CAS_CDRXCOFF((x)))
  195 
  196 #define CAS_CDTXSYNC(sc, x, n, ops)                                     \
  197 do {                                                                    \
  198         int __x, __n;                                                   \
  199                                                                         \
  200         __x = (x);                                                      \
  201         __n = (n);                                                      \
  202                                                                         \
  203         /* If it will wrap around, sync to the end of the ring. */      \
  204         if ((__x + __n) > CAS_NTXDESC) {                                \
  205                 bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap,     \
  206                     CAS_CDTXOFF(__x), sizeof(struct cas_desc) *         \
  207                     (CAS_NTXDESC - __x), (ops));                        \
  208                 __n -= (CAS_NTXDESC - __x);                             \
  209                 __x = 0;                                                \
  210         }                                                               \
  211                                                                         \
  212         /* Now sync whatever is left. */                                \
  213         bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap,             \
  214             CAS_CDTXOFF(__x), sizeof(struct cas_desc) * __n, (ops));    \
  215 } while (0)
  216 
  217 #define CAS_CDRXSYNC(sc, x, ops)                                        \
  218         bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap,             \
  219             CAS_CDRXOFF((x)), sizeof(struct cas_desc), (ops))
  220 
  221 #define CAS_CDRXCSYNC(sc, x, ops)                                       \
  222         bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap,             \
  223             CAS_CDRXCOFF((x)), sizeof(struct cas_desc), (ops))
  224 
  225 #define CAS_INIT_RXDESC(sc, d, s)                                       \
  226 do {                                                                    \
  227         struct cas_rxsoft *__rxs = &sc->sc_rxsoft[(s)];                 \
  228         struct cas_desc *__rxd = &sc->sc_rxdescs[(d)];                  \
  229                                                                         \
  230         __rxd->cd_addr =                                                \
  231             CAS_DMA_WRITE(__rxs->rxs_dmamap->dm_segs[0].ds_addr);       \
  232         __rxd->cd_flags =                                               \
  233             CAS_DMA_WRITE((s));                                         \
  234         CAS_CDRXSYNC((sc), (d), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
  235 } while (0)
  236 
  237 #endif

/* [<][>][^][v][top][bottom][index][help] */