PERFORCE change 39751 for review
Sam Leffler
sam at FreeBSD.org
Wed Oct 15 09:58:38 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=39751
Change 39751 by sam at 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 at 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 at lovett.com>
- *
- * Author email: <scott at 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) <<<
More information about the p4-projects
mailing list