summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorgd78059 <none@none>2007-04-25 16:13:46 -0700
committergd78059 <none@none>2007-04-25 16:13:46 -0700
commitcc291a4c7fa2364298503d990fac11ec307b1765 (patch)
tree5da06febb7e616c5ba40c01f84f1dca5cb3410f8 /usr/src
parentc17d6d0368a95d88a7901e522b92d3f7b95da5da (diff)
downloadillumos-gate-cc291a4c7fa2364298503d990fac11ec307b1765.tar.gz
PSARC 2007/221 DMFE conversion to GLDv3
6547091 dmfe should be converted to nemo
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/sun4u/dmfe/Makefile4
-rw-r--r--usr/src/uts/sun4u/io/dmfe/dmfe_main.c1200
-rw-r--r--usr/src/uts/sun4u/io/dmfe/dmfe_mii.c100
-rw-r--r--usr/src/uts/sun4u/sys/dmfe_impl.h191
4 files changed, 610 insertions, 885 deletions
diff --git a/usr/src/uts/sun4u/dmfe/Makefile b/usr/src/uts/sun4u/dmfe/Makefile
index f54fb779fe..db0b6a2f4f 100644
--- a/usr/src/uts/sun4u/dmfe/Makefile
+++ b/usr/src/uts/sun4u/dmfe/Makefile
@@ -20,7 +20,7 @@
#
#
# uts/sun4u/dmfe/Makefile
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -72,7 +72,7 @@ CFLAGS += $(CCVERBOSE)
#
# extra link arguments
#
-LDFLAGS += -dy -N misc/gld -N drv/ip
+LDFLAGS += -dy -N misc/mac -N drv/ip
#
# For now, disable these lint checks; maintainers should endeavor
diff --git a/usr/src/uts/sun4u/io/dmfe/dmfe_main.c b/usr/src/uts/sun4u/io/dmfe/dmfe_main.c
index c8c1d479dd..bd12b6d5b8 100644
--- a/usr/src/uts/sun4u/io/dmfe/dmfe_main.c
+++ b/usr/src/uts/sun4u/io/dmfe/dmfe_main.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,9 +29,8 @@
/*
* This is the string displayed by modinfo, etc.
- * Make sure you keep the version ID up to date!
*/
-static char dmfe_ident[] = "Davicom DM9102 v2.4";
+static char dmfe_ident[] = "Davicom DM9102 Ethernet";
/*
@@ -195,24 +194,37 @@ static uint32_t factotum_fast_tix;
static uint32_t factotum_start_tix;
/*
- * Versions of the O/S up to Solaris 8 didn't support network booting
- * from any network interface except the first (NET0). Patching this
- * flag to a non-zero value will tell the driver to work around this
- * limitation by creating an extra (internal) pathname node. To do
- * this, just add a line like the following to the CLIENT'S etc/system
- * file ON THE ROOT FILESYSTEM SERVER before booting the client:
- *
- * set dmfe:dmfe_net1_boot_support = 1;
- */
-static uint32_t dmfe_net1_boot_support = 0;
-
-/*
* Property names
*/
static char localmac_propname[] = "local-mac-address";
static char opmode_propname[] = "opmode-reg-value";
static char debug_propname[] = "dmfe-debug-flags";
+static int dmfe_m_start(void *);
+static void dmfe_m_stop(void *);
+static int dmfe_m_promisc(void *, boolean_t);
+static int dmfe_m_multicst(void *, boolean_t, const uint8_t *);
+static int dmfe_m_unicst(void *, const uint8_t *);
+static void dmfe_m_ioctl(void *, queue_t *, mblk_t *);
+static boolean_t dmfe_m_getcapab(void *, mac_capab_t, void *);
+static mblk_t *dmfe_m_tx(void *, mblk_t *);
+static int dmfe_m_stat(void *, uint_t, uint64_t *);
+
+static mac_callbacks_t dmfe_m_callbacks = {
+ (MC_IOCTL | MC_GETCAPAB),
+ dmfe_m_stat,
+ dmfe_m_start,
+ dmfe_m_stop,
+ dmfe_m_promisc,
+ dmfe_m_multicst,
+ dmfe_m_unicst,
+ dmfe_m_tx,
+ NULL,
+ dmfe_m_ioctl,
+ dmfe_m_getcapab,
+};
+
+
/*
* Describes the chip's DMA engine
*/
@@ -348,8 +360,6 @@ dmfe_set_opmode(dmfe_t *dmfep)
static void
dmfe_stop_chip(dmfe_t *dmfep, enum chip_state newstate)
{
- DMFE_TRACE(("dmfe_stop_chip($%p, %d)", (void *)dmfep, newstate));
-
ASSERT(mutex_owned(dmfep->oplock));
/*
@@ -481,21 +491,17 @@ dmfe_init_rings(dmfe_t *dmfep)
static void
dmfe_start_chip(dmfe_t *dmfep, int mode)
{
- DMFE_TRACE(("dmfe_start_chip($%p, %d)", (void *)dmfep, mode));
-
ASSERT(mutex_owned(dmfep->oplock));
dmfep->opmode |= mode;
dmfe_set_opmode(dmfep);
dmfe_chip_put32(dmfep, W_J_TIMER_REG, 0);
-#if defined(VLAN_VID_NONE)
/*
* Enable VLAN length mode (allows packets to be 4 bytes Longer).
*/
- if (gld_recv_tagged != NULL)
- dmfe_chip_put32(dmfep, W_J_TIMER_REG, VLAN_ENABLE);
-#endif
+ dmfe_chip_put32(dmfep, W_J_TIMER_REG, VLAN_ENABLE);
+
/*
* Clear any pending process-stopped interrupts
*/
@@ -572,11 +578,11 @@ dmfe_update_rx_stats(dmfe_t *dmfep, uint32_t desc0)
* the last-fragment and error summary bits are set.
*/
if (((RX_LAST_DESC | RX_ERR_SUMMARY) & ~desc0) == 0) {
- dmfep->rx_stats_errrcv += 1;
+ dmfep->rx_stats_ierrors += 1;
/*
* There are some other error bits in the descriptor for
- * which there don't seem to be appropriate GLD statistics,
+ * which there don't seem to be appropriate MAC statistics,
* notably RX_COLLISION and perhaps RX_DESC_ERR. The
* latter may not be possible if it is supposed to indicate
* that one buffer has been filled with a partial packet
@@ -585,16 +591,17 @@ dmfe_update_rx_stats(dmfe_t *dmfep, uint32_t desc0)
* enough for a whole packet without fragmenting.
*/
- if (desc0 & RX_OVERFLOW)
+ if (desc0 & RX_OVERFLOW) {
dmfep->rx_stats_overflow += 1;
- else if (desc0 & RX_RUNT_FRAME)
+
+ } else if (desc0 & RX_RUNT_FRAME)
dmfep->rx_stats_short += 1;
if (desc0 & RX_CRC)
- dmfep->rx_stats_crc += 1;
+ dmfep->rx_stats_fcs += 1;
if (desc0 & RX_FRAME2LONG)
- dmfep->rx_stats_frame_too_long += 1;
+ dmfep->rx_stats_toolong += 1;
}
/*
@@ -603,45 +610,21 @@ dmfe_update_rx_stats(dmfe_t *dmfep, uint32_t desc0)
* according to the chip data sheet :-?
*/
if (desc0 & RX_RCV_WD_TO)
- dmfep->rx_stats_mac_rcv_error += 1;
+ dmfep->rx_stats_macrcv_errors += 1;
if (desc0 & RX_DRIBBLING)
- dmfep->rx_stats_frame += 1;
+ dmfep->rx_stats_align += 1;
+
if (desc0 & RX_MII_ERR)
- dmfep->rx_stats_mac_rcv_error += 1;
+ dmfep->rx_stats_macrcv_errors += 1;
}
/*
- * Ethernet packet-checking macros used in the receive code below.
- * The <eap> parameter should be a pointer to the destination address found
- * at the start of a received packet (an array of 6 (ETHERADDRL) bytes).
- *
- * A packet is intended for this station if the destination address exactly
- * matches our own physical (unicast) address.
- *
- * A packet is a multicast (including broadcast) packet if the low-order bit
- * of the first byte of the destination address is set (unicast addresses
- * always have a zero in this bit).
- *
- * A packet should be passed up to GLD if it's multicast OR addressed to us
- * OR if the device is in promiscuous mode, when all packets are passed up
- * anyway.
- */
-#define PKT_IS_MINE(eap, dmfep) (ether_cmp(eap, dmfep->curr_addr) == 0)
-#define PKT_IS_MULTICAST(eap) (eap[0] & 1)
-#define DEV_IS_PROMISC(dmfep) ((dmfep->opmode & PROMISC_MODE) != 0)
-
-#define PKT_WANTED(eap, dmfep) (PKT_IS_MULTICAST(eap) || \
- PKT_IS_MINE(eap, dmfep) || \
- DEV_IS_PROMISC(dmfep))
-
-/*
* Receive incoming packet(s) and pass them up ...
*/
static mblk_t *
dmfe_getp(dmfe_t *dmfep)
{
- struct ether_header *ehp;
dma_area_t *descp;
mblk_t **tail;
mblk_t *head;
@@ -653,15 +636,13 @@ dmfe_getp(dmfe_t *dmfep)
int packet_length;
int index;
- DMFE_TRACE(("dmfe_getp($%p)", (void *)dmfep));
-
mutex_enter(dmfep->rxlock);
/*
* Update the missed frame statistic from the on-chip counter.
*/
misses = dmfe_chip_get32(dmfep, MISSED_FRAME_REG);
- dmfep->rx_stats_missed += (misses & MISSED_FRAME_MASK);
+ dmfep->rx_stats_norcvbuf += (misses & MISSED_FRAME_MASK);
/*
* sync (all) receive descriptors before inspecting them
@@ -713,6 +694,14 @@ dmfe_getp(dmfe_t *dmfep)
"length %d", packet_length));
goto skip;
} else if (packet_length < ETHERMIN) {
+ /*
+ * Note that VLAN packet would be even larger,
+ * but we don't worry about dropping runt VLAN
+ * frames.
+ *
+ * This check is probably redundant, as well,
+ * since the hardware should drop RUNT frames.
+ */
DMFE_DEBUG(("dmfe_getp: dropping undersize packet, "
"length %d", packet_length));
goto skip;
@@ -730,11 +719,14 @@ dmfe_getp(dmfe_t *dmfep)
index*DMFE_BUF_SIZE, DMFE_BUF_SIZE,
DDI_DMA_SYNC_FORKERNEL);
rxb = &dmfep->rx_buff.mem_va[index*DMFE_BUF_SIZE];
- ehp = (struct ether_header *)rxb;
- if (!PKT_WANTED(ehp->ether_dhost.ether_addr_octet, dmfep)) {
- DMFE_DEBUG(("dmfe_getp: dropping aliased packet"));
- goto skip;
- }
+
+
+ /*
+ * We do not bother to check that the packet is really for
+ * us, we let the MAC framework make that check instead.
+ * This is especially important if we ever want to support
+ * multiple MAC addresses.
+ */
/*
* Packet looks good; get a buffer to copy it into. We
@@ -752,46 +744,29 @@ dmfe_getp(dmfe_t *dmfep)
}
/*
+ * Account for statistics of good packets.
+ */
+ dmfep->rx_stats_ipackets += 1;
+ dmfep->rx_stats_rbytes += packet_length;
+ if (desc0 & RX_MULTI_FRAME) {
+ if (bcmp(rxb, dmfe_broadcast_addr, ETHERADDRL)) {
+ dmfep->rx_stats_multi += 1;
+ } else {
+ dmfep->rx_stats_bcast += 1;
+ }
+ }
+
+ /*
* Copy the packet into the STREAMS buffer
*/
dp = mp->b_rptr += DMFE_HEADROOM;
mp->b_cont = mp->b_next = NULL;
-#if !defined(VLAN_VID_NONE)
- bcopy(rxb, dp, packet_length);
-#else
- if (ehp->ether_type != ETHERTYPE_VLAN ||
- gld_recv_tagged == NULL) {
- /*
- * An untagged packet (or, there's no runtime support
- * for tagging so we treat all packets as untagged).
- * Just copy the contents verbatim.
- */
- bcopy(rxb, dp, packet_length);
- } else {
- /*
- * A tagged packet. Extract the vtag & stash it in
- * the b_cont field (we know that it's safe to grab
- * the vtag directly because the way buffers are
- * allocated guarantees their alignment). Copy the
- * rest of the packet data to the mblk, dropping the
- * vtag in the process.
- *
- * The magic number (2*ETHERADDRL) appears quite a
- * lot here, because the vtag comes immediately after
- * the destination & source Ethernet addresses in
- * the packet header ...
- */
- bcopy(rxb, dp, 2*ETHERADDRL);
- rxb += 2*ETHERADDRL;
- dp += 2*ETHERADDRL;
- mp->b_cont = U32TOPTR(*(uint32_t *)rxb);
- rxb += VTAG_SIZE;
- packet_length -= VTAG_SIZE;
-
- bcopy(rxb, dp, packet_length - 2*ETHERADDRL);
- }
-#endif /* defined(VLAN_VID_NONE) */
+ /*
+ * Don't worry about stripping the vlan tag, the MAC
+ * layer will take care of that for us.
+ */
+ bcopy(rxb, dp, packet_length);
/*
* Fix up the packet length, and link it to the chain
@@ -826,40 +801,6 @@ dmfe_getp(dmfe_t *dmfep)
return (head);
}
-/*
- * Take a chain of mblks (as returned by dmfe_getp() above) and pass
- * them up to gld_recv() one at a time. This function should be called
- * with *no* driver-defined locks held.
- *
- * If the driver is compiled with VLAN support enabled, this function
- * also deals with routing vlan-tagged packets to the appropriate GLD
- * entry point (gld_recv_tagged()).
- */
-static void
-dmfe_passup_chain(gld_mac_info_t *macinfo, mblk_t *mp)
-{
- mblk_t *next;
- uint32_t vtag;
-
- ASSERT(mp != NULL);
-
- do {
- next = mp->b_next;
- mp->b_next = NULL;
-#if !defined(VLAN_VID_NONE)
- gld_recv(macinfo, mp);
-#else
- vtag = PTRTOU32(mp->b_cont);
- mp->b_cont = NULL;
- if (vtag != VLAN_VTAG_NONE && gld_recv_tagged != NULL)
- gld_recv_tagged(macinfo, mp, vtag);
- else
- gld_recv(macinfo, mp);
-#endif /* defined(VLAN_VID_NONE) */
- mp = next;
- } while (mp != NULL);
-}
-
#undef DMFE_DBG
@@ -936,7 +877,7 @@ dmfe_passup_chain(gld_mac_info_t *macinfo, mblk_t *mp)
* Function to update transmit statistics on various errors
*/
static void
-dmfe_update_tx_stats(dmfe_t *dmfep, uint32_t desc0)
+dmfe_update_tx_stats(dmfe_t *dmfep, int index, uint32_t desc0, uint32_t desc1)
{
uint32_t collisions;
uint32_t errbits;
@@ -954,7 +895,7 @@ dmfe_update_tx_stats(dmfe_t *dmfep, uint32_t desc0)
}
if (desc0 & TX_ERR_SUMMARY) {
- dmfep->tx_stats_errxmt += 1;
+ dmfep->tx_stats_oerrors += 1;
/*
* If we ever see a transmit jabber timeout, we count it
@@ -963,7 +904,7 @@ dmfe_update_tx_stats(dmfe_t *dmfep, uint32_t desc0)
* the chip in order to recover
*/
if (desc0 & TX_JABBER_TO)
- dmfep->tx_stats_mac_xmt_error += 1;
+ dmfep->tx_stats_macxmt_errors += 1;
if (desc0 & TX_UNDERFLOW)
dmfep->tx_stats_underflow += 1;
@@ -977,6 +918,21 @@ dmfe_update_tx_stats(dmfe_t *dmfep, uint32_t desc0)
dmfep->tx_stats_excoll += 1;
collisions = 16;
}
+ } else {
+ int bit = index % NBBY;
+ int byt = index / NBBY;
+
+ if (dmfep->tx_mcast[byt] & bit) {
+ dmfep->tx_mcast[byt] &= ~bit;
+ dmfep->tx_stats_multi += 1;
+
+ } else if (dmfep->tx_bcast[byt] & bit) {
+ dmfep->tx_bcast[byt] &= ~bit;
+ dmfep->tx_stats_bcast += 1;
+ }
+
+ dmfep->tx_stats_opackets += 1;
+ dmfep->tx_stats_obytes += desc1 & TX_BUFFER_SIZE1;
}
if (collisions == 1)
@@ -1004,8 +960,6 @@ dmfe_reclaim_tx_desc(dmfe_t *dmfep)
int nfree;
int i;
- DMFE_TRACE(("dmfe_reclaim_tx_desc($%p)", (void *)dmfep));
-
ASSERT(mutex_owned(dmfep->txlock));
/*
@@ -1061,7 +1015,7 @@ dmfe_reclaim_tx_desc(dmfe_t *dmfep)
*/
ASSERT(dmfe_ring_get32(descp, i, BUFFER1) ==
dmfep->tx_buff.mem_dvma + i*DMFE_BUF_SIZE);
- dmfe_update_tx_stats(dmfep, desc0);
+ dmfe_update_tx_stats(dmfep, i, desc0, desc1);
}
#if DMFEDEBUG
@@ -1102,8 +1056,8 @@ dmfe_reclaim_tx_desc(dmfe_t *dmfep)
* Send the message in the message block chain <mp>.
*
* The message is freed if and only if its contents are successfully copied
- * and queued for transmission (so that the return value is GLD_SUCCESS).
- * If we can't queue the message, the return value is GLD_NORESOURCES and
+ * and queued for transmission (so that the return value is B_TRUE).
+ * If we can't queue the message, the return value is B_FALSE and
* the message is *not* freed.
*
* This routine handles the special case of <mp> == NULL, which indicates
@@ -1112,8 +1066,8 @@ dmfe_reclaim_tx_desc(dmfe_t *dmfep)
* to say its a setup packet (from the global <dmfe_setup_desc1>), and the
* setup packet *isn't* freed after use.
*/
-static int
-dmfe_send_msg(dmfe_t *dmfep, mblk_t *mp, uint32_t vtag)
+static boolean_t
+dmfe_send_msg(dmfe_t *dmfep, mblk_t *mp)
{
dma_area_t *descp;
mblk_t *bp;
@@ -1123,9 +1077,6 @@ dmfe_send_msg(dmfe_t *dmfep, mblk_t *mp, uint32_t vtag)
size_t totlen;
size_t mblen;
- DMFE_TRACE(("dmfe_send_msg($%p, $%p, 0x%x)",
- (void *)dmfep, (void *)mp, vtag));
-
/*
* If the number of free slots is below the reclaim threshold
* (soft limit), we'll try to reclaim some. If we fail, and
@@ -1137,13 +1088,13 @@ dmfe_send_msg(dmfe_t *dmfep, mblk_t *mp, uint32_t vtag)
dmfe_reclaim_tx_desc(dmfep) == B_FALSE &&
dmfep->tx.n_free <= dmfe_tx_min_free) {
/*
- * Resource shortage - return the proper GLD code,
- * so the packet will be queued for retry after the
- * next TX-done interrupt.
+ * Resource shortage - return B_FALSE so the packet
+ * will be queued for retry after the next TX-done
+ * interrupt.
*/
mutex_exit(dmfep->txlock);
DMFE_DEBUG(("dmfe_send_msg: no free descriptors"));
- return (GLD_NORESOURCES);
+ return (B_FALSE);
}
/*
@@ -1202,51 +1153,6 @@ dmfe_send_msg(dmfe_t *dmfep, mblk_t *mp, uint32_t vtag)
totlen = 0;
bp = mp;
-#if defined(VLAN_VID_NONE)
- if (vtag != VLAN_VTAG_NONE) {
- /*
- * A tagged packet. While copying the data from
- * the first mblk into the Tx buffer, insert the
- * vtag. IP and/or GLD have already guaranteed
- * that the entire struct ether_header (14 bytes)
- * at the start of the packet can be found in the
- * first mblk, so we don't have to worry about it
- * being split into multiple fragments.
- *
- * The magic number (2*ETHERADDRL) appears quite a
- * lot here, because the vtag comes immediately after
- * the destination & source Ethernet addresses in
- * the packet header.
- *
- * The way we allocated the buffers guarantees
- * their alignment, so it's safe to stash the vtag
- * directly into the buffer at the proper offset
- * (4 bytes, 12 bytes into the frame).
- *
- * Once we have copied the data from the first mblk,
- * we can fall through to the untagged packet code
- * to handle the rest of the chain, if any.
- */
- mblen = bp->b_wptr - bp->b_rptr;
- ASSERT(mblen >= sizeof (struct ether_header));
-
- bcopy(bp->b_rptr, txb, 2*ETHERADDRL);
- txb += 2*ETHERADDRL;
- totlen += 2*ETHERADDRL;
- mblen -= 2*ETHERADDRL;
-
- *(uint32_t *)txb = vtag;
- txb += VTAG_SIZE;
- totlen += VTAG_SIZE;
-
- bcopy(bp->b_rptr + 2*ETHERADDRL, txb, mblen);
- txb += mblen;
- totlen += mblen;
-
- bp = bp->b_cont;
- }
-#endif /* defined(VLAN_VID_NONE) */
-
/*
* Copy all (remaining) mblks in the message ...
*/
@@ -1259,6 +1165,22 @@ dmfe_send_msg(dmfe_t *dmfep, mblk_t *mp, uint32_t vtag)
}
/*
+ * Is this a multicast or broadcast packet? We do
+ * this so that we can track statistics accurately
+ * when we reclaim it.
+ */
+ txb = &dmfep->tx_buff.mem_va[index*DMFE_BUF_SIZE];
+ if (txb[0] & 0x1) {
+ if (bcmp(txb, dmfe_broadcast_addr, ETHERADDRL) == 0) {
+ dmfep->tx_bcast[index / NBBY] |=
+ (1 << (index % NBBY));
+ } else {
+ dmfep->tx_mcast[index / NBBY] |=
+ (1 << (index % NBBY));
+ }
+ }
+
+ /*
* We'e reached the end of the chain; and we should have
* collected no more than DMFE_MAX_PKT_SIZE bytes into our
* buffer. Note that the <size> field in the descriptor is
@@ -1272,6 +1194,7 @@ dmfe_send_msg(dmfe_t *dmfep, mblk_t *mp, uint32_t vtag)
(void) ddi_dma_sync(dmfep->tx_buff.dma_hdl,
index*DMFE_BUF_SIZE, DMFE_BUF_SIZE,
DDI_DMA_SYNC_FORDEV);
+
}
/*
@@ -1291,65 +1214,44 @@ dmfe_send_msg(dmfe_t *dmfep, mblk_t *mp, uint32_t vtag)
*/
if (mp)
freemsg(mp);
- return (GLD_SUCCESS);
+ return (B_TRUE);
}
/*
- * dmfe_gld_send() -- send a packet
+ * dmfe_m_tx() -- send a chain of packets
*
- * Called when a packet is ready to be transmitted. A pointer to an
+ * Called when packet(s) are ready to be transmitted. A pointer to an
* M_DATA message that contains the packet is passed to this routine.
* The complete LLC header is contained in the message's first message
* block, and the remainder of the packet is contained within
* additional M_DATA message blocks linked to the first message block.
- */
-static int
-dmfe_gld_send(gld_mac_info_t *macinfo, mblk_t *mp)
-{
- dmfe_t *dmfep; /* private device info */
-
- dmfep = DMFE_STATE(macinfo);
- DMFE_TRACE(("dmfe_gld_send($%p, $%p)",
- (void *)macinfo, (void *)mp));
-
- ASSERT(mp != NULL);
- ASSERT(dmfep->gld_state == GLD_STARTED);
-
- if (dmfep->chip_state != CHIP_RUNNING)
- return (GLD_NORESOURCES);
-
- return (dmfe_send_msg(dmfep, mp, VLAN_VTAG_NONE));
-}
-
-#if defined(VLAN_VID_NONE)
-/*
- * dmfe_gld_send_tagged() -- send a tagged packet
*
- * Called when a packet is ready to be transmitted. A pointer to an
- * M_DATA message that contains the packet is passed to this routine.
- * The complete LLC header is contained in the message's first message
- * block, and the remainder of the packet is contained within
- * additional M_DATA message blocks linked to the first message block.
+ * Additional messages may be passed by linking with b_next.
*/
-static int
-dmfe_gld_send_tagged(gld_mac_info_t *macinfo, mblk_t *mp, uint32_t vtag)
+static mblk_t *
+dmfe_m_tx(void *arg, mblk_t *mp)
{
- dmfe_t *dmfep; /* private device info */
-
- dmfep = DMFE_STATE(macinfo);
- DMFE_TRACE(("dmfe_gld_send_vtag($%p, $%p, $%x)",
- (void *)macinfo, (void *)mp, vtag));
+ dmfe_t *dmfep = arg; /* private device info */
+ mblk_t *next;
ASSERT(mp != NULL);
- ASSERT(dmfep->gld_state == GLD_STARTED);
+ ASSERT(dmfep->mac_state == DMFE_MAC_STARTED);
if (dmfep->chip_state != CHIP_RUNNING)
- return (GLD_NORESOURCES);
+ return (mp);
- return (dmfe_send_msg(dmfep, mp, vtag));
-}
-#endif /* defined(VLAN_VID_NONE) */
+ while (mp != NULL) {
+ next = mp->b_next;
+ mp->b_next = NULL;
+ if (!dmfe_send_msg(dmfep, mp)) {
+ mp->b_next = next;
+ break;
+ }
+ mp = next;
+ }
+ return (mp);
+}
#undef DMFE_DBG
@@ -1365,7 +1267,7 @@ dmfe_gld_send_tagged(gld_mac_info_t *macinfo, mblk_t *mp, uint32_t vtag)
* This must mirror the way the hardware will actually calculate it!
*/
static uint32_t
-dmfe_hash_index(uchar_t *address)
+dmfe_hash_index(const uint8_t *address)
{
uint32_t const POLY = HASH_POLY;
uint32_t crc = HASH_CRC;
@@ -1424,22 +1326,16 @@ dmfe_update_hash(dmfe_t *dmfep, uint32_t index, boolean_t val)
* changed), return B_FALSE
*/
static boolean_t
-dmfe_update_mcast(dmfe_t *dmfep, uchar_t *mca, boolean_t val, const char *what)
+dmfe_update_mcast(dmfe_t *dmfep, const uint8_t *mca, boolean_t val)
{
uint32_t index;
uint8_t *refp;
- uint8_t oldref;
boolean_t change;
index = dmfe_hash_index(mca);
refp = &dmfep->mcast_refs[index];
- oldref = *refp;
change = (val ? (*refp)++ : --(*refp)) == 0;
- DMFE_DEBUG(("dmfe_update_mcast: %s %s %s index %d ref %d->%d%s",
- ether_sprintf((void *)mca), val ? "ON" : "OFF", what,
- index, oldref, *refp, change ? " (CHANGED)" : ""));
-
if (change)
dmfe_update_hash(dmfep, index, val);
@@ -1454,21 +1350,15 @@ dmfe_send_setup(dmfe_t *dmfep)
{
int status;
- DMFE_TRACE(("dmfe_send_setup($%p)", (void *)dmfep));
-
ASSERT(mutex_owned(dmfep->oplock));
/*
* If the chip isn't running, we can't really send the setup frame
* now but it doesn't matter, 'cos it will be sent when the transmit
- * process is restarted (see dmfe_start()). It isn't an error; in
- * fact, GLD v2 will always call dmfe_gld_set_mac_addr() after a
- * reset, so that the address can be set up before the chip is
- * started. In this context, the return code GLD_NOTSUPPORTED is
- * taken as success!
+ * process is restarted (see dmfe_start()).
*/
if ((dmfep->opmode & START_TRANSMIT) == 0)
- return (GLD_NOTSUPPORTED);
+ return (0);
/*
* "Send" the setup frame. If it fails (e.g. no resources),
@@ -1477,25 +1367,21 @@ dmfe_send_setup(dmfe_t *dmfep)
* had previously failed. We tell the caller that it worked
* whether it did or not; after all, it *will* work eventually.
*/
- status = dmfe_send_msg(dmfep, NULL, VLAN_VTAG_NONE);
- dmfep->need_setup = status != GLD_SUCCESS;
- return (GLD_SUCCESS);
+ status = dmfe_send_msg(dmfep, NULL);
+ dmfep->need_setup = status ? B_FALSE : B_TRUE;
+ return (0);
}
/*
- * dmfe_gld_set_mac_addr() -- set the physical network address
+ * dmfe_m_unicst() -- set the physical network address
*/
static int
-dmfe_gld_set_mac_addr(gld_mac_info_t *macinfo, uchar_t *macaddr)
+dmfe_m_unicst(void *arg, const uint8_t *macaddr)
{
- dmfe_t *dmfep; /* private device info */
+ dmfe_t *dmfep = arg;
int status;
int index;
- dmfep = DMFE_STATE(macinfo);
- DMFE_TRACE(("dmfe_gld_set_mac_addr($%p, %s)",
- (void *)macinfo, ether_sprintf((void *)macaddr)));
-
/*
* Update our current address and send out a new setup packet
*
@@ -1533,13 +1419,11 @@ dmfe_gld_set_mac_addr(gld_mac_info_t *macinfo, uchar_t *macaddr)
mutex_enter(dmfep->oplock);
if (dmfep->addr_set && dmfe_setup_desc1 & TX_FILTER_TYPE1)
- (void) dmfe_update_mcast(dmfep, dmfep->curr_addr, B_FALSE,
- "xaddr");
+ (void) dmfe_update_mcast(dmfep, dmfep->curr_addr, B_FALSE);
if (dmfe_setup_desc1 & TX_FILTER_TYPE1)
- (void) dmfe_update_mcast(dmfep, macaddr, B_TRUE, "saddr");
+ (void) dmfe_update_mcast(dmfep, macaddr, B_TRUE);
if (!dmfep->addr_set)
- (void) dmfe_update_mcast(dmfep, dmfe_broadcast_addr, B_TRUE,
- "bcast");
+ (void) dmfe_update_mcast(dmfep, dmfe_broadcast_addr, B_TRUE);
/*
* Remember the new current address
@@ -1567,28 +1451,23 @@ dmfe_gld_set_mac_addr(gld_mac_info_t *macinfo, uchar_t *macaddr)
}
/*
- * dmfe_gld_set_multicast() -- enable or disable a multicast address
+ * dmfe_m_multicst() -- enable or disable a multicast address
*
* Program the hardware to enable/disable the multicast address
- * in "mca" (enable if "flag" is GLD_MULTI_ENABLE, otherwise disable).
+ * in "mca" (enable if add is true, otherwise disable it.)
* We keep a refcount for each bit in the map, so that it still
* works out properly if multiple addresses hash to the same bit.
* dmfe_update_mcast() tells us whether the map actually changed;
* if so, we have to re-"transmit" the magic setup packet.
*/
static int
-dmfe_gld_set_multicast(gld_mac_info_t *macinfo, uchar_t *mca, int flag)
+dmfe_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
{
- dmfe_t *dmfep; /* private device info */
- int status;
+ dmfe_t *dmfep = arg; /* private device info */
+ int status = 0;
- dmfep = DMFE_STATE(macinfo);
- DMFE_TRACE(("dmfe_gld_set_multicast($%p, %s, %d)",
- (void *)macinfo, ether_sprintf((void *)mca), flag));
-
- status = GLD_SUCCESS;
mutex_enter(dmfep->oplock);
- if (dmfe_update_mcast(dmfep, mca, flag == GLD_MULTI_ENABLE, "mcast"))
+ if (dmfe_update_mcast(dmfep, mca, add))
status = dmfe_send_setup(dmfep);
mutex_exit(dmfep->oplock);
@@ -1606,9 +1485,9 @@ dmfe_gld_set_multicast(gld_mac_info_t *macinfo, uchar_t *mca, int flag)
/*
* These routines provide all the functionality required by the
- * corresponding GLD entry points, but don't update the GLD state
+ * corresponding MAC layer entry points, but don't update the MAC layer state
* so they can be called internally without disturbing our record
- * of what GLD thinks we should be doing ...
+ * of what MAC layer thinks we should be doing ...
*/
/*
@@ -1617,8 +1496,6 @@ dmfe_gld_set_multicast(gld_mac_info_t *macinfo, uchar_t *mca, int flag)
static void
dmfe_stop(dmfe_t *dmfep)
{
- DMFE_TRACE(("dmfe_stop($%p)", (void *)dmfep));
-
ASSERT(mutex_owned(dmfep->oplock));
dmfe_stop_chip(dmfep, CHIP_STOPPED);
@@ -1630,8 +1507,6 @@ dmfe_stop(dmfe_t *dmfep)
static void
dmfe_reset(dmfe_t *dmfep)
{
- DMFE_TRACE(("dmfe_reset($%p)", (void *)dmfep));
-
ASSERT(mutex_owned(dmfep->oplock));
ASSERT(mutex_owned(dmfep->rxlock));
ASSERT(mutex_owned(dmfep->txlock));
@@ -1648,8 +1523,6 @@ dmfe_start(dmfe_t *dmfep)
{
uint32_t gpsr;
- DMFE_TRACE(("dmfe_start($%p)", (void *)dmfep));
-
ASSERT(mutex_owned(dmfep->oplock));
ASSERT(dmfep->chip_state == CHIP_RESET ||
@@ -1695,95 +1568,53 @@ dmfe_restart(dmfe_t *dmfep)
dmfe_reset(dmfep);
mutex_exit(dmfep->txlock);
mutex_exit(dmfep->rxlock);
- if (dmfep->gld_state == GLD_STARTED)
+ if (dmfep->mac_state == DMFE_MAC_STARTED)
dmfe_start(dmfep);
}
/*
- * ========== GLD-required management entry points ==========
- */
-
-/*
- * dmfe_gld_reset() -- reset to initial state
+ * ========== MAC-required management entry points ==========
*/
-static int
-dmfe_gld_reset(gld_mac_info_t *macinfo)
-{
- dmfe_t *dmfep; /* private device info */
-
- dmfep = DMFE_STATE(macinfo);
- DMFE_TRACE(("dmfe_gld_reset($%p)", (void *)macinfo));
-
- /*
- * Reset chip & rings to initial state; also reset address
- * filtering & record new GLD state. You need *all* the locks
- * in order to stop all other activity while doing this!
- */
- mutex_enter(dmfep->oplock);
- mutex_enter(dmfep->rxlock);
- mutex_enter(dmfep->txlock);
-
- dmfe_reset(dmfep);
- bzero(dmfep->tx_desc.setup_va, SETUPBUF_SIZE);
- bzero(dmfep->mcast_refs, MCASTBUF_SIZE);
- dmfep->addr_set = B_FALSE;
- dmfep->opmode &= ~(PROMISC_MODE | PASS_MULTICAST);
- dmfep->gld_state = GLD_RESET;
-
- mutex_exit(dmfep->txlock);
- mutex_exit(dmfep->rxlock);
- mutex_exit(dmfep->oplock);
-
- return (0);
-}
/*
- * dmfe_gld_stop() -- stop transmitting/receiving
+ * dmfe_m_stop() -- stop transmitting/receiving
*/
-static int
-dmfe_gld_stop(gld_mac_info_t *macinfo)
+static void
+dmfe_m_stop(void *arg)
{
- dmfe_t *dmfep; /* private device info */
-
- dmfep = DMFE_STATE(macinfo);
- DMFE_TRACE(("dmfe_gld_stop($%p)", (void *)macinfo));
+ dmfe_t *dmfep = arg; /* private device info */
/*
- * Just stop processing, then record new GLD state
+ * Just stop processing, then record new MAC state
*/
mutex_enter(dmfep->oplock);
dmfe_stop(dmfep);
- dmfep->gld_state = GLD_STOPPED;
+ dmfep->mac_state = DMFE_MAC_STOPPED;
mutex_exit(dmfep->oplock);
-
- return (0);
}
/*
- * dmfe_gld_start() -- start transmitting/receiving
+ * dmfe_m_start() -- start transmitting/receiving
*/
static int
-dmfe_gld_start(gld_mac_info_t *macinfo)
+dmfe_m_start(void *arg)
{
- dmfe_t *dmfep; /* private device info */
-
- dmfep = DMFE_STATE(macinfo);
- DMFE_TRACE(("dmfe_gld_start($%p)", (void *)macinfo));
+ dmfe_t *dmfep = arg; /* private device info */
/*
- * Start processing and record new GLD state
+ * Start processing and record new MAC state
*/
mutex_enter(dmfep->oplock);
dmfe_start(dmfep);
- dmfep->gld_state = GLD_STARTED;
+ dmfep->mac_state = DMFE_MAC_STARTED;
mutex_exit(dmfep->oplock);
return (0);
}
/*
- * dmfe_gld_set_promiscuous() -- set or reset promiscuous mode on the board
+ * dmfe_m_promisc() -- set or reset promiscuous mode on the board
*
* Program the hardware to enable/disable promiscuous and/or
* receive-all-multicast modes. Davicom don't document this
@@ -1791,48 +1622,60 @@ dmfe_gld_start(gld_mac_info_t *macinfo)
* without stopping & restarting the TX/RX processes).
*/
static int
-dmfe_gld_set_promiscuous(gld_mac_info_t *macinfo, int mode)
+dmfe_m_promisc(void *arg, boolean_t on)
{
- dmfe_t *dmfep;
- uint32_t pmode;
-
- dmfep = DMFE_STATE(macinfo);
- DMFE_TRACE(("dmfe_gld_set_promiscuous($%p, %d)",
- (void *)macinfo, mode));
-
- /*
- * Convert GLD-specified mode to DMFE opmode setting
- */
- switch (mode) {
- case GLD_MAC_PROMISC_NONE:
- pmode = 0;
- break;
-
- case GLD_MAC_PROMISC_MULTI:
- pmode = PASS_MULTICAST;
- break;
-
- case GLD_MAC_PROMISC_PHYS:
- pmode = PROMISC_MODE;
- break;
-
- default:
- return (GLD_NOTSUPPORTED);
- }
+ dmfe_t *dmfep = arg;
mutex_enter(dmfep->oplock);
dmfep->opmode &= ~(PROMISC_MODE | PASS_MULTICAST);
- dmfep->opmode |= pmode;
+ if (on)
+ dmfep->opmode |= PROMISC_MODE;
dmfe_set_opmode(dmfep);
- pmode = dmfep->opmode;
mutex_exit(dmfep->oplock);
- DMFE_DEBUG(("dmfe_gld_set_promiscuous: mode %d => opmode 0x%x",
- mode, pmode));
+ return (0);
+}
- return (GLD_SUCCESS);
+/*ARGSUSED*/
+static boolean_t
+dmfe_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
+{
+ /*
+ * Note that the chip could support some form of polling and
+ * multiaddress support. We should look into adding polling
+ * support later, once Solaris is better positioned to take
+ * advantage of it, although it may be of little use since
+ * even a lowly 500MHz US-IIe should be able to keep up with
+ * 100Mbps. (Esp. if the packets are not unreasonably sized.)
+ *
+ * Multiaddress support, however, is likely to be of more
+ * utility with crossbow and virtualized NICs. Although, the
+ * fact that dmfe is only supported on low-end US-IIe hardware
+ * makes one wonder whether VNICs are likely to be used on
+ * such platforms. The chip certainly supports the notion,
+ * since it can be run in HASH-ONLY mode. (Though this would
+ * require software to drop unicast packets that are
+ * incorrectly received due to hash collision of the
+ * destination mac address.)
+ *
+ * Interestingly enough, modern Davicom chips (the 9102D)
+ * support full IP checksum offload, though its unclear
+ * whether any of these chips are used on any systems that can
+ * run Solaris.
+ *
+ * If this driver is ever supported on x86 hardware, then
+ * these assumptions should be revisited.
+ */
+ switch (cap) {
+ case MAC_CAPAB_POLL:
+ case MAC_CAPAB_MULTIADDRESS:
+ case MAC_CAPAB_HCKSUM:
+ default:
+ return (B_FALSE);
+ }
}
+
#undef DMFE_DBG
@@ -1903,19 +1746,16 @@ dmfe_factotum(caddr_t arg)
dmfep->update_phy = B_FALSE;
}
dmfe_recheck_link(dmfep, B_FALSE);
- if (dmfep->gld_state == GLD_STARTED)
+ if (dmfep->mac_state == DMFE_MAC_STARTED)
dmfe_start(dmfep);
mutex_exit(dmfep->oplock);
}
mutex_exit(dmfep->milock);
/*
- * Keep GLD up-to-date about the state of the link ...
+ * Keep MAC up-to-date about the state of the link ...
*/
- if (gld_linkstate != NULL)
- gld_linkstate(DMFE_MACINFO(dmfep),
- dmfep->link_state == LINK_UP ?
- GLD_LINKSTATE_UP : GLD_LINKSTATE_DOWN);
+ mac_link_update(dmfep->mh, dmfep->link_state);
return (DDI_INTR_CLAIMED);
}
@@ -1976,11 +1816,12 @@ dmfe_tick_link_check(dmfe_t *dmfep, uint32_t gpsr, uint32_t istat)
* Has the link status changed? If so, we might want to wake
* the factotum to deal with it.
*/
- phy_state = (gpsr & GPS_LINK_STATUS) ? LINK_UP : LINK_DOWN;
- utp_state = (gpsr & GPS_UTP_SIG) ? LINK_UP : LINK_DOWN;
+ phy_state = (gpsr & GPS_LINK_STATUS) ? LINK_STATE_UP : LINK_STATE_DOWN;
+ utp_state = (gpsr & GPS_UTP_SIG) ? LINK_STATE_UP : LINK_STATE_DOWN;
if (phy_state != utp_state)
why = "tick (phy <> utp)";
- else if (dmfep->link_state == LINK_UP && phy_state == LINK_DOWN)
+ else if ((dmfep->link_state == LINK_STATE_UP) &&
+ (phy_state == LINK_STATE_DOWN))
why = "tick (UP -> DOWN)";
else if (phy_state != dmfep->link_state) {
if (dmfep->link_poll_tix > factotum_fast_tix)
@@ -2149,7 +1990,7 @@ dmfe_interrupt(caddr_t arg)
* need to get the lock before going any further ...
*/
mutex_enter(dmfep->oplock);
- dmfep->op_stats_intr += 1;
+ DRV_KS_INC(dmfep, KS_INTERRUPT);
/*
* Identify bits that represent enabled interrupts ...
@@ -2269,12 +2110,12 @@ dmfe_interrupt(caddr_t arg)
if (interrupts & RX_PKTDONE_INT)
if ((mp = dmfe_getp(dmfep)) != NULL)
- dmfe_passup_chain(DMFE_MACINFO(dmfep), mp);
+ mac_rx(dmfep->mh, NULL, mp);
if (interrupts & TX_PKTDONE_INT) {
/*
* The only reason for taking this interrupt is to give
- * GLD a chance to schedule queued packets after a
+ * MAC a chance to schedule queued packets after a
* ring-full condition. To minimise the number of
* redundant TX-Done interrupts, we only mark two of the
* ring descriptors as 'interrupt-on-complete' - all the
@@ -2284,7 +2125,7 @@ dmfe_interrupt(caddr_t arg)
(void) dmfe_reclaim_tx_desc(dmfep);
mutex_exit(dmfep->txlock);
}
- gld_sched(DMFE_MACINFO(dmfep));
+ mac_tx_update(dmfep->mh);
}
return (DDI_INTR_CLAIMED);
@@ -2300,47 +2141,226 @@ dmfe_interrupt(caddr_t arg)
#define DMFE_DBG DMFE_DBG_STATS /* debug flag for this code */
static int
-dmfe_gld_get_stats(gld_mac_info_t *macinfo, struct gld_stats *sp)
+dmfe_m_stat(void *arg, uint_t stat, uint64_t *val)
{
- dmfe_t *dmfep;
-
- dmfep = DMFE_STATE(macinfo);
+ dmfe_t *dmfep = arg;
+ int rv = 0;
+ mutex_enter(dmfep->milock);
mutex_enter(dmfep->oplock);
mutex_enter(dmfep->rxlock);
mutex_enter(dmfep->txlock);
- sp->glds_speed = dmfep->op_stats_speed;
- sp->glds_duplex = dmfep->op_stats_duplex;
- sp->glds_media = dmfep->op_stats_media;
- sp->glds_intr = dmfep->op_stats_intr;
-
- sp->glds_errrcv = dmfep->rx_stats_errrcv;
- sp->glds_overflow = dmfep->rx_stats_overflow;
- sp->glds_short = dmfep->rx_stats_short;
- sp->glds_crc = dmfep->rx_stats_crc;
- sp->glds_dot3_frame_too_long = dmfep->rx_stats_frame_too_long;
- sp->glds_dot3_mac_rcv_error = dmfep->rx_stats_mac_rcv_error;
- sp->glds_frame = dmfep->rx_stats_frame;
- sp->glds_missed = dmfep->rx_stats_missed;
- sp->glds_norcvbuf = dmfep->rx_stats_norcvbuf;
-
- sp->glds_errxmt = dmfep->tx_stats_errxmt;
- sp->glds_dot3_mac_xmt_error = dmfep->tx_stats_mac_xmt_error;
- sp->glds_underflow = dmfep->tx_stats_underflow;
- sp->glds_xmtlatecoll = dmfep->tx_stats_xmtlatecoll;
- sp->glds_nocarrier = dmfep->tx_stats_nocarrier;
- sp->glds_excoll = dmfep->tx_stats_excoll;
- sp->glds_dot3_first_coll = dmfep->tx_stats_first_coll;
- sp->glds_dot3_multi_coll = dmfep->tx_stats_multi_coll;
- sp->glds_collisions = dmfep->tx_stats_collisions;
- sp->glds_defer = dmfep->tx_stats_defer;
+ /* make sure we have all the stats collected */
+ (void) dmfe_reclaim_tx_desc(dmfep);
+
+ switch (stat) {
+ case MAC_STAT_IFSPEED:
+ *val = dmfep->op_stats_speed;
+ break;
+
+ case MAC_STAT_IPACKETS:
+ *val = dmfep->rx_stats_ipackets;
+ break;
+
+ case MAC_STAT_MULTIRCV:
+ *val = dmfep->rx_stats_multi;
+ break;
+
+ case MAC_STAT_BRDCSTRCV:
+ *val = dmfep->rx_stats_bcast;
+ break;
+
+ case MAC_STAT_RBYTES:
+ *val = dmfep->rx_stats_rbytes;
+ break;
+
+ case MAC_STAT_IERRORS:
+ *val = dmfep->rx_stats_ierrors;
+ break;
+
+ case MAC_STAT_NORCVBUF:
+ *val = dmfep->rx_stats_norcvbuf;
+ break;
+
+ case MAC_STAT_COLLISIONS:
+ *val = dmfep->tx_stats_collisions;
+ break;
+
+ case MAC_STAT_OERRORS:
+ *val = dmfep->tx_stats_oerrors;
+ break;
+
+ case MAC_STAT_OPACKETS:
+ *val = dmfep->tx_stats_opackets;
+ break;
+
+ case MAC_STAT_MULTIXMT:
+ *val = dmfep->tx_stats_multi;
+ break;
+
+ case MAC_STAT_BRDCSTXMT:
+ *val = dmfep->tx_stats_bcast;
+ break;
+
+ case MAC_STAT_OBYTES:
+ *val = dmfep->tx_stats_obytes;
+ break;
+
+ case MAC_STAT_OVERFLOWS:
+ *val = dmfep->rx_stats_overflow;
+ break;
+
+ case MAC_STAT_UNDERFLOWS:
+ *val = dmfep->tx_stats_underflow;
+ break;
+
+ case ETHER_STAT_ALIGN_ERRORS:
+ *val = dmfep->rx_stats_align;
+ break;
+
+ case ETHER_STAT_FCS_ERRORS:
+ *val = dmfep->rx_stats_fcs;
+ break;
+
+ case ETHER_STAT_TOOLONG_ERRORS:
+ *val = dmfep->rx_stats_toolong;
+ break;
+
+ case ETHER_STAT_TOOSHORT_ERRORS:
+ *val = dmfep->rx_stats_short;
+ break;
+
+ case ETHER_STAT_MACRCV_ERRORS:
+ *val = dmfep->rx_stats_macrcv_errors;
+ break;
+
+ case ETHER_STAT_MACXMT_ERRORS:
+ *val = dmfep->tx_stats_macxmt_errors;
+ break;
+
+ case ETHER_STAT_CARRIER_ERRORS:
+ *val = dmfep->tx_stats_nocarrier;
+ break;
+
+ case ETHER_STAT_TX_LATE_COLLISIONS:
+ *val = dmfep->tx_stats_xmtlatecoll;
+ break;
+
+ case ETHER_STAT_EX_COLLISIONS:
+ *val = dmfep->tx_stats_excoll;
+ break;
+
+ case ETHER_STAT_DEFER_XMTS:
+ *val = dmfep->tx_stats_defer;
+ break;
+
+ case ETHER_STAT_FIRST_COLLISIONS:
+ *val = dmfep->tx_stats_first_coll;
+ break;
+
+ case ETHER_STAT_MULTI_COLLISIONS:
+ *val = dmfep->tx_stats_multi_coll;
+ break;
+
+ case ETHER_STAT_XCVR_INUSE:
+ *val = dmfep->phy_inuse;
+ break;
+
+ case ETHER_STAT_XCVR_ID:
+ *val = dmfep->phy_id;
+ break;
+
+ case ETHER_STAT_XCVR_ADDR:
+ *val = dmfep->phy_addr;
+ break;
+
+ case ETHER_STAT_LINK_DUPLEX:
+ *val = dmfep->op_stats_duplex;
+ break;
+
+ case ETHER_STAT_CAP_100FDX:
+ *val = dmfep->param_bmsr_100fdx;
+ break;
+
+ case ETHER_STAT_CAP_100HDX:
+ *val = dmfep->param_bmsr_100hdx;
+ break;
+
+ case ETHER_STAT_CAP_10FDX:
+ *val = dmfep->param_bmsr_10fdx;
+ break;
+
+ case ETHER_STAT_CAP_10HDX:
+ *val = dmfep->param_bmsr_10hdx;
+ break;
+
+ case ETHER_STAT_CAP_AUTONEG:
+ *val = dmfep->param_bmsr_autoneg;
+ break;
+
+ case ETHER_STAT_CAP_REMFAULT:
+ *val = dmfep->param_bmsr_remfault;
+ break;
+
+ case ETHER_STAT_ADV_CAP_AUTONEG:
+ *val = dmfep->param_autoneg;
+ break;
+
+ case ETHER_STAT_ADV_CAP_100FDX:
+ *val = dmfep->param_anar_100fdx;
+ break;
+
+ case ETHER_STAT_ADV_CAP_100HDX:
+ *val = dmfep->param_anar_100hdx;
+ break;
+
+ case ETHER_STAT_ADV_CAP_10FDX:
+ *val = dmfep->param_anar_10fdx;
+ break;
+
+ case ETHER_STAT_ADV_CAP_10HDX:
+ *val = dmfep->param_anar_10hdx;
+ break;
+
+ case ETHER_STAT_ADV_REMFAULT:
+ *val = dmfep->param_anar_remfault;
+ break;
+
+ case ETHER_STAT_LP_CAP_AUTONEG:
+ *val = dmfep->param_lp_autoneg;
+ break;
+
+ case ETHER_STAT_LP_CAP_100FDX:
+ *val = dmfep->param_lp_100fdx;
+ break;
+
+ case ETHER_STAT_LP_CAP_100HDX:
+ *val = dmfep->param_lp_100hdx;
+ break;
+
+ case ETHER_STAT_LP_CAP_10FDX:
+ *val = dmfep->param_lp_10fdx;
+ break;
+
+ case ETHER_STAT_LP_CAP_10HDX:
+ *val = dmfep->param_lp_10hdx;
+ break;
+
+ case ETHER_STAT_LP_REMFAULT:
+ *val = dmfep->param_lp_remfault;
+ break;
+
+ default:
+ rv = ENOTSUP;
+ }
mutex_exit(dmfep->txlock);
mutex_exit(dmfep->rxlock);
mutex_exit(dmfep->oplock);
+ mutex_exit(dmfep->milock);
- return (GLD_SUCCESS);
+ return (rv);
}
#undef DMFE_DBG
@@ -2360,6 +2380,9 @@ dmfe_gld_get_stats(gld_mac_info_t *macinfo, struct gld_stats *sp)
* These will be used by netlbtest (see BugId 4370609)
*
* Note that changing the loopback mode causes a stop/restart cycle
+ *
+ * It would be nice to evolve this to support the ioctls in sys/netlb.h,
+ * but then it would be even better to use Brussels to configure this.
*/
static enum ioc_reply
dmfe_loop_ioctl(dmfe_t *dmfep, queue_t *wq, mblk_t *mp, int cmd)
@@ -2433,21 +2456,16 @@ dmfe_loop_ioctl(dmfe_t *dmfep, queue_t *wq, mblk_t *mp, int cmd)
}
/*
- * Specific dmfe IOCTLs, the gld module handles the generic ones.
+ * Specific dmfe IOCTLs, the mac module handles the generic ones.
*/
-static int
-dmfe_gld_ioctl(gld_mac_info_t *macinfo, queue_t *wq, mblk_t *mp)
+static void
+dmfe_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
{
- dmfe_t *dmfep;
+ dmfe_t *dmfep = arg;
struct iocblk *iocp;
enum ioc_reply status;
int cmd;
- dmfep = DMFE_STATE(macinfo);
-
- DMFE_TRACE(("dmfe_gld_ioctl($%p, $%p, $%p)",
- (void *)macinfo, (void *)wq, (void *)mp));
-
/*
* Validate the command before bothering with the mutexen ...
*/
@@ -2455,14 +2473,14 @@ dmfe_gld_ioctl(gld_mac_info_t *macinfo, queue_t *wq, mblk_t *mp)
cmd = iocp->ioc_cmd;
switch (cmd) {
default:
- DMFE_DEBUG(("dmfe_gld_ioctl: unknown cmd 0x%x", cmd));
+ DMFE_DEBUG(("dmfe_m_ioctl: unknown cmd 0x%x", cmd));
miocnak(wq, mp, 0, EINVAL);
- return (GLD_SUCCESS);
+ return;
case DMFE_SET_LOOP_MODE:
case DMFE_GET_LOOP_MODE:
- case DMFE_ND_GET:
- case DMFE_ND_SET:
+ case ND_GET:
+ case ND_SET:
break;
}
@@ -2480,8 +2498,8 @@ dmfe_gld_ioctl(gld_mac_info_t *macinfo, queue_t *wq, mblk_t *mp)
status = dmfe_loop_ioctl(dmfep, wq, mp, cmd);
break;
- case DMFE_ND_GET:
- case DMFE_ND_SET:
+ case ND_GET:
+ case ND_SET:
status = dmfe_nd_ioctl(dmfep, wq, mp, cmd);
break;
}
@@ -2518,7 +2536,7 @@ dmfe_gld_ioctl(gld_mac_info_t *macinfo, queue_t *wq, mblk_t *mp)
dmfe_wake_factotum(dmfep, KS_LINK_CHECK, "ioctl");
}
- if (dmfep->gld_state == GLD_STARTED)
+ if (dmfep->mac_state == DMFE_MAC_STARTED)
dmfe_start(dmfep);
break;
}
@@ -2563,8 +2581,6 @@ dmfe_gld_ioctl(gld_mac_info_t *macinfo, queue_t *wq, mblk_t *mp)
*/
break;
}
-
- return (GLD_SUCCESS);
}
#undef DMFE_DBG
@@ -2591,17 +2607,17 @@ dmfe_find_mac_address(dmfe_t *dmfep)
* the value of the property "local-mac-address", as set by OBP
* (or a .conf file!)
*/
- bzero(dmfep->vendor_addr, sizeof (dmfep->vendor_addr));
+ bzero(dmfep->curr_addr, sizeof (dmfep->curr_addr));
err = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dmfep->devinfo,
DDI_PROP_DONTPASS, localmac_propname, &prop, &propsize);
if (err == DDI_PROP_SUCCESS) {
if (propsize == ETHERADDRL)
- ethaddr_copy(prop, dmfep->vendor_addr);
+ ethaddr_copy(prop, dmfep->curr_addr);
ddi_prop_free(prop);
}
DMFE_DEBUG(("dmfe_setup_mac_address: factory %s",
- ether_sprintf((void *)dmfep->vendor_addr)));
+ ether_sprintf((void *)dmfep->curr_addr)));
}
static int
@@ -2703,6 +2719,12 @@ dmfe_alloc_bufs(dmfe_t *dmfep)
if (err != DDI_SUCCESS)
return (DDI_FAILURE);
+ /*
+ * Allocate bitmasks for tx packet type tracking
+ */
+ dmfep->tx_mcast = kmem_zalloc(dmfep->tx.n_desc / NBBY, KM_SLEEP);
+ dmfep->tx_bcast = kmem_zalloc(dmfep->tx.n_desc / NBBY, KM_SLEEP);
+
return (DDI_SUCCESS);
}
@@ -2739,6 +2761,8 @@ dmfe_free_bufs(dmfe_t *dmfep)
dmfe_free_dma_mem(&dmfep->rx_desc);
dmfe_free_dma_mem(&dmfep->tx_buff);
dmfe_free_dma_mem(&dmfep->tx_desc);
+ kmem_free(dmfep->tx_mcast, dmfep->tx.n_desc / NBBY);
+ kmem_free(dmfep->tx_bcast, dmfep->tx.n_desc / NBBY);
}
static void
@@ -2753,8 +2777,6 @@ dmfe_unattach(dmfe_t *dmfep)
mutex_exit(&cpu_lock);
dmfep->cycid = CYCLIC_NONE;
}
- if (dmfep->ksp_mii != NULL)
- kstat_delete(dmfep->ksp_mii);
if (dmfep->ksp_drv != NULL)
kstat_delete(dmfep->ksp_drv);
if (dmfep->progress & PROGRESS_HWINT) {
@@ -2772,7 +2794,6 @@ dmfe_unattach(dmfe_t *dmfep)
if (dmfep->progress & PROGRESS_NDD)
dmfe_nd_cleanup(dmfep);
- gld_mac_free(DMFE_MACINFO(dmfep));
kmem_free(dmfep, sizeof (*dmfep));
}
@@ -2812,44 +2833,12 @@ struct ks_index {
char *name;
};
-static const struct ks_index ks_mii_names[] = {
- { KS_MII_XCVR_ADDR, "xcvr_addr" },
- { KS_MII_XCVR_ID, "xcvr_id" },
- { KS_MII_XCVR_INUSE, "xcvr_inuse" },
-
- { KS_MII_LINK_UP, "link_up" },
- { KS_MII_LINK_DUPLEX, "link_duplex" },
-
- { KS_MII_CAP_100FDX, "cap_100fdx" },
- { KS_MII_CAP_100HDX, "cap_100hdx" },
- { KS_MII_CAP_10FDX, "cap_10fdx" },
- { KS_MII_CAP_10HDX, "cap_10hdx" },
- { KS_MII_CAP_REMFAULT, "cap_rem_fault" },
- { KS_MII_CAP_AUTONEG, "cap_autoneg" },
-
- { KS_MII_ADV_CAP_100FDX, "adv_cap_100fdx" },
- { KS_MII_ADV_CAP_100HDX, "adv_cap_100hdx" },
- { KS_MII_ADV_CAP_10FDX, "adv_cap_10fdx" },
- { KS_MII_ADV_CAP_10HDX, "adv_cap_10hdx" },
- { KS_MII_ADV_CAP_REMFAULT, "adv_rem_fault" },
- { KS_MII_ADV_CAP_AUTONEG, "adv_cap_autoneg" },
-
- { KS_MII_LP_CAP_100FDX, "lp_cap_100fdx" },
- { KS_MII_LP_CAP_100HDX, "lp_cap_100hdx" },
- { KS_MII_LP_CAP_10FDX, "lp_cap_10fdx" },
- { KS_MII_LP_CAP_10HDX, "lp_cap_10hdx" },
- { KS_MII_LP_CAP_REMFAULT, "lp_cap_rem_fault" },
- { KS_MII_LP_CAP_AUTONEG, "lp_cap_autoneg" },
-
- { -1, NULL }
-};
-
static const struct ks_index ks_drv_names[] = {
+ { KS_INTERRUPT, "intr" },
{ KS_CYCLIC_RUN, "cyclic_run" },
{ KS_TICK_LINK_STATE, "link_state_change" },
{ KS_TICK_LINK_POLL, "link_state_poll" },
- { KS_LINK_INTERRUPT, "link_state_interrupt" },
{ KS_TX_STALL, "tx_stall_detect" },
{ KS_CHIP_ERROR, "chip_error_interrupt" },
@@ -2878,21 +2867,7 @@ dmfe_init_kstats(dmfe_t *dmfep, int instance)
kstat_named_t *knp;
const struct ks_index *ksip;
- /* Create and initialise standard "mii" kstats */
- ksp = kstat_create(DRIVER_NAME, instance, "mii", "net",
- KSTAT_TYPE_NAMED, KS_MII_COUNT, KSTAT_FLAG_PERSISTENT);
- if (ksp != NULL) {
- for (knp = ksp->ks_data, ksip = ks_mii_names;
- ksip->name != NULL; ++ksip) {
- kstat_named_init(&knp[ksip->index], ksip->name,
- KSTAT_DATA_UINT32);
- }
- dmfep->ksp_mii = ksp;
- dmfep->knp_mii = knp;
- kstat_install(ksp);
- } else {
- dmfe_error(dmfep, "kstat_create() for mii failed");
- }
+ /* no need to create MII stats, the mac module already does it */
/* Create and initialise driver-defined kstats */
ksp = kstat_create(DRIVER_NAME, instance, "dmfe_events", "net",
@@ -2914,19 +2889,17 @@ dmfe_init_kstats(dmfe_t *dmfep, int instance)
static int
dmfe_resume(dev_info_t *devinfo)
{
- gld_mac_info_t *macinfo; /* GLD structure */
dmfe_t *dmfep; /* Our private data */
chip_id_t chipid;
- macinfo = (gld_mac_info_t *)ddi_get_driver_private(devinfo);
- if (macinfo == NULL)
+ dmfep = ddi_get_driver_private(devinfo);
+ if (dmfep == NULL)
return (DDI_FAILURE);
/*
* Refuse to resume if the data structures aren't consistent
*/
- dmfep = DMFE_STATE(macinfo);
- if (dmfep->devinfo != devinfo || dmfep->macinfo != macinfo)
+ if (dmfep->devinfo != devinfo)
return (DDI_FAILURE);
/*
@@ -2942,12 +2915,12 @@ dmfe_resume(dev_info_t *devinfo)
return (DDI_FAILURE);
/*
- * All OK, reinitialise h/w & kick off GLD scheduling
+ * All OK, reinitialise h/w & kick off MAC scheduling
*/
mutex_enter(dmfep->oplock);
dmfe_restart(dmfep);
mutex_exit(dmfep->oplock);
- gld_sched(macinfo);
+ mac_tx_update(dmfep->mh);
return (DDI_SUCCESS);
}
@@ -2959,7 +2932,7 @@ dmfe_resume(dev_info_t *devinfo)
static int
dmfe_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
{
- gld_mac_info_t *macinfo; /* GLD structure */
+ mac_register_t *macp;
cyc_handler_t cychand;
cyc_time_t cyctime;
dmfe_t *dmfep; /* Our private data */
@@ -2969,9 +2942,6 @@ dmfe_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
instance = ddi_get_instance(devinfo);
- DMFE_GTRACE(("dmfe_attach($%p, %d) instance %d",
- (void *)devinfo, cmd, instance));
-
switch (cmd) {
default:
return (DDI_FAILURE);
@@ -2983,21 +2953,10 @@ dmfe_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
break;
}
- /*
- * Allocate GLD macinfo and DMFE private structures, and
- * cross-link them so that given either one of these or
- * the devinfo the others can be derived.
- */
- macinfo = gld_mac_alloc(devinfo);
- ddi_set_driver_private(devinfo, (caddr_t)macinfo);
- if (macinfo == NULL)
- return (DDI_FAILURE);
-
dmfep = kmem_zalloc(sizeof (*dmfep), KM_SLEEP);
- dmfep->dmfe_guard = DMFE_GUARD;
+ ddi_set_driver_private(devinfo, dmfep);
dmfep->devinfo = devinfo;
- dmfep->macinfo = macinfo;
- macinfo->gldm_private = (caddr_t)dmfep;
+ dmfep->dmfe_guard = DMFE_GUARD;
/*
* Initialize more fields in DMFE private data
@@ -3095,92 +3054,58 @@ dmfe_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
* Reset & initialise the chip and the ring buffers
* Initialise the (internal) PHY
*/
- (void) dmfe_gld_reset(macinfo);
- dmfep->link_state = LINK_UNKNOWN;
+ mutex_enter(dmfep->oplock);
+ mutex_enter(dmfep->rxlock);
+ mutex_enter(dmfep->txlock);
+
+ dmfe_reset(dmfep);
+
+ /*
+ * Prepare the setup packet
+ */
+ bzero(dmfep->tx_desc.setup_va, SETUPBUF_SIZE);
+ bzero(dmfep->mcast_refs, MCASTBUF_SIZE);
+ dmfep->addr_set = B_FALSE;
+ dmfep->opmode &= ~(PROMISC_MODE | PASS_MULTICAST);
+ dmfep->mac_state = DMFE_MAC_RESET;
+
+ mutex_exit(dmfep->txlock);
+ mutex_exit(dmfep->rxlock);
+ mutex_exit(dmfep->oplock);
+
+ dmfep->link_state = LINK_STATE_UNKNOWN;
dmfep->link_up_msg = dmfep->link_down_msg = " (initialised)";
if (dmfe_init_phy(dmfep) != B_TRUE)
goto attach_fail;
dmfep->update_phy = B_TRUE;
/*
+ * Send a reasonable setup frame. This configures our starting
+ * address and the broadcast address.
+ */
+ dmfe_m_unicst(dmfep, dmfep->curr_addr);
+
+ /*
* Initialize pointers to device specific functions which
* will be used by the generic layer.
*/
- macinfo->gldm_reset = dmfe_gld_reset;
- macinfo->gldm_start = dmfe_gld_start;
- macinfo->gldm_stop = dmfe_gld_stop;
- macinfo->gldm_set_mac_addr = dmfe_gld_set_mac_addr;
- macinfo->gldm_set_multicast = dmfe_gld_set_multicast;
- macinfo->gldm_set_promiscuous = dmfe_gld_set_promiscuous;
- macinfo->gldm_ioctl = dmfe_gld_ioctl;
- macinfo->gldm_get_stats = dmfe_gld_get_stats;
- macinfo->gldm_intr = NULL;
- macinfo->gldm_send = dmfe_gld_send;
-#if defined(VLAN_VID_NONE)
- /*
- * This assignment wouldn't be safe if running a new DMFE binary
- * against an old GLD, because <gldm_send_tagged> extends the
- * macinfo structure. So we need a runtime test as well as the
- * compile-time one if we want full compatibility ...
- */
- if (gld_recv_tagged != NULL)
- macinfo->gldm_send_tagged = dmfe_gld_send_tagged;
-#endif /* defined(VLAN_VID_NONE) */
-
- /*
- * Initialize board characteristics needed by the generic layer.
- */
- macinfo->gldm_ident = dmfe_ident;
- macinfo->gldm_type = DL_ETHER;
- macinfo->gldm_minpkt = 0; /* no padding required */
- macinfo->gldm_maxpkt = ETHERMTU;
- macinfo->gldm_addrlen = ETHERADDRL;
- macinfo->gldm_saplen = -2;
- macinfo->gldm_broadcast_addr = dmfe_broadcast_addr;
- macinfo->gldm_vendor_addr = dmfep->vendor_addr;
- macinfo->gldm_ppa = instance;
- macinfo->gldm_devinfo = devinfo;
- macinfo->gldm_cookie = dmfep->iblk;
-#if defined(GLD_CAP_LINKSTATE)
- /*
- * This is safe even when running a new DMFE binary against an
- * old GLD, because <gldm_capabilities> replaces a reserved
- * field, rather than extending the macinfo structure
- */
- macinfo->gldm_capabilities = GLD_CAP_LINKSTATE;
-#endif /* defined(GLD_CAP_LINKSTATE) */
-
- /*
- * Workaround for booting from NET1 on early versions of Solaris,
- * enabled by patching the global variable (dmfe_net1_boot_support)
- * to non-zero.
- *
- * Up to Solaris 8, strplumb() assumed that PPA == minor number,
- * which is not (and never has been) true for any GLD-based driver.
- * In later versions, strplumb() and GLD have been made to cooperate
- * so this isn't necessary; specifically, strplumb() has been changed
- * to assume PPA == instance (rather than minor number), which *is*
- * true for GLD v2 drivers, and GLD also specifically tells it the
- * PPA for legacy (v0) drivers.
- *
- * The workaround creates an internal minor node with a minor number
- * equal to the PPA; this node shouldn't ever appear under /devices
- * in userland, but can be found internally when setting up the root
- * (NFS) filesystem.
- */
- if (dmfe_net1_boot_support) {
- extern int ddi_create_internal_pathname(dev_info_t *dip,
- char *name, int spec_type, minor_t minor_num);
-
- (void) ddi_create_internal_pathname(devinfo, DRIVER_NAME,
- S_IFCHR, macinfo->gldm_ppa);
- }
+ if ((macp = mac_alloc(MAC_VERSION)) == NULL)
+ goto attach_fail;
+ macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
+ macp->m_driver = dmfep;
+ macp->m_dip = devinfo;
+ macp->m_src_addr = dmfep->curr_addr;
+ macp->m_callbacks = &dmfe_m_callbacks;
+ macp->m_min_sdu = 0;
+ macp->m_max_sdu = ETHERMTU;
/*
- * Finally, we're ready to register ourselves with the GLD
+ * Finally, we're ready to register ourselves with the MAC layer
* interface; if this succeeds, we're all ready to start()
*/
- if (gld_register(devinfo, DRIVER_NAME, macinfo) != DDI_SUCCESS)
+ err = mac_register(macp, &dmfep->mh);
+ mac_free(macp);
+ if (err != 0)
goto attach_fail;
ASSERT(dmfep->dmfe_guard == DMFE_GUARD);
@@ -3228,17 +3153,9 @@ dmfe_suspend(dmfe_t *dmfep)
static int
dmfe_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
{
- gld_mac_info_t *macinfo; /* GLD structure */
dmfe_t *dmfep;
- DMFE_GTRACE(("dmfe_detach($%p, %d)", (void *)devinfo, cmd));
-
- /*
- * Get the GLD (macinfo) data from the devinfo and
- * derive the driver's own state structure from that
- */
- macinfo = (gld_mac_info_t *)ddi_get_driver_private(devinfo);
- dmfep = DMFE_STATE(macinfo);
+ dmfep = ddi_get_driver_private(devinfo);
switch (cmd) {
default:
@@ -3252,12 +3169,12 @@ dmfe_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
}
/*
- * Unregister from the GLD subsystem. This can fail, in
+ * Unregister from the MAC subsystem. This can fail, in
* particular if there are DLPI style-2 streams still open -
* in which case we just return failure without shutting
* down chip operations.
*/
- if (gld_unregister(macinfo) != DDI_SUCCESS)
+ if (mac_unregister(dmfep->mh) != DDI_SUCCESS)
return (DDI_FAILURE);
/*
@@ -3272,76 +3189,8 @@ dmfe_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
* ========== Module Loading Data & Entry Points ==========
*/
-static struct module_info dmfe_module_info = {
- DMFEIDNUM,
- DRIVER_NAME,
- 0,
- INFPSZ,
- DMFEHIWAT,
- DMFELOWAT
-};
-
-static struct qinit dmfe_r_qinit = { /* read queues */
- NULL,
- gld_rsrv,
- gld_open,
- gld_close,
- NULL,
- &dmfe_module_info,
- NULL
-};
-
-static struct qinit dmfe_w_qinit = { /* write queues */
- gld_wput,
- gld_wsrv,
- NULL,
- NULL,
- NULL,
- &dmfe_module_info,
- NULL
-};
-
-static struct streamtab dmfe_streamtab = {
- &dmfe_r_qinit,
- &dmfe_w_qinit,
- NULL,
- NULL
-};
-
-static struct cb_ops dmfe_cb_ops = {
- nulldev, /* cb_open */
- nulldev, /* cb_close */
- nodev, /* cb_strategy */
- nodev, /* cb_print */
- nodev, /* cb_dump */
- nodev, /* cb_read */
- nodev, /* cb_write */
- nodev, /* cb_ioctl */
- nodev, /* cb_devmap */
- nodev, /* cb_mmap */
- nodev, /* cb_segmap */
- nochpoll, /* cb_chpoll */
- ddi_prop_op, /* cb_prop_op */
- &dmfe_streamtab, /* cb_stream */
- D_MP, /* cb_flag */
- CB_REV, /* cb_rev */
- nodev, /* cb_aread */
- nodev /* cb_awrite */
-};
-
-static struct dev_ops dmfe_dev_ops = {
- DEVO_REV, /* devo_rev */
- 0, /* devo_refcnt */
- gld_getinfo, /* devo_getinfo */
- nulldev, /* devo_identify */
- nulldev, /* devo_probe */
- dmfe_attach, /* devo_attach */
- dmfe_detach, /* devo_detach */
- nodev, /* devo_reset */
- &dmfe_cb_ops, /* devo_cb_ops */
- (struct bus_ops *)NULL, /* devo_bus_ops */
- NULL /* devo_power */
-};
+DDI_DEFINE_STREAM_OPS(dmfe_dev_ops, nulldev, nulldev, dmfe_attach, dmfe_detach,
+ nodev, NULL, D_MP, NULL);
static struct modldrv dmfe_modldrv = {
&mod_driverops, /* Type of module. This one is a driver */
@@ -3356,8 +3205,6 @@ static struct modlinkage modlinkage = {
int
_info(struct modinfo *modinfop)
{
- DMFE_GTRACE(("_info called"));
-
return (mod_info(&modlinkage, modinfop));
}
@@ -3369,8 +3216,6 @@ _init(void)
int i;
int status;
- DMFE_GTRACE(("_init called"));
-
/* Calculate global timing parameters */
tmp100 = (dmfe_tx100_stall_us+dmfe_tick_us-1)/dmfe_tick_us;
tmp10 = (dmfe_tx10_stall_us+dmfe_tick_us-1)/dmfe_tick_us;
@@ -3406,8 +3251,9 @@ _init(void)
factotum_fast_tix = 1+(factotum_tix/5);
factotum_start_tix = 1+(factotum_tix*2);
+ mac_init_ops(&dmfe_dev_ops, "dmfe");
status = mod_install(&modlinkage);
- if (status == 0)
+ if (status == DDI_SUCCESS)
dmfe_log_init();
return (status);
@@ -3418,11 +3264,11 @@ _fini(void)
{
int status;
- DMFE_GTRACE(("_fini called"));
-
status = mod_remove(&modlinkage);
- if (status == 0)
+ if (status == DDI_SUCCESS) {
+ mac_fini_ops(&dmfe_dev_ops);
dmfe_log_fini();
+ }
return (status);
}
diff --git a/usr/src/uts/sun4u/io/dmfe/dmfe_mii.c b/usr/src/uts/sun4u/io/dmfe/dmfe_mii.c
index 22826921c9..1358453f28 100644
--- a/usr/src/uts/sun4u/io/dmfe/dmfe_mii.c
+++ b/usr/src/uts/sun4u/io/dmfe/dmfe_mii.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -311,13 +310,6 @@ dmfe_find_phy(dmfe_t *dmfep)
DMFE_DEBUG(("PHY at address %d, id 0x%x", mii_addr, dmfep->phy_id));
- /*
- * DM9102A has an integrated MII interface, therefore we set
- * the transceiver address kstat (KS_MII_XCVR_ADDR) to -1
- */
- MII_KS_SET(dmfep, KS_MII_XCVR_ADDR, dmfep->phy_addr);
- MII_KS_SET(dmfep, KS_MII_XCVR_ID, dmfep->phy_id);
-
switch (PHY_MANUFACTURER(dmfep->phy_id)) {
case OUI_DAVICOM:
return (B_TRUE);
@@ -527,7 +519,7 @@ dmfe_check_link(dmfe_t *dmfep)
{
if (dmfe_check_bmsr(dmfep))
return (B_TRUE);
- return (dmfep->link_state == LINK_UNKNOWN);
+ return (dmfep->link_state == LINK_STATE_UNKNOWN);
}
@@ -543,7 +535,6 @@ dmfe_media_update(dmfe_t *dmfep, link_state_t newstate, int speed, int duplex)
const char *duplex_msg;
const char *link_msg;
boolean_t report;
- int phy_inuse;
int ks_id;
ASSERT(mutex_owned(dmfep->milock));
@@ -551,7 +542,7 @@ dmfe_media_update(dmfe_t *dmfep, link_state_t newstate, int speed, int duplex)
ASSERT(newstate != dmfep->link_state);
switch (newstate) {
- case LINK_UP:
+ case LINK_STATE_UP:
dmfep->param_linkup = 1;
state_msg = "up";
link_msg = dmfep->link_up_msg;
@@ -569,37 +560,32 @@ dmfe_media_update(dmfe_t *dmfep, link_state_t newstate, int speed, int duplex)
switch (speed) {
case 100:
- dmfep->op_stats_media = GLDM_100BTX;
dmfep->op_stats_speed = 100000000;
dmfep->param_speed = speed;
- phy_inuse = XCVR_TYPE_100BASE_X;
+ dmfep->phy_inuse = XCVR_100X;
speed_msg = " 100 Mbps";
break;
case 10:
- dmfep->op_stats_media = GLDM_10BT;
dmfep->op_stats_speed = 10000000;
dmfep->param_speed = speed;
- phy_inuse = XCVR_TYPE_10BASE_T;
+ dmfep->phy_inuse = XCVR_10;
speed_msg = " 10 Mbps";
break;
default:
- dmfep->op_stats_media = GLDM_TP;
dmfep->op_stats_speed = 0;
- phy_inuse = XCVR_TYPE_UNDEFINED;
+ dmfep->phy_inuse = XCVR_UNDEFINED;
speed_msg = "";
break;
}
- MII_KS_SET(dmfep, KS_MII_XCVR_INUSE, phy_inuse);
-
switch (duplex) {
- case GLD_DUPLEX_FULL:
+ case LINK_DUPLEX_FULL:
duplex_msg = " Full-Duplex";
break;
- case GLD_DUPLEX_HALF:
+ case LINK_DUPLEX_HALF:
duplex_msg = " Half-Duplex";
break;
@@ -617,7 +603,7 @@ dmfe_media_update(dmfe_t *dmfep, link_state_t newstate, int speed, int duplex)
* just log it.
*/
report = link_msg[0] == '\0';
- if (newstate == LINK_UP)
+ if (newstate == LINK_STATE_UP)
ks_id = report ? KS_LINK_UP_CNT : KS_LINK_CYCLE_UP_CNT;
else
ks_id = report ? KS_LINK_DROP_CNT : KS_LINK_CYCLE_DOWN_CNT;
@@ -646,37 +632,33 @@ dmfe_link_change(dmfe_t *dmfep, link_state_t newstate)
ASSERT(newstate != dmfep->link_state);
switch (newstate) {
- case LINK_UP:
- MII_KS_SET(dmfep, KS_MII_LINK_UP, 1);
+ case LINK_STATE_UP:
gpsr = dmfe_chip_get32(dmfep, PHY_STATUS_REG);
speed = gpsr & GPS_LINK_100 ? 100 : 10;
- duplex =
- (gpsr & GPS_FULL_DUPLEX) ? GLD_DUPLEX_FULL: GLD_DUPLEX_HALF;
+ duplex = (gpsr & GPS_FULL_DUPLEX) ?
+ LINK_DUPLEX_FULL: LINK_DUPLEX_HALF;
report = B_TRUE;
break;
default:
speed = 0;
- duplex = GLD_DUPLEX_UNKNOWN;
- MII_KS_SET(dmfep, KS_MII_LINK_UP, 0);
+ duplex = LINK_DUPLEX_UNKNOWN;
switch (dmfep->link_state) {
- case LINK_DOWN: /* DOWN->UNKNOWN */
+ case LINK_STATE_DOWN: /* DOWN->UNKNOWN */
report = dmfep->link_down_msg[0] != '\0';
break;
- case LINK_UNKNOWN: /* UNKNOWN->DOWN */
+ case LINK_STATE_UNKNOWN: /* UNKNOWN->DOWN */
report = B_FALSE;
break;
- case LINK_UP: /* UP->DOWN/UNKNOWN */
+ case LINK_STATE_UP: /* UP->DOWN/UNKNOWN */
report = B_TRUE;
break;
}
break;
}
- MII_KS_SET(dmfep, KS_MII_LINK_DUPLEX, duplex);
-
/*
* Update status & report new link state if required ...
*/
@@ -739,28 +721,11 @@ dmfe_process_bmsr(dmfe_t *dmfep, clock_t time)
dmfep->param_bmsr_remfault = 1;
dmfep->param_bmsr_autoneg = BIS(bmsr, MII_STATUS_CANAUTONEG);
- MII_KS_SET(dmfep, KS_MII_CAP_100FDX, dmfep->param_bmsr_100fdx);
- MII_KS_SET(dmfep, KS_MII_CAP_100HDX, dmfep->param_bmsr_100hdx);
- MII_KS_SET(dmfep, KS_MII_CAP_10FDX, dmfep->param_bmsr_10fdx);
- MII_KS_SET(dmfep, KS_MII_CAP_10HDX, dmfep->param_bmsr_10hdx);
- MII_KS_SET(dmfep, KS_MII_CAP_REMFAULT, dmfep->param_bmsr_remfault);
- MII_KS_SET(dmfep, KS_MII_CAP_AUTONEG, dmfep->param_bmsr_autoneg);
-
/*
* Advertised abilities of DM9102A
*/
anar = dmfep->phy_anar_r;
- MII_KS_SET(dmfep, KS_MII_ADV_CAP_AUTONEG, dmfep->param_autoneg);
- MII_KS_SET(dmfep, KS_MII_ADV_CAP_100FDX,
- BIS(anar, MII_ABILITY_100BASE_TX_FD));
- MII_KS_SET(dmfep, KS_MII_ADV_CAP_100HDX,
- BIS(anar, MII_ABILITY_100BASE_TX));
- MII_KS_SET(dmfep, KS_MII_ADV_CAP_10FDX,
- BIS(anar, MII_ABILITY_10BASE_T_FD));
- MII_KS_SET(dmfep, KS_MII_ADV_CAP_10HDX,
- BIS(anar, MII_ABILITY_10BASE_T));
- MII_KS_SET(dmfep, KS_MII_ADV_CAP_REMFAULT,
- BIS(anar, MII_AN_ADVERT_REMFAULT));
+ dmfep->param_anar_remfault = BIS(anar, MII_AN_ADVERT_REMFAULT);
/*
* Link Partners advertised abilities
@@ -780,17 +745,11 @@ dmfe_process_bmsr(dmfe_t *dmfep, clock_t time)
dmfep->param_lp_10hdx = BIS(anlpar, MII_ABILITY_10BASE_T);
dmfep->param_lp_remfault = BIS(anlpar, MII_AN_ADVERT_REMFAULT);
- MII_KS_SET(dmfep, KS_MII_LP_CAP_100FDX, dmfep->param_lp_100fdx);
- MII_KS_SET(dmfep, KS_MII_LP_CAP_100HDX, dmfep->param_lp_100hdx);
- MII_KS_SET(dmfep, KS_MII_LP_CAP_10FDX, dmfep->param_lp_10fdx);
- MII_KS_SET(dmfep, KS_MII_LP_CAP_10HDX, dmfep->param_lp_10hdx);
- MII_KS_SET(dmfep, KS_MII_LP_CAP_AUTONEG, dmfep->param_lp_autoneg);
- MII_KS_SET(dmfep, KS_MII_LP_CAP_REMFAULT, dmfep->param_lp_remfault);
-
/*
* Derive new state & time since last change
*/
- newstate = (dmfep->phy_bmsr & MII_STATUS_LINKUP) ? LINK_UP : LINK_DOWN;
+ newstate = (dmfep->phy_bmsr & MII_STATUS_LINKUP) ?
+ LINK_STATE_UP : LINK_STATE_DOWN;
time -= dmfep->phy_bmsr_lbolt;
/*
@@ -798,17 +757,18 @@ dmfe_process_bmsr(dmfe_t *dmfep, clock_t time)
* for all sorts of special cases before we decide :(
*/
if (dmfep->phy_bmsr == MII_STATUS_INVAL)
- newstate = LINK_DOWN;
- else if (dmfep->link_state == LINK_UP && newstate == LINK_DOWN)
+ newstate = LINK_STATE_DOWN;
+ else if ((dmfep->link_state == LINK_STATE_UP) &&
+ (newstate == LINK_STATE_DOWN))
/*EMPTY*/;
else if (time < drv_usectohz(dmfe_mii_settle_time))
- newstate = LINK_UNKNOWN;
+ newstate = LINK_STATE_UNKNOWN;
else if (dmfep->phy_bmsr & MII_STATUS_ANDONE)
/*EMPTY*/;
else if (dmfep->phy_control & MII_CONTROL_ANE)
- newstate = LINK_UNKNOWN;
+ newstate = LINK_STATE_UNKNOWN;
- if (newstate == LINK_UP) {
+ if (newstate == LINK_STATE_UP) {
/*
* Link apparently UP - but get the PHY status register
* (GPSR) and make sure it also shows a consistent value.
@@ -824,7 +784,7 @@ dmfe_process_bmsr(dmfe_t *dmfep, clock_t time)
case GPS_LINK_STATUS|GPS_UTP_SIG:
break;
default:
- newstate = LINK_UNKNOWN;
+ newstate = LINK_STATE_UNKNOWN;
break;
}
@@ -833,7 +793,7 @@ dmfe_process_bmsr(dmfe_t *dmfep, clock_t time)
case GPS_LINK_10:
break;
default:
- newstate = LINK_UNKNOWN;
+ newstate = LINK_STATE_UNKNOWN;
break;
}
}
@@ -889,7 +849,7 @@ dmfe_recheck_link(dmfe_t *dmfep, boolean_t ioctl)
ASSERT(dmfep->link_state == newstate);
if (again)
continue;
- if (newstate == LINK_UP) {
+ if (newstate == LINK_STATE_UP) {
dmfep->update_phy = B_TRUE;
break;
}
diff --git a/usr/src/uts/sun4u/sys/dmfe_impl.h b/usr/src/uts/sun4u/sys/dmfe_impl.h
index ad3cc29045..2eac4c7633 100644
--- a/usr/src/uts/sun4u/sys/dmfe_impl.h
+++ b/usr/src/uts/sun4u/sys/dmfe_impl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,7 +41,6 @@ extern "C" {
#include <sys/modctl.h>
#include <sys/kstat.h>
#include <sys/ethernet.h>
-#include <sys/dlpi.h>
#include <sys/devops.h>
#include <sys/debug.h>
#include <sys/cyclic.h>
@@ -52,46 +50,18 @@ extern "C" {
#include <inet/nd.h>
#include <inet/mi.h>
+#include <sys/vlan.h>
+
#include <sys/dditypes.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/miiregs.h>
#include <sys/dmfe.h>
+#include <sys/mac.h>
+#include <sys/mac_ether.h>
-/*
- * The following function *may* be defined in <sys/gld.h>.
- * If so, the full definitions there will supplement these minimal
- * versions; otherwise, these will suffice to allow the code to
- * compile and then we'll test for them at runtime.
- */
-extern void gld_linkstate();
-extern void gld_recv_tagged();
-#pragma weak gld_linkstate
-#pragma weak gld_recv_tagged
-
-#include <sys/gld.h>
-
-/*
- * Define these symbols if they're not already in <sys/gld.h>
- */
-#ifndef GLD_LINKSTATE_UP
-#define GLD_LINKSTATE_UP 1
-#define GLD_LINKSTATE_UNKNOWN 0
-#define GLD_LINKSTATE_DOWN -1
-#endif /* GLD_LINKSTATE_UP */
-
-/*
- * This driver can be compiled with VLAN support (if VLAN_VID_NONE
- * is defined in <sys/gld.h>). If not, the definitions is the 'else'
- * clause will allow the code to compile anyway.
- */
-#ifdef VLAN_VID_NONE
-#define DMFE_MAX_PKT_SIZE (VTAG_SIZE + ETHERMAX + ETHERFCSL)
-#else
-#define DMFE_MAX_PKT_SIZE (ETHERMAX + ETHERFCSL)
-#define VLAN_VTAG_NONE 0 /* implies "untagged" */
-#endif /* VLAN_VID_NONE */
+#define DMFE_MAX_PKT_SIZE (VLAN_TAGSZ + ETHERMAX + ETHERFCSL)
#define DRIVER_NAME "dmfe"
@@ -166,6 +136,7 @@ enum {
PARAM_ADV_100HDX_CAP,
PARAM_ADV_10FDX_CAP,
PARAM_ADV_10HDX_CAP,
+ PARAM_ADV_REMFAULT,
PARAM_BMSR_AUTONEG_CAP,
PARAM_BMSR_100T4_CAP,
@@ -187,47 +158,6 @@ enum {
};
/*
- * Indexes into standard "mii" kstats, divided into:
- *
- * MII transceiver info
- * MII link state
- * MII device capabilities
- * MII advertised capabilities
- * MII link partner capabilities
- */
-enum {
- KS_MII_XCVR_ADDR,
- KS_MII_XCVR_ID,
- KS_MII_XCVR_INUSE,
-
- KS_MII_LINK_UP,
- KS_MII_LINK_DUPLEX,
-
- KS_MII_CAP_100FDX,
- KS_MII_CAP_100HDX,
- KS_MII_CAP_10FDX,
- KS_MII_CAP_10HDX,
- KS_MII_CAP_REMFAULT,
- KS_MII_CAP_AUTONEG,
-
- KS_MII_ADV_CAP_100FDX,
- KS_MII_ADV_CAP_100HDX,
- KS_MII_ADV_CAP_10FDX,
- KS_MII_ADV_CAP_10HDX,
- KS_MII_ADV_CAP_REMFAULT,
- KS_MII_ADV_CAP_AUTONEG,
-
- KS_MII_LP_CAP_100FDX,
- KS_MII_LP_CAP_100HDX,
- KS_MII_LP_CAP_10FDX,
- KS_MII_LP_CAP_10HDX,
- KS_MII_LP_CAP_REMFAULT,
- KS_MII_LP_CAP_AUTONEG,
-
- KS_MII_COUNT
-};
-
-/*
* Indexes into the driver-specific kstats, divided into:
*
* cyclic activity
@@ -241,7 +171,7 @@ enum {
KS_TICK_LINK_STATE,
KS_TICK_LINK_POLL,
- KS_LINK_INTERRUPT,
+ KS_INTERRUPT,
KS_TX_STALL,
KS_CHIP_ERROR,
@@ -277,29 +207,16 @@ enum chip_state {
};
/*
- * Required state according to GLD
+ * Required state according to MAC
*/
-enum gld_state {
- GLD_UNKNOWN,
- GLD_RESET,
- GLD_STOPPED,
- GLD_STARTED
+enum mac_state {
+ DMFE_MAC_UNKNOWN,
+ DMFE_MAC_RESET,
+ DMFE_MAC_STOPPED,
+ DMFE_MAC_STARTED
};
/*
- * Current state of the physical link
- *
- * DOWN No link established.
- * UNKNOWN Initial state, also indicates "autonegotiating".
- * UP Link established, commuication should be possible.
- */
-typedef enum {
- LINK_DOWN = -1,
- LINK_UNKNOWN = 0,
- LINK_UP
-} link_state_t;
-
-/*
* (Internal) return values from ioctl subroutines
*/
enum ioc_reply {
@@ -319,7 +236,7 @@ typedef struct {
* These fields are set by attach() and unchanged thereafter ...
*/
dev_info_t *devinfo; /* device instance */
- gld_mac_info_t *macinfo; /* GLD instance data */
+ mac_handle_t mh; /* MAC instance data */
ddi_acc_handle_t io_handle; /* DDI I/O handle */
caddr_t io_reg; /* mapped registers */
@@ -368,8 +285,8 @@ typedef struct {
* milock >>> oplock >>> rxlock >>> txlock.
*
* *None* of these locks may be held across calls out to the
- * GLD routines gld_recv() or gld_sched(); GLD's <maclock> must
- * be regarded as an *outermost* lock in all cases, as it will
+ * MAC routines mac_rx() or mac_tx_notify(); MAC locks must
+ * be regarded as *outermost* locks in all cases, as they will
* already be held before calling the ioctl() or get_stats()
* entry points - which then have to acquire multiple locks, in
* the order described here.
@@ -382,8 +299,6 @@ typedef struct {
/*
* DMFE Extended kstats, protected by <oplock>
*/
- kstat_t *ksp_mii;
- kstat_named_t *knp_mii;
kstat_t *ksp_drv;
kstat_named_t *knp_drv;
@@ -391,30 +306,36 @@ typedef struct {
* GLD statistics; the prefix tells which lock each is protected by.
*/
uint64_t op_stats_speed;
- uint32_t op_stats_duplex;
- uint32_t op_stats_media;
- uint32_t op_stats_intr;
-
- uint32_t rx_stats_errrcv;
- uint32_t rx_stats_overflow;
- uint32_t rx_stats_short;
- uint32_t rx_stats_crc;
- uint32_t rx_stats_frame_too_long;
- uint32_t rx_stats_mac_rcv_error;
- uint32_t rx_stats_frame;
- uint32_t rx_stats_missed;
- uint32_t rx_stats_norcvbuf;
-
- uint32_t tx_stats_errxmt;
- uint32_t tx_stats_mac_xmt_error;
- uint32_t tx_stats_underflow;
- uint32_t tx_stats_xmtlatecoll;
- uint32_t tx_stats_nocarrier;
- uint32_t tx_stats_excoll;
- uint32_t tx_stats_first_coll;
- uint32_t tx_stats_multi_coll;
- uint32_t tx_stats_collisions;
- uint32_t tx_stats_defer;
+ uint64_t op_stats_duplex;
+
+ uint64_t rx_stats_ipackets;
+ uint64_t rx_stats_multi;
+ uint64_t rx_stats_bcast;
+ uint64_t rx_stats_ierrors;
+ uint64_t rx_stats_norcvbuf;
+ uint64_t rx_stats_rbytes;
+ uint64_t rx_stats_missed;
+ uint64_t rx_stats_align;
+ uint64_t rx_stats_fcs;
+ uint64_t rx_stats_toolong;
+ uint64_t rx_stats_macrcv_errors;
+ uint64_t rx_stats_overflow;
+ uint64_t rx_stats_short;
+
+ uint64_t tx_stats_oerrors;
+ uint64_t tx_stats_opackets;
+ uint64_t tx_stats_multi;
+ uint64_t tx_stats_bcast;
+ uint64_t tx_stats_obytes;
+ uint64_t tx_stats_collisions;
+ uint64_t tx_stats_nocarrier;
+ uint64_t tx_stats_xmtlatecoll;
+ uint64_t tx_stats_excoll;
+ uint64_t tx_stats_macxmt_errors;
+ uint64_t tx_stats_defer;
+ uint64_t tx_stats_first_coll;
+ uint64_t tx_stats_multi_coll;
+ uint64_t tx_stats_underflow;
/*
* These two sets of desciptors are manipulated during
@@ -427,6 +348,8 @@ typedef struct {
* Miscellaneous Tx-side variables (protected by txlock)
*/
uint32_t tx_pending_tix; /* tix since reclaim */
+ uint8_t *tx_mcast; /* bitmask: pkt is mcast */
+ uint8_t *tx_bcast; /* bitmask: pkt is bcast */
/*
* Miscellaneous operating variables (protected by oplock)
@@ -436,7 +359,7 @@ typedef struct {
uint16_t need_setup; /* send-setup pending */
uint32_t opmode; /* operating mode shadow */
uint32_t imask; /* interrupt mask shadow */
- enum gld_state gld_state; /* RESET/STOPPED/STARTED */
+ enum mac_state mac_state; /* RESET/STOPPED/STARTED */
enum chip_state chip_state; /* see above */
/*
@@ -449,6 +372,7 @@ typedef struct {
/*
* PHYceiver state data (protected by milock)
*/
+ int phy_inuse;
int phy_addr; /* should be -1! */
uint16_t phy_control; /* last value written */
uint16_t phy_anar_w; /* last value written */
@@ -510,6 +434,7 @@ typedef struct {
#define param_anar_100hdx nd_params[PARAM_ADV_100HDX_CAP].ndp_val
#define param_anar_10fdx nd_params[PARAM_ADV_10FDX_CAP].ndp_val
#define param_anar_10hdx nd_params[PARAM_ADV_10HDX_CAP].ndp_val
+#define param_anar_remfault nd_params[PARAM_ADV_REMFAULT].ndp_val
#define param_bmsr_autoneg nd_params[PARAM_BMSR_AUTONEG_CAP].ndp_val
#define param_bmsr_100T4 nd_params[PARAM_BMSR_100T4_CAP].ndp_val
#define param_bmsr_100fdx nd_params[PARAM_BMSR_100FDX_CAP].ndp_val
@@ -526,12 +451,6 @@ typedef struct {
#define param_lp_remfault nd_params[PARAM_LP_REMFAULT].ndp_val
/*
- * Derive DMFE state from GLD's macinfo or vice versa
- */
-#define DMFE_STATE(macinfo) ((dmfe_t *)((macinfo)->gldm_private))
-#define DMFE_MACINFO(dmfep) ((dmfep)->macinfo)
-
-/*
* Sync a DMA area described by a dma_area_t
*/
#define DMA_SYNC(descp, flag) ((void) ddi_dma_sync((descp)->dma_hdl, \
@@ -619,7 +538,7 @@ typedef struct {
/*
* Debugging ...
*/
-#ifdef DEBUG
+#if defined(DEBUG) || defined(lint)
#define DMFEDEBUG 1
#else
#define DMFEDEBUG 0