/*
* Solaris driver for ethernet cards based on the Macronix 98715
*
* Copyright (c) 2007 by Garrett D'Amore <garrett@damore.org>.
* 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 <sys/mac_provider.h>
/*
* 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 */