Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Oct 2003 09:58:35 -0700 (PDT)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 39751 for review
Message-ID:  <200310151658.h9FGwZAj087116@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=39751

Change 39751 by sam@sam_ebb on 2003/10/15 09:58:00

	IFC

Affected files ...

.. //depot/projects/netperf/sys/amd64/amd64/exception.S#4 integrate
.. //depot/projects/netperf/sys/amd64/amd64/trap.c#5 integrate
.. //depot/projects/netperf/sys/amd64/include/frame.h#2 integrate
.. //depot/projects/netperf/sys/amd64/include/signal.h#3 integrate
.. //depot/projects/netperf/sys/amd64/include/ucontext.h#4 integrate
.. //depot/projects/netperf/sys/conf/files#13 integrate
.. //depot/projects/netperf/sys/dev/ata/ata-queue.c#6 integrate
.. //depot/projects/netperf/sys/dev/ath/if_ath.c#21 integrate
.. //depot/projects/netperf/sys/dev/ath/if_ath_pci.c#5 integrate
.. //depot/projects/netperf/sys/dev/ath/if_athvar.h#6 integrate
.. //depot/projects/netperf/sys/dev/em/if_em.c#8 integrate
.. //depot/projects/netperf/sys/dev/xe/if_xe.c#3 integrate
.. //depot/projects/netperf/sys/dev/xe/if_xe_pccard.c#4 integrate
.. //depot/projects/netperf/sys/dev/xe/if_xereg.h#2 integrate
.. //depot/projects/netperf/sys/dev/xe/if_xevar.h#2 integrate
.. //depot/projects/netperf/sys/i386/i386/locore.s#7 edit
.. //depot/projects/netperf/sys/i386/i386/pmap.c#18 integrate
.. //depot/projects/netperf/sys/kern/kern_poll.c#5 integrate
.. //depot/projects/netperf/sys/kern/kern_proc.c#5 integrate
.. //depot/projects/netperf/sys/kern/sched_ule.c#8 integrate
.. //depot/projects/netperf/sys/netinet/in_rmx.c#7 integrate
.. //depot/projects/netperf/sys/netinet/ip_input.c#11 integrate
.. //depot/projects/netperf/sys/netinet/ip_var.h#7 integrate
.. //depot/projects/netperf/sys/netinet6/nd6.c#10 integrate
.. //depot/projects/netperf/sys/vm/vm_fault.c#7 integrate

Differences ...

==== //depot/projects/netperf/sys/amd64/amd64/exception.S#4 (text+ko) ====

@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/amd64/exception.S,v 1.112 2003/09/22 22:54:14 peter Exp $
+ * $FreeBSD: src/sys/amd64/amd64/exception.S,v 1.113 2003/10/15 02:04:52 peter Exp $
  */
 
 #include <machine/asmacros.h>
@@ -228,7 +228,7 @@
 	movq	%rsp,PCPU(SCRATCH_RSP)
 	movq	common_tss+COMMON_TSS_RSP0,%rsp
 	/* Now emulate a trapframe. Make the 8 byte alignment odd for call. */
-	subq	$TF_SIZE+8,%rsp
+	subq	$TF_SIZE,%rsp
 	/* defer TF_RSP till we have a spare register */
 	movq	%r11,TF_RFLAGS(%rsp)
 	movq	%rcx,TF_RIP(%rsp)	/* %rcx original value is in %r10 */

==== //depot/projects/netperf/sys/amd64/amd64/trap.c#5 (text+ko) ====

@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/trap.c,v 1.265 2003/10/09 10:17:16 robert Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/trap.c,v 1.266 2003/10/15 02:04:52 peter Exp $");
 
 /*
  * AMD64 Trap and System call handling
@@ -258,6 +258,9 @@
 		default:
 			ucode = code + BUS_SEGM_FAULT ;
 			i = SIGBUS;
+printf("trap %d: pid %d err %p eva %p, rip %p, rax %p, rbx %p, rcx %p, rdx %p, rsp %p, rbp %p, rsi %p, rdi %p\n", type, p->p_pid, (void *)frame.tf_err,
+(void *)frame.tf_addr, (void *)frame.tf_rip, (void *)frame.tf_rax, (void *)frame.tf_rbx, (void *)frame.tf_rcx, (void *)frame.tf_rdx, (void *)frame.tf_rsp, (void *)frame.tf_rbp, (void *)frame.tf_rsi, (void *)frame.tf_rdi);
+
 			break;
 
 		case T_PAGEFLT:		/* page fault */
@@ -542,6 +545,12 @@
 		return (-1);
 	}
 
+printf("trap_pfault: pid %d %s %s %s eva %p, rip %p, rax %p, rbx %p, rcx %p, rdx %p, rsp %p, rbp %p, rsi %p, rdi %p\n", p->p_pid,
+			frame->tf_err & PGEX_U ? "user" : "supervisor",
+			frame->tf_err & PGEX_W ? "write" : "read",
+			frame->tf_err & PGEX_P ? "protection violation" : "page not present",
+(void *)eva, (void *)frame->tf_rip, (void *)frame->tf_rax, (void *)frame->tf_rbx, (void *)frame->tf_rcx, (void *)frame->tf_rdx, (void *)frame->tf_rsp, (void *)frame->tf_rbp, (void *)frame->tf_rsi, (void *)frame->tf_rdi);
+
 	return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
 }
 

