public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Pekka Pietikainen <pp@netppl.fi>
To: "David S. Miller" <davem@redhat.com>
Cc: linux-kernel@vger.kernel.org, jgarzik@pobox.com
Subject: Re: REQ: BCM4400 network driver for 2.4.22
Date: Mon, 14 Jul 2003 23:12:09 +0300	[thread overview]
Message-ID: <20030714201209.GA12841@netppl.fi> (raw)
In-Reply-To: <20030711202426.5b0e475b.davem@redhat.com>

On Fri, Jul 11, 2003 at 08:24:26PM -0700, David S. Miller wrote:
> Please be kind to us underprivileged big-endian users
> out here :-)
Whoops :-)
> You can't modify skb->data without doing something sane
> with skb->len and friends too, this is why we have skb_*()
> interfaces to do these kinds of operations which do all
> the necessary book-keeping :-)
Indeed, it did seem a bit suspicious when I did it ;) 

I've attached my current version, which fixes all the bugs I've noticed
in the previous one (including "it doesn't work unless I run tcpdump" and
"it crashes randomly"), tested with rawhide-2.4 and 2.6.0-test1. I adjusted
the b44_poll locking a bit in this version and have a almost-as-bad-a-feeling
about it as I did with the skb handling. However, it works my uniprocessor
box and doesn't spew out a screenful of backtraces for every 
packet on 2.6.0-test1 so for some definition of "improvement" it
is one... Might easily blow up on SMP, but I have no way 
of testing that ;) 

--- /stuff/src/linux-2.6.0-test1/drivers/net/b44.c.orig	2003-07-14 06:33:45.000000000 +0300
+++ /stuff/src/linux-2.6.0-test1/drivers/net/b44.c	2003-07-14 22:45:18.146899367 +0300
@@ -1,6 +1,7 @@
 /* b44.c: Broadcom 4400 device driver.
  *
  * Copyright (C) 2002 David S. Miller (davem@redhat.com)
+ * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
  */
 
 #include <linux/kernel.h>
@@ -14,6 +15,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/version.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -23,8 +25,8 @@
 
 #define DRV_MODULE_NAME		"b44"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.6"
-#define DRV_MODULE_RELDATE	"Nov 11, 2002"
+#define DRV_MODULE_VERSION	"0.6-pp2"
+#define DRV_MODULE_RELDATE	"Jul 14, 2003"
 
 #define B44_DEF_MSG_ENABLE	  \
 	(NETIF_MSG_DRV		| \
@@ -78,6 +80,15 @@
 
 static int b44_debug = -1;	/* -1 == use B44_DEF_MSG_ENABLE as value */
 
+#ifndef PCI_DEVICE_ID_BCM4401
+#define PCI_DEVICE_ID_BCM4401      0x4401
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define IRQ_RETVAL(x) 
+#define irqreturn_t void
+#endif
+
 static struct pci_device_id b44_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
@@ -259,7 +270,7 @@
 		== SBTMSLOW_CLOCK);
 }
 
-static void __b44_cam_write(struct b44 *bp, char *data, int index)
+static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
 {
 	u32 val;
 
@@ -521,7 +532,7 @@
 			/* Link now up */
 			netif_carrier_on(bp->dev);
 			b44_link_report(bp);
-		} else if (netif_carrier_ok(bp->dev)) {
+		} else if (netif_carrier_ok(bp->dev) && !(bmsr & BMSR_LSTATUS)) {
 			/* Link now down */
 			netif_carrier_off(bp->dev);
 			b44_link_report(bp);
@@ -650,8 +661,7 @@
 	src_map = &bp->rx_buffers[src_idx];
 
 	dest_map->skb = src_map->skb;
-	rh = (struct rx_header *)
-		(src_map->skb->data - bp->rx_offset);
+	rh = (struct rx_header *) src_map->skb->data;
 	rh->len = 0;
 	rh->flags = 0;
 	pci_unmap_addr_set(dest_map, mapping,
@@ -660,9 +670,12 @@
 	ctrl = src_desc->ctrl;
 	if (dest_idx == (B44_RX_RING_SIZE - 1))
 		ctrl |= cpu_to_le32(DESC_CTRL_EOT);
+	else
+		ctrl &= cpu_to_le32(~DESC_CTRL_EOT);
 
 	dest_desc->ctrl = ctrl;
 	dest_desc->addr = src_desc->addr;
+	src_map->skb = NULL;
 }
 
 static int b44_rx(struct b44 *bp, int budget)
@@ -685,7 +698,7 @@
 		pci_dma_sync_single(bp->pdev, map,
 				    RX_PKT_BUF_SZ,
 				    PCI_DMA_FROMDEVICE);
-		rh = (struct rx_header *) (skb->data - bp->rx_offset);
+		rh = (struct rx_header *) skb->data;
 		len = cpu_to_le16(rh->len);
 		if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) ||
 		    (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) {
@@ -718,7 +731,9 @@
 				goto drop_it;
 			pci_unmap_single(bp->pdev, map,
 					 skb_size, PCI_DMA_FROMDEVICE);
-			skb_put(skb, len);
+			/* Leave out rx_header */
+                	skb_put(skb, len+bp->rx_offset);
+            	        skb_pull(skb,bp->rx_offset);
 		} else {
 			struct sk_buff *copy_skb;
 
@@ -730,8 +745,8 @@
 			copy_skb->dev = bp->dev;
 			skb_reserve(copy_skb, 2);
 			skb_put(copy_skb, len);
-			/* DMA sync done above */
-			memcpy(copy_skb->data, skb->data, len);
+			/* DMA sync done above, copy just the actual packet */
+			memcpy(copy_skb->data, skb->data+bp->rx_offset, len);
 
 			skb = copy_skb;
 		}
