netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/3] rx_all e100 patch
@ 2003-11-25  7:55 Ben Greear
  2003-11-25 15:21 ` Rask Ingemann Lambertsen
  2003-11-25 16:56 ` Rask Ingemann Lambertsen
  0 siblings, 2 replies; 7+ messages in thread
From: Ben Greear @ 2003-11-25  7:55 UTC (permalink / raw)
  To: 'netdev@oss.sgi.com'

[-- Attachment #1: Type: text/plain, Size: 96 bytes --]


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


[-- Attachment #2: rx_all_e100.patch --]
[-- Type: text/plain, Size: 11631 bytes --]

--- linux-2.4.22/drivers/net/e100/e100_main.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22.p4s/drivers/net/e100/e100_main.c	2003-11-24 21:50:49.000000000 -0800
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/** -*-linux-c-*- ************************************************************
 
   
   Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
@@ -175,7 +175,7 @@
         MODULE_PARM_DESC(X, S);
 
 /* ====================================================================== */
-static u8 e100_D101M_checksum(struct e100_private *, struct sk_buff *);
+static u8 e100_D101M_checksum(struct e100_private *, struct sk_buff *, int crc_there);
 static u8 e100_D102_check_checksum(rfd_t *);
 static int e100_ioctl(struct net_device *, struct ifreq *, int);
 static int e100_change_mtu(struct net_device *, int);
@@ -644,8 +644,9 @@
 	dev->do_ioctl = &e100_ioctl;
 
 	if (bdp->flags & USE_IPCB)
-	dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
-			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+		dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
+			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
+		        NETIF_F_RX_ALL | NETIF_F_SAVE_CRC;
 		
 	if ((rc = register_netdev(dev)) != 0) {
 		goto err_pci;
@@ -1198,11 +1199,17 @@
 	struct e100_private *bdp = dev->priv;
 	unsigned char promisc_enbl;
 	unsigned char mulcast_enbl;
+	unsigned char enable_rx_all;
 
 	promisc_enbl = ((dev->flags & IFF_PROMISC) == IFF_PROMISC);
 	mulcast_enbl = ((dev->flags & IFF_ALLMULTI) ||
 			(dev->mc_count > MAX_MULTICAST_ADDRS));
+	enable_rx_all = ((dev->priv_flags & IFF_ACCEPT_ALL_FRAMES) == IFF_ACCEPT_ALL_FRAMES);
 
+	printk("e100_set_rx_multi (%s), promisc: %d  mcast: %d rxall: %d\n",
+	       dev->name, promisc_enbl, mulcast_enbl, enable_rx_all);
+        /* NOTE:  rx_long is unconditionally set to TRUE if the chipset supports it. */
+	e100_config_rx_all(bdp, enable_rx_all);
 	e100_config_promisc(bdp, promisc_enbl);
 	e100_config_mulcast_enbl(bdp, mulcast_enbl);
 
@@ -2016,8 +2023,14 @@
 		/* do not free & unmap badly received packet.
 		 * move it to the end of skb list for reuse */
 		if (!(rfd_status & RFD_STATUS_OK)) {
-			e100_add_skb_to_end(bdp, rx_struct);
-			continue;
+			if (unlikely(dev->priv_flags & IFF_ACCEPT_ALL_FRAMES)) {
+				/* printk("%s: Accepting a bogon, rfd_status: 0x%x\n",
+				   dev->name, rfd_status); */
+			}
+			else {
+				e100_add_skb_to_end(bdp, rx_struct);
+				continue;
+			}
 		}
 
 		data_sz = min_t(u16, (le16_to_cpu(rfd->rfd_act_cnt) & 0x3fff),
@@ -2052,13 +2065,26 @@
 			if (bdp->rev_id >= D102_REV_ID) {
 				skb->ip_summed = e100_D102_check_checksum(rfd);
 			} else {
-				skb->ip_summed = e100_D101M_checksum(bdp, skb);
+				skb->ip_summed = e100_D101M_checksum(bdp, skb, !!(dev->priv_flags & IFF_ACCEPT_ALL_FRAMES));
 			}
 		} else {
 			skb->ip_summed = CHECKSUM_NONE;
 		}
 
+		/* Show the FCS? */
+		if (unlikely(dev->priv_flags & IFF_SAVE_FCS)) {
+			if (bdp->rev_id < D102_REV_ID) {
+				/* Have to over-write the two IP checksum bytes
+				 * TODO:  Will this break vlan_hwaccel_rx???
+				 */
+				skb->tail[-4] = skb->tail[-2];
+				skb->tail[-3] = skb->tail[-1];
+				skb->tail[-2] = skb->tail[0];
+				skb->tail[-1] = skb->tail[1];
+			}
+		}
+		
 		bdp->drv_stats.net_stats.rx_bytes += skb->len;
 
 		if(bdp->vlgrp && (rfd_status & CB_STATUS_VLAN)) {
@@ -2934,13 +2972,16 @@
  * assign this value to skb->csum.
  */
 static unsigned char
-e100_D101M_checksum(struct e100_private *bdp, struct sk_buff *skb)
+e100_D101M_checksum(struct e100_private *bdp, struct sk_buff *skb, int crc_there)
 {
 	unsigned short proto = (skb->protocol);
-
+	int offset = 0;
+	if (unlikely(crc_there)) {
+		offset = -4;
+	}
 	if (proto == __constant_htons(ETH_P_IP)) {
 
-		skb->csum = get_unaligned((u16 *) (skb->tail));
+		skb->csum = get_unaligned((u16 *) (skb->tail - offset));
 		return CHECKSUM_HW;
 	}
 	return CHECKSUM_NONE;
@@ -3143,6 +3184,27 @@
 	}
 }
 
+static int e100_ethtool_setrxall(struct net_device *netdev, uint32_t val) {
+	unsigned short old_flags = netdev->priv_flags;
+	if (val) {
+		netdev->priv_flags |= IFF_ACCEPT_ALL_FRAMES;
+	}
+	else {
+		netdev->priv_flags &= ~(IFF_ACCEPT_ALL_FRAMES);
+	}
+
+	/* printk("e100_ethtool_setrxall (%s) val: %d\n",
+	   netdev->name, val); */
+	if (old_flags != netdev->priv_flags) {
+		/*  Kick the driver to flush the values...
+		 * TODO:  Needs review of driver folks to make sure locking is sane, etc
+		 */
+		/*printk("Kicking e100_set_multi..\n");*/
+		e100_set_multi(netdev);
+	}
+	return 0;
+}      
+
 static int
 e100_do_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
 {
@@ -3342,7 +3404,43 @@
 		return 0;
 	}
 #endif
+	case ETHTOOL_SETRXALL: {
+		struct ethtool_value id;
+		if (copy_from_user(&id, ifr->ifr_data, sizeof(id)))
+			return -EFAULT;
+		spin_lock_bh(&dev->xmit_lock);
+		e100_ethtool_setrxall(dev, id.data);
+		spin_unlock_bh(&dev->xmit_lock);
+		return 0;
+	}
+	case ETHTOOL_GETRXALL: {
+		struct ethtool_value edata = { ETHTOOL_GSG };
+		edata.data = !!(dev->priv_flags & IFF_ACCEPT_ALL_FRAMES);
+		/*printk("GETRXALL, data: %d  priv_flags: %hx\n",
+		  edata.data, netdev->priv_flags);*/
+		if (copy_to_user(ifr->ifr_data, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SETRXFCS: {
+		struct ethtool_value id;
+		if (copy_from_user(&id, ifr->ifr_data, sizeof(id)))
+			return -EFAULT;
+		spin_lock_bh(&dev->xmit_lock);
+		dev->priv_flags |= IFF_SAVE_FCS;
+		spin_unlock_bh(&dev->xmit_lock);
+		return 0;
+	}
+	case ETHTOOL_GETRXFCS: {
+		struct ethtool_value edata = { ETHTOOL_GSG };
+		edata.data = !!(dev->priv_flags & IFF_SAVE_FCS);
+		/*printk("GETRXFCS, data: %d  priv_flags: %hx\n",
+		  edata.data, netdev->priv_flags);*/
+		if (copy_to_user(ifr->ifr_data, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
 	default:
 		break;
 	}			//switch
--- linux-2.4.22/drivers/net/e100/e100_config.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22.p4s/drivers/net/e100/e100_config.c	2003-11-24 14:56:14.000000000 -0800
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/**** -*-linux-c-*- ***********************************************************
 
   
   Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
@@ -326,42 +326,92 @@
 {
 	spin_lock_bh(&(bdp->config_lock));
 
-	/* if in promiscuous mode, save bad frames */
+	/* Promiscuity */
 	if (enable) {
 
+		if (!(bdp->config[15] & CB_CFIG_PROMISCUOUS)) {
+			bdp->config[15] |= CB_CFIG_PROMISCUOUS;
+			E100_CONFIG(bdp, 15);
+		}
+
+	} else {		/* not in promiscuous mode */
+
+		if (bdp->config[15] & CB_CFIG_PROMISCUOUS) {
+			bdp->config[15] &= ~CB_CFIG_PROMISCUOUS;
+			E100_CONFIG(bdp, 15);
+		}
+	}
+
+	spin_unlock_bh(&(bdp->config_lock));
+}
+
+
+/**
+ * e100_config_promisc - configure promiscuous mode
+ * @bdp: atapter's private data struct
+ * @enable: should we enable this option or not
+ *
+ * This routine will enable or disable receiving all frames to
+ * memory, including bad ones, short ones, and long ones.  It also
+ * causes the Frame Check Sum (FCS) to be transferred to memory.
+ */
+void
+e100_config_rx_all(struct e100_private *bdp, unsigned char enable)
+{
+	spin_lock_bh(&(bdp->config_lock));
+
+	/* Should we save bad frames? */
+        if (enable) {
 		if (!(bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES)) {
 			bdp->config[6] |= CB_CFIG_SAVE_BAD_FRAMES;
 			E100_CONFIG(bdp, 6);
 		}
 
-		if (bdp->config[7] & (u8) BIT_0) {
-			bdp->config[7] &= (u8) (~BIT_0);
+                /* Don't discard short-receive */
+		if (bdp->config[7] & (u8) CB_CFIG_DISC_SHORT_FRAMES) {
+			bdp->config[7] &= (u8) (~CB_CFIG_DISC_SHORT_FRAMES);
 			E100_CONFIG(bdp, 7);
 		}
 
-		if (!(bdp->config[15] & CB_CFIG_PROMISCUOUS)) {
-			bdp->config[15] |= CB_CFIG_PROMISCUOUS;
-			E100_CONFIG(bdp, 15);
+		/* Save over-runs */
+		if (!(bdp->config[6] & CB_CFIG_SAVE_OVERRUNS)) {
+			bdp->config[6] |= CB_CFIG_SAVE_OVERRUNS;
+			E100_CONFIG(bdp, 6);
 		}
 
-	} else {		/* not in promiscuous mode */
-
+		/* Transfer the etherne CRC to memory too */
+		if (!(bdp->config[18] & CB_CFIG_CRC_IN_MEM)) {
+			bdp->config[18] |= CB_CFIG_CRC_IN_MEM;
+			E100_CONFIG(bdp, 18);
+		}
+		
+        }
+        else {
+		/* Don't discard short frames */
 		if (bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES) {
 			bdp->config[6] &= ~CB_CFIG_SAVE_BAD_FRAMES;
 			E100_CONFIG(bdp, 6);
 		}
 
-		if (!(bdp->config[7] & (u8) BIT_0)) {
-			bdp->config[7] |= (u8) (BIT_0);
+		/* Discard short-receive */
+		if (!(bdp->config[7] & (u8) CB_CFIG_DISC_SHORT_FRAMES)) {
+			bdp->config[7] |= (u8) (CB_CFIG_DISC_SHORT_FRAMES);
 			E100_CONFIG(bdp, 7);
 		}
 
-		if (bdp->config[15] & CB_CFIG_PROMISCUOUS) {
-			bdp->config[15] &= ~CB_CFIG_PROMISCUOUS;
-			E100_CONFIG(bdp, 15);
+		/* Discard over-runs */
+		if (bdp->config[6] & CB_CFIG_SAVE_OVERRUNS) {
+			bdp->config[6] &= !CB_CFIG_SAVE_OVERRUNS;
+			E100_CONFIG(bdp, 6);
 		}
-	}
+
+		/* Don't send CRC (FCS) to memory */
+		if (bdp->config[18] & CB_CFIG_CRC_IN_MEM) {
+			bdp->config[18] &= !CB_CFIG_CRC_IN_MEM;
+			E100_CONFIG(bdp, 18);
+		}
+        }
 
 	spin_unlock_bh(&(bdp->config_lock));
 }
--- linux-2.4.22/drivers/net/e100/e100_config.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22.p4s/drivers/net/e100/e100_config.h	2003-11-24 21:15:03.000000000 -0800
@@ -67,6 +67,7 @@
 #define CB_CFIG_CI_INT             BIT_3	/* Command Complete Interrupt */
 #define CB_CFIG_EXT_TCB_DIS        BIT_4	/* Extended TCB */
 #define CB_CFIG_EXT_STAT_DIS       BIT_5	/* Extended Stats */
+#define CB_CFIG_SAVE_OVERRUNS      BIT_6	/* Save over-run frames if != 0 */
 #define CB_CFIG_SAVE_BAD_FRAMES    BIT_7	/* Save Bad Frames Enabled */
 
 /* byte 7 bit definitions*/
@@ -117,6 +118,8 @@
 #define CB_CFIG_STRIPPING           BIT_0	/* Padding Disabled */
 #define CB_CFIG_PADDING             BIT_1	/* Padding Disabled */
 #define CB_CFIG_CRC_IN_MEM          BIT_2	/* Transfer CRC To Memory */
+/* Only valid for 82558 and 82559.  Must be zero for 82557 */
+#define CB_CFIG_LONG_RX_OK          BIT_3	/* OK to receive Long frames */
 
 /* byte 19 bit definitions*/
 #define CB_CFIG_TX_ADDR_WAKE        BIT_0	/* Address Wakeup */
@@ -142,8 +145,7 @@
 /* byte 22 bit defines */
 #define CB_CFIG_RECEIVE_GAMLA_MODE  BIT_0	/* D102 receive mode */
 #define CB_CFIG_VLAN_DROP_ENABLE    BIT_1	/* vlan stripping */
-
-#define CB_CFIG_LONG_RX_OK	    BIT_3
+/* LONG-RX OK (needed for VLAN) is in byte 18, bit 3, see above */
 
 #define NO_LOOPBACK	0	
 #define MAC_LOOPBACK	0x01
@@ -155,7 +157,8 @@
 extern unsigned char e100_config(struct e100_private *bdp);
 extern void e100_config_fc(struct e100_private *bdp);
 extern void e100_config_promisc(struct e100_private *bdp, unsigned char enable);
+extern void e100_config_rx_all(struct e100_private *bdp, unsigned char enable);
 extern void e100_config_brdcast_dsbl(struct e100_private *bdp);
 extern void e100_config_mulcast_enbl(struct e100_private *bdp,
 				     unsigned char enable);
--- linux-2.4.22/drivers/net/e100/e100.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22.p4s/drivers/net/e100/e100.h	2003-11-24 21:15:03.000000000 -0800
@@ -362,6 +362,7 @@
 #define CB_EL_BIT           BIT_15	/* CB EL Bit */
 #define CB_S_BIT            BIT_14	/* CB Suspend Bit */
 #define CB_I_BIT            BIT_13	/* CB Interrupt Bit */
+#define CB_TX_NC_BIT        BIT_4	        /* If true, do not calculate FCS */
 #define CB_TX_SF_BIT        BIT_3	/* TX CB Flexible Mode */
 #define CB_CMD_MASK         BIT_0_3	/* CB 4-bit CMD Mask */
 #define CB_CID_DEFAULT      (0x1f << 8)	/* CB 5-bit CID (max value) */

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] rx_all e100 patch
  2003-11-25  7:55 Ben Greear
@ 2003-11-25 15:21 ` Rask Ingemann Lambertsen
  2003-11-25 18:03   ` Ben Greear
  2003-11-25 16:56 ` Rask Ingemann Lambertsen
  1 sibling, 1 reply; 7+ messages in thread
From: Rask Ingemann Lambertsen @ 2003-11-25 15:21 UTC (permalink / raw)
  To: Ben Greear; +Cc: 'netdev@oss.sgi.com'

On Mon, Nov 24, 2003 at 11:55:26PM -0800, Ben Greear wrote:
> @@ -2052,13 +2065,26 @@
>  			if (bdp->rev_id >= D102_REV_ID) {
>  				skb->ip_summed = e100_D102_check_checksum(rfd);
>  			} else {
> -				skb->ip_summed = e100_D101M_checksum(bdp, skb);
> +				skb->ip_summed = e100_D101M_checksum(bdp, skb, !!(dev->priv_flags & IFF_ACCEPT_ALL_FRAMES));
>  			}

Shouldn't that be IFF_SAVE_FCS rather than IFF_ACCEPT_ALL_FRAMES?

>  		} else {
>  			skb->ip_summed = CHECKSUM_NONE;
>  		}
>  
> +		/* Show the FCS? */
> +		if (unlikely(dev->priv_flags & IFF_SAVE_FCS)) {
> +			if (bdp->rev_id < D102_REV_ID) {
> +				/* Have to over-write the two IP checksum bytes
> +				 * TODO:  Will this break vlan_hwaccel_rx???
> +				 */
> +				skb->tail[-4] = skb->tail[-2];
> +				skb->tail[-3] = skb->tail[-1];
> +				skb->tail[-2] = skb->tail[0];
> +				skb->tail[-1] = skb->tail[1];
> +			}
> +		}
> +		

I don't understand this part of the code. The 55x docs say that the IP
checksum bytes are transferred to memory _following_ the FCS.

> +/**
> + * e100_config_promisc - configure promiscuous mode
> + * @bdp: atapter's private data struct
> + * @enable: should we enable this option or not

s/atapter/adapter/g

s/etherne /ethernet /g too, somewhere, IIRC.

> +/* Only valid for 82558 and 82559.  Must be zero for 82557 */
> +#define CB_CFIG_LONG_RX_OK          BIT_3	/* OK to receive Long frames */

I find it disappointing that the good, old 82586 transfers long frames to
memory without complaint while newer chips such as the 82557 and tulip
can't/don't.

-- 
Regards,
Rask Ingemann Lambertsen

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] rx_all e100 patch
  2003-11-25  7:55 Ben Greear
  2003-11-25 15:21 ` Rask Ingemann Lambertsen
@ 2003-11-25 16:56 ` Rask Ingemann Lambertsen
  1 sibling, 0 replies; 7+ messages in thread
From: Rask Ingemann Lambertsen @ 2003-11-25 16:56 UTC (permalink / raw)
  To: Ben Greear; +Cc: 'netdev@oss.sgi.com'

On Mon, Nov 24, 2003 at 11:55:26PM -0800, Ben Greear wrote:

> +		/* Discard over-runs */
> +		if (bdp->config[6] & CB_CFIG_SAVE_OVERRUNS) {
> +			bdp->config[6] &= !CB_CFIG_SAVE_OVERRUNS;
> +			E100_CONFIG(bdp, 6);
>  		}
> -	}
> +
> +		/* Don't send CRC (FCS) to memory */
> +		if (bdp->config[18] & CB_CFIG_CRC_IN_MEM) {
> +			bdp->config[18] &= !CB_CFIG_CRC_IN_MEM;
> +			E100_CONFIG(bdp, 18);
> +		}
> +        }

I think you want ~CB_CFIG_XXX instead of !CB_CFIG_XXX.

-- 
Regards,
Rask Ingemann Lambertsen

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH 3/3] rx_all e100 patch
@ 2003-11-25 17:39 Feldman, Scott
  2003-11-25 18:05 ` Ben Greear
  0 siblings, 1 reply; 7+ messages in thread
From: Feldman, Scott @ 2003-11-25 17:39 UTC (permalink / raw)
  To: Ben Greear, netdev

Ben, I'd rather not touch e100-2.3.x as it's going to be replaced soon
with e100-3.0.x.  Can you switch over to e100-3.0.x for this
development?  It's up on the sf.net/projects/e1000 web site.  I think
you'll find this patch collapses into much fewer lines with the new
driver.  It has ethtool_ops support also.  I can work on the e100-3.0.x
patch if you don't want to redo the work.  Let me know.

-scott

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] rx_all e100 patch
  2003-11-25 15:21 ` Rask Ingemann Lambertsen
@ 2003-11-25 18:03   ` Ben Greear
  2003-11-25 23:41     ` Rask Ingemann Lambertsen
  0 siblings, 1 reply; 7+ messages in thread
From: Ben Greear @ 2003-11-25 18:03 UTC (permalink / raw)
  To: Rask Ingemann Lambertsen; +Cc: 'netdev@oss.sgi.com'

[-- Attachment #1: Type: text/plain, Size: 2553 bytes --]

Rask Ingemann Lambertsen wrote:
> On Mon, Nov 24, 2003 at 11:55:26PM -0800, Ben Greear wrote:
> 
>>@@ -2052,13 +2065,26 @@
>> 			if (bdp->rev_id >= D102_REV_ID) {
>> 				skb->ip_summed = e100_D102_check_checksum(rfd);
>> 			} else {
>>-				skb->ip_summed = e100_D101M_checksum(bdp, skb);
>>+				skb->ip_summed = e100_D101M_checksum(bdp, skb, !!(dev->priv_flags & IFF_ACCEPT_ALL_FRAMES));
>> 			}
> 
> 
> Shouldn't that be IFF_SAVE_FCS rather than IFF_ACCEPT_ALL_FRAMES?

Yes, will fix, actually, considering your next comment, it should not even
be needed at all, eh?

>> 		} else {
>> 			skb->ip_summed = CHECKSUM_NONE;
>> 		}
>> 
>>+		/* Show the FCS? */
>>+		if (unlikely(dev->priv_flags & IFF_SAVE_FCS)) {
>>+			if (bdp->rev_id < D102_REV_ID) {
>>+				/* Have to over-write the two IP checksum bytes
>>+				 * TODO:  Will this break vlan_hwaccel_rx???
>>+				 */
>>+				skb->tail[-4] = skb->tail[-2];
>>+				skb->tail[-3] = skb->tail[-1];
>>+				skb->tail[-2] = skb->tail[0];
>>+				skb->tail[-1] = skb->tail[1];
>>+			}
>>+		}
>>+		
> 
> 
> I don't understand this part of the code. The 55x docs say that the IP
> checksum bytes are transferred to memory _following_ the FCS.

I can't find this in the docs, but it could easily be true.  If you have a page/section
number, please let me know.  I don't appear to have hardware that takes this
branch at any rate.  Anyone know which chipset/NIC has this particular rev-id?

Also, this should invalidate all of the hacks from the e100_D101M_checksum code...

> 
> 
>>+/**
>>+ * e100_config_promisc - configure promiscuous mode
>>+ * @bdp: atapter's private data struct
>>+ * @enable: should we enable this option or not
> 
> 
> s/atapter/adapter/g
> 
> s/etherne /ethernet /g too, somewhere, IIRC.
> 
> 
>>+/* Only valid for 82558 and 82559.  Must be zero for 82557 */
>>+#define CB_CFIG_LONG_RX_OK          BIT_3	/* OK to receive Long frames */
> 
> 
> I find it disappointing that the good, old 82586 transfers long frames to
> memory without complaint while newer chips such as the 82557 and tulip
> can't/don't.

Tulip can at least work with VLANs with a hack or two, but not sure how it's
max longness.

There may be other ways to get the 82557 to do VLANs, but the docs definately
indicate the rx-long bit does not exist for 82557 (page 62-64, byte 18, bit 3)
of the e100 docs from sourceforge.

Thanks for the thorough review.  Attached is a new patch that I believe
addresses these problems.

Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


[-- Attachment #2: rx_all_e100.patch --]
[-- Type: text/plain, Size: 10278 bytes --]

--- linux-2.4.22/drivers/net/e100/e100_main.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22.p4s/drivers/net/e100/e100_main.c	2003-11-25 09:56:38.000000000 -0800
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/** -*-linux-c-*- ************************************************************
 
   
   Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
@@ -644,8 +644,9 @@
 	dev->do_ioctl = &e100_ioctl;
 
 	if (bdp->flags & USE_IPCB)
-	dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
-			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+		dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
+			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
+		        NETIF_F_RX_ALL | NETIF_F_SAVE_CRC;
 		
 	if ((rc = register_netdev(dev)) != 0) {
 		goto err_pci;
@@ -830,7 +831,7 @@
 /**
  * e100_check_options - check command line options
  * @board: board number
- * @bdp: atapter's private data struct
+ * @bdp: adapter's private data struct
  *
  * This routine does range checking on command-line options
  */
@@ -1198,11 +1199,17 @@
 	struct e100_private *bdp = dev->priv;
 	unsigned char promisc_enbl;
 	unsigned char mulcast_enbl;
+	unsigned char enable_rx_all;
 
 	promisc_enbl = ((dev->flags & IFF_PROMISC) == IFF_PROMISC);
 	mulcast_enbl = ((dev->flags & IFF_ALLMULTI) ||
 			(dev->mc_count > MAX_MULTICAST_ADDRS));
+	enable_rx_all = ((dev->priv_flags & IFF_ACCEPT_ALL_FRAMES) == IFF_ACCEPT_ALL_FRAMES);
 
+	printk("e100_set_rx_multi (%s), promisc: %d  mcast: %d rxall: %d\n",
+	       dev->name, promisc_enbl, mulcast_enbl, enable_rx_all);
+        /* NOTE:  rx_long is unconditionally set to TRUE if the chipset supports it. */
+	e100_config_rx_all(bdp, enable_rx_all);
 	e100_config_promisc(bdp, promisc_enbl);
 	e100_config_mulcast_enbl(bdp, mulcast_enbl);
 
@@ -2016,9 +2023,15 @@
 		/* do not free & unmap badly received packet.
 		 * move it to the end of skb list for reuse */
 		if (!(rfd_status & RFD_STATUS_OK)) {
-			e100_add_skb_to_end(bdp, rx_struct);
-			continue;
+			if (unlikely(dev->priv_flags & IFF_ACCEPT_ALL_FRAMES)) {
+				/* printk("%s: Accepting a bogon, rfd_status: 0x%x\n",
+				   dev->name, rfd_status); */
+			}
+			else {
+				e100_add_skb_to_end(bdp, rx_struct);
+				continue;
+			}
 		}
 
 		data_sz = min_t(u16, (le16_to_cpu(rfd->rfd_act_cnt) & 0x3fff),
@@ -2925,7 +2950,7 @@
 
 /**
  * e100_D101M_checksum
- * @bdp: atapter's private data struct
+ * @bdp: adapter's private data struct
  * @skb: skb received
  *
  * Sets the skb->csum value from D101 csum found at the end of the Rx frame. The
@@ -3143,6 +3168,27 @@
 	}
 }
 
+static int e100_ethtool_setrxall(struct net_device *netdev, uint32_t val) {
+	unsigned short old_flags = netdev->priv_flags;
+	if (val) {
+		netdev->priv_flags |= IFF_ACCEPT_ALL_FRAMES;
+	}
+	else {
+		netdev->priv_flags &= ~(IFF_ACCEPT_ALL_FRAMES);
+	}
+
+	/* printk("e100_ethtool_setrxall (%s) val: %d\n",
+	   netdev->name, val); */
+	if (old_flags != netdev->priv_flags) {
+		/*  Kick the driver to flush the values...
+		 * TODO:  Needs review of driver folks to make sure locking is sane, etc
+		 */
+		/*printk("Kicking e100_set_multi..\n");*/
+		e100_set_multi(netdev);
+	}
+	return 0;
+}      
+
 static int
 e100_do_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
 {
@@ -3342,7 +3388,43 @@
 		return 0;
 	}
 #endif
+	case ETHTOOL_SETRXALL: {
+		struct ethtool_value id;
+		if (copy_from_user(&id, ifr->ifr_data, sizeof(id)))
+			return -EFAULT;
+		spin_lock_bh(&dev->xmit_lock);
+		e100_ethtool_setrxall(dev, id.data);
+		spin_unlock_bh(&dev->xmit_lock);
+		return 0;
+	}
+	case ETHTOOL_GETRXALL: {
+		struct ethtool_value edata = { ETHTOOL_GSG };
+		edata.data = !!(dev->priv_flags & IFF_ACCEPT_ALL_FRAMES);
+		/*printk("GETRXALL, data: %d  priv_flags: %hx\n",
+		  edata.data, netdev->priv_flags);*/
+		if (copy_to_user(ifr->ifr_data, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SETRXFCS: {
+		struct ethtool_value id;
+		if (copy_from_user(&id, ifr->ifr_data, sizeof(id)))
+			return -EFAULT;
+		spin_lock_bh(&dev->xmit_lock);
+		dev->priv_flags |= IFF_SAVE_FCS;
+		spin_unlock_bh(&dev->xmit_lock);
+		return 0;
+	}
+	case ETHTOOL_GETRXFCS: {
+		struct ethtool_value edata = { ETHTOOL_GSG };
+		edata.data = !!(dev->priv_flags & IFF_SAVE_FCS);
+		/*printk("GETRXFCS, data: %d  priv_flags: %hx\n",
+		  edata.data, netdev->priv_flags);*/
+		if (copy_to_user(ifr->ifr_data, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
 	default:
 		break;
 	}			//switch
--- linux-2.4.22/drivers/net/e100/e100_config.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22.p4s/drivers/net/e100/e100_config.c	2003-11-25 09:05:26.000000000 -0800
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/**** -*-linux-c-*- ***********************************************************
 
   
   Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
@@ -326,42 +326,92 @@
 {
 	spin_lock_bh(&(bdp->config_lock));
 
-	/* if in promiscuous mode, save bad frames */
+	/* Promiscuity */
 	if (enable) {
 
+		if (!(bdp->config[15] & CB_CFIG_PROMISCUOUS)) {
+			bdp->config[15] |= CB_CFIG_PROMISCUOUS;
+			E100_CONFIG(bdp, 15);
+		}
+
+	} else {		/* not in promiscuous mode */
+
+		if (bdp->config[15] & CB_CFIG_PROMISCUOUS) {
+			bdp->config[15] &= ~CB_CFIG_PROMISCUOUS;
+			E100_CONFIG(bdp, 15);
+		}
+	}
+
+	spin_unlock_bh(&(bdp->config_lock));
+}
+
+
+/**
+ * e100_config_promisc - configure promiscuous mode
+ * @bdp: adapter's private data struct
+ * @enable: should we enable this option or not
+ *
+ * This routine will enable or disable receiving all frames to
+ * memory, including bad ones, short ones, and long ones.  It also
+ * causes the Frame Check Sum (FCS) to be transferred to memory.
+ */
+void
+e100_config_rx_all(struct e100_private *bdp, unsigned char enable)
+{
+	spin_lock_bh(&(bdp->config_lock));
+
+	/* Should we save bad frames? */
+        if (enable) {
 		if (!(bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES)) {
 			bdp->config[6] |= CB_CFIG_SAVE_BAD_FRAMES;
 			E100_CONFIG(bdp, 6);
 		}
 
-		if (bdp->config[7] & (u8) BIT_0) {
-			bdp->config[7] &= (u8) (~BIT_0);
+                /* Don't discard short-receive */
+		if (bdp->config[7] & (u8) CB_CFIG_DISC_SHORT_FRAMES) {
+			bdp->config[7] &= (u8) (~CB_CFIG_DISC_SHORT_FRAMES);
 			E100_CONFIG(bdp, 7);
 		}
 
-		if (!(bdp->config[15] & CB_CFIG_PROMISCUOUS)) {
-			bdp->config[15] |= CB_CFIG_PROMISCUOUS;
-			E100_CONFIG(bdp, 15);
+		/* Save over-runs */
+		if (!(bdp->config[6] & CB_CFIG_SAVE_OVERRUNS)) {
+			bdp->config[6] |= CB_CFIG_SAVE_OVERRUNS;
+			E100_CONFIG(bdp, 6);
 		}
 
-	} else {		/* not in promiscuous mode */
-
+		/* Transfer the etherne CRC to memory too */
+		if (!(bdp->config[18] & CB_CFIG_CRC_IN_MEM)) {
+			bdp->config[18] |= CB_CFIG_CRC_IN_MEM;
+			E100_CONFIG(bdp, 18);
+		}
+		
+        }
+        else {
+		/* Don't discard short frames */
 		if (bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES) {
 			bdp->config[6] &= ~CB_CFIG_SAVE_BAD_FRAMES;
 			E100_CONFIG(bdp, 6);
 		}
 
-		if (!(bdp->config[7] & (u8) BIT_0)) {
-			bdp->config[7] |= (u8) (BIT_0);
+		/* Discard short-receive */
+		if (!(bdp->config[7] & (u8) CB_CFIG_DISC_SHORT_FRAMES)) {
+			bdp->config[7] |= (u8) (CB_CFIG_DISC_SHORT_FRAMES);
 			E100_CONFIG(bdp, 7);
 		}
 
-		if (bdp->config[15] & CB_CFIG_PROMISCUOUS) {
-			bdp->config[15] &= ~CB_CFIG_PROMISCUOUS;
-			E100_CONFIG(bdp, 15);
+		/* Discard over-runs */
+		if (bdp->config[6] & CB_CFIG_SAVE_OVERRUNS) {
+			bdp->config[6] &= ~CB_CFIG_SAVE_OVERRUNS;
+			E100_CONFIG(bdp, 6);
 		}
-	}
+
+		/* Don't send CRC (FCS) to memory */
+		if (bdp->config[18] & CB_CFIG_CRC_IN_MEM) {
+			bdp->config[18] &= ~CB_CFIG_CRC_IN_MEM;
+			E100_CONFIG(bdp, 18);
+		}
+        }
 
 	spin_unlock_bh(&(bdp->config_lock));
 }
--- linux-2.4.22/drivers/net/e100/e100_config.h	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22.p4s/drivers/net/e100/e100_config.h	2003-11-24 23:21:53.000000000 -0800
@@ -67,6 +67,7 @@
 #define CB_CFIG_CI_INT             BIT_3	/* Command Complete Interrupt */
 #define CB_CFIG_EXT_TCB_DIS        BIT_4	/* Extended TCB */
 #define CB_CFIG_EXT_STAT_DIS       BIT_5	/* Extended Stats */
+#define CB_CFIG_SAVE_OVERRUNS      BIT_6	/* Save over-run frames if != 0 */
 #define CB_CFIG_SAVE_BAD_FRAMES    BIT_7	/* Save Bad Frames Enabled */
 
 /* byte 7 bit definitions*/
@@ -117,6 +118,8 @@
 #define CB_CFIG_STRIPPING           BIT_0	/* Padding Disabled */
 #define CB_CFIG_PADDING             BIT_1	/* Padding Disabled */
 #define CB_CFIG_CRC_IN_MEM          BIT_2	/* Transfer CRC To Memory */
+/* Only valid for 82558 and 82559.  Must be zero for 82557 */
+#define CB_CFIG_LONG_RX_OK          BIT_3	/* OK to receive Long frames */
 
 /* byte 19 bit definitions*/
 #define CB_CFIG_TX_ADDR_WAKE        BIT_0	/* Address Wakeup */
@@ -142,8 +145,7 @@
 /* byte 22 bit defines */
 #define CB_CFIG_RECEIVE_GAMLA_MODE  BIT_0	/* D102 receive mode */
 #define CB_CFIG_VLAN_DROP_ENABLE    BIT_1	/* vlan stripping */
-
-#define CB_CFIG_LONG_RX_OK	    BIT_3
+/* LONG-RX OK (needed for VLAN) is in byte 18, bit 3, see above */
 
 #define NO_LOOPBACK	0	
 #define MAC_LOOPBACK	0x01
@@ -155,7 +157,8 @@
 extern unsigned char e100_config(struct e100_private *bdp);
 extern void e100_config_fc(struct e100_private *bdp);
 extern void e100_config_promisc(struct e100_private *bdp, unsigned char enable);
+extern void e100_config_rx_all(struct e100_private *bdp, unsigned char enable);
 extern void e100_config_brdcast_dsbl(struct e100_private *bdp);
 extern void e100_config_mulcast_enbl(struct e100_private *bdp,
 				     unsigned char enable);
--- linux-2.4.22/drivers/net/e100/e100.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22.p4s/drivers/net/e100/e100.h	2003-11-24 23:21:53.000000000 -0800
@@ -362,6 +362,7 @@
 #define CB_EL_BIT           BIT_15	/* CB EL Bit */
 #define CB_S_BIT            BIT_14	/* CB Suspend Bit */
 #define CB_I_BIT            BIT_13	/* CB Interrupt Bit */
+#define CB_TX_NC_BIT        BIT_4	        /* If true, do not calculate FCS */
 #define CB_TX_SF_BIT        BIT_3	/* TX CB Flexible Mode */
 #define CB_CMD_MASK         BIT_0_3	/* CB 4-bit CMD Mask */
 #define CB_CID_DEFAULT      (0x1f << 8)	/* CB 5-bit CID (max value) */

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] rx_all e100 patch
  2003-11-25 17:39 [PATCH 3/3] rx_all e100 patch Feldman, Scott
@ 2003-11-25 18:05 ` Ben Greear
  0 siblings, 0 replies; 7+ messages in thread
From: Ben Greear @ 2003-11-25 18:05 UTC (permalink / raw)
  To: Feldman, Scott; +Cc: netdev

Feldman, Scott wrote:
> Ben, I'd rather not touch e100-2.3.x as it's going to be replaced soon
> with e100-3.0.x.  Can you switch over to e100-3.0.x for this
> development?  It's up on the sf.net/projects/e1000 web site.  I think
> you'll find this patch collapses into much fewer lines with the new
> driver.  It has ethtool_ops support also.  I can work on the e100-3.0.x
> patch if you don't want to redo the work.  Let me know.
> 
> -scott
> 


When is 3.0.X destined to hit 2.4?  My personal priority is to
get a patch that works against vanilla 2.4.$CURRENT, so I'll need to follow
it in my own patch set.

However, late-night typos aside, the changes to e100 are quite trivial,
so I imagine you could make the changes in very short time to your
other driver(s).  I have to ship my own patchset for other features
anyway, so one more doesn't hinder me too badly, ie if this takes
a while to become mainline, that's ok.

If we can get the ethtool and flags changes in soon, it will also
be easy for you to do the testing, as ethereal works out-of-the-box.
Dave seems interested, and the flags & ethtool changes are relatively
trivial as well, so hopefully these will go in sometime soon.

PS.  Scott, is there an e1000 document similar to the e100 one available?

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] rx_all e100 patch
  2003-11-25 18:03   ` Ben Greear
@ 2003-11-25 23:41     ` Rask Ingemann Lambertsen
  0 siblings, 0 replies; 7+ messages in thread
From: Rask Ingemann Lambertsen @ 2003-11-25 23:41 UTC (permalink / raw)
  To: Ben Greear; +Cc: 'netdev@oss.sgi.com'

On Tue, Nov 25, 2003 at 10:03:21AM -0800, Ben Greear wrote:
> Rask Ingemann Lambertsen wrote:
> > 
> > I don't understand this part of the code. The 55x docs say that the IP
> > checksum bytes are transferred to memory _following_ the FCS.
> 
> I can't find this in the docs, but it could easily be true.  If you have a page/section
> number, please let me know.

Section 6.4.3.4.1, page 102 if you go by the document page numbers or page
110 if you go by xpdf's page numbers.

> I don't appear to have hardware that takes this
> branch at any rate.  Anyone know which chipset/NIC has this particular rev-id?

The i82559. I wouldn't mind a few comment lines that map Intel's internal
names like D101M, D102 etc. into externally visible part numbers.

> Also, this should invalidate all of the hacks from the e100_D101M_checksum code...

I guess it does if you skb_put() the FCS along with the payload. I haven't
checked that, but I think you're right.

-- 
Regards,
Rask Ingemann Lambertsen

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-11-25 23:41 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-11-25 17:39 [PATCH 3/3] rx_all e100 patch Feldman, Scott
2003-11-25 18:05 ` Ben Greear
  -- strict thread matches above, loose matches on Subject: below --
2003-11-25  7:55 Ben Greear
2003-11-25 15:21 ` Rask Ingemann Lambertsen
2003-11-25 18:03   ` Ben Greear
2003-11-25 23:41     ` Rask Ingemann Lambertsen
2003-11-25 16:56 ` Rask Ingemann Lambertsen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).