==== //depot/projects/netperf/sys/amd64/include/frame.h#2 (text+ko) ====

@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)frame.h	5.2 (Berkeley) 1/18/91
- * $FreeBSD: src/sys/amd64/include/frame.h,v 1.24 2003/05/12 18:33:19 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/frame.h,v 1.25 2003/10/15 02:04:52 peter Exp $
  */
 
 #ifndef _MACHINE_FRAME_H_
@@ -69,6 +69,7 @@
 	register_t	tf_r15;
 	register_t	tf_trapno;
 	register_t	tf_addr;
+	register_t	tf_flags;
 	/* below portion defined in hardware */
 	register_t	tf_err;
 	register_t	tf_rip;
@@ -98,6 +99,7 @@
 	register_t	if_r15;
 	register_t	:64;		/* compat with trap frame - trapno */
 	register_t	:64;		/* compat with trap frame - addr */
+	register_t	:64;		/* compat with trap frame - flags */
 	register_t	:64;		/* compat with trap frame - err */
 	/* below portion defined in hardware */
 	register_t	if_rip;
@@ -127,6 +129,7 @@
 	register_t	cf_r15;
 	register_t	:64;		/* compat with trap frame - trapno */
 	register_t	:64;		/* compat with trap frame - addr */
+	register_t	:64;		/* compat with trap frame - flags */
 	register_t	:64;		/* compat with trap frame - err */
 	/* below portion defined in hardware */
 	register_t	cf_rip;

==== //depot/projects/netperf/sys/amd64/include/signal.h#3 (text+ko) ====

@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)signal.h	8.1 (Berkeley) 6/11/93
- * $FreeBSD: src/sys/amd64/include/signal.h,v 1.23 2003/09/08 18:31:48 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/signal.h,v 1.24 2003/10/15 02:04:52 peter Exp $
  */
 
 #ifndef _MACHINE_SIGNAL_H_
@@ -91,6 +91,7 @@
 	long	sc_r15;
 	long	sc_trapno;
 	long	sc_addr;
+	long	sc_flags;
 	long	sc_err;
 	long	sc_rip;
 	long	sc_cs;
@@ -104,9 +105,8 @@
 	 */
 	long	sc_fpformat;
 	long	sc_ownedfp;
-	long	sc_spare1[1];
 	long	sc_fpstate[64] __aligned(16);
-	long	sc_spare2[8];
+	long	sc_spare[8];
 };
 #endif /* __BSD_VISIBLE */
 

==== //depot/projects/netperf/sys/amd64/include/ucontext.h#4 (text+ko) ====

@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/ucontext.h,v 1.15 2003/10/01 01:08:04 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/ucontext.h,v 1.16 2003/10/15 02:04:52 peter Exp $
  */
 
 #ifndef _MACHINE_UCONTEXT_H_
@@ -55,6 +55,7 @@
 	__register_t	mc_r15;
 	__register_t	mc_trapno;
 	__register_t	mc_addr;
+	__register_t	mc_flags;
 	__register_t	mc_err;
 	__register_t	mc_rip;
 	__register_t	mc_cs;
@@ -70,12 +71,11 @@
 #define	_MC_FPOWNED_FPU		0x20001	/* FP state came from FPU */
 #define	_MC_FPOWNED_PCB		0x20002	/* FP state came from PCB */
 	long	mc_ownedfp;
-	long	mc_spare1[1];		/* align mc_fpstate to 16 bytes */
 	/*
 	 * See <machine/npx.h> for the internals of mc_fpstate[].
 	 */
 	long	mc_fpstate[64] __aligned(16);
-	long	mc_spare2[8];
+	long	mc_spare[8];
 } mcontext_t;
 
 #endif /* !_MACHINE_UCONTEXT_H_ */

==== //depot/projects/netperf/sys/conf/files#13 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/files,v 1.833 2003/10/13 19:26:07 ume Exp $
+# $FreeBSD: src/sys/conf/files,v 1.834 2003/10/15 08:53:04 phk Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -949,6 +949,9 @@
 geom/bde/g_bde_crypt.c		optional geom_bde
 geom/bde/g_bde_lock.c		optional geom_bde
 geom/bde/g_bde_work.c		optional geom_bde
+crypto/rijndael/rijndael-alg-fst.c	optional geom_bde
+crypto/rijndael/rijndael-api-fst.c	optional geom_bde
+crypto/sha2/sha2.c		optional geom_bde
 geom/geom_aes.c		optional geom_aes
 geom/geom_apple.c	optional geom_apple
 geom/geom_bsd.c		optional geom_bsd
@@ -974,8 +977,6 @@
 geom/geom_sunlabel.c	optional geom_sunlabel
 geom/geom_sunlabel_enc.c	optional geom_sunlabel
 geom/geom_vol_ffs.c	optional geom_vol
-crypto/rijndael/rijndael-alg-fst.c	optional geom
-crypto/rijndael/rijndael-api-fst.c	optional geom
 gnu/ext2fs/ext2_alloc.c		optional ext2fs \
 	warning "kernel contains GPL contaminated ext2fs filesystem"
 gnu/ext2fs/ext2_balloc.c	optional ext2fs

