[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

xl diff



Any and all feedback welcome, this could use testing on any
xl(4) gear whether its PCI or CardBus.

// Brad

----- Forwarded message from Brad <brad_(_at_)_comstyle_(_dot_)_com> -----

Date: Thu, 6 May 2004 02:00:30 -0400
From: Brad <brad_(_at_)_comstyle_(_dot_)_com>
To: hackers_(_at_)_openbsd_(_dot_)_org
Subject: xl diff
User-Agent: Mutt/1.5.6i

This needs testing...

- Enables VLAN support on 3c900/3c905 (pre-B/C); from FreeBSD
- Re-enables the hardware multicast filter setup on 3c905B's which
somehow was disabled by kjc ALTQ'ifying the driver quite some time ago.

// Brad

Index: xl.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/xl.c,v
retrieving revision 1.51
diff -u -p -r1.51 xl.c
--- xl.c	21 Oct 2003 18:58:50 -0000	1.51
+++ xl.c	6 May 2004 05:38:27 -0000
@@ -1247,6 +1247,7 @@ again:
 	    != 0) {
 		cur_rx = sc->xl_cdata.xl_rx_head;
 		sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
+		total_len = rxstat & XL_RXSTAT_LENMASK;
 
 		bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
 		    ((caddr_t)cur_rx->xl_ptr - sc->sc_listkva),
@@ -1254,6 +1255,15 @@ again:
 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
 		/*
+		 * Since we have told the chip to allow large frames,
+		 * we need to trap giant frame errors in software. We allow
+		 * a little more than the normal frame size to account for
+		 * frames with VLAN tags.
+		 */
+		if (total_len > XL_MAX_FRAMELEN)
+			rxstat |= (XL_RXSTAT_UP_ERROR|XL_RXSTAT_OVERSIZE);
+
+		/*
 		 * If an error occurs, update stats, clear the
 		 * status word and leave the mbuf cluster in place:
 		 * it should simply get re-used next time this descriptor
@@ -1266,7 +1276,7 @@ again:
 		}
 
 		/*
-		 * If there error bit was not set, the upload complete
+		 * If the error bit was not set, the upload complete
 		 * bit should be set which means we have a valid packet.
 		 * If not, something truly strange has happened.
 		 */
@@ -1280,8 +1290,6 @@ again:
 
 		/* No errors; receive the packet. */	
 		m = cur_rx->xl_mbuf;
-		total_len = letoh32(cur_rx->xl_ptr->xl_status) &
-		    XL_RXSTAT_LENMASK;
 
 		/*
 		 * Try to conjure up a new mbuf cluster. If that
@@ -2127,11 +2135,7 @@ void xl_init(xsc)
 	/*
 	 * Program the multicast filter, if necessary.
 	 */
-#if 0
 	if (sc->xl_type == XL_TYPE_905B)
-#else
-	if (0)	/* xl_setmulti_hash() does not work right */
-#endif
 		xl_setmulti_hash(sc);
 	else
 		xl_setmulti(sc);
@@ -2177,9 +2181,20 @@ void xl_init(xsc)
 		CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
 
 #if NVLAN > 0
-	/* Set max packet size to handle VLAN frames, only on 3c905B */
+	/*
+	 * increase packet size to allow reception of 802.1q or ISL packets.
+	 * For the 3c90x chip, set the 'allow large packets' bit in the MAC
+	 * control register. For 3c90xB/C chips, use the RX packet size
+	 * register.
+	 */
 	if (sc->xl_type == XL_TYPE_905B)
-		CSR_WRITE_2(sc, XL_W3_MAX_PKT_SIZE, 1514 + 4);
+		CSR_WRITE_2(sc, XL_W3_MAX_PKT_SIZE, XL_MAX_FRAMELEN);
+	else {
+		u_int8_t macctl;
+		macctl = CSR_READ_1(sc, XL_W3_MAC_CTRL);
+		macctl |= XL_MACCTRL_ALLOW_LARGE_PACK;
+		CSR_WRITE_1(sc, XL_W3_MAC_CTRL, macctl);
+	}
 #endif
 
 	/* Clear out the stats counters. */
@@ -2418,11 +2433,7 @@ xl_ioctl(ifp, command, data)
 			 * Multicast list has changed; set the hardware
 			 * filter accordingly.
 			 */
-#if 0
 			if (sc->xl_type == XL_TYPE_905B)
-#else
-			if (0)	/* xl_setmulti_hash() does not work right */
-#endif
 				xl_setmulti_hash(sc);
 			else
 				xl_setmulti(sc);
@@ -2665,9 +2676,15 @@ xl_attach(sc)
 	 * Figure out the card type. 3c905B adapters have the
 	 * 'supportsNoTxLength' bit set in the capabilities
 	 * word in the EEPROM.
+	 * Note: my 3c575C cardbus card lies. It returns a value
+	 * of 0x1578 for its capabilities word, which is somewhat
+	 * nonsensical. Another way to distinguish a 3c90x chip
+	 * from a 3c90xB/C chip is to check for the 'supportsLargePackets'
+	 * bit. This will only be set for 3c90x boomerage chips.
 	 */
 	xl_read_eeprom(sc, (caddr_t)&sc->xl_caps, XL_EE_CAPS, 1, 0);
-	if (sc->xl_caps & XL_CAPS_NO_TXLENGTH)
+	if (sc->xl_caps & XL_CAPS_NO_TXLENGTH ||
+	    !(sc->xl_caps & XL_CAPS_LARGE_PKTS))
 		sc->xl_type = XL_TYPE_905B;
 	else
 		sc->xl_type = XL_TYPE_90X;
@@ -2679,9 +2696,12 @@ xl_attach(sc)
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = xl_ioctl;
 	ifp->if_output = ether_output;
+#if NVLAN > 0
+	ifp->if_capabilities |= IFCAP_VLAN_MTU;
+#endif
 	if (sc->xl_type == XL_TYPE_905B) {
 		ifp->if_start = xl_start_90xB;
-		ifp->if_capabilities = IFCAP_CSUM_IPv4|IFCAP_CSUM_TCPv4|
+		ifp->if_capabilities |= IFCAP_CSUM_IPv4|IFCAP_CSUM_TCPv4|
 		    IFCAP_CSUM_UDPv4;
 	} else
 		ifp->if_start = xl_start;
@@ -2690,16 +2710,6 @@ xl_attach(sc)
 	IFQ_SET_MAXLEN(&ifp->if_snd, XL_TX_LIST_CNT - 1);
 	IFQ_SET_READY(&ifp->if_snd);
 	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
-
-#if NVLAN > 0
-	if (sc->xl_type == XL_TYPE_905B)
-		ifp->if_capabilities |= IFCAP_VLAN_MTU;
-	/*
-	 * XXX
-	 * Do other cards filter large packets or simply pass them through?
-	 * Apparently only the 905B has the capability to set a larger size.
- 	 */
-#endif
 
 	XL_SEL_WIN(3);
 	sc->xl_media = CSR_READ_2(sc, XL_W3_MEDIA_OPT);
Index: xlreg.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/xlreg.h,v
retrieving revision 1.17
diff -u -p -r1.17 xlreg.h
--- xlreg.h	21 Oct 2003 18:58:50 -0000	1.17
+++ xlreg.h	6 May 2004 05:38:27 -0000
@@ -83,8 +83,10 @@
 #define XL_CAPS_100MBPS		0x1000
 #define XL_CAPS_PWRMGMT		0x2000
 
-#define XL_PACKET_SIZE 1536
-	
+#define XL_PACKET_SIZE 1540
+
+#define XL_MAX_FRAMELEN	(ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN)
+
 /*
  * Register layouts.
  */


Index: if_ether.h
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.h,v
retrieving revision 1.29
diff -u -p -r1.29 if_ether.h
--- if_ether.h	2 Jun 2003 23:28:13 -0000	1.29
+++ if_ether.h	27 Apr 2004 07:20:14 -0000
@@ -44,6 +44,17 @@
 #define ETHER_HDR_LEN	((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN)
 #define ETHER_MIN_LEN	64	/* Minimum frame length, CRC included	*/
 #define ETHER_MAX_LEN	1518	/* Maximum frame length, CRC included	*/
+#define	ETHER_MAX_LEN_JUMBO	9018	/* max jumbo frame len, including CRC */
+
+#define	ETHER_VLAN_ENCAP_LEN	4	/* len of 802.1Q VLAN encapsulation */
+
+/*
+ * Mbuf adjust factor to force 32-bit alignment of IP header.
+ * Drivers should do m_adj(m, ETHER_ALIGN) when setting up a
+ * receive so the upper layers get the IP header properly aligned
+ * past the 14-byte Ethernet header.
+ */
+#define	ETHER_ALIGN		2	/* driver adjust for IP hdr alignment */
 
 /*
  * Ethernet address - 6 octets
@@ -55,7 +66,6 @@ struct ether_addr {
 /*
  * The length of the combined header.
  */
-
 struct	ether_header {
 	u_int8_t  ether_dhost[ETHER_ADDR_LEN];
 	u_int8_t  ether_shost[ETHER_ADDR_LEN];
@@ -68,6 +78,7 @@ struct	ether_header {
 
 #define	ETHERMTU	(ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
 #define	ETHERMIN	(ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+#define	ETHERMTU_JUMBO	(ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN)
 
 /*
  * Ethernet CRC32 polynomials (big- and little-endian verions).

----- End forwarded message -----



Visit your host, monkey.org