[parisc-linux] PCI Intel EtherExpressPro100 strangeness on C200 machine.

Grant Grundler grundler@dsl2.external.hp.com
Mon, 26 Aug 2002 12:14:54 -0600


Andreas Seltenreich wrote:
> just append " || defined(__hppa__)" to line 47 of drivers/net/eepro100.c
> I got mine working that way.

For some definition of "working".
That #ifdef "forces" the RX copy *most* of the time.
If the dev_alloc_skb() call fails , the "broken" code path is taken anyway.

The code needs to differentiate architectures that *could* (but it's not
efficient) avoid the copy from architectures that *must* copy.

Patch below assumes the archs listed in the ifdef *must* copy.
If the dev_alloc_skb() fails, we drop the packet and update stats.
Not sure if I'm doing the right thing in the failure case though...

grant


Index: drivers/net/eepro100.c
===================================================================
RCS file: /var/cvs/linux/drivers/net/eepro100.c,v
retrieving revision 1.17
diff -u -p -r1.17 eepro100.c
--- drivers/net/eepro100.c	4 Aug 2002 22:58:29 -0000	1.17
+++ drivers/net/eepro100.c	26 Aug 2002 17:25:58 -0000
@@ -1,4 +1,3 @@
-/* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. */
 /*
    NOTICE: For use with late 2.3 kernels only.
    May not compile for kernels 2.3.43-47.
@@ -43,11 +42,13 @@ static int rxdmacount /* = 0 */;
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
    Lower values use more memory, but are faster. */
+static int rx_copybreak = 200;
+
 #if defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
-    defined(__arm__)
-static int rx_copybreak = 1518;
+    defined(__arm__) || defined(__hppa__)
+#define RX_COPY(x)		1
 #else
-static int rx_copybreak = 200;
+#define RX_COPY(x) (x < rx_copybreak)
 #endif
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
@@ -1760,10 +1761,17 @@ speedo_rx(struct net_device *dev)
 		} else {
 			struct sk_buff *skb;
 
-			/* Check if the packet is long enough to just accept without
-			   copying to a properly sized skbuff. */
-			if (pkt_len < rx_copybreak
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != 0) {
+			/* Check if the packet is long enough to just accept
+			 * without copying to a properly sized skbuff.
+			 */
+			if (RX_COPY(pkt_len)) {
+				skb = dev_alloc_skb(pkt_len + 2);
+				if (!skb) {
+					printk(KERN_ERR "%s: dropping packet,"
+						"no user space buffer!",
+						status);
+					goto update_stats;
+				}
 				skb->dev = dev;
 				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 				/* 'skb_put()' points to the start of sk_buff data area. */
@@ -1797,6 +1805,7 @@ speedo_rx(struct net_device *dev)
 			sp->stats.rx_packets++;
 			sp->stats.rx_bytes += pkt_len;
 		}
+update_stats:
 		entry = (++sp->cur_rx) % RX_RING_SIZE;
 		sp->rx_ring_state &= ~RrPostponed;
 		/* Refill the recently taken buffers.