netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ben Greear <greearb@candelatech.com>
To: "'netdev@oss.sgi.com'" <netdev@oss.sgi.com>
Subject: [PATCH 3/3] rx_all e100 patch
Date: Mon, 24 Nov 2003 23:55:26 -0800	[thread overview]
Message-ID: <3FC30AEE.7000005@candelatech.com> (raw)

[-- 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) */

             reply	other threads:[~2003-11-25  7:55 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-11-25  7:55 Ben Greear [this message]
2003-11-25 15:21 ` [PATCH 3/3] rx_all e100 patch 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
  -- strict thread matches above, loose matches on Subject: below --
2003-11-25 17:39 Feldman, Scott
2003-11-25 18:05 ` Ben Greear

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3FC30AEE.7000005@candelatech.com \
    --to=greearb@candelatech.com \
    --cc=netdev@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).