[PATCH] netdrv: fix b44 loading after bcm4400

Linux Kernel Mailing List <[email protected]> Fri, 12 May 2006 18:59:47 GMT
Newsgroups gmane.linux.kernel.commits.2-4
Message-ID <[email protected]>
commit 66cd21fae5844a8f575b05e143e5ba77905d9613
tree 90997f0e561587c3642db473e141ea2175979054
parent 8511aca94801a49201cb31e7ab6a4d2373504411
author Willy TARREAU <willy@pcw.(none)> Sun, 07 May 2006 23:33:09 +0200
committer Willy TARREAU <willy@pcw.(none)> Sun, 07 May 2006 23:33:09 +0200

[PATCH] netdrv: fix b44 loading after bcm4400

From Pekka Pietikain :

This patch makes the b44-after-bcm4400 scenario work for me. What
was happening is that the broadcom driver sets a "power off MAC"
bit, and we didn't remove that when initializing the chip. Also
added some (a bit ugly, I know  ) logic to clear up the address
filter stuff, which is what recent broadcom drivers do...

This fix was merged in 2.6 late in 2004, but did not receive any
echo for 2.4. At least it made the b44 driver usable on an Asus
Pundit for me.

Signed-off-by: Willy Tarreau <[email protected]>

- Willy

 drivers/net/b44.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 1c87a14..0c489a9 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1183,8 +1183,9 @@ static void b44_init_hw(struct b44 *bp)
 	b44_chip_reset(bp);
 	b44_phy_reset(bp);
 	b44_setup_phy(bp);
-	val = br32(B44_MAC_CTRL);
-	bw32(B44_MAC_CTRL, val | MAC_CTRL_CRC32_ENAB);
+
+	/* Enable CRC32, set proper LED modes and power on PHY */
+	bw32(B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL);
 	bw32(B44_RCV_LAZY, (1 << RCV_LAZY_FC_SHIFT));
 
 	/* This sets the MAC address too.  */
@@ -1324,7 +1325,7 @@ static struct net_device_stats *b44_get_
 	return nstat;
 }
 
-static void __b44_load_mcast(struct b44 *bp, struct net_device *dev)
+static int __b44_load_mcast(struct b44 *bp, struct net_device *dev)
 {
 	struct dev_mc_list *mclist;
 	int i, num_ents;
@@ -1334,12 +1335,15 @@ static void __b44_load_mcast(struct b44 
 	for (i = 0; mclist && i < num_ents; i++, mclist = mclist->next) {
 		__b44_cam_write(bp, mclist->dmi_addr, i + 1);
 	}
+	return i+1;
 }
 
 static void __b44_set_rx_mode(struct net_device *dev)
 {
 	struct b44 *bp = dev->priv;
 	u32 val;
+	int i=0;
+	unsigned char zero[6] = {0,0,0,0,0,0};
 
 	val = br32(B44_RXCONFIG);
 	val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
@@ -1352,8 +1356,11 @@ static void __b44_set_rx_mode(struct net
 		if (dev->flags & IFF_ALLMULTI)
 			val |= RXCONFIG_ALLMULTI;
 		else
-			__b44_load_mcast(bp, dev);
-
+			i=__b44_load_mcast(bp, dev);
+		
+		for(;i<64;i++) {
+			__b44_cam_write(bp, zero, i);			
+		}
 		bw32(B44_RXCONFIG, val);
         	val = br32(B44_CAM_CTRL);
 	        bw32(B44_CAM_CTRL, val | CAM_CTRL_ENABLE);