Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Aug 2003 23:27:00 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 37061 for review
Message-ID:  <200308280627.h7S6R0bI063812@repoman.freebsd.org>

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

Change 37061 by marcel@marcel_nfs on 2003/08/27 23:26:01

	IFC @37059

Affected files ...

.. //depot/projects/uart/conf/majors#3 integrate
.. //depot/projects/uart/dev/ata/ata-all.c#4 integrate
.. //depot/projects/uart/dev/ata/ata-lowlevel.c#3 integrate
.. //depot/projects/uart/dev/ata/atapi-cam.c#4 integrate
.. //depot/projects/uart/dev/em/README#2 integrate
.. //depot/projects/uart/dev/em/if_em.c#4 integrate
.. //depot/projects/uart/dev/em/if_em.h#6 integrate
.. //depot/projects/uart/dev/em/if_em_hw.c#3 integrate
.. //depot/projects/uart/dev/em/if_em_hw.h#2 integrate
.. //depot/projects/uart/dev/exca/exca.c#3 integrate
.. //depot/projects/uart/dev/sio/sio.c#5 integrate
.. //depot/projects/uart/fs/specfs/spec_vnops.c#4 integrate
.. //depot/projects/uart/gnu/ext2fs/ext2_vfsops.c#3 integrate
.. //depot/projects/uart/gnu/ext2fs/fs.h#2 integrate
.. //depot/projects/uart/pccard/pcic.c#2 integrate
.. //depot/projects/uart/pci/if_dc.c#11 integrate

Differences ...

==== //depot/projects/uart/conf/majors#3 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/majors,v 1.176 2003/08/15 14:56:05 phk Exp $
+# $FreeBSD: src/sys/conf/majors,v 1.177 2003/08/27 07:35:12 simokawa Exp $
 #
 # This list is semi-obsoleted by DEVFS, but for now it still contains
 # the current allocation of device major numbers.
@@ -174,6 +174,7 @@
 180	nvidia		NVIDIA (nvidiaN/nvidiactl) <mdodd>
 181	casm		HP/Compaq ProLiant Advanced Server Management <peter>
 183	*smapi		SMAPI BIOS interface <mdodd>
+184	dcons		Dumb console driver <simokawa>
 200	??		entries from 200-252 are reserved for local use
 248	*isp		dev/isp/isp_freebsd.c
 252	??		entries from 200-252 are reserved for local use

==== //depot/projects/uart/dev/ata/ata-all.c#4 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-all.c,v 1.186 2003/08/25 09:01:49 sos Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-all.c,v 1.187 2003/08/27 15:27:56 sos Exp $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
@@ -437,8 +437,8 @@
 
 	ata_queue_request(request);
 
-	if (request->error)
-	    iocmd->u.request.error = request->error;
+	if (request->result)
+	    iocmd->u.request.error = request->result;
 	else {
 	    if (iocmd->u.request.flags & ATA_CMD_READ)
 		error = copyout(buf,

==== //depot/projects/uart/dev/ata/ata-lowlevel.c#3 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-lowlevel.c,v 1.5 2003/08/25 13:06:13 sos Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-lowlevel.c,v 1.6 2003/08/27 11:21:30 sos Exp $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
@@ -520,22 +520,22 @@
     ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_IDS | ATA_A_RESET);
     DELAY(10000); 
     ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_IDS);
-    DELAY(100000);
-    ATA_IDX_INB(ch, ATA_ERROR);
+    DELAY(10000);
 
     /* wait for BUSY to go inactive */
-    for (timeout = 0; timeout < 310000; timeout++) {
+    for (timeout = 0; timeout < 310; timeout++) {
 	if (stat0 & ATA_S_BUSY) {
 	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
 	    DELAY(10);
+    	    ATA_IDX_INB(ch, ATA_ERROR);
 
-	    /* check for ATAPI signature while its still there */
-	    lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
-	    msb = ATA_IDX_INB(ch, ATA_CYL_MSB);
 	    stat0 = ATA_IDX_INB(ch, ATA_STATUS);
-	    ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0x00);
-	    ATA_IDX_OUTB(ch, ATA_CYL_MSB, 0x00);
 	    if (!(stat0 & ATA_S_BUSY)) {
+		/* check for ATAPI signature while its still there */
+		lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
+		msb = ATA_IDX_INB(ch, ATA_CYL_MSB);
+		ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0x00);
+		ATA_IDX_OUTB(ch, ATA_CYL_MSB, 0x00);
 		if (bootverbose)
 		    ata_printf(ch, ATA_MASTER, "ATAPI %02x %02x\n", lsb, msb);
 		if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB)
@@ -545,14 +545,15 @@
 	if (stat1 & ATA_S_BUSY) {
 	    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
 	    DELAY(10);
+    	    ATA_IDX_INB(ch, ATA_ERROR);
 
-	    /* check for ATAPI signature while its still there */
-	    lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
-	    msb = ATA_IDX_INB(ch, ATA_CYL_MSB);
 	    stat1 = ATA_IDX_INB(ch, ATA_STATUS);
-	    ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0x00);
-	    ATA_IDX_OUTB(ch, ATA_CYL_MSB, 0x00);
 	    if (!(stat1 & ATA_S_BUSY)) {
+		/* check for ATAPI signature while its still there */
+		lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
+		msb = ATA_IDX_INB(ch, ATA_CYL_MSB);
+		ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0x00);
+		ATA_IDX_OUTB(ch, ATA_CYL_MSB, 0x00);
 		if (bootverbose)
 		    ata_printf(ch, ATA_SLAVE, "ATAPI %02x %02x\n", lsb, msb);
 		if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB)
