/* * Solaris driver for ethernet cards based on the Macronix 98715 * * Copyright (c) 2007 by Garrett D'Amore . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _MXFEIMPL_H #define _MXFEIMPL_H /* * This entire file is private to the MXFE driver. */ #ifdef _KERNEL #include /* * Compile time tunables. */ #define MXFE_TXRING 128 /* number of xmt buffers */ #define MXFE_RXRING 256 /* number of rcv buffers */ #define MXFE_TXRECLAIM 32 /* when to reclaim tx buffers (txavail) */ #define MXFE_TXRESCHED 120 /* when to resched (txavail) */ #define MXFE_LINKTIMER 5000 /* how often we check link state (msec) */ #define MXFE_HEADROOM 34 /* headroom in packet (should be 2 modulo 4) */ /* * Constants, do not change. The bufsize is setup to make sure it comes * in at a whole number of cache lines, even for 32-long-word aligned * caches. */ #define MXFE_BUFSZ (1664) /* big enough for a vlan frame */ #define MXFE_SETUP_LEN 192 /* size of a setup frame */ typedef struct mxfe mxfe_t; typedef struct mxfe_card mxfe_card_t; typedef struct mxfe_rxbuf mxfe_rxbuf_t; typedef struct mxfe_txbuf mxfe_txbuf_t; typedef struct mxfe_desc mxfe_desc_t; struct mxfe_card { uint16_t card_venid; /* PCI vendor id */ uint16_t card_devid; /* PCI device id */ uint16_t card_revid; /* PCI revision id */ uint16_t card_revmask; char *card_cardname; /* Description of the card */ unsigned card_model; /* Card specific flags */ }; /* * Device instance structure, one per PCI card. */ struct mxfe { dev_info_t *mxfe_dip; mac_handle_t mxfe_mh; mxfe_card_t *mxfe_cardp; ushort_t mxfe_cachesize; ushort_t mxfe_sromwidth; int mxfe_flags; kmutex_t mxfe_xmtlock; kmutex_t mxfe_intrlock; ddi_iblock_cookie_t mxfe_icookie; /* * Register access. */ uint32_t *mxfe_regs; ddi_acc_handle_t mxfe_regshandle; /* * Receive descriptors. */ int mxfe_rxhead; struct mxfe_desc *mxfe_rxdescp; ddi_dma_handle_t mxfe_rxdesc_dmah; ddi_acc_handle_t mxfe_rxdesc_acch; uint32_t mxfe_rxdesc_paddr; struct mxfe_rxbuf **mxfe_rxbufs; /* * Transmit descriptors. */ int mxfe_txreclaim; int mxfe_txsend; int mxfe_txavail; struct mxfe_desc *mxfe_txdescp; ddi_dma_handle_t mxfe_txdesc_dmah; ddi_acc_handle_t mxfe_txdesc_acch; uint32_t mxfe_txdesc_paddr; struct mxfe_txbuf **mxfe_txbufs; hrtime_t mxfe_txstall_time; boolean_t mxfe_wantw; /* * Address management. */ uchar_t mxfe_curraddr[ETHERADDRL]; boolean_t mxfe_promisc; /* * Link state. */ int mxfe_nwaystate; uint64_t mxfe_lastifspeed; link_duplex_t mxfe_lastduplex; link_state_t mxfe_lastlinkup; link_state_t mxfe_linkup; link_duplex_t mxfe_duplex; uint64_t mxfe_ifspeed; boolean_t mxfe_resetting; /* no link warning */ /* * Transceiver stuff. */ int mxfe_phyaddr; int mxfe_phyid; int mxfe_phyinuse; uint8_t mxfe_adv_aneg; uint8_t mxfe_adv_100T4; uint8_t mxfe_adv_100fdx; uint8_t mxfe_adv_100hdx; uint8_t mxfe_adv_10fdx; uint8_t mxfe_adv_10hdx; uint8_t mxfe_cap_aneg; uint8_t mxfe_cap_100T4; uint8_t mxfe_cap_100fdx; uint8_t mxfe_cap_100hdx; uint8_t mxfe_cap_10fdx; uint8_t mxfe_cap_10hdx; int mxfe_forcephy; uint16_t mxfe_bmsr; uint16_t mxfe_anlpar; uint16_t mxfe_aner; /* * Kstats. */ kstat_t *mxfe_intrstat; uint64_t mxfe_ipackets; uint64_t mxfe_opackets; uint64_t mxfe_rbytes; uint64_t mxfe_obytes; uint64_t mxfe_brdcstrcv; uint64_t mxfe_multircv; uint64_t mxfe_brdcstxmt; uint64_t mxfe_multixmt; unsigned mxfe_norcvbuf; unsigned mxfe_noxmtbuf; unsigned mxfe_errrcv; unsigned mxfe_errxmt; unsigned mxfe_missed; unsigned mxfe_underflow; unsigned mxfe_overflow; unsigned mxfe_align_errors; unsigned mxfe_fcs_errors; unsigned mxfe_carrier_errors; unsigned mxfe_collisions; unsigned mxfe_ex_collisions; unsigned mxfe_tx_late_collisions; unsigned mxfe_defer_xmts; unsigned mxfe_first_collisions; unsigned mxfe_multi_collisions; unsigned mxfe_sqe_errors; unsigned mxfe_macxmt_errors; unsigned mxfe_macrcv_errors; unsigned mxfe_toolong_errors; unsigned mxfe_runt; unsigned mxfe_jabber; }; struct mxfe_rxbuf { caddr_t rxb_buf; ddi_dma_handle_t rxb_dmah; ddi_acc_handle_t rxb_acch; uint32_t rxb_paddr; }; struct mxfe_txbuf { /* bcopy version of tx */ caddr_t txb_buf; uint32_t txb_paddr; ddi_dma_handle_t txb_dmah; ddi_acc_handle_t txb_acch; }; /* * Descriptor. We use rings rather than chains. */ struct mxfe_desc { unsigned desc_status; unsigned desc_control; unsigned desc_buffer1; unsigned desc_buffer2; }; #define PUTTXDESC(mxfep, member, val) \ ddi_put32(mxfep->mxfe_txdesc_acch, &member, val) #define PUTRXDESC(mxfep, member, val) \ ddi_put32(mxfep->mxfe_rxdesc_acch, &member, val) #define GETTXDESC(mxfep, member) \ ddi_get32(mxfep->mxfe_txdesc_acch, &member) #define GETRXDESC(mxfep, member) \ ddi_get32(mxfep->mxfe_rxdesc_acch, &member) /* * Receive descriptor fields. */ #define RXSTAT_OWN 0x80000000U /* ownership */ #define RXSTAT_RXLEN 0x3FFF0000U /* frame length, incl. crc */ #define RXSTAT_RXERR 0x00008000U /* error summary */ #define RXSTAT_DESCERR 0x00004000U /* descriptor error */ #define RXSTAT_RXTYPE 0x00003000U /* data type */ #define RXSTAT_RUNT 0x00000800U /* runt frame */ #define RXSTAT_GROUP 0x00000400U /* multicast/brdcast frame */ #define RXSTAT_FIRST 0x00000200U /* first descriptor */ #define RXSTAT_LAST 0x00000100U /* last descriptor */ #define RXSTAT_TOOLONG 0x00000080U /* frame too long */ #define RXSTAT_COLLSEEN 0x00000040U /* late collision seen */ #define RXSTAT_FRTYPE 0x00000020U /* frame type */ #define RXSTAT_WATCHDOG 0x00000010U /* receive watchdog */ #define RXSTAT_DRIBBLE 0x00000004U /* dribbling bit */ #define RXSTAT_CRCERR 0x00000002U /* crc error */ #define RXSTAT_OFLOW 0x00000001U /* fifo overflow */ #define RXSTAT_ERRS (RXSTAT_DESCERR | RXSTAT_RUNT | \ RXSTAT_COLLSEEN | RXSTAT_DRIBBLE | \ RXSTAT_CRCERR | RXSTAT_OFLOW) #define RXLENGTH(x) ((x & RXSTAT_RXLEN) >> 16) #define RXCTL_ENDRING 0x02000000U /* end of ring */ #define RXCTL_CHAIN 0x01000000U /* chained descriptors */ #define RXCTL_BUFLEN2 0x003FF800U /* buffer 2 length */ #define RXCTL_BUFLEN1 0x000007FFU /* buffer 1 length */ /* * Transmit descriptor fields. */ #define TXSTAT_OWN 0x80000000U /* ownership */ #define TXSTAT_URCNT 0x00C00000U /* underrun count */ #define TXSTAT_TXERR 0x00008000U /* error summary */ #define TXSTAT_JABBER 0x00004000U /* jabber timeout */ #define TXSTAT_CARRLOST 0x00000800U /* lost carrier */ #define TXSTAT_NOCARR 0x00000400U /* no carrier */ #define TXSTAT_LATECOL 0x00000200U /* late collision */ #define TXSTAT_EXCOLL 0x00000100U /* excessive collisions */ #define TXSTAT_SQE 0x00000080U /* heartbeat failure */ #define TXSTAT_COLLCNT 0x00000078U /* collision count */ #define TXSTAT_UFLOW 0x00000002U /* underflow */ #define TXSTAT_DEFER 0x00000001U /* deferred */ #define TXCOLLCNT(x) ((x & TXSTAT_COLLCNT) >> 3) #define TXUFLOWCNT(x) ((x & TXSTAT_URCNT) >> 22) #define TXCTL_INTCMPLTE 0x80000000U /* interrupt completed */ #define TXCTL_LAST 0x40000000U /* last descriptor */ #define TXCTL_FIRST 0x20000000U /* first descriptor */ #define TXCTL_NOCRC 0x04000000U /* disable crc */ #define TXCTL_SETUP 0x08000000U /* setup frame */ #define TXCTL_ENDRING 0x02000000U /* end of ring */ #define TXCTL_CHAIN 0x01000000U /* chained descriptors */ #define TXCTL_NOPAD 0x00800000U /* disable padding */ #define TXCTL_HASHPERF 0x00400000U /* hash perfect mode */ #define TXCTL_BUFLEN2 0x003FF800U /* buffer length 2 */ #define TXCTL_BUFLEN1 0x000007FFU /* buffer length 1 */ /* * Interface flags. */ #define MXFE_RUNNING 0x1 /* chip is initialized */ #define MXFE_SUSPENDED 0x2 /* interface is suspended */ #define MXFE_SYMBOL 0x8 /* use symbol mode */ /* * Link flags... */ #define MXFE_NOLINK 0x0 /* initial link state, no timer */ #define MXFE_NWAYCHECK 0x2 /* checking for NWay support */ #define MXFE_NWAYRENEG 0x3 /* renegotiating NWay mode */ #define MXFE_GOODLINK 0x4 /* detected link is good */ /* * Card models. */ #define MXFE_MODEL(mxfep) ((mxfep)->mxfe_cardp->card_model) #define MXFE_98715 0x1 #define MXFE_98715A 0x2 #define MXFE_98715AEC 0x3 #define MXFE_98715B 0x4 #define MXFE_98725 0x5 #define MXFE_98713 0x6 #define MXFE_98713A 0x7 #define MXFE_PNICII 0x8 /* * Register definitions located in mxfe.h exported header file. */ /* * Macros to simplify hardware access. Note that the reg/4 is used to * help with pointer arithmetic. */ #define GETCSR(mxfep, reg) \ ddi_get32(mxfep->mxfe_regshandle, mxfep->mxfe_regs + (reg/4)) #define PUTCSR(mxfep, reg, val) \ ddi_put32(mxfep->mxfe_regshandle, mxfep->mxfe_regs + (reg/4), val) #define SETBIT(mxfep, reg, val) \ PUTCSR(mxfep, reg, GETCSR(mxfep, reg) | (val)) #define CLRBIT(mxfep, reg, val) \ PUTCSR(mxfep, reg, GETCSR(mxfep, reg) & ~(val)) #define SYNCTXDESC(mxfep, index, who) \ (void) ddi_dma_sync(mxfep->mxfe_txdesc_dmah, \ (index * sizeof (mxfe_desc_t)), sizeof (mxfe_desc_t), who) #define SYNCTXBUF(txb, len, who) \ (void) (ddi_dma_sync(txb->txb_dmah, 0, len, who)) #define SYNCRXDESC(mxfep, index, who) \ (void) ddi_dma_sync(mxfep->mxfe_rxdesc_dmah, \ (index * sizeof (mxfe_desc_t)), sizeof (mxfe_desc_t), who) #define SYNCRXBUF(rxb, len, who) \ (void) (ddi_dma_sync(rxb->rxb_dmah, 0, len, who)) /* * Debugging flags. */ #define DWARN 0x0001 #define DINTR 0x0002 #define DWSRV 0x0004 #define DMACID 0x0008 #define DDLPI 0x0010 #define DPHY 0x0020 #define DPCI 0x0040 #define DCHATTY 0x0080 #define DDMA 0x0100 #define DLINK 0x0200 #define DSROM 0x0400 #define DRECV 0x0800 #define DXMIT 0x1000 #ifdef DEBUG #define DBG(lvl, ...) mxfe_dprintf(mxfep, __func__, lvl, __VA_ARGS__); #else #define DBG(lvl, ...) #endif #endif /* _KERNEL */ #endif /* _MXFEIMPL_H */