1 --- linux-2.4.30/drivers/net/b44.c 2004-08-08 01:26:05.000000000 +0200
2 +++ openwrt/build_mipsel/linux-2.4.30/drivers/net/b44.c 2005-05-01 20:10:19.193354917 +0200
4 /* b44.c: Broadcom 4400 device driver.
6 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
7 - * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
8 + * Copyright (C) 2004 Pekka Pietikainen (pp@ee.oulu.fi)
9 + * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
11 * Distribute under GPL.
17 +#include <typedefs.h>
19 +#include <bcmutils.h>
21 +#include <bcmutils.h>
22 +#include <bcmnvram.h>
23 +#include <sbconfig.h>
27 #define DRV_MODULE_NAME "b44"
28 #define PFX DRV_MODULE_NAME ": "
29 #define DRV_MODULE_VERSION "0.93"
31 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
33 MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
34 -MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
35 +MODULE_DESCRIPTION("Broadcom 4400/47xx 10/100 PCI ethernet driver");
36 MODULE_LICENSE("GPL");
37 MODULE_PARM(b44_debug, "i");
38 MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
40 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
41 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1,
42 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
43 + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4713,
44 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
45 { } /* terminate list with empty entry */
52 +static int b44_4713_instance;
54 static int ssb_core_unit(struct b44 *bp)
61 + if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
62 + return b44_4713_instance++;
71 +static void __b44_cam_read(struct b44 *bp, unsigned char *data, int index)
75 + bw32(B44_CAM_CTRL, (CAM_CTRL_READ |
76 + (index << CAM_CTRL_INDEX_SHIFT)));
78 + b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
80 + val = br32(B44_CAM_DATA_LO);
82 + data[2] = (val >> 24) & 0xFF;
83 + data[3] = (val >> 16) & 0xFF;
84 + data[4] = (val >> 8) & 0xFF;
85 + data[5] = (val >> 0) & 0xFF;
87 + val = br32(B44_CAM_DATA_HI);
89 + data[0] = (val >> 8) & 0xFF;
90 + data[1] = (val >> 0) & 0xFF;
93 static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
100 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
103 bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
104 bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
105 (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
108 static int b44_writephy(struct b44 *bp, int reg, u32 val)
110 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
113 bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
114 bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
115 (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) |
120 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
123 err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
130 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
133 if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
135 if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
140 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
141 + bp->flags |= B44_FLAG_100_BASE_T;
142 + bp->flags |= B44_FLAG_FULL_DUPLEX;
143 + if (!netif_carrier_ok(bp->dev)) {
144 + u32 val = br32(B44_TX_CTRL);
145 + val |= TX_CTRL_DUPLEX;
146 + bw32(B44_TX_CTRL, val);
147 + netif_carrier_on(bp->dev);
148 + b44_link_report(bp);
153 if (!b44_readphy(bp, MII_BMSR, &bmsr) &&
154 !b44_readphy(bp, B44_MII_AUXCTRL, &aux) &&
156 @@ -1092,6 +1157,8 @@
157 /* bp->lock is held. */
158 static void b44_chip_reset(struct b44 *bp)
160 + unsigned int sb_clock;
162 if (ssb_is_core_up(bp)) {
163 bw32(B44_RCV_LAZY, 0);
164 bw32(B44_ENET_CTRL, ENET_CTRL_DISABLE);
165 @@ -1105,9 +1172,10 @@
166 bw32(B44_DMARX_CTRL, 0);
167 bp->rx_prod = bp->rx_cons = 0;
169 - ssb_pci_setup(bp, (bp->core_unit == 0 ?
172 + /*if (bp->pdev->device != PCI_DEVICE_ID_BCM4713)*/
173 + ssb_pci_setup(bp, (bp->core_unit == 0 ?
179 @@ -1115,6 +1183,11 @@
182 /* Make PHY accessible. */
183 + if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
184 + sb_clock = 100000000; /* 100 MHz */
186 + sb_clock = 62500000; /* 62.5 MHz */
188 bw32(B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
189 (0x0d & MDIO_CTRL_MAXF_MASK)));
191 @@ -1669,20 +1742,42 @@
195 + unsigned long flags;
197 - err = b44_read_eeprom(bp, &eeprom[0]);
201 - bp->dev->dev_addr[0] = eeprom[79];
202 - bp->dev->dev_addr[1] = eeprom[78];
203 - bp->dev->dev_addr[2] = eeprom[81];
204 - bp->dev->dev_addr[3] = eeprom[80];
205 - bp->dev->dev_addr[4] = eeprom[83];
206 - bp->dev->dev_addr[5] = eeprom[82];
208 - bp->phy_addr = eeprom[90] & 0x1f;
209 - bp->mdc_port = (eeprom[90] >> 14) & 0x1;
210 + if (bp->pdev->device == PCI_DEVICE_ID_BCM4713) {
212 + * BCM47xx boards don't have a EEPROM. The MAC is stored in
213 + * a NVRAM area somewhere in the flash memory. As we don't
214 + * know the location and/or the format of the NVRAM area
215 + * here, we simply rely on the bootloader to write the
216 + * MAC into the CAM.
218 + spin_lock_irqsave(&bp->lock, flags);
219 + __b44_cam_read(bp, bp->dev->dev_addr, 0);
220 + spin_unlock_irqrestore(&bp->lock, flags);
223 + * BCM47xx boards don't have a PHY. Usually there is a switch
224 + * chip with multiple PHYs connected to the PHY port.
226 + bp->phy_addr = B44_PHY_ADDR_NO_PHY;
227 + bp->dma_offset = 0;
229 + err = b44_read_eeprom(bp, &eeprom[0]);
233 + bp->dev->dev_addr[0] = eeprom[79];
234 + bp->dev->dev_addr[1] = eeprom[78];
235 + bp->dev->dev_addr[2] = eeprom[81];
236 + bp->dev->dev_addr[3] = eeprom[80];
237 + bp->dev->dev_addr[4] = eeprom[83];
238 + bp->dev->dev_addr[5] = eeprom[82];
240 + bp->phy_addr = eeprom[90] & 0x1f;
241 + bp->dma_offset = SB_PCI_DMA;
242 + bp->mdc_port = (eeprom[90] >> 14) & 0x1;
245 /* With this, plus the rx_header prepended to the data by the
246 * hardware, we'll land the ethernet header on a 2-byte boundary.
247 @@ -1692,13 +1787,12 @@
248 bp->imask = IMASK_DEF;
250 bp->core_unit = ssb_core_unit(bp);
251 - bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0);
253 /* XXX - really required?
254 bp->flags |= B44_FLAG_BUGGY_TXPTR;
262 static int __devinit b44_init_one(struct pci_dev *pdev,
263 @@ -1819,7 +1913,8 @@
265 pci_save_state(bp->pdev, bp->pci_cfg_state);
267 - printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
268 + printk(KERN_INFO "%s: Broadcom %s 10/100BaseT Ethernet ", dev->name,
269 + (pdev->device == PCI_DEVICE_ID_BCM4713) ? "47xx" : "4400");
270 for (i = 0; i < 6; i++)
271 printk("%2.2x%c", dev->dev_addr[i],
272 i == 5 ? '\n' : ':');