@@ -568,7 +569,7 @@
 	if (mask == 0x03)      /* wait for both master & slave */
 	    if (!(stat0 & ATA_S_BUSY) && !(stat1 & ATA_S_BUSY))
 		break;
-	DELAY(100);
+	DELAY(100000);
     }	
     DELAY(10);
     ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_4BIT);

==== //depot/projects/uart/dev/ata/atapi-cam.c#4 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cam.c,v 1.20 2003/08/24 17:48:05 obrien Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cam.c,v 1.21 2003/08/28 03:56:04 thomas Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -465,9 +465,10 @@
 	if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN && (len & 1)) {
 	    /* ATA always transfers an even number of bytes */
 	    if (!(buf = hcb->dxfer_alloc = malloc(++len, M_ATACAM,
-						  M_NOWAIT | M_ZERO)))
+						  M_NOWAIT | M_ZERO))) {
 		printf("cannot allocate ATAPI/CAM buffer\n");
 		goto action_oom;
+	    }
 	}
 	request->device = dev;
 	request->driver = hcb;

==== //depot/projects/uart/dev/em/README#2 (text+ko) ====

@@ -1,8 +1,8 @@
-$FreeBSD: src/sys/dev/em/README,v 1.7 2003/06/05 17:51:37 pdeuskar Exp $
+$FreeBSD: src/sys/dev/em/README,v 1.8 2003/08/27 21:52:36 pdeuskar Exp $
 FreeBSD* Driver for the Intel(R) PRO/1000 Family of Adapters
 ============================================================
 
-April 13, 2003
+July 24, 2003
 
 
 Contents
@@ -21,7 +21,7 @@
 Overview
 ========
 
-This file describes the FreeBSD* driver, version 1.5.x, for the Intel(R)
+This file describes the FreeBSD* driver, version 1.7.x, for the Intel(R)
 PRO/1000 Family of Adapters. This driver has been developed for use with 
 FreeBSD, version 4.7. 
 
@@ -51,9 +51,10 @@
    82544       PRO/1000 XF Server Adapter           A50484-xxx
 
    82544       PRO/1000 T Desktop Adapter           A62947-xxx
- 
+
    82540       PRO/1000 MT Desktop Adapter          A78408-xxx
-   82541                                            C91016-xxx
+
+   82541       PRO/1000 MT Desktop Adapter          C91016-xxx
 
    82545       PRO/1000 MT Server Adapter           A92165-xxx
 
@@ -67,6 +68,7 @@
 
    82546EB     PRO/1000 MT Quad Port Server Adapter C11227-xxx 
 
+   82547       PRO/1000 CT Network Connection
 
 
 To verify your Intel adapter is supported, find the board ID number on the
@@ -281,8 +283,46 @@
 Known Limitations
 =================
  
-There are known performance issues with this driver when running UDP traffic
-with Jumbo Frames. Intel recommends not using Jumbo Frames for UDP traffic.
+  There are known performance issues with this driver when running UDP traffic
+  with Jumbo Frames. Intel recommends not using Jumbo Frames for UDP traffic.
+
+
+  82541/82547 can't link or is slow to link with some link partners
+  -----------------------------------------------------------------
+
+  There is a known compatibility issue with 82541/82547 and some switches 
+  where link will not be established, or will be slow to establish.  In 
+  particular, these switches are known to be incompatible with 82541/82547:
+
+        Planex FXG-08TE
+        I-O Data ETG-SH8
+
+  To workaround the issue, the driver can be compiled with an override of the 
+  PHY's master/slave setting.  Forcing master or forcing slave mode will 
+  improve time-to-link.
+
+  Edit ./em.x.x.x/src/if_em.h to remove the #define EM_MASTER_SLAVE 
+  from within the comments.  
+
+      /* #define EM_MASTER_SLAVE  2 */
+      #define EM_MASTER_SLAVE  2 
+
+  Use one of the following options.
+      0 = Hardware default
+      1 = Master mode
+      2 = Slave mode
+      3 = Auto master/slave
+
+  Recompile the module (refer to step 3 above)
+  a. To compile the module
+
+          cd em-x.x.x
+          make clean
+          make
+
+   b. To install the compiled module in system directory:
+ 
+          make install
 
 
 Support

