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