==== //depot/projects/netperf/sys/dev/ata/ata-queue.c#6 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-queue.c,v 1.8 2003/10/12 12:38:03 sos Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-queue.c,v 1.9 2003/10/14 16:53:13 sos Exp $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
@@ -315,20 +315,21 @@
 static void
 ata_timeout(struct ata_request *request)
 {
+    struct ata_channel *ch = request->device->channel;
+    int quiet = request->flags & ATA_R_QUIET;
+
     /* clear timeout etc */
     request->timeout_handle.callout = NULL;
-#if 0
-    /* call interrupt to try finish up the command */
-    request->device->channel->hw.interrupt(request->device->channel);
 
-    if (request->device->channel->running == NULL) {
-	if (!(request->flags & ATA_R_QUIET))
+    /* call hw.interrupt to try finish up the command */
+    ch->hw.interrupt(request->device->channel);
+    if (ch->running != request) {
+	if (!quiet)
 	    ata_prtdev(request->device,
 		       "WARNING - %s recovered from missing interrupt\n",
 		       ata_cmd2str(request));
 	return;
     }
-#endif
 
     /* if this was a DMA request stop the engine to be on the safe side */
     if (request->flags & ATA_R_DMA) {

==== //depot/projects/netperf/sys/dev/ath/if_ath.c#21 (text+ko) ====

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.24 2003/10/13 04:57:31 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.25 2003/10/14 22:51:45 sam Exp $");
 
 /*
  * Driver for the Atheros Wireless LAN controller.

==== //depot/projects/netperf/sys/dev/ath/if_ath_pci.c#5 (text+ko) ====

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.3 2003/08/13 21:29:35 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.4 2003/10/14 22:51:45 sam Exp $");
 
 /*
  * PCI/Cardbus front-end for the Atheros Wireless LAN controller driver.

==== //depot/projects/netperf/sys/dev/ath/if_athvar.h#6 (text+ko) ====

@@ -33,7 +33,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGES.
  *
- * $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.8 2003/09/15 22:34:46 sam Exp $
+ * $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.9 2003/10/14 22:51:45 sam Exp $
  */
 
 /*

==== //depot/projects/netperf/sys/dev/em/if_em.c#8 (text+ko) ====

@@ -31,7 +31,7 @@
 
 ***************************************************************************/
 
-/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.31 2003/10/10 23:14:20 sam Exp $*/
+/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.32 2003/10/15 05:34:41 deischen Exp $*/
 
 #include <dev/em/if_em.h>
 
@@ -167,6 +167,7 @@
 static void em_82547_update_fifo_head(struct adapter *, int);
 static int  em_82547_tx_fifo_reset(struct adapter *);
 static void em_82547_move_tail(void *arg);
+static void em_82547_move_tail_locked(struct adapter *);
 static int  em_dma_malloc(struct adapter *, bus_size_t,
 			  struct em_dma_alloc *, int);
 static void em_dma_free(struct adapter *, struct em_dma_alloc *);
@@ -1284,7 +1285,7 @@
          */
         if (adapter->hw.mac_type == em_82547 &&
             adapter->link_duplex == HALF_DUPLEX) {
-                em_82547_move_tail(adapter);
+                em_82547_move_tail_locked(adapter);
         } else {
                 E1000_WRITE_REG(&adapter->hw, TDT, i);
                 if (adapter->hw.mac_type == em_82547) {
@@ -1304,9 +1305,8 @@
  *
  **********************************************************************/
 static void
-em_82547_move_tail(void *arg)
+em_82547_move_tail_locked(struct adapter *adapter)
 {
-	struct adapter *adapter = arg;
 	uint16_t hw_tdt;
 	uint16_t sw_tdt;
 	struct em_tx_desc *tx_desc;
@@ -1340,6 +1340,16 @@
 	return;
 }
 
+static void
+em_82547_move_tail(void *arg)
+{
+        struct adapter *adapter = arg;
+
+        EM_LOCK(adapter);
+        em_82547_move_tail_locked(adapter);
+        EM_UNLOCK(adapter);
+}
+
 static int
 em_82547_fifo_workaround(struct adapter *adapter, int len)
 {	

==== //depot/projects/netperf/sys/dev/xe/if_xe.c#3 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998, 1999 Scott Mitchell
+ * Copyright (c) 1998, 1999, 2003  Scott Mitchell
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,16 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/xe/if_xe.c,v 1.38 2003/08/24 17:55:58 obrien Exp $");
-
-/*
- * XXX TODO XXX
- *
- * I've pushed this fairly far, but there are some things that need to be
- * done here.  I'm documenting them here in case I get destracted. -- imp
- *
- * xe_cem56fix -- need to figure out how to map the extra stuff.
- */
+__FBSDID("$FreeBSD: src/sys/dev/xe/if_xe.c,v 1.39 2003/10/14 22:51:35 rsm Exp $");
 
 /*
  * Portions of this software were derived from Werner Koch's xirc2ps driver
@@ -99,14 +90,8 @@
  * the CEM56/REM56 support code; and the FreeBSD UK Users' Group for hosting
  * the web pages.
  *
- * Contact points:
- *
+ * Author email: <scott@uk.freebsd.org>
  * Driver web page: http://ukug.uk.freebsd.org/~scott/xe_drv/
- *
- * Mailing list: http://www.lovett.com/lists/freebsd-xircom/
- * or send "subscribe freebsd-xircom" to <majordomo@lovett.com>
- *
- * Author email: <scott@uk.freebsd.org>
  */
 
 
@@ -159,6 +144,10 @@
 #define XE_AUTONEG_100TX	3	/* Trying to force 100baseTX link */
 #define XE_AUTONEG_FAIL		4	/* Autonegotiation failed */
 
+/*
+ * Multicast hashing CRC constants
+ */
+#define XE_CRC_POLY  0x04c11db6
 
 /*
  * Prototypes start here
@@ -170,16 +159,14 @@
 static int       xe_media_change	(struct ifnet *ifp);
 static void      xe_media_status	(struct ifnet *ifp, struct ifmediareq *mrp);
 static timeout_t xe_setmedia;
-static void      xe_hard_reset		(struct xe_softc *scp);
-static void      xe_soft_reset		(struct xe_softc *scp);
+static void      xe_reset		(struct xe_softc *scp);
 static void      xe_stop		(struct xe_softc *scp);
 static void      xe_enable_intr		(struct xe_softc *scp);
 static void      xe_disable_intr	(struct xe_softc *scp);
-static void      xe_setmulti		(struct xe_softc *scp);
-static void      xe_setaddrs		(struct xe_softc *scp);
+static void      xe_set_multicast	(struct xe_softc *scp);
+static void      xe_set_addr		(struct xe_softc *scp, u_int8_t* addr, unsigned idx);
+static void      xe_set_hash		(struct xe_softc *scp, u_int8_t* addr);
 static int       xe_pio_write_packet	(struct xe_softc *scp, struct mbuf *mbp);
-static u_int32_t xe_compute_crc		(u_int8_t *data, int len) __unused;
-static int       xe_compute_hashbit	(u_int32_t crc) __unused;
 
 /*
  * MII functions
@@ -192,12 +179,16 @@
 static u_int16_t xe_phy_readreg		(struct xe_softc *scp, u_int16_t reg);
 static void      xe_phy_writereg	(struct xe_softc *scp, u_int16_t reg, u_int16_t data);
 
+
 /*
- * Debug functions -- uncomment for VERY verbose dignostic information.
- * Set to 1 for less verbose information
+ * Debug logging level (comment out for normal operation):
+ * 1 = Log more hardware details, xe_ioctl details
+ * 2 = Log most function calls, some (eg. multicast, MII) in detail
+ * 3 = Log everything, including all interrupts and packets sent
  */
-/* #define XE_DEBUG 2 */
-#ifdef XE_DEBUG
+#define XE_DEBUG 0
+
+#if XE_DEBUG > 2
 #define XE_REG_DUMP(scp)		xe_reg_dump((scp))
 #define XE_MII_DUMP(scp)		xe_mii_dump((scp))
 static void      xe_reg_dump		(struct xe_softc *scp);
@@ -207,6 +198,7 @@
 #define XE_MII_DUMP(scp)
 #endif
 
+
 /*
  * Attach a device.
  */
@@ -215,20 +207,16 @@
 {
   struct xe_softc *scp = device_get_softc(dev);
 
-#ifdef XE_DEBUG
+#if XE_DEBUG > 1
   device_printf(dev, "attach\n");
 #endif
 
-  /* Fill in some private data */
+  /* Initialise stuff... */
+  scp->dev = dev;
   scp->ifp = &scp->arpcom.ac_if;
   scp->ifm = &scp->ifmedia;
-  scp->autoneg_status = 0;
-
-  /* Hopefully safe to read this here */
-  XE_SELECT_PAGE(4);
-  scp->version = XE_INB(XE_BOV);
+  scp->autoneg_status = XE_AUTONEG_NONE;
 
-  scp->dev = dev;
   /* Initialise the ifnet structure */
   if (!scp->ifp->if_name) {
     scp->ifp->if_softc = scp;
@@ -243,6 +231,7 @@
     scp->ifp->if_ioctl = xe_ioctl;
     scp->ifp->if_watchdog = xe_watchdog;
     scp->ifp->if_init = xe_init;
+    scp->ifp->if_baudrate = 100000000;
     scp->ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
   }
 
@@ -250,44 +239,52 @@
   ifmedia_init(scp->ifm, 0, xe_media_change, xe_media_status);
   callout_handle_init(&scp->chand);
 
-  /*
-   * Fill in supported media types.  Some cards _do_ support full duplex
-   * operation, but this driver doesn't, yet.  Therefore we leave those modes
-   * out of the list.  We support some form of autoselection in all cases.
-   */
+  /* Add supported media types */
   if (scp->mohawk) {
     ifmedia_add(scp->ifm, IFM_ETHER|IFM_100_TX, 0, NULL);
-    ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL);
+    ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
+    ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
   }
-  else {
-    ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL);
+  ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL);
+  if (scp->ce2)
     ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_2, 0, NULL);
-  }
   ifmedia_add(scp->ifm, IFM_ETHER|IFM_AUTO, 0, NULL);
 
   /* Default is to autoselect best supported media type */
   ifmedia_set(scp->ifm, IFM_ETHER|IFM_AUTO);
 
+  /* Get the hardware into a known state */
+  xe_reset(scp);
+
+  /* Get hardware version numbers */
+  XE_SELECT_PAGE(4);
+  scp->version = XE_INB(XE_BOV);
+  if (scp->mohawk)
+    scp->srev = (XE_INB(XE_BOV) & 0x70) >> 4;
+  else
+    scp->srev = (XE_INB(XE_BOV) & 0x30) >> 4;
+
   /* Print some useful information */
-  device_printf(dev, "%s %s, bonding version %#x%s%s\n",
+  device_printf(dev, "%s %s, version 0x%02x/0x%02x%s%s\n",
 	 scp->vendor,
 	 scp->card_type,
 	 scp->version,
+	 scp->srev,
 	 scp->mohawk ? ", 100Mbps capable" : "",
 	 scp->modem ?  ", with modem"      : "");
+#if XE_DEBUG > 0
   if (scp->mohawk) {
     XE_SELECT_PAGE(0x10);
-    device_printf(dev, "DingoID = %#x, RevisionID = %#x, VendorID = %#x\n",
+    device_printf(dev, "DingoID=0x%04x, RevisionID=0x%04x, VendorID=0x%04x\n",
 	   XE_INW(XE_DINGOID),
 	   XE_INW(XE_RevID),
 	   XE_INW(XE_VendorID));
   }
   if (scp->ce2) {
     XE_SELECT_PAGE(0x45);
-    device_printf(dev, "CE2 version = %#x\n", XE_INB(XE_REV));
+    device_printf(dev, "CE2 version = 0x%#02x\n", XE_INB(XE_REV));
   }
-
-  /* Print MAC address */
+#endif
   device_printf(dev, "Ethernet address %6D\n", scp->arpcom.ac_enaddr, ":");
 
   /* Attach the interface */
@@ -299,105 +296,153 @@
 
 
 /*
- * Initialize device.  Completes the reset procedure on the card and starts
- * output.  If there's an autonegotiation in progress we DON'T do anything;
- * the media selection code will call us again when it's done.
+ * Complete hardware intitialisation and enable output.  Exits without doing
+ * anything if there's no address assigned to the card, or if media selection
+ * is in progress (the latter implies we've already run this function).
  */
 static void
 xe_init(void *xscp) {
   struct xe_softc *scp = xscp;
+  unsigned i;
   int s;
 
-#ifdef XE_DEBUG
+  if (TAILQ_EMPTY(&scp->ifp->if_addrhead)) return;
+
+  if (scp->autoneg_status != XE_AUTONEG_NONE) return;
+
+#if XE_DEBUG > 1
   device_printf(scp->dev, "init\n");
 #endif
 
-  if (TAILQ_EMPTY(&scp->ifp->if_addrhead)) return;
+  s = splimp();
 
   /* Reset transmitter flags */
   scp->tx_queued = 0;
   scp->tx_tpr = 0;
-  scp->tx_collisions = 0;
+  scp->tx_timeouts = 0;
+  scp->tx_thres = 64;
+  scp->tx_min = ETHER_MIN_LEN - ETHER_CRC_LEN;
   scp->ifp->if_timer = 0;
 
-  s = splimp();
+  /* Soft reset the card */
+  XE_SELECT_PAGE(0);
+  XE_OUTB(XE_CR, XE_CR_SOFT_RESET);
+  DELAY(40000);
+  XE_OUTB(XE_CR, 0);
+  DELAY(40000);
+
+  if (scp->mohawk) {
+    /*
+     * set GP1 and GP2 as outputs (bits 2 & 3)
+     * set GP1 low to power on the ML6692 (bit 0)
+     * set GP2 high to power on the 10Mhz chip (bit 1)
+     */
+    XE_SELECT_PAGE(4);
+    XE_OUTB(XE_GPR0, XE_GPR0_GP2_SELECT|XE_GPR0_GP1_SELECT|XE_GPR0_GP2_OUT);
+  }
+
+  /* Shut off interrupts */
+  xe_disable_intr(scp);
+
+  /* Wait for everything to wake up */
+  DELAY(500000);
+
+  /* Check for PHY */
+  if (scp->mohawk)
+    scp->phy_ok = xe_mii_init(scp);
 
+  /* Disable 'source insertion' (not sure what that means) */
   XE_SELECT_PAGE(0x42);
-  XE_OUTB(XE_SWC0, 0x20);	/* Disable source insertion (WTF is that?) */
+  XE_OUTB(XE_SWC0, XE_SWC0_NO_SRC_INSERT);
 
-  /*
-   * Set the 'local memory dividing line' -- splits the 32K card memory into
-   * 8K for transmit buffers and 24K for receive.  This is done automatically
-   * on newer revision cards.
-   */
+  /* Set 8K/24K Tx/Rx buffer split */
   if (scp->srev != 1) {
     XE_SELECT_PAGE(2);
     XE_OUTW(XE_RBS, 0x2000);
   }
 
+  /* Enable early transmit mode on Mohawk/Dingo */
+  if (scp->mohawk) {
+    XE_SELECT_PAGE(0x03);
+    XE_OUTW(XE_TPT, scp->tx_thres);
+    XE_SELECT_PAGE(0x01);
+    XE_OUTB(XE_ECR, XE_INB(XE_ECR) | XE_ECR_EARLY_TX);
+  }
+
+  /* Put MAC address in first 'individual address' register */
+  XE_SELECT_PAGE(0x50);
+  for (i = 0; i < 6; i++)
+    XE_OUTB(0x08 + i, scp->arpcom.ac_enaddr[scp->mohawk ? 5 - i : i]);
+
   /* Set up multicast addresses */
-  xe_setmulti(scp);
+  xe_set_multicast(scp);
 
-  /* Fix the data offset register -- reset leaves it off-by-one */
+  /* Fix the receive data offset -- reset can leave it off-by-one */
   XE_SELECT_PAGE(0);
   XE_OUTW(XE_DO, 0x2000);
 
-  /*
-   * Set MAC interrupt masks and clear status regs.  The bit names are direct
-   * from the Linux code; I have no idea what most of them do.
-   */
-  XE_SELECT_PAGE(0x40);		/* Bit 7..0 */
-  XE_OUTB(XE_RX0Msk, 0xff);	/* ROK, RAB, rsv, RO,  CRC, AE,  PTL, MP  */
-  XE_OUTB(XE_TX0Msk, 0xff);	/* TOK, TAB, SQE, LL,  TU,  JAB, EXC, CRS */
-  XE_OUTB(XE_TX0Msk+1, 0xb0);	/* rsv, rsv, PTD, EXT, rsv, rsv, rsv, rsv */
-  XE_OUTB(XE_RST0, 0x00);	/* ROK, RAB, REN, RO,  CRC, AE,  PTL, MP  */
-  XE_OUTB(XE_TXST0, 0x00);	/* TOK, TAB, SQE, LL,  TU,  JAB, EXC, CRS */
-  XE_OUTB(XE_TXST1, 0x00);	/* TEN, rsv, PTD, EXT, retry_counter:4    */
+  /* Set interrupt masks */
+  XE_SELECT_PAGE(1);
+  XE_OUTB(XE_IMR0, XE_IMR0_TX_PACKET | XE_IMR0_MAC_INTR | XE_IMR0_RX_PACKET);
+
+  /* Set MAC interrupt masks */
+  XE_SELECT_PAGE(0x40);
+  XE_OUTB(XE_RX0Msk,
+	  ~(XE_RX0M_RX_OVERRUN | XE_RX0M_CRC_ERROR
+	    | XE_RX0M_ALIGN_ERROR | XE_RX0M_LONG_PACKET));
+  XE_OUTB(XE_TX0Msk,
+	  ~(XE_TX0M_SQE_FAIL | XE_TX0M_LATE_COLLISION | XE_TX0M_TX_UNDERRUN
+	    | XE_TX0M_16_COLLISIONS | XE_TX0M_NO_CARRIER));
+
+  /* Clear MAC status registers */
+  XE_SELECT_PAGE(0x40);
+  XE_OUTB(XE_RST0, 0x00);
+  XE_OUTB(XE_TXST0, 0x00);
+
+  /* Enable receiver and put MAC online */
+  XE_SELECT_PAGE(0x40);
+  XE_OUTB(XE_CMD0, XE_CMD0_RX_ENABLE|XE_CMD0_ONLINE);
 
-  /*
-   * Check for an in-progress autonegotiation.  If one is active, just set
-   * IFF_RUNNING and return.  The media selection code will call us again when 
-   * it's done.
-   */
-  if (scp->autoneg_status) {
-    scp->ifp->if_flags |= IFF_RUNNING;
-  }
-  else {
-    /* Enable receiver, put MAC online */
-    XE_SELECT_PAGE(0x40);
-    XE_OUTB(XE_CMD0, XE_CMD0_RX_ENABLE|XE_CMD0_ONLINE);
+  /* Set up IMR, enable interrupts */
+  xe_enable_intr(scp);
 
-    /* Set up IMR, enable interrupts */
-    xe_enable_intr(scp);
+  /* Start media selection */
+  xe_setmedia(scp);
 
-    /* Attempt to start output */
-    scp->ifp->if_flags |= IFF_RUNNING;
-    scp->ifp->if_flags &= ~IFF_OACTIVE;
-    xe_start(scp->ifp);
-  }
+  /* Enable output */
+  scp->ifp->if_flags |= IFF_RUNNING;
+  scp->ifp->if_flags &= ~IFF_OACTIVE;
 
   (void)splx(s);
 }
 
 
 /*
- * Start output on interface.  We make two assumptions here:
- *  1) that the current priority is set to splimp _before_ this code
- *     is called *and* is returned to the appropriate priority after
- *     return
- *  2) that the IFF_OACTIVE flag is checked before this code is called
- *     (i.e. that the output part of the interface is idle)
+ * Start output on interface.  Should be called at splimp() priority.  Check
+ * that the output is idle (ie, IFF_OACTIVE is not set) before calling this
+ * function.  If media selection is in progress we set IFF_OACTIVE ourselves
+ * and return immediately.
  */
 static void
 xe_start(struct ifnet *ifp) {
   struct xe_softc *scp = ifp->if_softc;
   struct mbuf *mbp;
 
+  if (scp->autoneg_status != XE_AUTONEG_NONE) {
+    ifp->if_flags |= IFF_OACTIVE;
+    return;
+  }
+
+#if XE_DEBUG > 2
+  device_printf(scp->dev, "start\n");
+#endif
+
   /*
    * Loop while there are packets to be sent, and space to send them.
    */
   while (1) {
-    IF_DEQUEUE(&ifp->if_snd, mbp);	/* Suck a packet off the send queue */
+    /* Suck a packet off the send queue */
+    IF_DEQUEUE(&ifp->if_snd, mbp);
 
     if (mbp == NULL) {
       /*
@@ -412,7 +457,8 @@
     }
 
     if (xe_pio_write_packet(scp, mbp) != 0) {
-      IF_PREPEND(&ifp->if_snd, mbp);	/* Push the packet back onto the queue */
+      /* Push the packet back onto the queue */
+      IF_PREPEND(&ifp->if_snd, mbp);
       ifp->if_flags |= IFF_OACTIVE;
       return;
     }
@@ -420,7 +466,8 @@
     /* Tap off here if there is a bpf listener */
     BPF_MTAP(ifp, mbp);
 
-    ifp->if_timer = 5;			/* In case we don't hear from the card again */
+    /* In case we don't hear from the card again... */
+    ifp->if_timer = 5;
     scp->tx_queued++;
 
     m_freem(mbp);
@@ -443,15 +490,17 @@
 
   switch (command) {
 
-   case SIOCSIFFLAGS:
+  case SIOCSIFFLAGS:
+#if XE_DEBUG > 1
+    device_printf(scp->dev, "ioctl: SIOCSIFFLAGS: 0x%04x\n", ifp->if_flags);
+#endif
     /*
      * If the interface is marked up and stopped, then start it.  If it is
      * marked down and running, then stop it.
      */
     if (ifp->if_flags & IFF_UP) {
       if (!(ifp->if_flags & IFF_RUNNING)) {
-	xe_hard_reset(scp);
-	xe_setmedia(scp);
+	xe_reset(scp);
 	xe_init(scp);
       }
     }
@@ -459,27 +508,36 @@
       if (ifp->if_flags & IFF_RUNNING)
 	xe_stop(scp);
     }
-   /* XXX: intentional fall-through ? */
-   case SIOCADDMULTI:
-   case SIOCDELMULTI:
+    /* FALL THROUGH  (handle changes to PROMISC/ALLMULTI flags) */
+
+  case SIOCADDMULTI:
+  case SIOCDELMULTI:
+#if XE_DEBUG > 1
+    device_printf(scp->dev, "ioctl: SIOC{ADD,DEL}MULTI\n");
+#endif
     /*
-     * Multicast list has (maybe) changed; set the hardware filter
-     * accordingly.  This also serves to deal with promiscuous mode if we have 
-     * a BPF listener active.
+     * Multicast list has (maybe) changed; set the hardware filters
+     * accordingly.
      */
-    xe_setmulti(scp);
+    xe_set_multicast(scp);
     error = 0;
     break;
 
-   case SIOCSIFMEDIA:
-   case SIOCGIFMEDIA:
+  case SIOCSIFMEDIA:
+  case SIOCGIFMEDIA:
+#if XE_DEBUG > 1
+    device_printf(scp->dev, "ioctl: bounce to ifmedia_ioctl\n");
+#endif
     /*
      * Someone wants to get/set media options.
      */
     error = ifmedia_ioctl(ifp, (struct ifreq *)data, &scp->ifmedia, command);
     break;
 
-   default:
+  default:
+#if XE_DEBUG > 1
+    device_printf(scp->dev, "ioctl: bounce to ether_ioctl\n");
+#endif
     error = ether_ioctl(ifp, command, data);
   }
 
@@ -512,245 +570,272 @@
 {
   struct xe_softc *scp = (struct xe_softc *) xscp;
   struct ifnet *ifp;
-  u_int16_t rx_bytes, rxs, txs;
-  u_int8_t psr, isr, esr, rsr;
+  u_int8_t psr, isr, esr, rsr, rst0, txst0, txst1, coll;
 
   ifp = &scp->arpcom.ac_if;
-  rx_bytes = 0;			/* Bytes received on this interrupt */
+
+  /* Disable interrupts */
+  if (scp->mohawk)
+    XE_OUTB(XE_CR, 0);
 
-  if (scp->mohawk) {
-    XE_OUTB(XE_CR, 0);		/* Disable interrupts */
-  }
+  /* Cache current register page */
+  psr = XE_INB(XE_PR);
 
-  psr = XE_INB(XE_PR);		/* Stash the current register page */
+  /* Read ISR to see what caused this interrupt */
+  while ((isr = XE_INB(XE_ISR)) != 0) {
 
-  /*
-   * Read ISR to see what caused this interrupt.  Note that this clears the
-   * ISR on CE2 type cards.
-   */
-  if ((isr = XE_INB(XE_ISR)) && isr != 0xff) {
+    /* 0xff might mean the card is no longer around */
+    if (isr == 0xff) {
+#if XE_DEBUG > 2
+      device_printf(scp->dev, "intr: interrupt received for missing card?\n");
+#endif
+      break;
+    }
 
-    esr = XE_INB(XE_ESR);	/* Read the other status registers */
+    /* Read other status registers */
     XE_SELECT_PAGE(0x40);
-    rxs = XE_INB(XE_RST0);
-    XE_OUTB(XE_RST0, ~rxs & 0xff);
-    txs = XE_INB(XE_TXST0);
-    txs |= XE_INB(XE_TXST1) << 8;
+    rst0 = XE_INB(XE_RST0);
+    XE_OUTB(XE_RST0, 0);
+    txst0 = XE_INB(XE_TXST0);
+    txst1 = XE_INB(XE_TXST1);
+    coll = txst1 & XE_TXST1_RETRY_COUNT;
     XE_OUTB(XE_TXST0, 0);
     XE_OUTB(XE_TXST1, 0);
     XE_SELECT_PAGE(0);
 
 #if XE_DEBUG > 2
-    printf("xe%d: ISR=%#2.2x ESR=%#2.2x RST=%#2.2x TXST=%#4.4x\n", unit, isr, esr, rxs, txs);
+    device_printf(scp->dev, "intr: ISR=0x%02x, RST=0x%02x, TXT=0x%02x%02x, COLL=0x%01x\n", isr, rst0, txst1, txst0, coll);
 #endif
 
-    /*
-     * Handle transmit interrupts
-     */
+    /* Handle transmitted packet(s) */
     if (isr & XE_ISR_TX_PACKET) {
-      u_int8_t new_tpr, sent;
-      
-      if ((new_tpr = XE_INB(XE_TPR)) < scp->tx_tpr)	/* Update packet count */
-	sent = (0xff - scp->tx_tpr) + new_tpr;		/* TPR rolled over */
-      else
-	sent = new_tpr - scp->tx_tpr;
+      u_int8_t tpr, sent;
+
+      /* Update packet count, accounting for rollover */
+      tpr = XE_INB(XE_TPR);
+      sent = -scp->tx_tpr + tpr;
 
-      if (sent > 0) {				/* Packets sent since last interrupt */
-	scp->tx_tpr = new_tpr;
+      /* Update statistics if we actually sent anything */
+      if (sent > 0) {
+	scp->tx_tpr = tpr;
 	scp->tx_queued -= sent;
 	ifp->if_opackets += sent;
-	ifp->if_collisions += scp->tx_collisions;
+	ifp->if_collisions += coll;
 
 	/*
-	 * Collision stats are a PITA.  If multiples frames have been sent, we 
-	 * distribute any outstanding collision count equally amongst them.
-	 * However, if we're missing interrupts we're quite likely to also
-	 * miss some collisions; thus the total count will be off anyway.
-	 * Likewise, if we miss a frame dropped due to excessive collisions
-	 * any outstanding collisions count will be held against the next
-	 * frame to be successfully sent.  Hopefully it averages out in the
-	 * end!
-	 * XXX - This will screw up if tx_collisions/sent > 14. FIX IT!
+	 * According to the Xircom manual, Dingo will sometimes manage to
+	 * transmit a packet with triggering an interrupt.  If this happens,
+	 * we have sent > 1 and the collision count only reflects collisions
+	 * on the last packet sent (the one that triggered the interrupt).
+	 * Collision stats might therefore be a bit low, but there doesn't
+	 * seem to be anything we can do about that.
 	 */
-	switch (scp->tx_collisions) {
-	 case 0:
+
+	switch (coll) {
+	case 0:
 	  break;
-	 case 1:
+	case 1:
 	  scp->mibdata.dot3StatsSingleCollisionFrames++;
 	  scp->mibdata.dot3StatsCollFrequencies[0]++;
 	  break;
-	 default:
-	  if (sent == 1) {
-	    scp->mibdata.dot3StatsMultipleCollisionFrames++;
-	    scp->mibdata.dot3StatsCollFrequencies[scp->tx_collisions-1]++;
-	  }
-	  else {		/* Distribute across multiple frames */
-	    scp->mibdata.dot3StatsMultipleCollisionFrames += sent;
-	    scp->mibdata.
-	      dot3StatsCollFrequencies[scp->tx_collisions/sent] += sent - scp->tx_collisions%sent;
-	    scp->mibdata.
-	      dot3StatsCollFrequencies[scp->tx_collisions/sent + 1] += scp->tx_collisions%sent;
-	  }
+	default:
+	  scp->mibdata.dot3StatsMultipleCollisionFrames++;
+	  scp->mibdata.dot3StatsCollFrequencies[coll-1]++;
 	}
-	scp->tx_collisions = 0;
       }
       ifp->if_timer = 0;
       ifp->if_flags &= ~IFF_OACTIVE;
     }
-    if (txs & 0x0002) {		/* Excessive collisions (packet dropped) */
-      ifp->if_collisions += 16;
-      ifp->if_oerrors++;
-      scp->tx_collisions = 0;
-      scp->mibdata.dot3StatsExcessiveCollisions++;
-      scp->mibdata.dot3StatsMultipleCollisionFrames++;
-      scp->mibdata.dot3StatsCollFrequencies[15]++;
-      XE_OUTB(XE_CR, XE_CR_RESTART_TX);
+
+    /* Handle most MAC interrupts */
+    if (isr & XE_ISR_MAC_INTR) {
+
+#if 0
+      /* Carrier sense lost -- only in 10Mbit HDX mode */
+      if (txst0 & XE_TXST0_NO_CARRIER || !(txst1 & XE_TXST1_LINK_STATUS)) {

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310151658.h9FGwZAj087116>