root/dev/ic/atwvar.h

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

INCLUDED FROM


    1 /*      $OpenBSD: atwvar.h,v 1.13 2007/06/07 20:20:15 damien Exp $      */
    2 /*      $NetBSD: atwvar.h,v 1.13 2004/07/23 07:07:55 dyoung Exp $       */
    3 
    4 /*
    5  * Copyright (c) 2003, 2004 The NetBSD Foundation, Inc.  All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by David Young.
    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  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of the author nor the names of any co-contributors
   23  *    may be used to endorse or promote products derived from this software
   24  *    without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY David Young AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL David Young
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   36  * THE POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #ifndef _DEV_IC_ATWVAR_H_
   40 #define _DEV_IC_ATWVAR_H_
   41 
   42 #include <sys/queue.h>
   43 #include <sys/time.h>
   44 #include <sys/timeout.h>
   45 
   46 /*
   47  * Some misc. statics, useful for debugging.
   48  */
   49 struct atw_stats {
   50         u_long          ts_tx_tuf;      /* transmit underflow errors */
   51         u_long          ts_tx_tro;      /* transmit jabber timeouts */
   52         u_long          ts_tx_trt;      /* retry count exceeded */
   53         u_long          ts_tx_tlt;      /* lifetime exceeded */
   54         u_long          ts_tx_sofbr;    /* packet size mismatch */
   55 };
   56 
   57 /*
   58  * Transmit descriptor list size.  This is arbitrary, but allocate
   59  * enough descriptors for 64 pending transmissions and 16 segments
   60  * per packet.  Since a descriptor holds 2 buffer addresses, that's
   61  * 8 descriptors per packet.  This MUST work out to a power of 2.
   62  */
   63 #define ATW_NTXSEGS             16
   64 
   65 #define ATW_TXQUEUELEN  64
   66 #define ATW_NTXDESC             (ATW_TXQUEUELEN * ATW_NTXSEGS)
   67 #define ATW_NTXDESC_MASK        (ATW_NTXDESC - 1)
   68 #define ATW_NEXTTX(x)           ((x + 1) & ATW_NTXDESC_MASK)
   69 
   70 /*
   71  * Receive descriptor list size.  We have one Rx buffer per incoming
   72  * packet, so this logic is a little simpler.
   73  */
   74 #define ATW_NRXDESC             64
   75 #define ATW_NRXDESC_MASK        (ATW_NRXDESC - 1)
   76 #define ATW_NEXTRX(x)           ((x + 1) & ATW_NRXDESC_MASK)
   77 
   78 /*
   79  * Control structures are DMA'd to the ADM8211 chip.  We allocate them in
   80  * a single clump that maps to a single DMA segment to make several things
   81  * easier.
   82  */
   83 struct atw_control_data {
   84         /*
   85          * The transmit descriptors.
   86          */
   87         struct atw_txdesc acd_txdescs[ATW_NTXDESC];
   88 
   89         /*
   90          * The receive descriptors.
   91          */
   92         struct atw_rxdesc acd_rxdescs[ATW_NRXDESC];
   93 };
   94 
   95 #define ATW_CDOFF(x)            offsetof(struct atw_control_data, x)
   96 #define ATW_CDTXOFF(x)  ATW_CDOFF(acd_txdescs[(x)])
   97 #define ATW_CDRXOFF(x)  ATW_CDOFF(acd_rxdescs[(x)])
   98 
   99 struct atw_duration {
  100         uint16_t        d_rts_dur;
  101         uint16_t        d_data_dur;
  102         uint16_t        d_plcp_len;
  103         uint8_t         d_residue;      /* unused octets in time slot */
  104 };
  105 
  106 /*
  107  * Software state for transmit jobs.
  108  */
  109 struct atw_txsoft {
  110         struct mbuf *txs_mbuf;          /* head of our mbuf chain */
  111         bus_dmamap_t txs_dmamap;        /* our DMA map */
  112         int txs_firstdesc;              /* first descriptor in packet */
  113         int txs_lastdesc;               /* last descriptor in packet */
  114         int txs_ndescs;                 /* number of descriptors */
  115         struct atw_duration txs_d0;
  116         struct atw_duration txs_dn;
  117         SIMPLEQ_ENTRY(atw_txsoft) txs_q;
  118 };
  119 
  120 SIMPLEQ_HEAD(atw_txsq, atw_txsoft);
  121 
  122 /*
  123  * Software state for receive jobs.
  124  */
  125 struct atw_rxsoft {
  126         struct mbuf *rxs_mbuf;          /* head of our mbuf chain */
  127         bus_dmamap_t rxs_dmamap;        /* our DMA map */
  128 };
  129 
  130 /*
  131  * Table which describes the transmit threshold mode.  We generally
  132  * start at index 0.  Whenever we get a transmit underrun, we increment
  133  * our index, falling back if we encounter the NULL terminator.
  134  */
  135 struct atw_txthresh_tab {
  136         u_int32_t txth_opmode;          /* OPMODE bits */
  137         const char *txth_name;          /* name of mode */
  138 };
  139 
  140 #define ATW_TXTHRESH_TAB_LO_RATE {                                      \
  141         { ATW_NAR_TR_L64,       "64 bytes" },                           \
  142         { ATW_NAR_TR_L160,      "160 bytes" },                          \
  143         { ATW_NAR_TR_L192,      "192 bytes" },                          \
  144         { ATW_NAR_SF,           "store and forward" },                  \
  145         { 0,                    NULL },                                 \
  146 }
  147 
  148 #define ATW_TXTHRESH_TAB_HI_RATE {                                      \
  149         { ATW_NAR_TR_H96,       "96 bytes" },                           \
  150         { ATW_NAR_TR_H288,      "288 bytes" },                          \
  151         { ATW_NAR_TR_H544,      "544 bytes" },                          \
  152         { ATW_NAR_SF,           "store and forward" },                  \
  153         { 0,                    NULL },                                 \
  154 }
  155 
  156 enum atw_rftype { ATW_RFTYPE_INTERSIL = 0, ATW_RFTYPE_RFMD  = 1,
  157        ATW_RFTYPE_MARVEL = 2 };
  158 
  159 enum atw_bbptype { ATW_BBPTYPE_INTERSIL = 0, ATW_BBPTYPE_RFMD  = 1,
  160        ATW_BBPTYPE_MARVEL = 2, ATW_C_BBPTYPE_RFMD  = 5 };
  161 
  162 /* Radio capture format for ADMtek. */
  163 
  164 #define ATW_RX_RADIOTAP_PRESENT \
  165         ((1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | \
  166          (1 << IEEE80211_RADIOTAP_CHANNEL) | \
  167          (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
  168 
  169 struct atw_rx_radiotap_header {
  170         struct ieee80211_radiotap_header        ar_ihdr;
  171         u_int8_t                                ar_flags;
  172         u_int8_t                                ar_rate;
  173         u_int16_t                               ar_chan_freq;
  174         u_int16_t                               ar_chan_flags;
  175         u_int8_t                                ar_antsignal;
  176 } __packed;
  177 
  178 #define ATW_TX_RADIOTAP_PRESENT ((1 << IEEE80211_RADIOTAP_FLAGS) | \
  179                                  (1 << IEEE80211_RADIOTAP_RATE) | \
  180                                  (1 << IEEE80211_RADIOTAP_CHANNEL))
  181 
  182 struct atw_tx_radiotap_header {
  183         struct ieee80211_radiotap_header        at_ihdr;
  184         u_int8_t                                at_flags;
  185         u_int8_t                                at_rate;
  186         u_int16_t                               at_chan_freq;
  187         u_int16_t                               at_chan_flags;
  188 } __packed;
  189 
  190 enum atw_revision {
  191         ATW_REVISION_AB = 0x11, /* ADM8211A */
  192         ATW_REVISION_AF = 0x15, /* ADM8211A? */
  193         ATW_REVISION_BA = 0x20, /* ADM8211B */
  194         ATW_REVISION_CA = 0x30  /* ADM8211C/CR */
  195 };
  196 
  197 struct atw_softc {
  198         struct device           sc_dev;
  199         struct ieee80211com     sc_ic;
  200         int                     (*sc_enable)(struct atw_softc *);
  201         void                    (*sc_disable)(struct atw_softc *);
  202         void                    (*sc_power)(struct atw_softc *, int);
  203         int                     (*sc_newstate)(struct ieee80211com *,
  204                                         enum ieee80211_state, int);
  205         void                    (*sc_recv_mgmt)(struct ieee80211com *,
  206                                     struct mbuf *, struct ieee80211_node *,
  207                                     int, int, u_int32_t);
  208         struct ieee80211_node   *(*sc_node_alloc)(struct ieee80211com *);
  209         void                    (*sc_node_free)(struct ieee80211com *,
  210                                         struct ieee80211_node *);
  211 
  212         struct atw_stats sc_stats;      /* debugging stats */
  213 
  214         int                     sc_tx_timer;
  215         int                     sc_rescan_timer;
  216 
  217         bus_space_tag_t         sc_st;          /* bus space tag */
  218         bus_space_handle_t      sc_sh;          /* bus space handle */
  219         bus_dma_tag_t           sc_dmat;        /* bus dma tag */
  220         void                    *sc_sdhook;     /* shutdown hook */
  221         void                    *sc_powerhook;  /* power management hook */
  222         u_int32_t               sc_cacheline;   /* cache line size */
  223         u_int32_t               sc_maxburst;    /* maximum burst length */
  224 
  225         const struct atw_txthresh_tab   *sc_txth;
  226         int                             sc_txthresh; /* current tx threshold */
  227 
  228         u_int                   sc_cur_chan;    /* current channel */
  229 
  230         int                     sc_flags;
  231 
  232         u_int16_t               *sc_srom;
  233         u_int16_t               sc_sromsz;
  234 
  235         caddr_t                 sc_radiobpf;
  236 
  237         bus_dma_segment_t       sc_cdseg;       /* control data memory */
  238         int                     sc_cdnseg;      /* number of segments */
  239         bus_dmamap_t            sc_cddmamap;    /* control data DMA map */
  240 #define sc_cddma        sc_cddmamap->dm_segs[0].ds_addr
  241 
  242         /*
  243          * Software state for transmit and receive descriptors.
  244          */
  245         struct atw_txsoft sc_txsoft[ATW_TXQUEUELEN];
  246         struct atw_rxsoft sc_rxsoft[ATW_NRXDESC];
  247 
  248         /*
  249          * Control data structures.
  250          */
  251         struct atw_control_data *sc_control_data;
  252 #define sc_txdescs      sc_control_data->acd_txdescs
  253 #define sc_rxdescs      sc_control_data->acd_rxdescs
  254 #define sc_setup_desc   sc_control_data->acd_setup_desc
  255 
  256         int     sc_txfree;              /* number of free Tx descriptors */
  257         int     sc_txnext;              /* next ready Tx descriptor */
  258         int     sc_ntxsegs;             /* number of transmit segs per pkt */
  259 
  260         struct atw_txsq sc_txfreeq;     /* free Tx descsofts */
  261         struct atw_txsq sc_txdirtyq;    /* dirty Tx descsofts */
  262 
  263         int     sc_rxptr;               /* next ready RX descriptor/descsoft */
  264 
  265         u_int32_t       sc_busmode;     /* copy of ATW_PAR */
  266         u_int32_t       sc_opmode;      /* copy of ATW_NAR */
  267         u_int32_t       sc_inten;       /* copy of ATW_IER */
  268         u_int32_t       sc_wepctl;      /* copy of ATW_WEPCTL */
  269 
  270         u_int32_t       sc_rxint_mask;  /* mask of Rx interrupts we want */
  271         u_int32_t       sc_txint_mask;  /* mask of Tx interrupts we want */
  272         u_int32_t       sc_linkint_mask;/* link-state interrupts mask */
  273 
  274         enum atw_rftype         sc_rftype;
  275         enum atw_bbptype        sc_bbptype;
  276         u_int32_t       sc_synctl_rd;
  277         u_int32_t       sc_synctl_wr;
  278         u_int32_t       sc_bbpctl_rd;
  279         u_int32_t       sc_bbpctl_wr;
  280 
  281         void            (*sc_recv_beacon)(struct ieee80211com *, struct mbuf *,
  282                             int, u_int32_t);
  283         void            (*sc_recv_prresp)(struct ieee80211com *, struct mbuf *,
  284                             int, u_int32_t);
  285 
  286         /* ADM8211 state variables. */
  287         u_int8_t        sc_sram[ATW_SRAM_MAXSIZE];
  288         u_int           sc_sramlen;
  289         u_int8_t        sc_bssid[IEEE80211_ADDR_LEN];
  290         u_int8_t        sc_rev;
  291         u_int8_t        sc_rf3000_options1;
  292         u_int8_t        sc_rf3000_options2;
  293 
  294         struct timeval  sc_last_beacon;
  295         struct timeout  sc_scan_to;
  296         union {
  297                 struct atw_rx_radiotap_header   tap;
  298                 u_int8_t                        pad[64];
  299         } sc_rxtapu;
  300         union {
  301                 struct atw_tx_radiotap_header   tap;
  302                 u_int8_t                        pad[64];
  303         } sc_txtapu;
  304 };
  305 
  306 #define sc_rxtap        sc_rxtapu.tap
  307 #define sc_txtap        sc_txtapu.tap
  308 
  309 #define sc_if                   sc_ic.ic_if
  310 
  311 /* XXX this is fragile. try not to introduce any u_int32_t's. */
  312 struct atw_frame {
  313 /*00*/  u_int8_t                        atw_dst[IEEE80211_ADDR_LEN];
  314 /*06*/  u_int8_t                        atw_rate;       /* TX rate in 100Kbps */
  315 /*07*/  u_int8_t                        atw_service;    /* 0 */
  316 /*08*/  u_int16_t                       atw_paylen;     /* payload length */
  317 /*0a*/  u_int8_t                        atw_fc[2];      /* 802.11 Frame
  318                                                          * Control
  319                                                          */
  320         /* 802.11 PLCP Length for first & last fragment */
  321 /*0c*/  u_int16_t                       atw_tail_plcplen;
  322 /*0e*/  u_int16_t                       atw_head_plcplen;
  323         /* 802.11 Duration for first & last fragment */
  324 /*10*/  u_int16_t                       atw_tail_dur;
  325 /*12*/  u_int16_t                       atw_head_dur;
  326 /*14*/  u_int8_t                        atw_addr4[IEEE80211_ADDR_LEN];
  327         union {
  328                 struct {
  329 /*1a*/                  u_int16_t       hdrctl; /*transmission control*/
  330 /*1c*/                  u_int16_t       fragthr;/* fragmentation threshold
  331                                                  * [0:11], zero [12:15].
  332                                                  */
  333 /*1e*/                  u_int8_t        fragnum;/* fragment number [4:7],
  334                                                  * zero [0:3].
  335                                                  */
  336 /*1f*/                  u_int8_t        rtylmt; /* retry limit */
  337 /*20*/                  u_int8_t        wepkey0[4];/* ??? */
  338 /*24*/                  u_int8_t        wepkey1[4];/* ??? */
  339 /*28*/                  u_int8_t        wepkey2[4];/* ??? */
  340 /*2c*/                  u_int8_t        wepkey3[4];/* ??? */
  341 /*30*/                  u_int8_t        keyid;
  342 /*31*/                  u_int8_t        reserved0[7];
  343                 } s1;
  344                 struct {
  345                         u_int8_t                pad[6];
  346                         struct ieee80211_frame  ihdr;
  347                 } s2;
  348         } u;
  349 } __attribute__((__packed__));
  350 
  351 #define atw_hdrctl      u.s1.hdrctl
  352 #define atw_fragthr     u.s1.fragthr
  353 #define atw_fragnum     u.s1.fragnum
  354 #define atw_rtylmt      u.s1.rtylmt
  355 #define atw_keyid       u.s1.keyid
  356 #define atw_ihdr        u.s2.ihdr
  357 
  358 #define ATW_HDRCTL_SHORT_PREAMBLE       BIT(0)  /* use short preamble */
  359 #define ATW_HDRCTL_RTSCTS               BIT(4)  /* send RTS */
  360 #define ATW_HDRCTL_WEP                  BIT(5)
  361 #define ATW_HDRCTL_UNKNOWN1             BIT(15) /* MAC adds FCS? */
  362 #define ATW_HDRCTL_UNKNOWN2             BIT(8)
  363 
  364 #define ATW_FRAGTHR_FRAGTHR_MASK        BITS(0, 11)
  365 #define ATW_FRAGNUM_FRAGNUM_MASK        BITS(4, 7)
  366 
  367 /* Values for sc_flags. */
  368 #define ATWF_MRL                0x00000010      /* memory read line okay */
  369 #define ATWF_MRM                0x00000020      /* memory read multi okay */
  370 #define ATWF_MWI                0x00000040      /* memory write inval okay */
  371 #define ATWF_SHORT_PREAMBLE     0x00000080      /* short preamble enabled */
  372 #define ATWF_RTSCTS             0x00000100      /* RTS/CTS enabled */
  373 #define ATWF_ATTACHED           0x00000800      /* attach has succeeded */
  374 #define ATWF_ENABLED            0x00001000      /* chip is enabled */
  375 
  376 #define ATW_IS_ENABLED(sc)      ((sc)->sc_flags & ATWF_ENABLED)
  377 
  378 #define ATW_CDTXADDR(sc, x)     ((sc)->sc_cddma + ATW_CDTXOFF((x)))
  379 #define ATW_CDRXADDR(sc, x)     ((sc)->sc_cddma + ATW_CDRXOFF((x)))
  380 
  381 #define ATW_CDTXSYNC(sc, x, n, ops)                                     \
  382 do {                                                                    \
  383         int __x, __n;                                                   \
  384                                                                         \
  385         __x = (x);                                                      \
  386         __n = (n);                                                      \
  387                                                                         \
  388         /* If it will wrap around, sync to the end of the ring. */      \
  389         if ((__x + __n) > ATW_NTXDESC) {                                \
  390                 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,       \
  391                     ATW_CDTXOFF(__x), sizeof(struct atw_txdesc) *       \
  392                     (ATW_NTXDESC - __x), (ops));                        \
  393                 __n -= (ATW_NTXDESC - __x);                             \
  394                 __x = 0;                                                \
  395         }                                                               \
  396                                                                         \
  397         /* Now sync whatever is left. */                                \
  398         bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,               \
  399             ATW_CDTXOFF(__x), sizeof(struct atw_txdesc) * __n, (ops)); \
  400 } while (0)
  401 
  402 #define ATW_CDRXSYNC(sc, x, ops)                                        \
  403         bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,               \
  404             ATW_CDRXOFF((x)), sizeof(struct atw_rxdesc), (ops))
  405 
  406 /*
  407  * Note we rely on MCLBYTES being a power of two.  Because the `length'
  408  * field is only 11 bits, we must subtract 1 from the length to avoid
  409  * having it truncated to 0!
  410  */
  411 #define ATW_INIT_RXDESC(sc, x)                                          \
  412 do {                                                                    \
  413         struct atw_rxsoft *__rxs = &sc->sc_rxsoft[(x)];                 \
  414         struct atw_rxdesc *__rxd = &sc->sc_rxdescs[(x)];                \
  415         struct mbuf *__m = __rxs->rxs_mbuf;                             \
  416                                                                         \
  417         __rxd->ar_buf1 =                                                \
  418             htole32(__rxs->rxs_dmamap->dm_segs[0].ds_addr);             \
  419         __rxd->ar_buf2 =        /* for descriptor chaining */           \
  420             htole32(ATW_CDRXADDR((sc), ATW_NEXTRX((x))));               \
  421         __rxd->ar_ctl =                                                 \
  422             htole32(LSHIFT(((__m->m_ext.ext_size - 1) & ~0x3U),         \
  423                            ATW_RXCTL_RBS1_MASK) |                       \
  424                     0 /* ATW_RXCTL_RCH */ |                             \
  425             ((x) == (ATW_NRXDESC - 1) ? ATW_RXCTL_RER : 0));            \
  426         __rxd->ar_stat = htole32(ATW_RXSTAT_OWN);                       \
  427                                                                         \
  428         ATW_CDRXSYNC((sc), (x),                                         \
  429             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);                  \
  430 } while (0)
  431 
  432 /* country codes from ADM8211 SROM */
  433 #define ATW_COUNTRY_FCC 0               /* USA 1-11 */
  434 #define ATW_COUNTRY_IC 1                /* Canada 1-11 */
  435 #define ATW_COUNTRY_ETSI 2              /* European Union (?) 1-13 */
  436 #define ATW_COUNTRY_SPAIN 3             /* 10-11 */
  437 #define ATW_COUNTRY_FRANCE 4            /* 10-13 */
  438 #define ATW_COUNTRY_MKK 5               /* Japan: 14 */
  439 #define ATW_COUNTRY_MKK2 6              /* Japan: 1-14 */
  440 
  441 /*
  442  * register space access macros
  443  */
  444 #define ATW_READ(sc, reg)                                               \
  445         bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
  446 
  447 #define ATW_WRITE(sc, reg, val)                                 \
  448         bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
  449 
  450 #define ATW_SET(sc, reg, mask)                                  \
  451         ATW_WRITE((sc), (reg), ATW_READ((sc), (reg)) | (mask))
  452 
  453 #define ATW_CLR(sc, reg, mask)                                  \
  454         ATW_WRITE((sc), (reg), ATW_READ((sc), (reg)) & ~(mask))
  455 
  456 #define ATW_ISSET(sc, reg, mask)                                        \
  457         (ATW_READ((sc), (reg)) & (mask))
  458 
  459 void    atw_attach(struct atw_softc *);
  460 int     atw_detach(struct atw_softc *);
  461 int     atw_activate(struct device *, enum devact);
  462 int     atw_intr(void *arg);
  463 int     atw_enable(struct atw_softc *);
  464 void    atw_power(int, void *);
  465 void    atw_shutdown(void *);
  466 
  467 #endif /* _DEV_IC_ATWVAR_H_ */

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