root/dev/pci/if_tht.c

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

DEFINITIONS

This source file includes following definitions.
  1. thtc_lookup
  2. thtc_match
  3. thtc_attach
  4. thtc_print
  5. tht_match
  6. tht_attach
  7. tht_mountroot
  8. tht_intr
  9. tht_ioctl
  10. tht_up
  11. tht_iff
  12. tht_down
  13. tht_start
  14. tht_load_pkt
  15. tht_txf
  16. tht_rxf_fill
  17. tht_rxf_drain
  18. tht_rxd
  19. tht_watchdog
  20. tht_media_change
  21. tht_media_status
  22. tht_fifo_alloc
  23. tht_fifo_free
  24. tht_fifo_readable
  25. tht_fifo_writable
  26. tht_fifo_pre
  27. tht_fifo_read
  28. tht_fifo_write
  29. tht_fifo_write_dmap
  30. tht_fifo_write_pad
  31. tht_fifo_post
  32. tht_lladdr_read
  33. tht_lladdr_write
  34. tht_sw_reset
  35. tht_fw_load
  36. tht_fw_tick
  37. tht_link_state
  38. tht_read
  39. tht_write
  40. tht_write_region
  41. tht_wait_eq
  42. tht_wait_ne
  43. tht_dmamem_alloc
  44. tht_dmamem_free
  45. tht_pkt_alloc
  46. tht_pkt_free
  47. tht_pkt_put
  48. tht_pkt_get
  49. tht_pkt_used

    1 /*      $OpenBSD: if_tht.c,v 1.108 2007/07/22 03:54:15 dlg Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 /*
   20  * Driver for the Tehuti TN30xx multi port 10Gb Ethernet chipsets,
   21  * see http://www.tehutinetworks.net/.
   22  *
   23  * This driver was made possible because Tehuti networks provided
   24  * hardware and documentation. Thanks!
   25  */
   26 
   27 #include "bpfilter.h"
   28 
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/sockio.h>
   32 #include <sys/mbuf.h>
   33 #include <sys/kernel.h>
   34 #include <sys/socket.h>
   35 #include <sys/malloc.h>
   36 #include <sys/device.h>
   37 #include <sys/proc.h>
   38 #include <sys/queue.h>
   39 #include <sys/rwlock.h>
   40 
   41 #include <machine/bus.h>
   42 
   43 #include <dev/pci/pcireg.h>
   44 #include <dev/pci/pcivar.h>
   45 #include <dev/pci/pcidevs.h>
   46 
   47 #include <net/if.h>
   48 #include <net/if_dl.h>
   49 #include <net/if_media.h>
   50 #include <net/if_types.h>
   51 
   52 #if NBPFILTER > 0
   53 #include <net/bpf.h>
   54 #endif
   55 
   56 #ifdef INET
   57 #include <netinet/in.h>
   58 #include <netinet/if_ether.h>
   59 #endif
   60 
   61 #ifdef THT_DEBUG
   62 #define THT_D_FIFO              (1<<0)
   63 #define THT_D_TX                (1<<1)
   64 #define THT_D_RX                (1<<2)
   65 #define THT_D_INTR              (1<<3)
   66 
   67 int thtdebug = THT_D_TX | THT_D_RX | THT_D_INTR;
   68 
   69 #define DPRINTF(l, f...)        do { if (thtdebug & (l)) printf(f); } while (0)
   70 #else
   71 #define DPRINTF(l, f...)
   72 #endif
   73 
   74 /* registers */
   75 
   76 #define THT_PCI_BAR             0x10
   77 
   78 #define _Q(_q)                  ((_q) * 4)
   79 
   80 /* General Configuration */
   81 #define THT_REG_END_SEL         0x5448 /* PCI Endian Select */
   82 #define THT_REG_CLKPLL          0x5000
   83 #define  THT_REG_CLKPLL_PLLLK           (1<<9) /* PLL is locked */
   84 #define  THT_REG_CLKPLL_RSTEND          (1<<8) /* Reset ended */
   85 #define  THT_REG_CLKPLL_TXF_DIS         (1<<3) /* TX Free disabled */
   86 #define  THT_REG_CLKPLL_VNT_STOP        (1<<2) /* VENETO Stop */
   87 #define  THT_REG_CLKPLL_PLLRST          (1<<1) /* PLL Reset */
   88 #define  THT_REG_CLKPLL_SFTRST          (1<<0) /* Software Reset */
   89 /* Descriptors and FIFO Registers */
   90 #define THT_REG_TXT_CFG0(_q)    (0x4040 + _Q(_q)) /* CFG0 TX Task queues */
   91 #define THT_REG_RXF_CFG0(_q)    (0x4050 + _Q(_q)) /* CFG0 RX Free queues */
   92 #define THT_REG_RXD_CFG0(_q)    (0x4060 + _Q(_q)) /* CFG0 RX DSC queues */
   93 #define THT_REG_TXF_CFG0(_q)    (0x4070 + _Q(_q)) /* CFG0 TX Free queues */
   94 #define THT_REG_TXT_CFG1(_q)    (0x4000 + _Q(_q)) /* CFG1 TX Task queues */
   95 #define THT_REG_RXF_CFG1(_q)    (0x4010 + _Q(_q)) /* CFG1 RX Free queues */
   96 #define THT_REG_RXD_CFG1(_q)    (0x4020 + _Q(_q)) /* CFG1 RX DSC queues */
   97 #define THT_REG_TXF_CFG1(_q)    (0x4030 + _Q(_q)) /* CFG1 TX Free queues */
   98 #define THT_REG_TXT_RPTR(_q)    (0x40c0 + _Q(_q)) /* TX Task read ptr */
   99 #define THT_REG_RXF_RPTR(_q)    (0x40d0 + _Q(_q)) /* RX Free read ptr */
  100 #define THT_REG_RXD_RPTR(_q)    (0x40e0 + _Q(_q)) /* RX DSC read ptr */
  101 #define THT_REG_TXF_RPTR(_q)    (0x40f0 + _Q(_q)) /* TX Free read ptr */
  102 #define THT_REG_TXT_WPTR(_q)    (0x4080 + _Q(_q)) /* TX Task write ptr */
  103 #define THT_REG_RXF_WPTR(_q)    (0x4090 + _Q(_q)) /* RX Free write ptr */
  104 #define THT_REG_RXD_WPTR(_q)    (0x40a0 + _Q(_q)) /* RX DSC write ptr */
  105 #define THT_REG_TXF_WPTR(_q)    (0x40b0 + _Q(_q)) /* TX Free write ptr */
  106 #define THT_REG_HTB_ADDR        0x4100 /* HTB Addressing Mechanism enable */
  107 #define THT_REG_HTB_ADDR_HI     0x4110 /* High HTB Address */
  108 #define THT_REG_HTB_ST_TMR      0x3290 /* HTB Timer */
  109 #define THT_REG_RDINTCM(_q)     (0x5120 + _Q(_q)) /* RX DSC Intr Coalescing */
  110 #define  THT_REG_RDINTCM_PKT_TH(_c)     ((_c)<<20) /* pkt count threshold */
  111 #define  THT_REG_RDINTCM_RXF_TH(_c)     ((_c)<<16) /* rxf intr req thresh */
  112 #define  THT_REG_RDINTCM_COAL_RC        (1<<15) /* coalescing timer recharge */
  113 #define  THT_REG_RDINTCM_COAL(_c)       (_c) /* coalescing timer */
  114 #define THT_REG_TDINTCM(_q)     (0x5130 + _Q(_q)) /* TX DSC Intr Coalescing */
  115 #define  THT_REG_TDINTCM_PKT_TH(_c)     ((_c)<<20) /* pkt count threshold */
  116 #define  THT_REG_TDINTCM_COAL_RC        (1<<15) /* coalescing timer recharge */
  117 #define  THT_REG_TDINTCM_COAL(_c)       (_c) /* coalescing timer */
  118 /* 10G Ethernet MAC */
  119 #define THT_REG_10G_REV         0x6000 /* Revision */
  120 #define THT_REG_10G_SCR         0x6004 /* Scratch */
  121 #define THT_REG_10G_CTL         0x6008 /* Control/Status */
  122 #define  THT_REG_10G_CTL_CMD_FRAME_EN   (1<<13) /* cmd frame enable */
  123 #define  THT_REG_10G_CTL_SW_RESET       (1<<12) /* sw reset */
  124 #define  THT_REG_10G_CTL_STATS_AUTO_CLR (1<<11) /* auto clear statistics */
  125 #define  THT_REG_10G_CTL_LOOPBACK       (1<<10) /* enable loopback */
  126 #define  THT_REG_10G_CTL_TX_ADDR_INS    (1<<9) /* set mac on tx */
  127 #define  THT_REG_10G_CTL_PAUSE_IGNORE   (1<<8) /* ignore pause */
  128 #define  THT_REG_10G_CTL_PAUSE_FWD      (1<<7) /* forward pause */
  129 #define  THT_REG_10G_CTL_CRC_FWD        (1<<6) /* crc forward */
  130 #define  THT_REG_10G_CTL_PAD            (1<<5) /* frame padding */
  131 #define  THT_REG_10G_CTL_PROMISC        (1<<4) /* promiscuous mode */
  132 #define  THT_REG_10G_CTL_WAN_MODE       (1<<3) /* WAN mode */
  133 #define  THT_REG_10G_CTL_RX_EN          (1<<1) /* RX enable */
  134 #define  THT_REG_10G_CTL_TX_EN          (1<<0) /* TX enable */
  135 #define THT_REG_10G_FRM_LEN     0x6014 /* Frame Length */
  136 #define THT_REG_10G_PAUSE       0x6018 /* Pause Quanta */
  137 #define THT_REG_10G_RX_SEC      0x601c /* RX Section */
  138 #define THT_REG_10G_TX_SEC      0x6020 /* TX Section */
  139 #define  THT_REG_10G_SEC_AVAIL(_t)      (_t) /* section available thresh*/
  140 #define  THT_REG_10G_SEC_EMPTY(_t)      ((_t)<<16) /* section empty avail */
  141 #define THT_REG_10G_RFIFO_AEF   0x6024 /* RX FIFO Almost Empty/Full */
  142 #define THT_REG_10G_TFIFO_AEF   0x6028 /* TX FIFO Almost Empty/Full */
  143 #define  THT_REG_10G_FIFO_AE(_t)        (_t) /* almost empty */
  144 #define  THT_REG_10G_FIFO_AF(_t)        ((_t)<<16) /* almost full */
  145 #define THT_REG_10G_SM_STAT     0x6030 /* MDIO Status */
  146 #define THT_REG_10G_SM_CMD      0x6034 /* MDIO Command */
  147 #define THT_REG_10G_SM_DAT      0x6038 /* MDIO Data */
  148 #define THT_REG_10G_SM_ADD      0x603c /* MDIO Address */
  149 #define THT_REG_10G_STAT        0x6040 /* Status */
  150 /* Statistic Counters */
  151 /* XXX todo */
  152 /* Status Registers */
  153 #define THT_REG_MAC_LNK_STAT    0x0200 /* Link Status */
  154 #define  THT_REG_MAC_LNK_STAT_DIS       (1<<4) /* Mac Stats read disable */
  155 #define  THT_REG_MAC_LNK_STAT_LINK      (1<<2) /* Link State */
  156 #define  THT_REG_MAC_LNK_STAT_REM_FAULT (1<<1) /* Remote Fault */
  157 #define  THT_REG_MAC_LNK_STAT_LOC_FAULT (1<<0) /* Local Fault */
  158 /* Interrupt Registers */
  159 #define THT_REG_ISR             0x5100 /* Interrupt Status */
  160 #define THT_REG_ISR_LINKCHG(_p)         (1<<(27+(_p))) /* link changed */
  161 #define THT_REG_ISR_GPIO                (1<<26) /* GPIO */
  162 #define THT_REG_ISR_RFRSH               (1<<25) /* DDR Refresh */
  163 #define THT_REG_ISR_SWI                 (1<<23) /* software interrupt */
  164 #define THT_REG_ISR_RXF(_q)             (1<<(19+(_q))) /* rx free fifo */
  165 #define THT_REG_ISR_TXF(_q)             (1<<(15+(_q))) /* tx free fifo */
  166 #define THT_REG_ISR_RXD(_q)             (1<<(11+(_q))) /* rx desc fifo */
  167 #define THT_REG_ISR_TMR(_t)             (1<<(6+(_t))) /* timer */
  168 #define THT_REG_ISR_VNT                 (1<<5) /* optistrata */
  169 #define THT_REG_ISR_RxFL                (1<<4) /* RX Full */
  170 #define THT_REG_ISR_TR                  (1<<2) /* table read */
  171 #define THT_REG_ISR_PCIE_LNK_INT        (1<<1) /* pcie link fail */
  172 #define THT_REG_ISR_GPLE_CLR            (1<<0) /* pcie timeout */
  173 #define THT_FMT_ISR             "\020" "\035LINKCHG1" "\034LINKCHG0" \
  174                                     "\033GPIO" "\032RFRSH" "\030SWI" \
  175                                     "\027RXF3" "\026RXF2" "\025RXF1" \
  176                                     "\024RXF0" "\023TXF3" "\022TXF2" \
  177                                     "\021TXF1" "\020TXF0" "\017RXD3" \
  178                                     "\016RXD2" "\015RXD1" "\014RXD0" \
  179                                     "\012TMR3" "\011TMR2" "\010TMR1" \
  180                                     "\007TMR0" "\006VNT" "\005RxFL" \
  181                                     "\003TR" "\002PCI_LNK_INT" \
  182                                     "\001GPLE_CLR"
  183 #define THT_REG_ISR_GTI         0x5080 /* GTI Interrupt Status */
  184 #define THT_REG_IMR             0x5110 /* Interrupt Mask */
  185 #define THT_REG_IMR_LINKCHG(_p)         (1<<(27+(_p))) /* link changed */
  186 #define THT_REG_IMR_GPIO                (1<<26) /* GPIO */
  187 #define THT_REG_IMR_RFRSH               (1<<25) /* DDR Refresh */
  188 #define THT_REG_IMR_SWI                 (1<<23) /* software interrupt */
  189 #define THT_REG_IMR_RXF(_q)             (1<<(19+(_q))) /* rx free fifo */
  190 #define THT_REG_IMR_TXF(_q)             (1<<(15+(_q))) /* tx free fifo */
  191 #define THT_REG_IMR_RXD(_q)             (1<<(11+(_q))) /* rx desc fifo */
  192 #define THT_REG_IMR_TMR(_t)             (1<<(6+(_t))) /* timer */
  193 #define THT_REG_IMR_VNT                 (1<<5) /* optistrata */
  194 #define THT_REG_IMR_RxFL                (1<<4) /* RX Full */
  195 #define THT_REG_IMR_TR                  (1<<2) /* table read */
  196 #define THT_REG_IMR_PCIE_LNK_INT        (1<<1) /* pcie link fail */
  197 #define THT_REG_IMR_GPLE_CLR            (1<<0) /* pcie timeout */
  198 #define THT_REG_IMR_GTI         0x5090 /* GTI Interrupt Mask */
  199 #define THT_REG_ISR_MSK         0x5140 /* ISR Masked */
  200 /* Global Counters */
  201 /* XXX todo */
  202 /* DDR2 SDRAM Controller Registers */
  203 /* XXX TBD */
  204 /* EEPROM Registers */
  205 /* XXX todo */
  206 /* Init arbitration and status registers */
  207 #define THT_REG_INIT_SEMAPHORE  0x5170 /* Init Semaphore */
  208 #define THT_REG_INIT_STATUS     0x5180 /* Init Status */
  209 /* PCI Credits Registers */
  210 /* XXX todo */
  211 /* TX Arbitration Registers */
  212 #define THT_REG_TXTSK_PR(_q)    (0x41b0 + _Q(_q)) /* TX Queue Priority */
  213 /* RX Part Registers */
  214 #define THT_REG_RX_FLT          0x1240 /* RX Filter Configuration */
  215 #define  THT_REG_RX_FLT_ATXER           (1<<15) /* accept with xfer err */
  216 #define  THT_REG_RX_FLT_ATRM            (1<<14) /* accept with term err */
  217 #define  THT_REG_RX_FLT_AFTSQ           (1<<13) /* accept with fault seq */
  218 #define  THT_REG_RX_FLT_OSEN            (1<<12) /* enable pkts */
  219 #define  THT_REG_RX_FLT_APHER           (1<<11) /* accept with phy err */
  220 #define  THT_REG_RX_FLT_TXFC            (1<<10) /* TX flow control */
  221 #define  THT_REG_RX_FLT_FDA             (1<<8) /* filter direct address */
  222 #define  THT_REG_RX_FLT_AOF             (1<<7) /* accept overflow frame */
  223 #define  THT_REG_RX_FLT_ACF             (1<<6) /* accept control frame */
  224 #define  THT_REG_RX_FLT_ARUNT           (1<<5) /* accept runt */
  225 #define  THT_REG_RX_FLT_ACRC            (1<<4) /* accept crc error */
  226 #define  THT_REG_RX_FLT_AM              (1<<3) /* accept multicast */
  227 #define  THT_REG_RX_FLT_AB              (1<<2) /* accept broadcast */
  228 #define  THT_REG_RX_FLT_PRM_MASK        0x3 /* promiscuous mode */
  229 #define  THT_REG_RX_FLT_PRM_NORMAL      0x0 /* normal mode */
  230 #define  THT_REG_RX_FLT_PRM_ALL         0x1 /* pass all incoming frames */
  231 #define THT_REG_RX_MAX_FRAME    0x12c0 /* Max Frame Size */
  232 #define THT_REG_RX_UNC_MAC0     0x1250 /* MAC Address low word */
  233 #define THT_REG_RX_UNC_MAC1     0x1260 /* MAC Address mid word */
  234 #define THT_REG_RX_UNC_MAC2     0x1270 /* MAC Address high word */
  235 #define THT_REG_RX_MAC_MCST0(_m) (0x1a80 + (_m)*8)
  236 #define THT_REG_RX_MAC_MCST1(_m) (0x1a84 + (_m)*8)
  237 #define  THT_REG_RX_MAC_MCST_CNT        15
  238 #define THT_REG_RX_MCST_HASH    0x1a00 /* imperfect multicast filter hash */
  239 #define  THT_REG_RX_MCST_HASH_SIZE      (256 / NBBY)
  240 /* OptiStrata Debug Registers */
  241 #define THT_REG_VPC             0x2300 /* Program Counter */
  242 #define THT_REG_VLI             0x2310 /* Last Interrupt */
  243 #define THT_REG_VIC             0x2320 /* Interrupts Count */
  244 #define THT_REG_VTMR            0x2330 /* Timer */
  245 #define THT_REG_VGLB            0x2340 /* Global */
  246 /* SW Reset Registers */
  247 #define THT_REG_RST_PRT         0x7000 /* Reset Port */
  248 #define  THT_REG_RST_PRT_ACTIVE         0x1 /* port reset is active */
  249 #define THT_REG_DIS_PRT         0x7010 /* Disable Port */
  250 #define THT_REG_RST_QU_0        0x7020 /* Reset Queue 0 */
  251 #define THT_REG_RST_QU_1        0x7028 /* Reset Queue 1 */
  252 #define THT_REG_DIS_QU_0        0x7030 /* Disable Queue 0 */
  253 #define THT_REG_DIS_QU_1        0x7038 /* Disable Queue 1 */
  254 
  255 #define THT_PORT_SIZE           0x8000
  256 #define THT_PORT_REGION(_p)     ((_p) * THT_PORT_SIZE)
  257 #define THT_NQUEUES             4
  258 
  259 #define THT_FIFO_ALIGN          4096
  260 #define THT_FIFO_SIZE_4k        0x0
  261 #define THT_FIFO_SIZE_8k        0x1
  262 #define THT_FIFO_SIZE_16k       0x2
  263 #define THT_FIFO_SIZE_32k       0x3
  264 #define THT_FIFO_SIZE(_r)       (4096 * (1<<(_r)))
  265 #define THT_FIFO_GAP            8 /* keep 8 bytes between ptrs */
  266 #define THT_FIFO_PTR_MASK       0x00007ff8 /* rptr/wptr mask */
  267 
  268 #define THT_FIFO_DESC_LEN       208 /* a descriptor cant be bigger than this */
  269 
  270 #define THT_IMR_DOWN(_p)        (THT_REG_IMR_LINKCHG(_p))
  271 #define THT_IMR_UP(_p)          (THT_REG_IMR_LINKCHG(_p) | \
  272                                     THT_REG_IMR_RXF(0) | THT_REG_IMR_TXF(0) | \
  273                                     THT_REG_IMR_RXD(0))
  274 
  275 /* hardware structures (we're using the 64 bit variants) */
  276 
  277 /* physical buffer descriptor */
  278 struct tht_pbd {
  279         u_int32_t               addr_lo;
  280         u_int32_t               addr_hi;
  281         u_int32_t               len;
  282 } __packed;
  283 #define THT_PBD_PKTLEN          (64 * 1024)
  284 
  285 /* rx free fifo */
  286 struct tht_rx_free {
  287         u_int16_t               bc; /* buffer count (0:4) */
  288         u_int16_t               type;
  289 
  290         u_int64_t               uid;
  291 
  292         /* followed by a pdb list */
  293 } __packed;
  294 #define THT_RXF_TYPE            1
  295 #define THT_RXF_1ST_PDB_LEN     128
  296 #define THT_RXF_SGL_LEN         ((THT_FIFO_DESC_LEN - \
  297                                     sizeof(struct tht_rx_free)) / \
  298                                     sizeof(struct tht_pbd))
  299 
  300 /* rx descriptor */
  301 struct tht_rx_desc {
  302         u_int32_t               flags;
  303 #define THT_RXD_FLAGS_BC(_f)            ((_f) & 0x1f) /* buffer count */
  304 #define THT_RXD_FLAGS_RXFQ(_f)          (((_f)>>8) & 0x3) /* rxf queue id */
  305 #define THT_RXD_FLAGS_TO                (1<<15)
  306 #define THT_RXD_FLAGS_TYPE(_f)          (((_f)>>16) & 0xf) /* desc type */
  307 #define THT_RXD_FLAGS_OVF               (1<<21) /* overflow error */
  308 #define THT_RXD_FLAGS_RUNT              (1<<22) /* runt error */
  309 #define THT_RXD_FLAGS_CRC               (1<<23) /* crc error */
  310 #define THT_RXD_FLAGS_UDPCS             (1<<24) /* udp checksum error */
  311 #define THT_RXD_FLAGS_TCPCS             (1<<25) /* tcp checksum error */
  312 #define THT_RXD_FLAGS_IPCS              (1<<26) /* ip checksum error */
  313 #define THT_RXD_FLAGS_PKT_ID            0x70000000
  314 #define THT_RXD_FLAGS_PKT_ID_NONIP      0x00000000
  315 #define THT_RXD_FLAGS_PKT_ID_TCP4       0x10000000
  316 #define THT_RXD_FLAGS_PKT_ID_UDP4       0x20000000
  317 #define THT_RXD_FLAGS_PKT_ID_IPV4       0x30000000
  318 #define THT_RXD_FLAGS_PKT_ID_TCP6       0x50000000
  319 #define THT_RXD_FLAGS_PKT_ID_UDP6       0x60000000
  320 #define THT_RXD_FLAGS_PKT_ID_IPV6       0x70000000
  321 #define THT_RXD_FLAGS_VTAG              (1<<31)
  322         u_int16_t               len;
  323         u_int16_t               vlan;
  324 #define THT_RXD_VLAN_ID(_v)             ((_v) & 0xfff)
  325 #define THT_RXD_VLAN_CFI                (1<<12)
  326 #define THT_RXD_VLAN_PRI(_v)            ((_v) & 0x7) >> 13)
  327 
  328         u_int64_t               uid;
  329 } __packed;
  330 #define THT_RXD_TYPE            2
  331 
  332 /* rx decriptor type 3: data chain instruction */
  333 struct tht_rx_desc_dc {
  334         /* preceded by tht_rx_desc */
  335 
  336         u_int16_t               cd_offset;
  337         u_int16_t               flags;
  338 
  339         u_int8_t                data[4];
  340 } __packed;
  341 #define THT_RXD_TYPE_DC         3
  342 
  343 /* rx descriptor type 4: rss (recv side scaling) information */
  344 struct tht_rx_desc_rss {
  345         /* preceded by tht_rx_desc */
  346 
  347         u_int8_t                rss_hft;
  348         u_int8_t                rss_type;
  349         u_int8_t                rss_tcpu;
  350         u_int8_t                reserved;
  351 
  352         u_int32_t               rss_hash;
  353 } __packed;
  354 #define THT_RXD_TYPE_RSS        4
  355 
  356 /* tx task fifo */
  357 struct tht_tx_task {
  358         u_int32_t               flags;
  359 #define THT_TXT_FLAGS_BC(_f)    (_f) /* buffer count */
  360 #define THT_TXT_FLAGS_UDPCS     (1<<5) /* udp checksum */
  361 #define THT_TXT_FLAGS_TCPCS     (1<<6) /* tcp checksum */
  362 #define THT_TXT_FLAGS_IPCS      (1<<7) /* ip checksum */
  363 #define THT_TXT_FLAGS_VTAG      (1<<8) /* insert vlan tag */
  364 #define THT_TXT_FLAGS_LGSND     (1<<9) /* tcp large send enabled */
  365 #define THT_TXT_FLAGS_FRAG      (1<<10) /* ip fragmentation enabled */
  366 #define THT_TXT_FLAGS_CFI       (1<<12) /* canonical format indicator */
  367 #define THT_TXT_FLAGS_PRIO(_f)  ((_f)<<13) /* vlan priority */
  368 #define THT_TXT_FLAGS_VLAN(_f)  ((_f)<<20) /* vlan id */
  369         u_int16_t               mss_mtu;
  370         u_int16_t               len;
  371 
  372         u_int64_t               uid;
  373 
  374         /* followed by a pbd list */
  375 } __packed;
  376 #define THT_TXT_TYPE            (3<<16)
  377 #define THT_TXT_SGL_LEN         ((THT_FIFO_DESC_LEN - \
  378                                     sizeof(struct tht_tx_task)) / \
  379                                     sizeof(struct tht_pbd))
  380 
  381 /* tx free fifo */
  382 struct tht_tx_free {
  383         u_int32_t               status;
  384 
  385         u_int64_t               uid;
  386 
  387         u_int32_t               pad;
  388 } __packed;
  389 
  390 /* pci controller autoconf glue */
  391 
  392 struct thtc_softc {
  393         struct device           sc_dev;
  394 
  395         bus_dma_tag_t           sc_dmat;
  396 
  397         bus_space_tag_t         sc_memt;
  398         bus_space_handle_t      sc_memh;
  399         bus_size_t              sc_mems;
  400 };
  401 
  402 int                     thtc_match(struct device *, void *, void *);
  403 void                    thtc_attach(struct device *, struct device *, void *);
  404 int                     thtc_print(void *, const char *);
  405 
  406 struct cfattach thtc_ca = {
  407         sizeof(struct thtc_softc), thtc_match, thtc_attach
  408 };
  409 
  410 struct cfdriver thtc_cd = {
  411         NULL, "thtc", DV_DULL
  412 };
  413 
  414 /* glue between the controller and the port */
  415 
  416 struct tht_attach_args {
  417         int                     taa_port;
  418 
  419         struct pci_attach_args  *taa_pa;
  420         pci_intr_handle_t       taa_ih;
  421 };
  422 
  423 /* tht itself */
  424 
  425 struct tht_dmamem {
  426         bus_dmamap_t            tdm_map;
  427         bus_dma_segment_t       tdm_seg;
  428         size_t                  tdm_size;
  429         caddr_t                 tdm_kva;
  430 };
  431 #define THT_DMA_MAP(_tdm)       ((_tdm)->tdm_map)
  432 #define THT_DMA_DVA(_tdm)       ((_tdm)->tdm_map->dm_segs[0].ds_addr)
  433 #define THT_DMA_KVA(_tdm)       ((void *)(_tdm)->tdm_kva)
  434 
  435 struct tht_fifo_desc {
  436         bus_size_t              tfd_cfg0;
  437         bus_size_t              tfd_cfg1;
  438         bus_size_t              tfd_rptr;
  439         bus_size_t              tfd_wptr;
  440         u_int32_t               tfd_size;
  441         int                     tfd_write;
  442 };
  443 #define THT_FIFO_PRE_SYNC(_d)   ((_d)->tfd_write ? \
  444                                     BUS_DMASYNC_PREWRITE : \
  445                                     BUS_DMASYNC_PREREAD)
  446 #define THT_FIFO_POST_SYNC(_d)  ((_d)->tfd_write ? \
  447                                     BUS_DMASYNC_POSTWRITE : \
  448                                     BUS_DMASYNC_POSTREAD)
  449 
  450 struct tht_fifo {
  451         struct tht_fifo_desc    *tf_desc;
  452         struct tht_dmamem       *tf_mem;
  453         int                     tf_len;
  454         int                     tf_rptr;
  455         int                     tf_wptr;
  456         int                     tf_ready;
  457 };
  458 
  459 struct tht_pkt {
  460         u_int64_t               tp_id;
  461 
  462         bus_dmamap_t            tp_dmap;
  463         struct mbuf             *tp_m;
  464 
  465         TAILQ_ENTRY(tht_pkt)    tp_link;
  466 };
  467 
  468 struct tht_pkt_list {
  469         struct tht_pkt          *tpl_pkts;
  470         TAILQ_HEAD(, tht_pkt)   tpl_free;
  471         TAILQ_HEAD(, tht_pkt)   tpl_used;
  472 };
  473 
  474 struct tht_softc {
  475         struct device           sc_dev;
  476         struct thtc_softc       *sc_thtc;
  477         int                     sc_port;
  478 
  479         void                    *sc_ih;
  480 
  481         bus_space_handle_t      sc_memh;
  482 
  483         struct arpcom           sc_ac;
  484         struct ifmedia          sc_media;
  485 
  486         u_int16_t               sc_lladdr[3];
  487 
  488         struct tht_pkt_list     sc_tx_list;
  489         struct tht_pkt_list     sc_rx_list;
  490 
  491         struct tht_fifo         sc_txt;
  492         struct tht_fifo         sc_rxf;
  493         struct tht_fifo         sc_rxd;
  494         struct tht_fifo         sc_txf;
  495 
  496         u_int32_t               sc_imr;
  497 
  498         struct rwlock           sc_lock;
  499 };
  500 
  501 int                     tht_match(struct device *, void *, void *);
  502 void                    tht_attach(struct device *, struct device *, void *);
  503 void                    tht_mountroot(void *);
  504 int                     tht_intr(void *);
  505 
  506 struct cfattach tht_ca = {
  507         sizeof(struct tht_softc), tht_match, tht_attach
  508 };
  509 
  510 struct cfdriver tht_cd = {
  511         NULL, "tht", DV_IFNET
  512 };
  513 
  514 /* pkts */
  515 int                     tht_pkt_alloc(struct tht_softc *,
  516                             struct tht_pkt_list *, int, int);
  517 void                    tht_pkt_free(struct tht_softc *,
  518                             struct tht_pkt_list *);
  519 void                    tht_pkt_put(struct tht_pkt_list *, struct tht_pkt *);
  520 struct tht_pkt          *tht_pkt_get(struct tht_pkt_list *);
  521 struct tht_pkt          *tht_pkt_used(struct tht_pkt_list *);
  522 
  523 /* fifos */
  524 
  525 struct tht_fifo_desc tht_txt_desc = {
  526         THT_REG_TXT_CFG0(0),
  527         THT_REG_TXT_CFG1(0),
  528         THT_REG_TXT_RPTR(0),
  529         THT_REG_TXT_WPTR(0),
  530         THT_FIFO_SIZE_16k,
  531         1
  532 };
  533 
  534 struct tht_fifo_desc tht_rxf_desc = {
  535         THT_REG_RXF_CFG0(0),
  536         THT_REG_RXF_CFG1(0),
  537         THT_REG_RXF_RPTR(0),
  538         THT_REG_RXF_WPTR(0),
  539         THT_FIFO_SIZE_16k,
  540         1
  541 };
  542 
  543 struct tht_fifo_desc tht_rxd_desc = {
  544         THT_REG_RXD_CFG0(0),
  545         THT_REG_RXD_CFG1(0),
  546         THT_REG_RXD_RPTR(0),
  547         THT_REG_RXD_WPTR(0),
  548         THT_FIFO_SIZE_16k,
  549         0
  550 };
  551 
  552 struct tht_fifo_desc tht_txf_desc = {
  553         THT_REG_TXF_CFG0(0),
  554         THT_REG_TXF_CFG1(0),
  555         THT_REG_TXF_RPTR(0),
  556         THT_REG_TXF_WPTR(0),
  557         THT_FIFO_SIZE_4k,
  558         0
  559 };
  560 
  561 int                     tht_fifo_alloc(struct tht_softc *, struct tht_fifo *,
  562                             struct tht_fifo_desc *);
  563 void                    tht_fifo_free(struct tht_softc *, struct tht_fifo *);
  564 
  565 size_t                  tht_fifo_readable(struct tht_softc *,
  566                             struct tht_fifo *);
  567 size_t                  tht_fifo_writable(struct tht_softc *,
  568                             struct tht_fifo *);
  569 void                    tht_fifo_pre(struct tht_softc *,
  570                             struct tht_fifo *);
  571 void                    tht_fifo_read(struct tht_softc *, struct tht_fifo *,
  572                             void *, size_t);
  573 void                    tht_fifo_write(struct tht_softc *, struct tht_fifo *,
  574                             void *, size_t);
  575 void                    tht_fifo_write_dmap(struct tht_softc *,
  576                             struct tht_fifo *, bus_dmamap_t);
  577 void                    tht_fifo_write_pad(struct tht_softc *,
  578                             struct tht_fifo *, int);
  579 void                    tht_fifo_post(struct tht_softc *,
  580                             struct tht_fifo *);
  581 
  582 /* port operations */
  583 void                    tht_lladdr_read(struct tht_softc *);
  584 void                    tht_lladdr_write(struct tht_softc *);
  585 int                     tht_sw_reset(struct tht_softc *);
  586 int                     tht_fw_load(struct tht_softc *);
  587 void                    tht_fw_tick(void *arg);
  588 void                    tht_link_state(struct tht_softc *);
  589 
  590 /* interface operations */
  591 int                     tht_ioctl(struct ifnet *, u_long, caddr_t);
  592 void                    tht_watchdog(struct ifnet *);
  593 void                    tht_start(struct ifnet *);
  594 int                     tht_load_pkt(struct tht_softc *, struct tht_pkt *,
  595                             struct mbuf *);
  596 void                    tht_txf(struct tht_softc *sc);
  597 
  598 void                    tht_rxf_fill(struct tht_softc *, int);
  599 void                    tht_rxf_drain(struct tht_softc *);
  600 void                    tht_rxd(struct tht_softc *);
  601 
  602 void                    tht_up(struct tht_softc *);
  603 void                    tht_iff(struct tht_softc *);
  604 void                    tht_down(struct tht_softc *);
  605 
  606 /* ifmedia operations */
  607 int                     tht_media_change(struct ifnet *);
  608 void                    tht_media_status(struct ifnet *, struct ifmediareq *);
  609 
  610 /* wrapper around dma memory */
  611 struct tht_dmamem       *tht_dmamem_alloc(struct tht_softc *, bus_size_t,
  612                             bus_size_t);
  613 void                    tht_dmamem_free(struct tht_softc *,
  614                             struct tht_dmamem *);
  615 
  616 /* bus space operations */
  617 u_int32_t               tht_read(struct tht_softc *, bus_size_t);
  618 void                    tht_write(struct tht_softc *, bus_size_t, u_int32_t);
  619 void                    tht_write_region(struct tht_softc *, bus_size_t,
  620                             void *, size_t);
  621 int                     tht_wait_eq(struct tht_softc *, bus_size_t, u_int32_t,
  622                             u_int32_t, int);
  623 int                     tht_wait_ne(struct tht_softc *, bus_size_t, u_int32_t,
  624                             u_int32_t, int);
  625 
  626 #define tht_set(_s, _r, _b)             tht_write((_s), (_r), \
  627                                             tht_read((_s), (_r)) | (_b))
  628 #define tht_clr(_s, _r, _b)             tht_write((_s), (_r), \
  629                                             tht_read((_s), (_r)) & ~(_b))
  630 #define tht_wait_set(_s, _r, _b, _t)    tht_wait_eq((_s), (_r), \
  631                                             (_b), (_b), (_t))
  632 
  633 
  634 /* misc */
  635 #define DEVNAME(_sc)    ((_sc)->sc_dev.dv_xname)
  636 #define sizeofa(_a)     (sizeof(_a) / sizeof((_a)[0]))
  637 #define LWORDS(_b)      (((_b) + 7) >> 3)
  638 
  639 
  640 struct thtc_device {
  641         pci_vendor_id_t         td_vendor;
  642         pci_vendor_id_t         td_product;
  643         u_int                   td_nports;
  644 };
  645 
  646 const struct thtc_device *thtc_lookup(struct pci_attach_args *);
  647 
  648 static const struct thtc_device thtc_devices[] = {
  649         { PCI_VENDOR_TEHUTI,    PCI_PRODUCT_TEHUTI_TN3009, 1 },
  650         { PCI_VENDOR_TEHUTI,    PCI_PRODUCT_TEHUTI_TN3010, 1 },
  651         { PCI_VENDOR_TEHUTI,    PCI_PRODUCT_TEHUTI_TN3014, 2 }
  652 };
  653 
  654 const struct thtc_device *
  655 thtc_lookup(struct pci_attach_args *pa)
  656 {
  657         int                             i;
  658         const struct thtc_device        *td;
  659 
  660         for (i = 0; i < sizeofa(thtc_devices); i++) {
  661                 td = &thtc_devices[i];
  662                 if (td->td_vendor == PCI_VENDOR(pa->pa_id) &&
  663                     td->td_product == PCI_PRODUCT(pa->pa_id))
  664                         return (td);
  665         }
  666 
  667         return (NULL);
  668 }
  669 
  670 int
  671 thtc_match(struct device *parent, void *match, void *aux)
  672 {
  673         struct pci_attach_args          *pa = aux;
  674 
  675         if (thtc_lookup(pa) != NULL)
  676                 return (1);
  677 
  678         return (0);
  679 }
  680 
  681 void
  682 thtc_attach(struct device *parent, struct device *self, void *aux)
  683 {
  684         struct thtc_softc               *sc = (struct thtc_softc *)self;
  685         struct pci_attach_args          *pa = aux;
  686         pcireg_t                        memtype;
  687         const struct thtc_device        *td;
  688         struct tht_attach_args          taa;
  689         int                             i;
  690 
  691         bzero(&taa, sizeof(taa));
  692         td = thtc_lookup(pa);
  693 
  694         sc->sc_dmat = pa->pa_dmat;
  695 
  696         memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, THT_PCI_BAR);
  697         if (pci_mapreg_map(pa, THT_PCI_BAR, memtype, 0, &sc->sc_memt,
  698             &sc->sc_memh, NULL, &sc->sc_mems, 0) != 0) {
  699                 printf(": unable to map host registers\n");
  700                 return;
  701         }
  702 
  703         if (pci_intr_map(pa, &taa.taa_ih) != 0) {
  704                 printf(": unable to map interrupt\n");
  705                 goto unmap;
  706         }
  707         printf(": %s\n", pci_intr_string(pa->pa_pc, taa.taa_ih));
  708 
  709         taa.taa_pa = pa;
  710         for (i = 0; i < td->td_nports; i++) {
  711                 taa.taa_port = i;
  712 
  713                 config_found(self, &taa, thtc_print);
  714         }
  715 
  716         return;
  717 
  718 unmap:
  719         bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
  720         sc->sc_mems = 0;
  721 }
  722 
  723 int
  724 thtc_print(void *aux, const char *pnp)
  725 {
  726         struct tht_attach_args          *taa = aux;
  727 
  728         if (pnp != NULL)
  729                 printf("\"%s\" at %s", tht_cd.cd_name, pnp);
  730 
  731         printf(" port %d", taa->taa_port);
  732 
  733         return (UNCONF);
  734 }
  735 
  736 int
  737 tht_match(struct device *parent, void *match, void *aux)
  738 {
  739         return (1);
  740 }
  741 
  742 void
  743 tht_attach(struct device *parent, struct device *self, void *aux)
  744 {
  745         struct thtc_softc               *csc = (struct thtc_softc *)parent;
  746         struct tht_softc                *sc = (struct tht_softc *)self;
  747         struct tht_attach_args          *taa = aux;
  748         struct ifnet                    *ifp;
  749 
  750         sc->sc_thtc = csc;
  751         sc->sc_port = taa->taa_port;
  752         sc->sc_imr = THT_IMR_DOWN(sc->sc_port);
  753         rw_init(&sc->sc_lock, "thtioc");
  754 
  755         if (bus_space_subregion(csc->sc_memt, csc->sc_memh,
  756             THT_PORT_REGION(sc->sc_port), THT_PORT_SIZE,
  757             &sc->sc_memh) != 0) {
  758                 printf(": unable to map port registers\n");
  759                 return;
  760         }
  761 
  762         if (tht_sw_reset(sc) != 0) {
  763                 printf(": unable to reset port\n");
  764                 /* bus_space(9) says we dont have to free subregions */
  765                 return;
  766         }
  767 
  768         sc->sc_ih = pci_intr_establish(taa->taa_pa->pa_pc, taa->taa_ih,
  769             IPL_NET, tht_intr, sc, DEVNAME(sc));
  770         if (sc->sc_ih == NULL) {
  771                 printf(": unable to establish interrupt\n");
  772                 /* bus_space(9) says we dont have to free subregions */
  773                 return;
  774         }
  775 
  776         tht_lladdr_read(sc);
  777         bcopy(sc->sc_lladdr, sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
  778 
  779         ifp = &sc->sc_ac.ac_if;
  780         ifp->if_softc = sc;
  781         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  782         ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_IPv4 |
  783             IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
  784         ifp->if_ioctl = tht_ioctl;
  785         ifp->if_start = tht_start;
  786         ifp->if_watchdog = tht_watchdog;
  787         ifp->if_hardmtu = MCLBYTES - ETHER_HDR_LEN - ETHER_CRC_LEN; /* XXX */
  788         strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
  789         IFQ_SET_MAXLEN(&ifp->if_snd, 400);
  790         IFQ_SET_READY(&ifp->if_snd);
  791 
  792         ifmedia_init(&sc->sc_media, 0, tht_media_change, tht_media_status);
  793         ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_AUTO, 0, NULL);
  794         ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
  795 
  796         if_attach(ifp);
  797         ether_ifattach(ifp);
  798 
  799         printf(": address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr));
  800 
  801         mountroothook_establish(tht_mountroot, sc);
  802 }
  803 
  804 void
  805 tht_mountroot(void *arg)
  806 {
  807         struct tht_softc                *sc = arg;
  808 
  809         if (tht_fifo_alloc(sc, &sc->sc_txt, &tht_txt_desc) != 0)
  810                 return;
  811 
  812         if (tht_fw_load(sc) != 0)
  813                 printf("%s: firmware load failed\n", DEVNAME(sc));
  814 
  815         tht_sw_reset(sc);
  816 
  817         tht_fifo_free(sc, &sc->sc_txt);
  818 
  819         tht_link_state(sc);
  820         tht_write(sc, THT_REG_IMR, sc->sc_imr);
  821 }
  822 
  823 int
  824 tht_intr(void *arg)
  825 {
  826         struct tht_softc                *sc = arg;
  827         struct ifnet                    *ifp;
  828         u_int32_t                       isr;
  829 
  830         isr = tht_read(sc, THT_REG_ISR);
  831         if (isr == 0x0) {
  832                 tht_write(sc, THT_REG_IMR, sc->sc_imr);
  833                 return (0);
  834         }
  835 
  836         DPRINTF(THT_D_INTR, "%s: isr: 0x%b\n", DEVNAME(sc), isr, THT_FMT_ISR);
  837 
  838         if (ISSET(isr, THT_REG_ISR_LINKCHG(0) | THT_REG_ISR_LINKCHG(1)))
  839                 tht_link_state(sc);
  840 
  841         ifp = &sc->sc_ac.ac_if;
  842         if (ifp->if_flags & IFF_RUNNING) {
  843                 if (ISSET(isr, THT_REG_ISR_RXD(0)))
  844                         tht_rxd(sc);
  845 
  846                 if (ISSET(isr, THT_REG_ISR_RXF(0)))
  847                         tht_rxf_fill(sc, 0);
  848 
  849                 if (ISSET(isr, THT_REG_ISR_TXF(0)))
  850                         tht_txf(sc);
  851 
  852                 tht_start(ifp);
  853         }
  854 
  855         tht_write(sc, THT_REG_IMR, sc->sc_imr);
  856         return (1);
  857 }
  858 
  859 int
  860 tht_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
  861 {
  862         struct tht_softc                *sc = ifp->if_softc;
  863         struct ifreq                    *ifr = (struct ifreq *)addr;
  864         struct ifaddr                   *ifa;
  865         int                             error;
  866         int                             s;
  867 
  868         rw_enter_write(&sc->sc_lock);
  869         s = splnet();
  870 
  871         error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr);
  872         if (error > 0)
  873                 goto err;
  874 
  875         switch (cmd) {
  876         case SIOCSIFADDR:
  877                 ifa = (struct ifaddr *)addr;
  878 
  879 #ifdef INET
  880                 if (ifa->ifa_addr->sa_family == AF_INET)
  881                         arp_ifinit(&sc->sc_ac, ifa);
  882 #endif
  883 
  884                 ifp->if_flags |= IFF_UP;
  885                 /* FALLTHROUGH */
  886         case SIOCSIFFLAGS:
  887                 if (ifp->if_flags & IFF_UP) {
  888                         if (ifp->if_flags & IFF_RUNNING)
  889                                 tht_iff(sc);
  890                         else
  891                                 tht_up(sc);
  892                 } else {
  893                         if (ifp->if_flags & IFF_RUNNING)
  894                                 tht_down(sc);
  895                 }
  896                 break;
  897 
  898         case SIOCSIFMTU:
  899                 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
  900                         error = EINVAL;
  901                 else
  902                         ifp->if_mtu = ifr->ifr_mtu;
  903                 break;
  904 
  905         case SIOCADDMULTI:
  906                 error = ether_addmulti(ifr, &sc->sc_ac);
  907                 break;
  908         case SIOCDELMULTI:
  909                 error = ether_delmulti(ifr, &sc->sc_ac);
  910                 break;
  911 
  912         case SIOCGIFMEDIA:
  913         case SIOCSIFMEDIA:
  914                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
  915                 break;
  916 
  917         default:
  918                 error = ENOTTY;
  919                 break;
  920         }
  921 
  922         if (error == ENETRESET) {
  923                 if (ifp->if_flags & IFF_RUNNING)
  924                         tht_iff(sc);
  925                 error = 0;
  926         }
  927 
  928 err:
  929         splx(s);
  930         rw_exit_write(&sc->sc_lock);
  931 
  932         return (error);
  933 }
  934 
  935 void
  936 tht_up(struct tht_softc *sc)
  937 {
  938         struct ifnet                    *ifp = &sc->sc_ac.ac_if;
  939 
  940         if (ISSET(ifp->if_flags, IFF_RUNNING)) {
  941                 printf("%s: interface is already up\n", DEVNAME(sc));
  942                 return;
  943         }
  944 
  945         if (tht_pkt_alloc(sc, &sc->sc_tx_list, 128, THT_TXT_SGL_LEN) != 0)
  946                 return;
  947         if (tht_pkt_alloc(sc, &sc->sc_rx_list, 128, THT_RXF_SGL_LEN) != 0)
  948                 goto free_tx_list;
  949 
  950         if (tht_fifo_alloc(sc, &sc->sc_txt, &tht_txt_desc) != 0)
  951                 goto free_rx_list;
  952         if (tht_fifo_alloc(sc, &sc->sc_rxf, &tht_rxf_desc) != 0)
  953                 goto free_txt;
  954         if (tht_fifo_alloc(sc, &sc->sc_rxd, &tht_rxd_desc) != 0)
  955                 goto free_rxf;
  956         if (tht_fifo_alloc(sc, &sc->sc_txf, &tht_txf_desc) != 0)
  957                 goto free_rxd;
  958 
  959         tht_write(sc, THT_REG_10G_FRM_LEN, MCLBYTES - ETHER_ALIGN);
  960         tht_write(sc, THT_REG_10G_PAUSE, 0x96);
  961         tht_write(sc, THT_REG_10G_RX_SEC, THT_REG_10G_SEC_AVAIL(0x10) |
  962             THT_REG_10G_SEC_EMPTY(0x80));
  963         tht_write(sc, THT_REG_10G_TX_SEC, THT_REG_10G_SEC_AVAIL(0x10) |
  964             THT_REG_10G_SEC_EMPTY(0xe0));
  965         tht_write(sc, THT_REG_10G_RFIFO_AEF, THT_REG_10G_FIFO_AE(0x0) |
  966             THT_REG_10G_FIFO_AF(0x0));
  967         tht_write(sc, THT_REG_10G_TFIFO_AEF, THT_REG_10G_FIFO_AE(0x0) |
  968             THT_REG_10G_FIFO_AF(0x0));
  969         tht_write(sc, THT_REG_10G_CTL, THT_REG_10G_CTL_TX_EN |
  970             THT_REG_10G_CTL_RX_EN | THT_REG_10G_CTL_PAD |
  971             THT_REG_10G_CTL_PROMISC);
  972 
  973         tht_write(sc, THT_REG_VGLB, 0);
  974 
  975         tht_write(sc, THT_REG_RX_MAX_FRAME, MCLBYTES - ETHER_ALIGN);
  976 
  977         tht_write(sc, THT_REG_RDINTCM(0), THT_REG_RDINTCM_PKT_TH(12) |
  978             THT_REG_RDINTCM_RXF_TH(4) | THT_REG_RDINTCM_COAL_RC |
  979             THT_REG_RDINTCM_COAL(0x20));
  980         tht_write(sc, THT_REG_TDINTCM(0), THT_REG_TDINTCM_PKT_TH(12) |
  981             THT_REG_TDINTCM_COAL_RC | THT_REG_TDINTCM_COAL(0x20));
  982 
  983         bcopy(sc->sc_ac.ac_enaddr, sc->sc_lladdr, ETHER_ADDR_LEN);
  984         tht_lladdr_write(sc);
  985 
  986         /* populate rxf fifo */
  987         tht_rxf_fill(sc, 1);
  988 
  989         tht_iff(sc);
  990 
  991         ifp->if_flags |= IFF_RUNNING;
  992         ifp->if_flags &= ~IFF_OACTIVE;
  993         
  994         /* enable interrupts */
  995         sc->sc_imr = THT_IMR_UP(sc->sc_port);
  996         tht_write(sc, THT_REG_IMR, sc->sc_imr);
  997 
  998         return;
  999 
 1000 free_rxd:
 1001         tht_fifo_free(sc, &sc->sc_rxd);
 1002 free_rxf:
 1003         tht_fifo_free(sc, &sc->sc_rxf);
 1004 free_txt:
 1005         tht_fifo_free(sc, &sc->sc_txt);
 1006 
 1007         tht_sw_reset(sc);
 1008 
 1009 free_rx_list:
 1010         tht_pkt_free(sc, &sc->sc_rx_list);
 1011 free_tx_list:
 1012         tht_pkt_free(sc, &sc->sc_tx_list);
 1013 }
 1014 
 1015 void
 1016 tht_iff(struct tht_softc *sc)
 1017 {
 1018         struct ifnet                    *ifp = &sc->sc_ac.ac_if;
 1019         struct ether_multi              *enm;
 1020         struct ether_multistep          step;
 1021         u_int32_t                       rxf;
 1022         u_int8_t                        imf[THT_REG_RX_MCST_HASH_SIZE];
 1023         u_int8_t                        hash;
 1024         int                             i;
 1025 
 1026         ifp->if_flags &= ~IFF_ALLMULTI;
 1027 
 1028         rxf = THT_REG_RX_FLT_OSEN | THT_REG_RX_FLT_AM | THT_REG_RX_FLT_AB;
 1029         for (i = 0; i < THT_REG_RX_MAC_MCST_CNT; i++) {
 1030                 tht_write(sc, THT_REG_RX_MAC_MCST0(i), 0);
 1031                 tht_write(sc, THT_REG_RX_MAC_MCST1(i), 0);
 1032         }
 1033         memset(imf, 0x00, sizeof(imf));
 1034 
 1035         if (ifp->if_flags & IFF_PROMISC)
 1036                 rxf |= THT_REG_RX_FLT_PRM_ALL;
 1037         else if (sc->sc_ac.ac_multirangecnt > 0) {
 1038                 ifp->if_flags |= IFF_ALLMULTI;
 1039                 memset(imf, 0xff, sizeof(imf));
 1040         } else {
 1041                 ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
 1042 
 1043 #if 0
 1044                 /* fill the perfect multicast filters */
 1045                 for (i = 0; i < THT_REG_RX_MAC_MCST_CNT; i++) {
 1046                         if (enm == NULL)
 1047                                 break;
 1048 
 1049                         tht_write(sc, THT_REG_RX_MAC_MCST0(i),
 1050                             (enm->enm_addrlo[0] << 0) |
 1051                             (enm->enm_addrlo[1] << 8) |
 1052                             (enm->enm_addrlo[2] << 16) |
 1053                             (enm->enm_addrlo[3] << 24));
 1054                         tht_write(sc, THT_REG_RX_MAC_MCST1(i),
 1055                             (enm->enm_addrlo[4] << 0) |
 1056                             (enm->enm_addrlo[5] << 8));
 1057 
 1058                         ETHER_NEXT_MULTI(step, enm);
 1059                 }
 1060 #endif
 1061 
 1062                 /* fill the imperfect multicast filter with whats left */
 1063                 while (enm != NULL) {
 1064                         hash = 0x00;
 1065                         for (i = 0; i < ETHER_ADDR_LEN; i++)
 1066                                 hash ^= enm->enm_addrlo[i];
 1067                         setbit(imf, hash);
 1068 
 1069                         ETHER_NEXT_MULTI(step, enm);
 1070                 }
 1071         }
 1072 
 1073         tht_write_region(sc, THT_REG_RX_MCST_HASH, imf, sizeof(imf));
 1074         tht_write(sc, THT_REG_RX_FLT, rxf);
 1075 }
 1076 
 1077 void
 1078 tht_down(struct tht_softc *sc)
 1079 {
 1080         struct ifnet                    *ifp = &sc->sc_ac.ac_if;
 1081 
 1082         if (!ISSET(ifp->if_flags, IFF_RUNNING)) {
 1083                 printf("%s: interface is already down\n", DEVNAME(sc));
 1084                 return;
 1085         }
 1086 
 1087         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE | IFF_ALLMULTI);
 1088 
 1089         while (tht_fifo_writable(sc, &sc->sc_txt) < sc->sc_txt.tf_len &&
 1090             tht_fifo_readable(sc, &sc->sc_txf) > 0)
 1091                 tsleep(sc, 0, "thtdown", hz);
 1092 
 1093         sc->sc_imr = THT_IMR_DOWN(sc->sc_port);
 1094         tht_write(sc, THT_REG_IMR, sc->sc_imr);
 1095 
 1096         tht_sw_reset(sc);
 1097 
 1098         tht_fifo_free(sc, &sc->sc_txf);
 1099         tht_fifo_free(sc, &sc->sc_rxd);
 1100         tht_fifo_free(sc, &sc->sc_rxf);
 1101         tht_fifo_free(sc, &sc->sc_txt);
 1102 
 1103         /* free mbufs that were on the rxf fifo */
 1104         tht_rxf_drain(sc);
 1105 
 1106         tht_pkt_free(sc, &sc->sc_rx_list);
 1107         tht_pkt_free(sc, &sc->sc_tx_list);
 1108 }
 1109 
 1110 void
 1111 tht_start(struct ifnet *ifp)
 1112 {
 1113         struct tht_softc                *sc = ifp->if_softc;
 1114         struct tht_pkt                  *pkt;
 1115         struct tht_tx_task              txt;
 1116         u_int32_t                       flags;
 1117         struct mbuf                     *m;
 1118         int                             bc;
 1119 
 1120         if (!(ifp->if_flags & IFF_RUNNING))
 1121                 return;
 1122         if (ifp->if_flags & IFF_OACTIVE)
 1123                 return;
 1124         if (IFQ_IS_EMPTY(&ifp->if_snd))
 1125                 return;
 1126 
 1127         if (tht_fifo_writable(sc, &sc->sc_txt) <= THT_FIFO_DESC_LEN)
 1128                 return;
 1129 
 1130         bzero(&txt, sizeof(txt));
 1131 
 1132         tht_fifo_pre(sc, &sc->sc_txt);
 1133 
 1134         do {
 1135                 IFQ_POLL(&ifp->if_snd, m);
 1136                 if (m == NULL)
 1137                         break;
 1138 
 1139                 pkt = tht_pkt_get(&sc->sc_tx_list);
 1140                 if (pkt == NULL) {
 1141                         ifp->if_flags |= IFF_OACTIVE;
 1142                         break;
 1143                 }
 1144 
 1145                 IFQ_DEQUEUE(&ifp->if_snd, m);
 1146                 if (tht_load_pkt(sc, pkt, m) != 0) {
 1147                         m_freem(m);
 1148                         tht_pkt_put(&sc->sc_tx_list, pkt);
 1149                         ifp->if_oerrors++;
 1150                         break;
 1151                 }
 1152                 /* thou shalt not use m after this point, only pkt->tp_m */
 1153 
 1154 #if NBPFILTER > 0
 1155                 if (ifp->if_bpf)
 1156                         bpf_mtap(ifp->if_bpf, pkt->tp_m, BPF_DIRECTION_OUT);
 1157 #endif
 1158 
 1159                 bc = sizeof(txt) +
 1160                     sizeof(struct tht_pbd) * pkt->tp_dmap->dm_nsegs;
 1161 
 1162                 flags = THT_TXT_TYPE | THT_TXT_FLAGS_UDPCS |
 1163                     THT_TXT_FLAGS_TCPCS | THT_TXT_FLAGS_IPCS | LWORDS(bc);
 1164                 txt.flags = htole32(flags);
 1165                 txt.len = htole16(pkt->tp_m->m_pkthdr.len);
 1166                 txt.uid = pkt->tp_id;
 1167 
 1168                 DPRINTF(THT_D_TX, "%s: txt uid 0x%llx flags 0x%08x len %d\n",
 1169                     DEVNAME(sc), pkt->tp_id, flags, pkt->tp_m->m_pkthdr.len);
 1170 
 1171                 tht_fifo_write(sc, &sc->sc_txt, &txt, sizeof(txt));
 1172                 tht_fifo_write_dmap(sc, &sc->sc_txt, pkt->tp_dmap);
 1173                 tht_fifo_write_pad(sc, &sc->sc_txt, bc);
 1174 
 1175                 bus_dmamap_sync(sc->sc_thtc->sc_dmat, pkt->tp_dmap, 0,
 1176                     pkt->tp_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
 1177 
 1178                 ifp->if_opackets++;
 1179 
 1180         } while (sc->sc_txt.tf_ready > THT_FIFO_DESC_LEN);
 1181 
 1182         tht_fifo_post(sc, &sc->sc_txt);
 1183 }
 1184 
 1185 int
 1186 tht_load_pkt(struct tht_softc *sc, struct tht_pkt *pkt, struct mbuf *m)
 1187 {
 1188         bus_dma_tag_t                   dmat = sc->sc_thtc->sc_dmat;
 1189         bus_dmamap_t                    dmap = pkt->tp_dmap;
 1190         struct mbuf                     *m0 = NULL;
 1191 
 1192         switch(bus_dmamap_load_mbuf(dmat, dmap, m, BUS_DMA_NOWAIT)) {
 1193         case 0:
 1194                 pkt->tp_m = m;
 1195                 break;
 1196 
 1197         case EFBIG: /* mbuf chain is too fragmented */
 1198                 MGETHDR(m0, M_DONTWAIT, MT_DATA);
 1199                 if (m0 == NULL)
 1200                         return (ENOBUFS);
 1201                 if (m->m_pkthdr.len > MHLEN) {
 1202                         MCLGET(m0, M_DONTWAIT);
 1203                         if (!(m0->m_flags & M_EXT)) {
 1204                                 m_freem(m0);
 1205                                 return (ENOBUFS);
 1206                         }
 1207                 }
 1208                 m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
 1209                 m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
 1210                 if (bus_dmamap_load_mbuf(dmat, dmap, m0, BUS_DMA_NOWAIT)) {
 1211                         m_freem(m0);
 1212                         return (ENOBUFS);
 1213                 }
 1214 
 1215                 m_freem(m);
 1216                 pkt->tp_m = m0;
 1217                 break;
 1218 
 1219         default:
 1220                 return (ENOBUFS);
 1221         }
 1222 
 1223         return (0);
 1224 }
 1225 
 1226 void
 1227 tht_txf(struct tht_softc *sc)
 1228 {
 1229         struct ifnet                    *ifp = &sc->sc_ac.ac_if;
 1230         bus_dma_tag_t                   dmat = sc->sc_thtc->sc_dmat;
 1231         bus_dmamap_t                    dmap;
 1232         struct tht_tx_free              txf;
 1233         struct tht_pkt                  *pkt;
 1234 
 1235         if (tht_fifo_readable(sc, &sc->sc_txf) < sizeof(txf))
 1236                 return;
 1237 
 1238         tht_fifo_pre(sc, &sc->sc_txf);
 1239 
 1240         do {
 1241                 tht_fifo_read(sc, &sc->sc_txf, &txf, sizeof(txf));
 1242 
 1243                 DPRINTF(THT_D_TX, "%s: txf uid 0x%llx\n", DEVNAME(sc), txf.uid);
 1244 
 1245                 pkt = &sc->sc_tx_list.tpl_pkts[txf.uid];
 1246                 dmap = pkt->tp_dmap;
 1247 
 1248                 bus_dmamap_sync(dmat, dmap, 0, dmap->dm_mapsize,
 1249                     BUS_DMASYNC_POSTWRITE);
 1250                 bus_dmamap_unload(dmat, dmap);
 1251 
 1252                 m_freem(pkt->tp_m);
 1253 
 1254                 tht_pkt_put(&sc->sc_tx_list, pkt);
 1255 
 1256         } while (sc->sc_txf.tf_ready >= sizeof(txf));
 1257 
 1258         ifp->if_flags &= ~IFF_OACTIVE;
 1259 
 1260         tht_fifo_post(sc, &sc->sc_txf);
 1261 }
 1262 
 1263 void
 1264 tht_rxf_fill(struct tht_softc *sc, int wait)
 1265 {
 1266         bus_dma_tag_t                   dmat = sc->sc_thtc->sc_dmat;
 1267         bus_dmamap_t                    dmap;
 1268         struct tht_rx_free              rxf;
 1269         struct tht_pkt                  *pkt;
 1270         struct mbuf                     *m;
 1271         int                             bc;
 1272 
 1273         if (tht_fifo_writable(sc, &sc->sc_rxf) <= THT_FIFO_DESC_LEN)
 1274                 return;
 1275 
 1276         tht_fifo_pre(sc, &sc->sc_rxf);
 1277 
 1278         for (;;) {
 1279                 if ((pkt = tht_pkt_get(&sc->sc_rx_list)) == NULL)
 1280                         goto done;
 1281 
 1282                 MGETHDR(m, wait ? M_WAIT : M_DONTWAIT, MT_DATA);
 1283                 if (m == NULL)
 1284                         goto put_pkt;
 1285 
 1286                 MCLGET(m, wait ? M_WAIT : M_DONTWAIT);
 1287                 if (!ISSET(m->m_flags, M_EXT))
 1288                         goto free_m;
 1289 
 1290                 m->m_data += ETHER_ALIGN;
 1291                 m->m_len = m->m_pkthdr.len = MCLBYTES - ETHER_ALIGN;
 1292 
 1293                 dmap = pkt->tp_dmap;
 1294                 if (bus_dmamap_load_mbuf(dmat, dmap, m,
 1295                     wait ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT) != 0)
 1296                         goto free_m;
 1297 
 1298                 pkt->tp_m = m;
 1299 
 1300                 bc = sizeof(rxf) + sizeof(struct tht_pbd) * dmap->dm_nsegs;
 1301 
 1302                 rxf.bc = htole16(LWORDS(bc));
 1303                 rxf.type = htole16(THT_RXF_TYPE);
 1304                 rxf.uid = pkt->tp_id;
 1305 
 1306                 tht_fifo_write(sc, &sc->sc_rxf, &rxf, sizeof(rxf));
 1307                 tht_fifo_write_dmap(sc, &sc->sc_rxf, dmap);
 1308                 tht_fifo_write_pad(sc, &sc->sc_rxf, bc);
 1309 
 1310                 bus_dmamap_sync(dmat, dmap, 0, dmap->dm_mapsize,
 1311                     BUS_DMASYNC_PREREAD);
 1312 
 1313                 if (sc->sc_rxf.tf_ready <= THT_FIFO_DESC_LEN)
 1314                         goto done;
 1315         }
 1316 
 1317 free_m:
 1318         m_freem(m);
 1319 put_pkt:
 1320         tht_pkt_put(&sc->sc_rx_list, pkt);
 1321 done:
 1322         tht_fifo_post(sc, &sc->sc_rxf);
 1323 }
 1324 
 1325 void
 1326 tht_rxf_drain(struct tht_softc *sc)
 1327 {
 1328         bus_dma_tag_t                   dmat = sc->sc_thtc->sc_dmat;
 1329         bus_dmamap_t                    dmap;
 1330         struct tht_pkt                  *pkt;
 1331 
 1332         while ((pkt = tht_pkt_used(&sc->sc_rx_list)) != NULL) {
 1333                 dmap = pkt->tp_dmap;
 1334 
 1335                 bus_dmamap_sync(dmat, dmap, 0, dmap->dm_mapsize,
 1336                     BUS_DMASYNC_POSTREAD);
 1337                 bus_dmamap_unload(dmat, dmap);
 1338 
 1339                 m_freem(pkt->tp_m);
 1340 
 1341                 tht_pkt_put(&sc->sc_rx_list, pkt);
 1342         }
 1343 }
 1344 
 1345 void
 1346 tht_rxd(struct tht_softc *sc)
 1347 {
 1348         struct ifnet                    *ifp = &sc->sc_ac.ac_if;
 1349         bus_dma_tag_t                   dmat = sc->sc_thtc->sc_dmat;
 1350         bus_dmamap_t                    dmap;
 1351         struct tht_rx_desc              rxd;
 1352         struct tht_pkt                  *pkt;
 1353         struct mbuf                     *m;
 1354         int                             bc;
 1355         u_int32_t                       flags;
 1356 
 1357         if (tht_fifo_readable(sc, &sc->sc_rxd) < sizeof(rxd))
 1358                 return;
 1359 
 1360         tht_fifo_pre(sc, &sc->sc_rxd);
 1361 
 1362         do {
 1363                 tht_fifo_read(sc, &sc->sc_rxd, &rxd, sizeof(rxd));
 1364 
 1365                 flags = letoh32(rxd.flags);
 1366                 bc = THT_RXD_FLAGS_BC(flags) * 8;
 1367                 bc -= sizeof(rxd);
 1368                 pkt = &sc->sc_rx_list.tpl_pkts[rxd.uid];
 1369 
 1370                 dmap = pkt->tp_dmap;
 1371 
 1372                 bus_dmamap_sync(dmat, dmap, 0, dmap->dm_mapsize,
 1373                     BUS_DMASYNC_POSTREAD);
 1374                 bus_dmamap_unload(dmat, dmap);
 1375 
 1376                 m = pkt->tp_m;
 1377                 m->m_pkthdr.rcvif = ifp;
 1378                 m->m_pkthdr.len = m->m_len = letoh16(rxd.len);
 1379 
 1380                 if (!ISSET(flags, THT_RXD_FLAGS_IPCS))
 1381                         m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
 1382                 if (!ISSET(flags, THT_RXD_FLAGS_TCPCS))
 1383                         m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK;
 1384                 if (!ISSET(flags, THT_RXD_FLAGS_UDPCS))
 1385                         m->m_pkthdr.csum_flags |= M_UDP_CSUM_IN_OK;
 1386 
 1387                 /* XXX process type 3 rx descriptors */
 1388 
 1389 #if NBPFILTER > 0
 1390                 if (ifp->if_bpf)
 1391                         bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
 1392 #endif
 1393 
 1394                 ether_input_mbuf(ifp, m);
 1395 
 1396                 tht_pkt_put(&sc->sc_rx_list, pkt);
 1397 
 1398                 while (bc > 0) {
 1399                         static u_int32_t pad;
 1400 
 1401                         tht_fifo_read(sc, &sc->sc_rxd, &pad, sizeof(pad));
 1402                         bc -= sizeof(pad);
 1403                 }
 1404 
 1405                 ifp->if_ipackets++;
 1406 
 1407         } while (sc->sc_rxd.tf_ready >= sizeof(rxd));
 1408 
 1409         tht_fifo_post(sc, &sc->sc_rxd);
 1410 
 1411         /* put more pkts on the fifo */
 1412         tht_rxf_fill(sc, 0);
 1413 }
 1414 
 1415 void
 1416 tht_watchdog(struct ifnet *ifp)
 1417 {
 1418         /* do nothing */
 1419 }
 1420 
 1421 int
 1422 tht_media_change(struct ifnet *ifp)
 1423 {
 1424         /* ignore */
 1425         return (0);
 1426 }
 1427 
 1428 void
 1429 tht_media_status(struct ifnet *ifp, struct ifmediareq *imr)
 1430 {
 1431         struct tht_softc                *sc = ifp->if_softc;
 1432 
 1433         imr->ifm_active = IFM_ETHER | IFM_AUTO;
 1434         imr->ifm_status = IFM_AVALID;
 1435 
 1436         tht_link_state(sc);
 1437 
 1438         if (LINK_STATE_IS_UP(ifp->if_link_state))
 1439                 imr->ifm_status |= IFM_ACTIVE;
 1440 }
 1441 
 1442 int
 1443 tht_fifo_alloc(struct tht_softc *sc, struct tht_fifo *tf,
 1444     struct tht_fifo_desc *tfd)
 1445 {
 1446         u_int64_t                       dva;
 1447 
 1448         tf->tf_len = THT_FIFO_SIZE(tfd->tfd_size);
 1449         tf->tf_mem = tht_dmamem_alloc(sc, tf->tf_len, THT_FIFO_ALIGN);
 1450         if (tf->tf_mem == NULL)
 1451                 return (1);
 1452 
 1453         tf->tf_desc = tfd;
 1454         tf->tf_rptr = tf->tf_wptr = 0;
 1455 
 1456         bus_dmamap_sync(sc->sc_thtc->sc_dmat, THT_DMA_MAP(tf->tf_mem),
 1457             0, tf->tf_len, THT_FIFO_PRE_SYNC(tfd));
 1458 
 1459         dva = THT_DMA_DVA(tf->tf_mem);
 1460         tht_write(sc, tfd->tfd_cfg0, (u_int32_t)dva | tfd->tfd_size);
 1461         tht_write(sc, tfd->tfd_cfg1, (u_int32_t)(dva >> 32));
 1462 
 1463         return (0);
 1464 }
 1465 
 1466 void
 1467 tht_fifo_free(struct tht_softc *sc, struct tht_fifo *tf)
 1468 {
 1469         bus_dmamap_sync(sc->sc_thtc->sc_dmat, THT_DMA_MAP(tf->tf_mem),
 1470             0, tf->tf_len, THT_FIFO_POST_SYNC(tf->tf_desc));
 1471         tht_dmamem_free(sc, tf->tf_mem);
 1472 }
 1473 
 1474 size_t
 1475 tht_fifo_readable(struct tht_softc *sc, struct tht_fifo *tf)
 1476 {
 1477         tf->tf_wptr = tht_read(sc, tf->tf_desc->tfd_wptr);
 1478         tf->tf_wptr &= THT_FIFO_PTR_MASK;
 1479         tf->tf_ready = tf->tf_wptr - tf->tf_rptr;
 1480         if (tf->tf_ready < 0)
 1481                 tf->tf_ready += tf->tf_len;
 1482 
 1483         DPRINTF(THT_D_FIFO, "%s: fifo rdable wptr: %d rptr: %d ready: %d\n",
 1484             DEVNAME(sc), tf->tf_wptr, tf->tf_rptr, tf->tf_ready);
 1485 
 1486         return (tf->tf_ready);
 1487 }
 1488 
 1489 size_t
 1490 tht_fifo_writable(struct tht_softc *sc, struct tht_fifo *tf)
 1491 {
 1492         tf->tf_rptr = tht_read(sc, tf->tf_desc->tfd_rptr);
 1493         tf->tf_rptr &= THT_FIFO_PTR_MASK;
 1494         tf->tf_ready = tf->tf_rptr - tf->tf_wptr;
 1495         if (tf->tf_ready <= 0)
 1496                 tf->tf_ready += tf->tf_len;
 1497 
 1498         DPRINTF(THT_D_FIFO, "%s: fifo wrable wptr: %d rptr: %d ready: %d\n",
 1499             DEVNAME(sc), tf->tf_wptr, tf->tf_rptr, tf->tf_ready);
 1500 
 1501         return (tf->tf_ready);
 1502 }
 1503 
 1504 void
 1505 tht_fifo_pre(struct tht_softc *sc, struct tht_fifo *tf)
 1506 {
 1507         bus_dmamap_sync(sc->sc_thtc->sc_dmat, THT_DMA_MAP(tf->tf_mem),
 1508             0, tf->tf_len, THT_FIFO_POST_SYNC(tf->tf_desc));
 1509 }
 1510 
 1511 void
 1512 tht_fifo_read(struct tht_softc *sc, struct tht_fifo *tf,
 1513     void *buf, size_t buflen)
 1514 {
 1515         u_int8_t                        *fifo = THT_DMA_KVA(tf->tf_mem);
 1516         u_int8_t                        *desc = buf;
 1517         size_t                          len;
 1518 
 1519         tf->tf_ready -= buflen;
 1520 
 1521         len = tf->tf_len - tf->tf_rptr;
 1522 
 1523         if (len < buflen) {
 1524                 memcpy(desc, fifo + tf->tf_rptr, len);
 1525 
 1526                 buflen -= len;
 1527                 desc += len;
 1528 
 1529                 tf->tf_rptr = 0;
 1530         }
 1531 
 1532         memcpy(desc, fifo + tf->tf_rptr, buflen);
 1533         tf->tf_rptr += buflen;
 1534 
 1535         DPRINTF(THT_D_FIFO, "%s: fifo rd wptr: %d rptr: %d ready: %d\n",
 1536             DEVNAME(sc), tf->tf_wptr, tf->tf_rptr, tf->tf_ready);
 1537 }
 1538 
 1539 void
 1540 tht_fifo_write(struct tht_softc *sc, struct tht_fifo *tf,
 1541     void *buf, size_t buflen)
 1542 {
 1543         u_int8_t                        *fifo = THT_DMA_KVA(tf->tf_mem);
 1544         u_int8_t                        *desc = buf;
 1545         size_t                          len;
 1546 
 1547         tf->tf_ready -= buflen;
 1548 
 1549         len = tf->tf_len - tf->tf_wptr;
 1550 
 1551         if (len < buflen) {
 1552                 memcpy(fifo + tf->tf_wptr, desc, len);
 1553 
 1554                 buflen -= len;
 1555                 desc += len;
 1556 
 1557                 tf->tf_wptr = 0;
 1558         }
 1559 
 1560         memcpy(fifo + tf->tf_wptr, desc, buflen);
 1561         tf->tf_wptr += buflen;
 1562         tf->tf_wptr %= tf->tf_len;
 1563 
 1564         DPRINTF(THT_D_FIFO, "%s: fifo wr wptr: %d rptr: %d ready: %d\n",
 1565             DEVNAME(sc), tf->tf_wptr, tf->tf_rptr, tf->tf_ready);
 1566 }
 1567 
 1568 void
 1569 tht_fifo_write_dmap(struct tht_softc *sc, struct tht_fifo *tf,
 1570     bus_dmamap_t dmap)
 1571 {
 1572         struct tht_pbd                  pbd;
 1573         u_int64_t                       dva;
 1574         int                             i;
 1575 
 1576         for (i = 0; i < dmap->dm_nsegs; i++) {
 1577                 dva = dmap->dm_segs[i].ds_addr;
 1578 
 1579                 pbd.addr_lo = htole32(dva);
 1580                 pbd.addr_hi = htole32(dva >> 32);
 1581                 pbd.len = htole32(dmap->dm_segs[i].ds_len);
 1582 
 1583                 tht_fifo_write(sc, tf, &pbd, sizeof(pbd));
 1584         }
 1585 }
 1586 
 1587 void
 1588 tht_fifo_write_pad(struct tht_softc *sc, struct tht_fifo *tf, int bc)
 1589 {
 1590         const static u_int32_t pad = 0x0;
 1591 
 1592         /* this assumes you'll only ever be writing multiples of 4 bytes */
 1593         if (bc % 8)
 1594                 tht_fifo_write(sc, tf, (void *)&pad, sizeof(pad));
 1595 }
 1596 
 1597 void
 1598 tht_fifo_post(struct tht_softc *sc, struct tht_fifo *tf)
 1599 {
 1600         bus_dmamap_sync(sc->sc_thtc->sc_dmat, THT_DMA_MAP(tf->tf_mem),
 1601             0, tf->tf_len, THT_FIFO_PRE_SYNC(tf->tf_desc));
 1602         if (tf->tf_desc->tfd_write)
 1603                 tht_write(sc, tf->tf_desc->tfd_wptr, tf->tf_wptr);
 1604         else
 1605                 tht_write(sc, tf->tf_desc->tfd_rptr, tf->tf_rptr);
 1606 
 1607         DPRINTF(THT_D_FIFO, "%s: fifo post wptr: %d rptr: %d\n", DEVNAME(sc),
 1608             tf->tf_wptr, tf->tf_rptr);
 1609 }
 1610 
 1611 const static bus_size_t tht_mac_regs[3] = {
 1612     THT_REG_RX_UNC_MAC2, THT_REG_RX_UNC_MAC1, THT_REG_RX_UNC_MAC0
 1613 };
 1614 
 1615 void
 1616 tht_lladdr_read(struct tht_softc *sc)
 1617 {
 1618         int                             i;
 1619 
 1620         for (i = 0; i < sizeofa(tht_mac_regs); i++)
 1621                 sc->sc_lladdr[i] = betoh16(tht_read(sc, tht_mac_regs[i]));
 1622 }
 1623 
 1624 void
 1625 tht_lladdr_write(struct tht_softc *sc)
 1626 {
 1627         int                             i;
 1628 
 1629         for (i = 0; i < sizeofa(tht_mac_regs); i++)
 1630                 tht_write(sc, tht_mac_regs[i], htobe16(sc->sc_lladdr[i]));
 1631 }
 1632 
 1633 #define tht_swrst_set(_s, _r) tht_write((_s), (_r), 0x1)
 1634 #define tht_swrst_clr(_s, _r) tht_write((_s), (_r), 0x0)
 1635 int
 1636 tht_sw_reset(struct tht_softc *sc)
 1637 {
 1638         int                             i;
 1639 
 1640         /* this follows SW Reset process in 8.8 of the doco */
 1641 
 1642         /* 1. disable rx */
 1643         tht_clr(sc, THT_REG_RX_FLT, THT_REG_RX_FLT_OSEN);
 1644 
 1645         /* 2. initiate port disable */
 1646         tht_swrst_set(sc, THT_REG_DIS_PRT);
 1647 
 1648         /* 3. initiate queue disable */
 1649         tht_swrst_set(sc, THT_REG_DIS_QU_0);
 1650         tht_swrst_set(sc, THT_REG_DIS_QU_1);
 1651 
 1652         /* 4. wait for successful finish of previous tasks */
 1653         if (!tht_wait_set(sc, THT_REG_RST_PRT, THT_REG_RST_PRT_ACTIVE, 1000))
 1654                 return (1);
 1655 
 1656         /* 5. Reset interrupt registers */
 1657         tht_write(sc, THT_REG_IMR, 0x0); /* 5.a */
 1658         tht_read(sc, THT_REG_ISR); /* 5.b */
 1659         for (i = 0; i < THT_NQUEUES; i++) {
 1660                 tht_write(sc, THT_REG_RDINTCM(i), 0x0); /* 5.c/5.d */
 1661                 tht_write(sc, THT_REG_TDINTCM(i), 0x0); /* 5.e */
 1662         }
 1663 
 1664         /* 6. initiate queue reset */
 1665         tht_swrst_set(sc, THT_REG_RST_QU_0);
 1666         tht_swrst_set(sc, THT_REG_RST_QU_1);
 1667 
 1668         /* 7. initiate port reset */
 1669         tht_swrst_set(sc, THT_REG_RST_PRT);
 1670 
 1671         /* 8. clear txt/rxf/rxd/txf read and write ptrs */
 1672         for (i = 0; i < THT_NQUEUES; i++) {
 1673                 tht_write(sc, THT_REG_TXT_RPTR(i), 0);
 1674                 tht_write(sc, THT_REG_RXF_RPTR(i), 0);
 1675                 tht_write(sc, THT_REG_RXD_RPTR(i), 0);
 1676                 tht_write(sc, THT_REG_TXF_RPTR(i), 0);
 1677 
 1678                 tht_write(sc, THT_REG_TXT_WPTR(i), 0);
 1679                 tht_write(sc, THT_REG_RXF_WPTR(i), 0);
 1680                 tht_write(sc, THT_REG_RXD_WPTR(i), 0);
 1681                 tht_write(sc, THT_REG_TXF_WPTR(i), 0);
 1682         }
 1683 
 1684         /* 9. unset port disable */
 1685         tht_swrst_clr(sc, THT_REG_DIS_PRT);
 1686 
 1687         /* 10. unset queue disable */
 1688         tht_swrst_clr(sc, THT_REG_DIS_QU_0);
 1689         tht_swrst_clr(sc, THT_REG_DIS_QU_1);
 1690 
 1691         /* 11. unset queue reset */
 1692         tht_swrst_clr(sc, THT_REG_RST_QU_0);
 1693         tht_swrst_clr(sc, THT_REG_RST_QU_1);
 1694 
 1695         /* 12. unset port reset */
 1696         tht_swrst_clr(sc, THT_REG_RST_PRT);
 1697 
 1698         /* 13. enable rx */
 1699         tht_set(sc, THT_REG_RX_FLT, THT_REG_RX_FLT_OSEN);
 1700 
 1701         return (0);
 1702 }
 1703 
 1704 int
 1705 tht_fw_load(struct tht_softc *sc)
 1706 {
 1707         struct timeout                  ticker;
 1708         volatile int                    ok = 1;
 1709         u_int8_t                        *fw, *buf;
 1710         size_t                          fwlen, wrlen;
 1711         int                             error = 1;
 1712 
 1713         if (loadfirmware("tht", &fw, &fwlen) != 0)
 1714                 return (1);
 1715 
 1716         if ((fwlen % 8) != 0)
 1717                 goto err;
 1718 
 1719         buf = fw;
 1720         while (fwlen > 0) {
 1721                 while (tht_fifo_writable(sc, &sc->sc_txt) <= THT_FIFO_GAP) {
 1722                         if (tsleep(sc, PCATCH, "thtfw", 1) == EINTR)
 1723                                 goto err;
 1724                 }
 1725 
 1726                 wrlen = MIN(sc->sc_txt.tf_ready - THT_FIFO_GAP, fwlen);
 1727                 tht_fifo_pre(sc, &sc->sc_txt);
 1728                 tht_fifo_write(sc, &sc->sc_txt, buf, wrlen);
 1729                 tht_fifo_post(sc, &sc->sc_txt);
 1730 
 1731                 fwlen -= wrlen;
 1732                 buf += wrlen;
 1733         }
 1734 
 1735         timeout_set(&ticker, tht_fw_tick, &ticker);
 1736         timeout_add(&ticker, 2*hz);
 1737         while (ok) {
 1738                 if (tht_read(sc, THT_REG_INIT_STATUS) != 0) {
 1739                         error = 0;
 1740                         break;
 1741                 }
 1742 
 1743                 if (tsleep(sc, PCATCH, "thtinit", 1) == EINTR)
 1744                         goto err;
 1745         }
 1746         timeout_del(&ticker);
 1747 
 1748         tht_write(sc, THT_REG_INIT_SEMAPHORE, 0x1);
 1749 
 1750 err:
 1751         free(fw, M_DEVBUF);
 1752         return (error);
 1753 }
 1754 
 1755 void
 1756 tht_fw_tick(void *arg)
 1757 {
 1758         volatile int                    *ok = arg;
 1759 
 1760         *ok = 0;
 1761 }
 1762 
 1763 void
 1764 tht_link_state(struct tht_softc *sc)
 1765 {
 1766         struct ifnet                    *ifp = &sc->sc_ac.ac_if;
 1767         int                             link_state = LINK_STATE_DOWN;
 1768 
 1769         if (tht_read(sc, THT_REG_MAC_LNK_STAT) & THT_REG_MAC_LNK_STAT_LINK)
 1770                 link_state = LINK_STATE_UP;
 1771 
 1772         if (ifp->if_link_state != link_state) {
 1773                 ifp->if_link_state = link_state;
 1774                 if_link_state_change(ifp);
 1775         }
 1776 }
 1777 
 1778 u_int32_t
 1779 tht_read(struct tht_softc *sc, bus_size_t r)
 1780 {
 1781         bus_space_barrier(sc->sc_thtc->sc_memt, sc->sc_memh, r, 4,
 1782             BUS_SPACE_BARRIER_READ);
 1783         return (bus_space_read_4(sc->sc_thtc->sc_memt, sc->sc_memh, r));
 1784 }
 1785 
 1786 void
 1787 tht_write(struct tht_softc *sc, bus_size_t r, u_int32_t v)
 1788 {
 1789         bus_space_write_4(sc->sc_thtc->sc_memt, sc->sc_memh, r, v);
 1790         bus_space_barrier(sc->sc_thtc->sc_memt, sc->sc_memh, r, 4,
 1791             BUS_SPACE_BARRIER_WRITE);
 1792 }
 1793 
 1794 void
 1795 tht_write_region(struct tht_softc *sc, bus_size_t r, void *buf, size_t len)
 1796 {
 1797         bus_space_write_raw_region_4(sc->sc_thtc->sc_memt, sc->sc_memh, r,
 1798             buf, len);
 1799         bus_space_barrier(sc->sc_thtc->sc_memt, sc->sc_memh, r, len,
 1800             BUS_SPACE_BARRIER_WRITE);
 1801 }
 1802 
 1803 int
 1804 tht_wait_eq(struct tht_softc *sc, bus_size_t r, u_int32_t m, u_int32_t v,
 1805     int timeout)
 1806 {
 1807         while ((tht_read(sc, r) & m) != v) {
 1808                 if (timeout == 0)
 1809                         return (0);
 1810 
 1811                 delay(1000);
 1812                 timeout--;
 1813         }
 1814 
 1815         return (1);
 1816 }
 1817 
 1818 int
 1819 tht_wait_ne(struct tht_softc *sc, bus_size_t r, u_int32_t m, u_int32_t v,
 1820     int timeout)
 1821 {
 1822         while ((tht_read(sc, r) & m) == v) {
 1823                 if (timeout == 0)
 1824                         return (0);
 1825 
 1826                 delay(1000);
 1827                 timeout--;
 1828         }
 1829 
 1830         return (1);
 1831 }
 1832 
 1833 struct tht_dmamem *
 1834 tht_dmamem_alloc(struct tht_softc *sc, bus_size_t size, bus_size_t align)
 1835 {
 1836         bus_dma_tag_t                   dmat = sc->sc_thtc->sc_dmat;
 1837         struct tht_dmamem               *tdm;
 1838         int                             nsegs;
 1839 
 1840         tdm = malloc(sizeof(struct tht_dmamem), M_DEVBUF, M_WAITOK);
 1841         bzero(tdm, sizeof(struct tht_dmamem));
 1842         tdm->tdm_size = size;
 1843 
 1844         if (bus_dmamap_create(dmat, size, 1, size, 0,
 1845             BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &tdm->tdm_map) != 0)
 1846                 goto tdmfree;
 1847 
 1848         if (bus_dmamem_alloc(dmat, size, align, 0, &tdm->tdm_seg, 1, &nsegs,
 1849             BUS_DMA_WAITOK) != 0)
 1850                 goto destroy;
 1851 
 1852         if (bus_dmamem_map(dmat, &tdm->tdm_seg, nsegs, size, &tdm->tdm_kva,
 1853             BUS_DMA_WAITOK) != 0)
 1854                 goto free;
 1855 
 1856         if (bus_dmamap_load(dmat, tdm->tdm_map, tdm->tdm_kva, size,
 1857             NULL, BUS_DMA_WAITOK) != 0)
 1858                 goto unmap;
 1859 
 1860         bzero(tdm->tdm_kva, size);
 1861 
 1862         return (tdm);
 1863 
 1864 unmap:
 1865         bus_dmamem_unmap(dmat, tdm->tdm_kva, size);
 1866 free:
 1867         bus_dmamem_free(dmat, &tdm->tdm_seg, 1);
 1868 destroy:
 1869         bus_dmamap_destroy(dmat, tdm->tdm_map);
 1870 tdmfree:
 1871         free(tdm, M_DEVBUF);
 1872 
 1873         return (NULL);
 1874 }
 1875 
 1876 void
 1877 tht_dmamem_free(struct tht_softc *sc, struct tht_dmamem *tdm)
 1878 {
 1879         bus_dma_tag_t                   dmat = sc->sc_thtc->sc_dmat;
 1880 
 1881         bus_dmamap_unload(dmat, tdm->tdm_map);
 1882         bus_dmamem_unmap(dmat, tdm->tdm_kva, tdm->tdm_size);
 1883         bus_dmamem_free(dmat, &tdm->tdm_seg, 1);
 1884         bus_dmamap_destroy(dmat, tdm->tdm_map);
 1885         free(tdm, M_DEVBUF);
 1886 }
 1887 
 1888 int
 1889 tht_pkt_alloc(struct tht_softc *sc, struct tht_pkt_list *tpl, int npkts,
 1890     int nsegs)
 1891 {
 1892         bus_dma_tag_t                   dmat = sc->sc_thtc->sc_dmat;
 1893         struct tht_pkt                  *pkt;
 1894         int                             i;
 1895 
 1896         tpl->tpl_pkts = malloc(sizeof(struct tht_pkt) * npkts, M_DEVBUF,
 1897             M_WAITOK);
 1898         bzero(tpl->tpl_pkts, sizeof(struct tht_pkt) * npkts);
 1899 
 1900         TAILQ_INIT(&tpl->tpl_free);
 1901         TAILQ_INIT(&tpl->tpl_used);
 1902         for (i = 0; i < npkts; i++) {
 1903                 pkt = &tpl->tpl_pkts[i];
 1904 
 1905                 pkt->tp_id = i;
 1906                 if (bus_dmamap_create(dmat, THT_PBD_PKTLEN, nsegs,
 1907                     THT_PBD_PKTLEN, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
 1908                     &pkt->tp_dmap) != 0) {
 1909                         tht_pkt_free(sc, tpl);
 1910                         return (1);
 1911                 }
 1912 
 1913                 TAILQ_INSERT_TAIL(&tpl->tpl_free, pkt, tp_link);
 1914         }
 1915 
 1916         return (0);
 1917 }
 1918 
 1919 void
 1920 tht_pkt_free(struct tht_softc *sc, struct tht_pkt_list *tpl)
 1921 {
 1922         bus_dma_tag_t                   dmat = sc->sc_thtc->sc_dmat;
 1923         struct tht_pkt                  *pkt;
 1924 
 1925         while ((pkt = tht_pkt_get(tpl)) != NULL)
 1926                 bus_dmamap_destroy(dmat, pkt->tp_dmap);
 1927         free(tpl->tpl_pkts, M_DEVBUF);
 1928         tpl->tpl_pkts = NULL;
 1929 }
 1930 
 1931 void
 1932 tht_pkt_put(struct tht_pkt_list *tpl, struct tht_pkt *pkt)
 1933 {
 1934         TAILQ_REMOVE(&tpl->tpl_used, pkt, tp_link);
 1935         TAILQ_INSERT_TAIL(&tpl->tpl_free, pkt, tp_link);
 1936 }
 1937 
 1938 struct tht_pkt *
 1939 tht_pkt_get(struct tht_pkt_list *tpl)
 1940 {
 1941         struct tht_pkt                  *pkt;
 1942 
 1943         pkt = TAILQ_FIRST(&tpl->tpl_free);
 1944         if (pkt != NULL) {
 1945                 TAILQ_REMOVE(&tpl->tpl_free, pkt, tp_link);
 1946                 TAILQ_INSERT_TAIL(&tpl->tpl_used, pkt, tp_link);
 1947 
 1948         }
 1949 
 1950         return (pkt);
 1951 }
 1952 
 1953 struct tht_pkt *
 1954 tht_pkt_used(struct tht_pkt_list *tpl)
 1955 {
 1956         return (TAILQ_FIRST(&tpl->tpl_used));
 1957 }

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