==== //depot/projects/uart/dev/em/if_em.c#4 (text+ko) ====

@@ -31,7 +31,7 @@
 
 ***************************************************************************/
 
-/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.28 2003/08/01 17:33:59 jdp Exp $*/
+/*$FreeBSD: src/sys/dev/em/if_em.c,v 1.29 2003/08/27 21:52:36 pdeuskar Exp $*/
 
 #include <dev/em/if_em.h>
 
@@ -51,7 +51,7 @@
  *  Driver version
  *********************************************************************/
 
-char em_driver_version[] = "1.6.6";
+char em_driver_version[] = "1.7.16";
 
 
 /*********************************************************************
@@ -89,6 +89,16 @@
         { 0x8086, 0x101A, PCI_ANY_ID, PCI_ANY_ID, 0},
 	{ 0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0},
 	{ 0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0},
+	{ 0x8086, 0x1026, PCI_ANY_ID, PCI_ANY_ID, 0},
+        { 0x8086, 0x1027, PCI_ANY_ID, PCI_ANY_ID, 0},
+        { 0x8086, 0x1028, PCI_ANY_ID, PCI_ANY_ID, 0},
+        { 0x8086, 0x1075, PCI_ANY_ID, PCI_ANY_ID, 0},
+        { 0x8086, 0x1076, PCI_ANY_ID, PCI_ANY_ID, 0},
+        { 0x8086, 0x1077, PCI_ANY_ID, PCI_ANY_ID, 0},
+        { 0x8086, 0x1078, PCI_ANY_ID, PCI_ANY_ID, 0},
+        { 0x8086, 0x1079, PCI_ANY_ID, PCI_ANY_ID, 0},
+        { 0x8086, 0x107A, PCI_ANY_ID, PCI_ANY_ID, 0},
+        { 0x8086, 0x107B, PCI_ANY_ID, PCI_ANY_ID, 0},
         /* required last entry */
         { 0, 0, 0, 0, 0}
 };
@@ -163,6 +173,9 @@
 static int  em_is_valid_ether_addr(u_int8_t *);
 static int  em_sysctl_stats(SYSCTL_HANDLER_ARGS);
 static int  em_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
+static u_int32_t em_fill_descriptors (u_int64_t address, 
+				      u_int32_t length, 
+				      PDESC_ARRAY desc_array);
 static int  em_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
 static void em_add_int_delay_sysctl(struct adapter *, const char *,
 				    const char *, struct em_int_delay_info *,
@@ -367,7 +380,13 @@
         adapter->hw.fc = em_fc_full;
 
 	adapter->hw.phy_init_script = 1;
+	adapter->hw.phy_reset_disable = FALSE;
 
+#ifndef EM_MASTER_SLAVE
+	adapter->hw.master_slave = em_ms_hw_default;
+#else
+	adapter->hw.master_slave = EM_MASTER_SLAVE;
+#endif
 	/* 
 	 * Set the max frame size assuming standard ethernet 
 	 * sized frames 
@@ -465,6 +484,15 @@
 	} else
 		printf("em%d:  Speed:N/A  Duplex:N/A\n", adapter->unit);
 
+	/* Identify 82544 on PCIX */
+        em_get_bus_info(&adapter->hw);
+        if(adapter->hw.bus_type == em_bus_type_pcix &&
+           adapter->hw.mac_type == em_82544) {
+                adapter->pcix_82544 = TRUE;
+        }
+        else {
+                adapter->pcix_82544 = FALSE;
+        }
 	INIT_DEBUGOUT("em_attach: end");
 	splx(s);
 	return(0);
@@ -525,6 +553,9 @@
                 adapter->rx_desc_base = NULL;
         }
 
+	/* Free the sysctl tree */
+	sysctl_ctx_free(&adapter->sysctl_ctx);
+
 	/* Remove from the adapter list */
 	if (em_adapter_list == adapter)
 		em_adapter_list = adapter->next;
@@ -641,8 +672,11 @@
 	case SIOCSIFFLAGS:
 		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)");
 		if (ifp->if_flags & IFF_UP) {
-			if (!(ifp->if_flags & IFF_RUNNING))
+			if (!(ifp->if_flags & IFF_RUNNING)) {
+				bcopy(IF_LLADDR(ifp), adapter->hw.mac_addr, 
+				      ETHER_ADDR_LEN);
 				em_init(adapter);
+			}
 
 			em_disable_promisc(adapter);
 			em_set_promisc(adapter);
@@ -685,7 +719,7 @@
 		}
 		break;
 	default:
-		IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%d)\n", (int)command);
+		IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%x)\n", (int)command);
 		error = EINVAL;
 	}
 
