1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 #ifndef _IPRB_H
  17 #define _IPRB_H
  18 
  19 /*
  20  * iprb - Intel Pro/100B Ethernet Driver
  21  */
  22 
  23 /*
  24  * Tunables.
  25  */
  26 #define NUM_TX          128     /* outstanding tx queue */
  27 #define NUM_RX          128     /* outstanding rx queue */
  28 
  29 #define RX_WATCHDOG     15      /* timeout for rx watchdog (sec) */
  30 #define TX_WATCHDOG     15      /* timeout for tx watchdog (sec) */
  31 
  32 /*
  33  * Driver structures.
  34  */
  35 typedef struct {
  36         ddi_acc_handle_t        acch;
  37         ddi_dma_handle_t        dmah;
  38         caddr_t                 vaddr;
  39         uint32_t                paddr;
  40 } iprb_dma_t;
  41 
  42 typedef struct iprb_mcast {
  43         list_node_t             node;
  44         uint8_t                 addr[6];
  45 } iprb_mcast_t;
  46 
  47 typedef struct iprb {
  48         dev_info_t              *dip;
  49         ddi_acc_handle_t        pcih;
  50         ddi_acc_handle_t        regsh;
  51         caddr_t                 regs;
  52 
  53         uint16_t                devid;
  54         uint8_t                 revid;
  55 
  56         mac_handle_t            mach;
  57         mii_handle_t            miih;
  58 
  59         ddi_intr_handle_t       intrh;
  60 
  61         ddi_periodic_t          perh;
  62 
  63         kmutex_t                culock;
  64         kmutex_t                rulock;
  65 
  66         uint8_t                 factaddr[6];
  67         uint8_t                 curraddr[6];
  68 
  69         int                     nmcast;
  70         list_t                  mcast;
  71         boolean_t               promisc;
  72         iprb_dma_t              cmds[NUM_TX];
  73         iprb_dma_t              rxb[NUM_RX];
  74         iprb_dma_t              stats;
  75         time_t                  stats_time;
  76 
  77         uint16_t                cmd_head;
  78         uint16_t                cmd_last;
  79         uint16_t                cmd_tail;
  80         uint16_t                cmd_count;
  81 
  82         uint16_t                rx_index;
  83         uint16_t                rx_last;
  84         time_t                  rx_wdog;
  85         time_t                  rx_timeout;
  86         time_t                  tx_wdog;
  87         time_t                  tx_timeout;
  88 
  89         uint16_t                eeprom_bits;
  90 
  91         boolean_t               running;
  92         boolean_t               suspended;
  93         boolean_t               wantw;
  94         boolean_t               rxhangbug;
  95         boolean_t               resumebug;
  96         boolean_t               is557;
  97         boolean_t               canpause;
  98         boolean_t               canmwi;
  99 
 100         /*
 101          * Statistics
 102          */
 103         uint64_t                ipackets;
 104         uint64_t                rbytes;
 105         uint64_t                multircv;
 106         uint64_t                brdcstrcv;
 107         uint64_t                opackets;
 108         uint64_t                obytes;
 109         uint64_t                multixmt;
 110         uint64_t                brdcstxmt;
 111         uint64_t                ex_coll;
 112         uint64_t                late_coll;
 113         uint64_t                uflo;
 114         uint64_t                defer_xmt;
 115         uint64_t                one_coll;
 116         uint64_t                multi_coll;
 117         uint64_t                collisions;
 118         uint64_t                fcs_errs;
 119         uint64_t                align_errs;
 120         uint64_t                norcvbuf;
 121         uint64_t                oflo;
 122         uint64_t                runt;
 123         uint64_t                nocarrier;
 124         uint64_t                toolong;
 125         uint64_t                macxmt_errs;
 126         uint64_t                macrcv_errs;
 127 } iprb_t;
 128 
 129 /*
 130  * Idenfication values.
 131  */
 132 #define REV_82557       1
 133 #define REV_82558_A4    4
 134 #define REV_82558_B0    5
 135 #define REV_82559_A0    8
 136 #define REV_82559S_A    9
 137 #define REV_82550       12
 138 #define REV_82550_C     13
 139 #define REV_82551_E     14
 140 #define REV_82551_F     15
 141 #define REV_82551_10    16
 142 
 143 /*
 144  * Device registers.
 145  */
 146 #define CSR_STATE       0x00
 147 #define CSR_STS         0x01
 148 #define CSR_CMD         0x02
 149 #define CSR_INTCTL      0x03
 150 #define CSR_GEN_PTR     0x04
 151 #define CSR_PORT        0x08
 152 #define CSR_EECTL       0x0e
 153 #define CSR_MDICTL      0x10
 154 
 155 #define STATE_CUS       0xc0    /* CU state (mask) */
 156 #define STATE_CUS_IDLE  0x00    /* CU idle */
 157 #define STATE_CUS_SUSP  0x40    /* CU suspended */
 158 #define STATE_CUS_LPQA  0x80    /* LPQ active */
 159 #define STATE_CUS_HQPA  0xc0    /* HQP active */
 160 #define STATE_RUS       0x3c    /* RU state (mask) */
 161 #define STATE_RUS_IDLE  0x00    /* RU idle */
 162 #define STATE_RUS_SUSP  0x04    /* RU suspended */
 163 #define STATE_RUS_NORES 0x08    /* RU no resources */
 164 #define STATE_RUS_READY 0x10    /* RU ready */
 165 
 166 #define STS_FCP         0x01    /* flow control pause */
 167 #define STS_RSVD        0x02    /* reserved bit */
 168 #define STS_SWI         0x04    /* software interrupt */
 169 #define STS_MDI         0x08    /* MDI read/write done */
 170 #define STS_RNR         0x10    /* RU not ready */
 171 #define STS_CNA         0x20    /* CU state change */
 172 #define STS_FR          0x40    /* frame receive */
 173 #define STS_CX          0x80    /* cmd exec done */
 174 
 175 #define CMD_CUC         0xf0    /* CU command (mask) */
 176 #define CUC_NOP         0x00    /* no operation */
 177 #define CUC_START       0x10    /* start CU */
 178 #define CUC_RESUME      0x20    /* resume CU */
 179 #define CUC_STATSBASE   0x40    /* load statistics address */
 180 #define CUC_STATS       0x50    /* dump statistics */
 181 #define CUC_CUBASE      0x60    /* load CU base address */
 182 #define CUC_STATS_RST   0x70    /* dump statistics and reset */
 183 #define CUC_SRES        0xa0    /* static resume CU */
 184 #define CMD_RUC         0x07    /* RU command (mask) */
 185 #define RUC_NOP         0x00    /* no operation */
 186 #define RUC_START       0x01    /* start RU */
 187 #define RUC_RESUME      0x02    /* resume RU */
 188 #define RUC_DMAREDIR    0x03    /* receive DMA redirect */
 189 #define RUC_ABORT       0x40    /* abort RU */
 190 #define RUC_HDRSZ       0x50    /* load header data size */
 191 #define RUC_RUBASE      0x60    /* load RU base address */
 192 
 193 #define INTCTL_MASK     0x01    /* disable all interrupts */
 194 #define INTCTL_SI       0x02    /* generate software interrupt */
 195 #define INTCTL_FCP      0x04    /* flow control pause */
 196 #define INTCTL_ER       0x08    /* early receive */
 197 #define INTCTL_RNR      0x10    /* RU not ready */
 198 #define INTCTL_CNA      0x20    /* CU state change */
 199 #define INTCTL_FR       0x40    /* frame receive */
 200 #define INTCTL_CX       0x80    /* cmd exec done */
 201 
 202 #define PORT_SW_RESET   0x00
 203 #define PORT_SELF_TEST  0x01
 204 #define PORT_SEL_RESET  0x02
 205 
 206 #define EEPROM_EEDO     0x0008  /* data out */
 207 #define EEPROM_EEDI     0x0004  /* data in */
 208 #define EEPROM_EECS     0x0002  /* chip select */
 209 #define EEPROM_EESK     0x0001  /* clock */
 210 
 211 #define EEPROM_OP_RD    0x06
 212 #define EEPROM_OP_WR    0x05
 213 #define EEPROM_OP_WE    0x13    /* write enable */
 214 #define EEPROM_OP_WD    0x13    /* write disable */
 215 
 216 #define MDI_IE          0x20000000      /* interrupt enable */
 217 #define MDI_R           0x10000000      /* ready */
 218 #define MDI_OP_RD       0x08000000      /* read */
 219 #define MDI_OP_WR       0x04000000      /* write */
 220 #define MDI_PHYAD_SHIFT 21
 221 #define MDI_REGAD_SHIFT 16
 222 
 223 #define GET8(ip, offset)                                        \
 224         ddi_get8(ip->regsh, (void *)(ip->regs + (offset)))
 225 #define GET16(ip, offset)                                       \
 226         ddi_get16(ip->regsh, (void *)(ip->regs + (offset)))
 227 #define GET32(ip, offset)                                       \
 228         ddi_get32(ip->regsh, (void *)(ip->regs + (offset)))
 229 #define PUT8(ip, offset, val)                                           \
 230         ddi_put8(ip->regsh, (void *)(ip->regs + (offset)), (val))
 231 #define PUT16(ip, offset, val)                                          \
 232         ddi_put16(ip->regsh, (void *)(ip->regs + (offset)), (val))
 233 #define PUT32(ip, offset, val)                                          \
 234         ddi_put32(ip->regsh, (void *)(ip->regs + (offset)), (val))
 235 
 236 
 237 #define PUTDMA8(d, off, val)                                    \
 238         ddi_put8(d->acch, (void *)(d->vaddr + (off)), LE_8(val))
 239 #define PUTDMA16(d, off, val)                                           \
 240         ddi_put16(d->acch, (void *)(d->vaddr + (off)), LE_16(val))
 241 #define PUTDMA32(d, off, val)                                           \
 242         ddi_put32(d->acch, (void *)(d->vaddr + (off)), LE_32(val))
 243 #define GETDMA8(d, off)                                         \
 244         LE_8(ddi_get8(d->acch, (void *)(d->vaddr + (off))))
 245 #define GETDMA16(d, off)                                        \
 246         LE_16(ddi_get16(d->acch, (void *)(d->vaddr + (off))))
 247 #define GETDMA32(d, off)                                        \
 248         LE_32(ddi_get32(d->acch, (void *)(d->vaddr + (off))))
 249 #define SYNCDMA(d, off, size, dir)                      \
 250         (void) ddi_dma_sync(d->dmah, off, size, dir)
 251 
 252 /*
 253  * Command block offsets.
 254  */
 255 #define CB_STS_OFFSET           0
 256 #define CB_CMD_OFFSET           2
 257 #define CB_LNK_OFFSET           4
 258 #define CB_SIZE                 2048    /* size of cmd blk */
 259 
 260 #define CB_IAS_ADR_OFFSET       8
 261 
 262 #define CB_MCS_CNT_OFFSET       8
 263 #define CB_MCS_ADR_OFFSET       10
 264 #define CB_MCS_CNT_MAX          ((CB_SIZE - CB_MCS_ADR_OFFSET) / 6)
 265 
 266 #define CB_UCODE_OFFSET         8
 267 
 268 #define CB_CONFIG_OFFSET        8
 269 
 270 #define CB_TX_TBD_OFFSET        8
 271 #define CB_TX_COUNT_OFFSET      12
 272 #define CB_TX_EOF               0x8000
 273 #define CB_TX_THRESH_OFFSET     14
 274 #define CB_TX_NUMBER_OFFSET     15
 275 #define CB_TX_DATA_OFFSET       16
 276 
 277 #define PUTCB8(cb, o, v)        PUTDMA8(cb, o, v)
 278 #define PUTCB16(cb, o, v)       PUTDMA16(cb, o, v)
 279 #define PUTCB32(cb, o, v)       PUTDMA32(cb, o, v)
 280 #define PUTCBEA(cb, o, enet)                                            \
 281         ddi_rep_put8(cb->acch, enet, (void *)(cb->vaddr + (o)), 6,        \
 282         DDI_DEV_AUTOINCR);
 283 #define GETCB8(cb, o)           GETDMA8(cb, o)
 284 #define GETCB16(cb, o)          GETDMA16(cb, o)
 285 #define GETCB32(cb, o)          GETDMA32(cb, o)
 286 #define SYNCCB(cb, o, s, dir)   SYNCDMA(cb, o, s, dir)
 287 /*
 288  * CB status bits.
 289  */
 290 #define CB_STS_OK               0x2000
 291 #define CB_STS_C                0x8000
 292 
 293 /*
 294  * Commands.
 295  */
 296 #define CB_CMD_NOP              0x0
 297 #define CB_CMD_IAS              0x1
 298 #define CB_CMD_CONFIG           0x2
 299 #define CB_CMD_MCS              0x3
 300 #define CB_CMD_TX               0x4
 301 #define CB_CMD_UCODE            0x5
 302 /* and flags to go with */
 303 #define CB_CMD_SF               0x0008  /* simple/flex */
 304 #define CB_CMD_I                0x2000  /* generate an interrupt */
 305 #define CB_CMD_S                0x4000  /* suspend on completion */
 306 #define CB_CMD_EL               0x8000  /* end of list */
 307 
 308 /*
 309  * RFD offsets.
 310  */
 311 #define GETRFD16(r, o)          GETDMA16(r, o)
 312 #define PUTRFD16(r, o, v)       PUTDMA16(r, o, v)
 313 #define PUTRFD32(r, o, v)       PUTDMA32(r, o, v)
 314 #define SYNCRFD(r, o, s, dir)   SYNCDMA(r, o, s, dir)
 315 
 316 #define RFD_STS_OFFSET          0x00
 317 #define RFD_CTL_OFFSET          0x02
 318 #define RFD_LNK_OFFSET          0x04
 319 #define RFD_CNT_OFFSET          0x0c    /* bytes received */
 320 #define RFD_SIZ_OFFSET          0x0e    /* size of packet area */
 321 #define RFD_PKT_OFFSET          0x10
 322 #define RFD_SIZE                2048
 323 
 324 #define RFD_CTL_EL              0x8000
 325 #define RFD_CTL_S               0x4000
 326 #define RFD_CTL_H               0x0010
 327 #define RFD_CTL_SF              0x0008
 328 
 329 #define RFD_STS_C               0x8000
 330 #define RFD_STS_OK              0x2000
 331 #define RFD_STS_FCS             0x0800
 332 #define RFD_STS_ALIGN           0x0400
 333 #define RFD_STS_TOOBIG          0x0200
 334 #define RFD_STS_DMAOFLO         0x0100
 335 #define RFD_STS_TOOSHORT        0x0080
 336 #define RFD_STS_802             0x0020
 337 #define RFD_STS_RXERR           0x0010
 338 #define RFD_STS_NOMATCH         0x0004
 339 #define RFD_STS_IAMATCH         0x0002
 340 #define RFD_STS_COLL_TCO        0x0001
 341 #define RFD_STS_ERRS            0x0d90
 342 
 343 #define RFD_CNT_EOF             0x8000
 344 #define RFD_CNT_F               0x4000
 345 
 346 /*
 347  * Stats offsets.
 348  */
 349 #define STATS_TX_GOOD_OFFSET    0
 350 #define STATS_TX_MAXCOL_OFFSET  4
 351 #define STATS_TX_LATECOL_OFFSET 8
 352 #define STATS_TX_UFLO_OFFSET    16
 353 #define STATS_TX_DEFER_OFFSET   20
 354 #define STATS_TX_ONECOL_OFFSET  24
 355 #define STATS_TX_MULTCOL_OFFSET 28
 356 #define STATS_TX_TOTCOL_OFFSET  32
 357 #define STATS_RX_GOOD_OFFSET    36
 358 #define STATS_RX_FCS_OFFSET     40
 359 #define STATS_RX_ALIGN_OFFSET   44
 360 #define STATS_RX_NOBUF_OFFSET   48
 361 #define STATS_RX_OFLO_OFFSET    52
 362 #define STATS_RX_COL_OFFSET     56
 363 #define STATS_RX_SHORT_OFFSET   60
 364 #define STATS_DONE_OFFSET       64
 365 #define STATS_SIZE              68
 366 #define STATS_DONE              0xa005
 367 #define STATS_RST_DONE          0xa007
 368 
 369 #define SYNCSTATS(sp, o, s, dir)        SYNCDMA(sp, o, s, dir)
 370 #define PUTSTAT(sp, o, v)               PUTDMA32(sp, o, v)
 371 #define GETSTAT(sp, o)                  GETDMA32(sp, o)
 372 
 373 #endif /* _IPRB_H */