diff options
| author | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-04-09 22:24:25 +0000 | 
|---|---|---|
| committer | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-04-09 22:24:25 +0000 | 
| commit | 525ea4a23f7a430b633fb099ed57efca55e4aa5c (patch) | |
| tree | 22b6b18c9136a32e422779fb68abfe27d61edd85 /package/linux | |
| parent | c3ce709da231db36328e7645f46043027d5ba1be (diff) | |
add backport of Jolt's b44 patch to support the bcm47xx
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@608 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/linux')
| -rw-r--r-- | package/linux/kernel-patches/309-b44-bcm47xx-support.patch | 301 | ||||
| -rw-r--r-- | package/linux/linux.config | 37 | 
2 files changed, 337 insertions, 1 deletions
| diff --git a/package/linux/kernel-patches/309-b44-bcm47xx-support.patch b/package/linux/kernel-patches/309-b44-bcm47xx-support.patch new file mode 100644 index 000000000..d803fc96f --- /dev/null +++ b/package/linux/kernel-patches/309-b44-bcm47xx-support.patch @@ -0,0 +1,301 @@ +This patch adds BCM47xx support for the B44 driver. It has been backported +from Florian Schirmer's 2.6 port. + +Imre Kaloz <kaloz@dune.hu> + +diff -Nur linux-2.4.29/drivers/net/b44.c linux-2.4.29-b44/drivers/net/b44.c +--- linux-2.4.29/drivers/net/b44.c	2004-08-08 01:26:05.000000000 +0200 ++++ linux-2.4.29-b44/drivers/net/b44.c	2005-04-09 10:17:33.000000000 +0200 +@@ -1,7 +1,8 @@ + /* b44.c: Broadcom 4400 device driver. +  * +  * Copyright (C) 2002 David S. Miller (davem@redhat.com) +- * Fixed by Pekka Pietikainen (pp@ee.oulu.fi) ++ * Copyright (C) 2004 Pekka Pietikainen (pp@ee.oulu.fi) ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) +  * +  * Distribute under GPL. +  */ +@@ -25,6 +26,16 @@ +  + #include "b44.h" +  ++#include <typedefs.h> ++#include <bcmdevs.h> ++#include <bcmutils.h> ++#include <osl.h> ++#include <bcmutils.h> ++#include <bcmnvram.h> ++#include <sbconfig.h> ++#include <sbchipc.h> ++#include <sflash.h> ++ + #define DRV_MODULE_NAME		"b44" + #define PFX DRV_MODULE_NAME	": " + #define DRV_MODULE_VERSION	"0.93" +@@ -75,7 +86,7 @@ + 	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +  + MODULE_AUTHOR("David S. Miller (davem@redhat.com)"); +-MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver"); ++MODULE_DESCRIPTION("Broadcom 4400/47xx 10/100 PCI ethernet driver"); + MODULE_LICENSE("GPL"); + MODULE_PARM(b44_debug, "i"); + MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value"); +@@ -89,6 +100,8 @@ + 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1, + 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4713, ++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + 	{ }	/* terminate list with empty entry */ + }; +  +@@ -236,6 +249,8 @@ + 	udelay(1); + } +  ++static int b44_4713_instance; ++ + static int ssb_core_unit(struct b44 *bp) + { + #if 0 +@@ -258,6 +273,9 @@ + 		break; + 	}; + #endif ++	if (bp->pdev->device == PCI_DEVICE_ID_BCM4713) ++		return b44_4713_instance++; ++	else + 	return 0; + } +  +@@ -267,6 +285,28 @@ + 		== SBTMSLOW_CLOCK); + } +  ++static void __b44_cam_read(struct b44 *bp, unsigned char *data, int index) ++{ ++	u32 val; ++ ++	bw32(B44_CAM_CTRL, (CAM_CTRL_READ | ++			    (index << CAM_CTRL_INDEX_SHIFT))); ++ ++	b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1); ++ ++	val = br32(B44_CAM_DATA_LO); ++ ++	data[2] = (val >> 24) & 0xFF; ++	data[3] = (val >> 16) & 0xFF; ++	data[4] = (val >> 8) & 0xFF; ++	data[5] = (val >> 0) & 0xFF; ++ ++	val = br32(B44_CAM_DATA_HI); ++ ++	data[0] = (val >> 8) & 0xFF; ++	data[1] = (val >> 0) & 0xFF; ++} ++ + static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index) + { + 	u32 val; +@@ -307,6 +347,9 @@ + { + 	int err; +  ++	if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) ++		return 0; ++ + 	bw32(B44_EMAC_ISTAT, EMAC_INT_MII); + 	bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START | + 			     (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) | +@@ -321,6 +364,9 @@ +  + static int b44_writephy(struct b44 *bp, int reg, u32 val) + { ++	if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) ++		return 0; ++ + 	bw32(B44_EMAC_ISTAT, EMAC_INT_MII); + 	bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START | + 			     (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) | +@@ -336,6 +382,9 @@ + 	u32 val; + 	int err; +  ++	if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) ++		return 0; ++ + 	err = b44_writephy(bp, MII_BMCR, BMCR_RESET); + 	if (err) + 		return err; +@@ -406,6 +455,9 @@ + 	u32 val; + 	int err; +  ++	if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) ++		return 0; ++ + 	if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0) + 		goto out; + 	if ((err = b44_writephy(bp, B44_MII_ALEDCTRL, +@@ -498,6 +550,19 @@ + { + 	u32 bmsr, aux; +  ++	if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) { ++		bp->flags |= B44_FLAG_100_BASE_T; ++		bp->flags |= B44_FLAG_FULL_DUPLEX; ++		if (!netif_carrier_ok(bp->dev)) { ++			u32 val = br32(B44_TX_CTRL); ++			val |= TX_CTRL_DUPLEX; ++			bw32(B44_TX_CTRL, val); ++			netif_carrier_on(bp->dev); ++			b44_link_report(bp); ++		} ++		return; ++	} ++ + 	if (!b44_readphy(bp, MII_BMSR, &bmsr) && + 	    !b44_readphy(bp, B44_MII_AUXCTRL, &aux) && + 	    (bmsr != 0xffff)) { +@@ -1092,6 +1157,8 @@ + /* bp->lock is held. */ + static void b44_chip_reset(struct b44 *bp) + { ++	unsigned int sb_clock; ++ + 	if (ssb_is_core_up(bp)) { + 		bw32(B44_RCV_LAZY, 0); + 		bw32(B44_ENET_CTRL, ENET_CTRL_DISABLE); +@@ -1105,9 +1172,10 @@ + 		bw32(B44_DMARX_CTRL, 0); + 		bp->rx_prod = bp->rx_cons = 0; + 	} else { +-		ssb_pci_setup(bp, (bp->core_unit == 0 ? +-				   SBINTVEC_ENET0 : +-				   SBINTVEC_ENET1)); ++		if (bp->pdev->device != PCI_DEVICE_ID_BCM4713) ++			ssb_pci_setup(bp, (bp->core_unit == 0 ? ++				   	SBINTVEC_ENET0 : ++				   	SBINTVEC_ENET1)); + 	} +  + 	ssb_core_reset(bp); +@@ -1115,6 +1183,11 @@ + 	b44_clear_stats(bp); +  + 	/* Make PHY accessible. */ ++	if (bp->pdev->device == PCI_DEVICE_ID_BCM4713) ++		sb_clock = 100000000; /* 100 MHz */ ++	else ++		sb_clock = 62500000; /* 62.5 MHz */ ++ + 	bw32(B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE | + 			     (0x0d & MDIO_CTRL_MAXF_MASK))); + 	br32(B44_MDIO_CTRL); +@@ -1669,20 +1742,42 @@ + { + 	u8 eeprom[128]; + 	int err; ++	unsigned long flags; +  +-	err = b44_read_eeprom(bp, &eeprom[0]); +-	if (err) +-		goto out; +- +-	bp->dev->dev_addr[0] = eeprom[79]; +-	bp->dev->dev_addr[1] = eeprom[78]; +-	bp->dev->dev_addr[2] = eeprom[81]; +-	bp->dev->dev_addr[3] = eeprom[80]; +-	bp->dev->dev_addr[4] = eeprom[83]; +-	bp->dev->dev_addr[5] = eeprom[82]; +- +-	bp->phy_addr = eeprom[90] & 0x1f; +-	bp->mdc_port = (eeprom[90] >> 14) & 0x1; ++	if (bp->pdev->device == PCI_DEVICE_ID_BCM4713) { ++		/* ++		 * BCM47xx boards don't have a EEPROM. The MAC is stored in ++		 * a NVRAM area somewhere in the flash memory. As we don't ++		 * know the location and/or the format of the NVRAM area ++		 * here, we simply rely on the bootloader to write the ++		 * MAC into the CAM. ++		 */ ++		spin_lock_irqsave(&bp->lock, flags); ++		__b44_cam_read(bp, bp->dev->dev_addr, 0); ++		spin_unlock_irqrestore(&bp->lock, flags); ++ ++		/* ++		 * BCM47xx boards don't have a PHY. Usually there is a switch ++		 * chip with multiple PHYs connected to the PHY port. ++		 */ ++		bp->phy_addr = B44_PHY_ADDR_NO_PHY; ++		bp->dma_offset = 0; ++	} else { ++		err = b44_read_eeprom(bp, &eeprom[0]); ++		if (err) ++			return err; ++ ++		bp->dev->dev_addr[0] = eeprom[79]; ++		bp->dev->dev_addr[1] = eeprom[78]; ++		bp->dev->dev_addr[2] = eeprom[81]; ++		bp->dev->dev_addr[3] = eeprom[80]; ++		bp->dev->dev_addr[4] = eeprom[83]; ++		bp->dev->dev_addr[5] = eeprom[82]; ++ ++		bp->phy_addr = eeprom[90] & 0x1f; ++		bp->dma_offset = SB_PCI_DMA; ++		bp->mdc_port = (eeprom[90] >> 14) & 0x1; ++	} +  + 	/* With this, plus the rx_header prepended to the data by the + 	 * hardware, we'll land the ethernet header on a 2-byte boundary. +@@ -1692,13 +1787,12 @@ + 	bp->imask = IMASK_DEF; +  + 	bp->core_unit = ssb_core_unit(bp); +-	bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0); +  + 	/* XXX - really required?  + 	   bp->flags |= B44_FLAG_BUGGY_TXPTR; +          */ +-out: +-	return err; ++ ++	return 0; + } +  + static int __devinit b44_init_one(struct pci_dev *pdev, +@@ -1819,7 +1913,8 @@ +  + 	pci_save_state(bp->pdev, bp->pci_cfg_state); +  +-	printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name); ++	printk(KERN_INFO "%s: Broadcom %s 10/100BaseT Ethernet ", dev->name, ++		(pdev->device == PCI_DEVICE_ID_BCM4713) ? "47xx" : "4400"); + 	for (i = 0; i < 6; i++) + 		printk("%2.2x%c", dev->dev_addr[i], + 		       i == 5 ? '\n' : ':'); +diff -Nur linux-2.4.29/drivers/net/b44.h linux-2.4.29-b44/drivers/net/b44.h +--- linux-2.4.29/drivers/net/b44.h	2003-08-25 13:44:42.000000000 +0200 ++++ linux-2.4.29-b44/drivers/net/b44.h	2005-04-09 10:13:55.000000000 +0200 +@@ -461,6 +461,8 @@ + }; +  + #define B44_MCAST_TABLE_SIZE	32 ++#define B44_PHY_ADDR_NO_PHY	30 ++#define B44_MDC_RATIO		5000000 +  + /* SW copy of device statistics, kept up to date by periodic timer +  * which probes HW values.  Must have same relative layout as HW +diff -Nur linux-2.4.29/include/linux/pci_ids.h linux-2.4.29-b44/include/linux/pci_ids.h +--- linux-2.4.29/include/linux/pci_ids.h	2005-01-19 15:10:12.000000000 +0100 ++++ linux-2.4.29-b44/include/linux/pci_ids.h	2005-04-09 10:13:55.000000000 +0200 +@@ -1735,6 +1735,7 @@ + #define PCI_DEVICE_ID_TIGON3_5901_2	0x170e + #define PCI_DEVICE_ID_BCM4401		0x4401 + #define PCI_DEVICE_ID_BCM4401B0		0x4402 ++#define PCI_DEVICE_ID_BCM4713		0x4713 +  + #define PCI_VENDOR_ID_ENE		0x1524 + #define PCI_DEVICE_ID_ENE_1211		0x1211 diff --git a/package/linux/linux.config b/package/linux/linux.config index 91dabe4e7..d4074ee90 100644 --- a/package/linux/linux.config +++ b/package/linux/linux.config @@ -660,7 +660,42 @@ CONFIG_NET_ETHERNET=y  # CONFIG_NET_VENDOR_RACAL is not set  # CONFIG_HP100 is not set  # CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +CONFIG_B44=m +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_FORCEDETH is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 is not set  # CONFIG_NET_POCKET is not set  # | 