@@ -1052,9 +1086,15 @@
 em_encap(struct adapter *adapter, struct mbuf *m_head)
 {
         u_int32_t       txd_upper;
-        u_int32_t       txd_lower;
+        u_int32_t       txd_lower, txd_used = 0, txd_saved = 0;
         int             i, j, error;
-        
+        u_int64_t       address;
+
+	/* For 82544 Workaround */
+	DESC_ARRAY              desc_array;
+	u_int32_t               array_elements;
+	u_int32_t               counter;
+
 #if __FreeBSD_version < 500000
         struct ifvlan *ifv = NULL;
 #else
@@ -1118,23 +1158,66 @@
 #endif
 
         i = adapter->next_avail_tx_desc;
+	if (adapter->pcix_82544) {
+		txd_saved = i;
+		txd_used = 0;
+	}
         for (j = 0; j < q.nsegs; j++) {
-                tx_buffer = &adapter->tx_buffer_area[i];
-                current_tx_desc = &adapter->tx_desc_base[i];
+		/* If adapter is 82544 and on PCIX bus */
+		if(adapter->pcix_82544) {
+			array_elements = 0;
+			address = htole64(q.segs[j].ds_addr);
+			/* 
+			 * Check the Address and Length combination and 
+			 * split the data accordingly 
+			 */
+                        array_elements = em_fill_descriptors(address,
+							     htole32(q.segs[j].ds_len),
+							     &desc_array);
+			for (counter = 0; counter < array_elements; counter++) {
+                                if (txd_used == adapter->num_tx_desc_avail) {
+                                         adapter->next_avail_tx_desc = txd_saved;
+                                          adapter->no_tx_desc_avail2++;
+					  bus_dmamap_destroy(adapter->txtag, q.map);
+                                          return (ENOBUFS);
+                                }
+                                tx_buffer = &adapter->tx_buffer_area[i];
+                                current_tx_desc = &adapter->tx_desc_base[i];
+                                current_tx_desc->buffer_addr = htole64(
+					desc_array.descriptor[counter].address);
+                                current_tx_desc->lower.data = htole32(
+					(adapter->txd_cmd | txd_lower | 
+					 (u_int16_t)desc_array.descriptor[counter].length));
+                                current_tx_desc->upper.data = htole32((txd_upper));
+                                if (++i == adapter->num_tx_desc)
+                                         i = 0;
+
+                                tx_buffer->m_head = NULL;
+                                txd_used++;
+                        }
+		} else {
+			tx_buffer = &adapter->tx_buffer_area[i];
+			current_tx_desc = &adapter->tx_desc_base[i];
 
-                current_tx_desc->buffer_addr = htole64(q.segs[j].ds_addr);
-                current_tx_desc->lower.data = htole32(
-                        adapter->txd_cmd | txd_lower | q.segs[j].ds_len);
-                current_tx_desc->upper.data = htole32(txd_upper);
+			current_tx_desc->buffer_addr = htole64(q.segs[j].ds_addr);
+			current_tx_desc->lower.data = htole32(
+				adapter->txd_cmd | txd_lower | q.segs[j].ds_len);
+			current_tx_desc->upper.data = htole32(txd_upper);
 
-                if (++i == adapter->num_tx_desc)
-                        i = 0;
+			if (++i == adapter->num_tx_desc)
+				i = 0;
 
-                tx_buffer->m_head = NULL;
+			tx_buffer->m_head = NULL;
+		}
         }
 
-        adapter->num_tx_desc_avail -= q.nsegs;
-        adapter->next_avail_tx_desc = i;
+	adapter->next_avail_tx_desc = i;
+	if (adapter->pcix_82544) {
+		adapter->num_tx_desc_avail -= txd_used;
+	}
+	else {
+		adapter->num_tx_desc_avail -= q.nsegs;
+	}
 
 #if __FreeBSD_version < 500000
         if (ifv != NULL) {
@@ -1474,7 +1557,7 @@
 	struct adapter * adapter = arg;
 	ifp = &adapter->interface_data.ac_if;
 
-	INIT_DEBUGOUT("em_stop: begin\n");
+	INIT_DEBUGOUT("em_stop: begin");
 	em_disable_intr(adapter);
 	em_reset_hw(&adapter->hw);
 	untimeout(em_local_timer, adapter, adapter->timer_handle);	
@@ -1522,6 +1605,12 @@
 	/* Identify the MAC */
         if (em_set_mac_type(&adapter->hw))
                 printf("em%d: Unknown MAC Type\n", adapter->unit);
+	
+	if(adapter->hw.mac_type == em_82541 || 
+	   adapter->hw.mac_type == em_82541_rev_2 ||
+	   adapter->hw.mac_type == em_82547 || 
+	   adapter->hw.mac_type == em_82547_rev_2)
+		adapter->hw.phy_init_script = TRUE;
 
         return;
 }
@@ -1629,6 +1718,7 @@
 static int
 em_hardware_init(struct adapter * adapter)
 {
+        INIT_DEBUGOUT("em_hardware_init: begin");
 	/* Issue a global reset */
 	em_reset_hw(&adapter->hw);
 
@@ -1984,6 +2074,7 @@
 	u_int32_t       reg_tipg = 0;
 	u_int64_t	bus_addr;
 
+         INIT_DEBUGOUT("em_initialize_transmit_unit: begin");
 	/* Setup the Base and Length of the Tx Descriptor Ring */
 	bus_addr = adapter->txdma.dma_paddr;
 	E1000_WRITE_REG(&adapter->hw, TDBAL, (u_int32_t)bus_addr);
@@ -2399,6 +2490,7 @@
 	struct ifnet    *ifp;
 	u_int64_t	bus_addr;
 
+        INIT_DEBUGOUT("em_initialize_receive_unit: begin");
 	ifp = &adapter->interface_data.ac_if;
 
 	/* Make sure receives are disabled while setting up the descriptor ring */
@@ -2469,6 +2561,7 @@
 	/* Enable Receives */
 	E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
 
+        em_set_promisc(adapter);
 	return;
 }
 
@@ -2805,6 +2898,59 @@
 	return;
 }
 