@@ -748,6 +763,7 @@
 	}
 
 	bp->rx_cons = cons;
+	bw32(B44_DMARX_PTR, cons * sizeof(struct dma_desc));
 
 	return received;
 }
@@ -764,6 +780,7 @@
 		b44_tx(bp);
 		/* spin_unlock(&bp->tx_lock); */
 	}
+	spin_unlock_irq(&bp->lock);
 
 	done = 1;
 	if (bp->istat & ISTAT_RX) {
@@ -783,10 +800,12 @@
 	}
 
 	if (bp->istat & ISTAT_ERRORS) {
+		spin_lock_irq(&bp->lock);
 		b44_halt(bp);
 		b44_init_rings(bp);
 		b44_init_hw(bp);
 		netif_wake_queue(bp->dev);
+		spin_unlock_irq(&bp->lock);
 		done = 1;
 	}
 
@@ -794,7 +813,6 @@
 		netif_rx_complete(netdev);
 		b44_enable_ints(bp);
 	}
-	spin_unlock_irq(&bp->lock);
 
 	return (done ? 0 : 1);
 }
@@ -885,7 +903,7 @@
 		ctrl |= DESC_CTRL_EOT;
 
 	bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl);
-	bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping);
+	bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
 
 	entry = NEXT_TX(entry);
 
@@ -1173,8 +1191,8 @@
 	__b44_set_rx_mode(bp->dev);
 
 	/* MTU + eth header + possible VLAN tag + struct rx_header */
-	bw32(B44_RXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + 24);
-	bw32(B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + 24);
+	bw32(B44_RXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
+	bw32(B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
 
 	bw32(B44_TX_WMARK, 56); /* XXX magic */
 	bw32(B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
@@ -1184,6 +1202,7 @@
 	bw32(B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
 
 	bw32(B44_DMARX_PTR, bp->rx_pending);
+	bp->rx_prod = bp->rx_pending;	
 
 	bw32(B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
 
@@ -1345,6 +1364,8 @@
 			__b44_load_mcast(bp, dev);
 
 		bw32(B44_RXCONFIG, val);
+        	val = br32(B44_CAM_CTRL);
+	        bw32(B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
 	}
 }
 
@@ -1678,8 +1699,9 @@
 	bp->core_unit = ssb_core_unit(bp);
 	bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0);
 
-	bp->flags |= B44_FLAG_BUGGY_TXPTR;
-
+	/* XXX - really required? 
+	   bp->flags |= B44_FLAG_BUGGY_TXPTR;
+         */
 out:
 	return err;
 }
--- /stuff/src/linux-2.6.0-test1/drivers/net/b44.h~	2003-07-09 18:28:09.000000000 +0300
+++ /stuff/src/linux-2.6.0-test1/drivers/net/b44.h	2003-07-09 18:28:15.000000000 +0300
@@ -142,7 +142,7 @@
 #define  MDIO_OP_READ		2
 #define  MDIO_DATA_SB_MASK	0xc0000000 /* Start Bits */
 #define  MDIO_DATA_SB_SHIFT	30
-#define  MDIO_DATA_SB_START	0x10000000 /* Start Of Frame */
+#define  MDIO_DATA_SB_START	0x40000000 /* Start Of Frame */
 #define B44_EMAC_IMASK	0x0418UL /* EMAC Interrupt Mask */
 #define B44_EMAC_ISTAT	0x041CUL /* EMAC Interrupt Status */
 #define  EMAC_INT_MII		0x00000001 /* MII MDIO Interrupt */

-- 
Pekka Pietikainen

      reply	other threads:[~2003-07-14 20:00 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-09 21:34 REQ: BCM4400 network driver for 2.4.22 Bas Mevissen
2003-07-09 22:05 ` Jeff Garzik
2003-07-11 16:33   ` Pekka Pietikainen
2003-07-11 16:58     ` Jeff Garzik
2003-07-11 20:04     ` Pekka Pietikainen
2003-07-12  3:24     ` David S. Miller
2003-07-14 20:12       ` Pekka Pietikainen [this message]

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=20030714201209.GA12841@netppl.fi \
    --to=pp@netppl.fi \
    --cc=davem@redhat.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-kernel@vger.kernel.org \
    /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