+/*********************************************************************
+* 82544 Coexistence issue workaround.
+*    There are 2 issues.
+*       1. Transmit Hang issue.
+*    To detect this issue, following equation can be used...
+*          SIZE[3:0] + ADDR[2:0] = SUM[3:0].
+*          If SUM[3:0] is in between 1 to 4, we will have this issue.
+*
+*       2. DAC issue.
+*    To detect this issue, following equation can be used...
+*          SIZE[3:0] + ADDR[2:0] = SUM[3:0].
+*          If SUM[3:0] is in between 9 to c, we will have this issue.
+*
+*
+*    WORKAROUND:
+*          Make sure we do not have ending address as 1,2,3,4(Hang) or 9,a,b,c (DAC)
+*
+*** *********************************************************************/
+static u_int32_t
+em_fill_descriptors (u_int64_t address,
+                              u_int32_t length,
+                              PDESC_ARRAY desc_array)
+{
+        /* Since issue is sensitive to length and address.*/
+        /* Let us first check the address...*/
+        u_int32_t safe_terminator;
+        if (length <= 4) {
+                desc_array->descriptor[0].address = address;
+                desc_array->descriptor[0].length = length;
+                desc_array->elements = 1;
+                return desc_array->elements;
+        }
+        safe_terminator = (u_int32_t)((((u_int32_t)address & 0x7) + (length & 0xF)) & 0xF);
+        /* if it does not fall between 0x1 to 0x4 and 0x9 to 0xC then return */
+        if (safe_terminator == 0   ||
+        (safe_terminator > 4   &&
+        safe_terminator < 9)   ||
+        (safe_terminator > 0xC &&
+        safe_terminator <= 0xF)) {
+                desc_array->descriptor[0].address = address;
+                desc_array->descriptor[0].length = length;
+                desc_array->elements = 1;
+                return desc_array->elements;
+        }
+         
+        desc_array->descriptor[0].address = address;
+        desc_array->descriptor[0].length = length - 4;
+        desc_array->descriptor[1].address = address + (length - 4);
+        desc_array->descriptor[1].length = 4;
+        desc_array->elements = 2;
+        return desc_array->elements;
+}
+
 /**********************************************************************
  *
  *  Update the board statistics counters. 
@@ -2815,8 +2961,12 @@
 {
 	struct ifnet   *ifp;
 
+	if(adapter->hw.media_type == em_media_type_copper ||
+	   (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
+		adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, SYMERRS);
+		adapter->stats.sec += E1000_READ_REG(&adapter->hw, SEC);
+	}
 	adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, CRCERRS);
-	adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, SYMERRS);
 	adapter->stats.mpc += E1000_READ_REG(&adapter->hw, MPC);
 	adapter->stats.scc += E1000_READ_REG(&adapter->hw, SCC);
 	adapter->stats.ecol += E1000_READ_REG(&adapter->hw, ECOL);
@@ -2825,7 +2975,6 @@
 	adapter->stats.latecol += E1000_READ_REG(&adapter->hw, LATECOL);
 	adapter->stats.colc += E1000_READ_REG(&adapter->hw, COLC);
 	adapter->stats.dc += E1000_READ_REG(&adapter->hw, DC);
-	adapter->stats.sec += E1000_READ_REG(&adapter->hw, SEC);
 	adapter->stats.rlec += E1000_READ_REG(&adapter->hw, RLEC);
 	adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, XONRXC);
 	adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, XONTXC);

==== //depot/projects/uart/dev/em/if_em.h#6 (text+ko) ====

@@ -31,7 +31,7 @@
 
 ***************************************************************************/
 
-/*$FreeBSD: src/sys/dev/em/if_em.h,v 1.20 2003/08/22 05:54:51 imp Exp $*/
+/*$FreeBSD: src/sys/dev/em/if_em.h,v 1.21 2003/08/27 21:52:37 pdeuskar Exp $*/
 
 #ifndef _EM_H_DEFINED_
 #define _EM_H_DEFINED_
@@ -81,7 +81,7 @@
 /* Tunables */
 
 /*
- * TxDescriptors
+ * EM_MAX_TXD: Maximum number of Transmit Descriptors
  * Valid Range: 80-256 for 82542 and 82543-based adapters
  *              80-4096 for others
  * Default Value: 256
@@ -92,7 +92,7 @@
 #define EM_MAX_TXD                      256
 
 /*
- * RxDescriptors
+ * EM_MAX_RXD - Maximum number of receive Descriptors
  * Valid Range: 80-256 for 82542 and 82543-based adapters
  *              80-4096 for others
  * Default Value: 256
@@ -105,7 +105,7 @@
 #define EM_MAX_RXD                      256
 
 /*
- * TxIntDelay
+ * EM_TIDV - Transmit Interrupt Delay Value
  * Valid Range: 0-65535 (0=off)
  * Default Value: 64
  *   This value delays the generation of transmit interrupts in units of
@@ -117,20 +117,20 @@
 #define EM_TIDV                         64
 
 /*
- * TxAbsIntDelay (Not valid for 82542/82543/82544)
+ * EM_TADV - Transmit Absolute Interrupt Delay Value (Not valid for 82542/82543/82544)
  * Valid Range: 0-65535 (0=off)
  * Default Value: 64
  *   This value, in units of 1.024 microseconds, limits the delay in which a
- *   transmit interrupt is generated. Useful only if TxIntDelay is non-zero,
+ *   transmit interrupt is generated. Useful only if EM_TIDV is non-zero,
  *   this value ensures that an interrupt is generated after the initial
  *   packet is sent on the wire within the set amount of time.  Proper tuning,
- *   along with TxIntDelay, may improve traffic throughput in specific
+ *   along with EM_TIDV, may improve traffic throughput in specific
  *   network conditions.
  */
 #define EM_TADV                         64
 
 /*
- * RxIntDelay
+ * EM_RDTR - Receive Interrupt Delay Timer (Packet Timer)
  * Valid Range: 0-65535 (0=off)
  * Default Value: 0
  *   This value delays the generation of receive interrupts in units of 1.024
@@ -141,24 +141,24 @@
  *   may be set too high, causing the driver to run out of available receive
  *   descriptors.
  *
- *   CAUTION: When setting RxIntDelay to a value other than 0, adapters
+ *   CAUTION: When setting EM_RDTR to a value other than 0, adapters
  *            may hang (stop transmitting) under certain network conditions.
  *            If this occurs a WATCHDOG message is logged in the system event log.
  *            In addition, the controller is automatically reset, restoring the
  *            network connection. To eliminate the potential for the hang
- *            ensure that RxIntDelay is set to 0.
+ *            ensure that EM_RDTR is set to 0.
  */
 #define EM_RDTR                         0
 
 /*
- * RxAbsIntDelay (Not valid for 82542/82543/82544)
+ * Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544)
  * Valid Range: 0-65535 (0=off)
  * Default Value: 64
  *   This value, in units of 1.024 microseconds, limits the delay in which a
- *   receive interrupt is generated. Useful only if RxIntDelay is non-zero,
+ *   receive interrupt is generated. Useful only if EM_RDTR is non-zero,
  *   this value ensures that an interrupt is generated after the initial
  *   packet is received within the set amount of time.  Proper tuning,
- *   along with RxIntDelay, may improve traffic throughput in specific network
+ *   along with EM_RDTR, may improve traffic throughput in specific network
  *   conditions.
  */
 #define EM_RADV                         64
@@ -202,6 +202,17 @@
  */
 #define WAIT_FOR_AUTO_NEG_DEFAULT       0
 
+/*
+ * EM_MASTER_SLAVE is only defined to enable a workaround for a known compatibility issue
+ * with 82541/82547 devices and some switches.  See the "Known Limitations" section of
+ * the README file for a complete description and a list of affected switches.
+ *
+ *              0 = Hardware default
+ *              1 = Master mode
+ *              2 = Slave mode
+ *              3 = Auto master/slave
+ */
+/* #define EM_MASTER_SLAVE      2 */
 
 /* Tunables -- End */
 
@@ -301,6 +312,19 @@
 	int value;			/* Current value in usecs */
 };
 
+/* For 82544 PCIX  Workaround */
+typedef struct _ADDRESS_LENGTH_PAIR
+{
+    u_int64_t   address;
+    u_int32_t   length;
+} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
+
+typedef struct _DESCRIPTOR_PAIR
+{
+    ADDRESS_LENGTH_PAIR descriptor[4];
+    u_int32_t   elements;
+} DESC_ARRAY, *PDESC_ARRAY;
+
 /* Our adapter structure */
 struct adapter {
 	struct arpcom   interface_data;
@@ -389,6 +413,9 @@
 	u_int64_t       tx_fifo_reset;
 	u_int64_t       tx_fifo_wrk;
 
+        /* For 82544 PCIX Workaround */
+        boolean_t       pcix_82544;
+
 #ifdef DBG_STATS
 	unsigned long   no_pkts_avail;
 	unsigned long   clean_tx_interrupts;

==== //depot/projects/uart/dev/em/if_em_hw.c#3 (text+ko) ====

@@ -36,20 +36,21 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/em/if_em_hw.c,v 1.10 2003/08/24 17:46:04 obrien Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/em/if_em_hw.c,v 1.11 2003/08/27 21:52:37 pdeuskar Exp $");
 
 #include <dev/em/if_em_hw.h>
 
 static int32_t em_set_phy_type(struct em_hw *hw);
 static void em_phy_init_script(struct em_hw *hw);
-static int32_t em_setup_fiber_link(struct em_hw *hw);
 static int32_t em_setup_copper_link(struct em_hw *hw);
+static int32_t em_setup_fiber_serdes_link(struct em_hw *hw);
+static int32_t em_adjust_serdes_amplitude(struct em_hw *hw);
 static int32_t em_phy_force_speed_duplex(struct em_hw *hw);
 static int32_t em_config_mac_to_phy(struct em_hw *hw);
-static int32_t em_force_mac_fc(struct em_hw *hw);
 static void em_raise_mdi_clk(struct em_hw *hw, uint32_t *ctrl);
 static void em_lower_mdi_clk(struct em_hw *hw, uint32_t *ctrl);
-static void em_shift_out_mdi_bits(struct em_hw *hw, uint32_t data, uint16_t count);
+static void em_shift_out_mdi_bits(struct em_hw *hw, uint32_t data,
+                                     uint16_t count);
 static uint16_t em_shift_in_mdi_bits(struct em_hw *hw);
 static int32_t em_phy_reset_dsp(struct em_hw *hw);
 static int32_t em_write_eeprom_spi(struct em_hw *hw, uint16_t offset,
@@ -60,13 +61,30 @@
 static int32_t em_spi_eeprom_ready(struct em_hw *hw);
 static void em_raise_ee_clk(struct em_hw *hw, uint32_t *eecd);
 static void em_lower_ee_clk(struct em_hw *hw, uint32_t *eecd);
-static void em_shift_out_ee_bits(struct em_hw *hw, uint16_t data, uint16_t count);
+static void em_shift_out_ee_bits(struct em_hw *hw, uint16_t data,
+                                    uint16_t count);
+static int32_t em_write_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr,
+                                      uint16_t phy_data);
+static int32_t em_read_phy_reg_ex(struct em_hw *hw,uint32_t reg_addr,
+                                     uint16_t *phy_data);
 static uint16_t em_shift_in_ee_bits(struct em_hw *hw, uint16_t count);
 static int32_t em_acquire_eeprom(struct em_hw *hw);
 static void em_release_eeprom(struct em_hw *hw);
 static void em_standby_eeprom(struct em_hw *hw);
 static int32_t em_id_led_init(struct em_hw * hw);
+static int32_t em_set_vco_speed(struct em_hw *hw);
 
+/* IGP cable length table */
+static const
+uint16_t em_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
+    { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+      5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
+      25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
+      40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
+      60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
+      90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+      100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+      110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
 
 
 /******************************************************************************
@@ -108,41 +126,64 @@
     DEBUGFUNC("em_phy_init_script");
 
     if(hw->phy_init_script) {
-        msec_delay(10);
+        msec_delay(20);
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
         em_write_phy_reg(hw,0x0000,0x0140);
 
         msec_delay(5);
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F95);
-        em_write_phy_reg(hw,0x0015,0x0001);
+
+        if(hw->mac_type == em_82541 || hw->mac_type == em_82547) {
+            em_write_phy_reg(hw, 0x1F95, 0x0001);
+
+            em_write_phy_reg(hw, 0x1F71, 0xBD21);
+
+            em_write_phy_reg(hw, 0x1F79, 0x0018);
+
+            em_write_phy_reg(hw, 0x1F30, 0x1600);
+
+            em_write_phy_reg(hw, 0x1F31, 0x0014);
+
+            em_write_phy_reg(hw, 0x1F32, 0x161C);
+
+            em_write_phy_reg(hw, 0x1F94, 0x0003);
+
+            em_write_phy_reg(hw, 0x1F96, 0x003F);
+
+            em_write_phy_reg(hw, 0x2010, 0x0008);
+        } else {
+            em_write_phy_reg(hw, 0x1F73, 0x0099);
+        }
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F71);
-        em_write_phy_reg(hw,0x0011,0xBD21);
+        em_write_phy_reg(hw, 0x0000, 0x3300);
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F79);
-        em_write_phy_reg(hw,0x0019,0x0018);
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F30);
-        em_write_phy_reg(hw,0x0010,0x1600);
+        if(hw->mac_type == em_82547) {
+            uint16_t fused, fine, coarse;
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F31);
-        em_write_phy_reg(hw,0x0011,0x0014);
+            /* Move to analog registers page */
+            em_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F32);
-        em_write_phy_reg(hw,0x0012,0x161C);
+            if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
+                em_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused);
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F94);
-        em_write_phy_reg(hw,0x0014,0x0003);
+                fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
+                coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F96);
-        em_write_phy_reg(hw,0x0016,0x003F);
+                if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
+                    coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10;
+                    fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
+                } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
+                    fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x2010);
-        em_write_phy_reg(hw,0x0010,0x0008);
+                fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
+                        (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
+                        (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);
 
-        em_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
-        em_write_phy_reg(hw,0x0000,0x3300);
+                em_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
+                em_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
+                                    IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
+            }
+        }
     }
 }
 
@@ -191,32 +232,89 @@
     case E1000_DEV_ID_82545EM_FIBER:
         hw->mac_type = em_82545;
         break;
+    case E1000_DEV_ID_82545GM_COPPER:
+    case E1000_DEV_ID_82545GM_FIBER:
+    case E1000_DEV_ID_82545GM_SERDES:
+        hw->mac_type = em_82545_rev_3;
+        break;
     case E1000_DEV_ID_82546EB_COPPER:
     case E1000_DEV_ID_82546EB_FIBER:
     case E1000_DEV_ID_82546EB_QUAD_COPPER:
         hw->mac_type = em_82546;
         break;
+    case E1000_DEV_ID_82546GB_COPPER:
+    case E1000_DEV_ID_82546GB_FIBER:
+    case E1000_DEV_ID_82546GB_SERDES:
+        hw->mac_type = em_82546_rev_3;
+        break;
     case E1000_DEV_ID_82541EI:
-    case E1000_DEV_ID_82541EP:
+    case E1000_DEV_ID_82541EI_MOBILE:
         hw->mac_type = em_82541;
         break;
+    case E1000_DEV_ID_82541ER:
+    case E1000_DEV_ID_82541GI:
+    case E1000_DEV_ID_82541GI_MOBILE:
+        hw->mac_type = em_82541_rev_2;
+        break;
     case E1000_DEV_ID_82547EI:
         hw->mac_type = em_82547;
         break;
+    case E1000_DEV_ID_82547GI:
+        hw->mac_type = em_82547_rev_2;
+        break;
     default:
         /* Should never have loaded on this device */
         return -E1000_ERR_MAC_TYPE;
     }
 
+    return E1000_SUCCESS;
+}
 
-    return E1000_SUCCESS;
+/*****************************************************************************
+ * Set media type and TBI compatibility.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * **************************************************************************/
+void
+em_set_media_type(struct em_hw *hw)
+{
+    uint32_t status;
+
+    DEBUGFUNC("em_set_media_type");
+
+    if(hw->mac_type != em_82543) {
+        /* tbi_compatibility is only valid on 82543 */
+        hw->tbi_compatibility_en = FALSE;
+    }
+
+    switch (hw->device_id) {
+    case E1000_DEV_ID_82545GM_SERDES:
+    case E1000_DEV_ID_82546GB_SERDES:
+        hw->media_type = em_media_type_internal_serdes;
+        break;
+    default:
+        if(hw->mac_type >= em_82543) {
+            status = E1000_READ_REG(hw, STATUS);
+            if(status & E1000_STATUS_TBIMODE) {
+                hw->media_type = em_media_type_fiber;
+                /* tbi_compatibility not valid on fiber */
+                hw->tbi_compatibility_en = FALSE;
+            } else {
+                hw->media_type = em_media_type_copper;
+            }
+        } else {
+            /* This is an 82542 (fiber only) */
+            hw->media_type = em_media_type_fiber;
+        }
+    }
 }
+
 /******************************************************************************
  * Reset the transmit and receive units; mask and clear all interrupts.
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+int32_t
 em_reset_hw(struct em_hw *hw)
 {
     uint32_t ctrl;
@@ -253,49 +351,75 @@
      */
     msec_delay(10);
 
+    ctrl = E1000_READ_REG(hw, CTRL);
+
+    /* Must reset the PHY before resetting the MAC */
+    if((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) {
+        E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
+        msec_delay(5);
+    }
+
     /* Issue a global reset to the MAC.  This will reset the chip's
      * transmit, receive, DMA, and link units.  It will not effect
      * the current PCI configuration.  The global reset bit is self-
      * clearing, and should clear within a microsecond.
      */
     DEBUGOUT("Issuing a global reset to MAC\n");
-    ctrl = E1000_READ_REG(hw, CTRL);
 
-    /* Must reset the PHY before resetting the MAC */

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



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