update oleg's b44 patch to initialize switch access on driver load
[openwrt.git] / package / linux / kernel-patches / 309-drivers_net_b44_c.patch
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
3 @@ -1,7 +1,8 @@
4 /* b44.c: Broadcom 4400 device driver.
5 *
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)
10 *
11 * Distribute under GPL.
12 */
13 @@ -25,6 +26,16 @@
14
15 #include "b44.h"
16
17 +#include <typedefs.h>
18 +#include <bcmdevs.h>
19 +#include <bcmutils.h>
20 +#include <osl.h>
21 +#include <bcmutils.h>
22 +#include <bcmnvram.h>
23 +#include <sbconfig.h>
24 +#include <sbchipc.h>
25 +#include <sflash.h>
26 +
27 #define DRV_MODULE_NAME "b44"
28 #define PFX DRV_MODULE_NAME ": "
29 #define DRV_MODULE_VERSION "0.93"
30 @@ -75,7 +86,7 @@
31 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
32
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");
39 @@ -89,6 +100,8 @@
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 */
46 };
47
48 @@ -236,6 +249,8 @@
49 udelay(1);
50 }
51
52 +static int b44_4713_instance;
53 +
54 static int ssb_core_unit(struct b44 *bp)
55 {
56 #if 0
57 @@ -258,6 +273,9 @@
58 break;
59 };
60 #endif
61 + if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
62 + return b44_4713_instance++;
63 + else
64 return 0;
65 }
66
67 @@ -267,6 +285,28 @@
68 == SBTMSLOW_CLOCK);
69 }
70
71 +static void __b44_cam_read(struct b44 *bp, unsigned char *data, int index)
72 +{
73 + u32 val;
74 +
75 + bw32(B44_CAM_CTRL, (CAM_CTRL_READ |
76 + (index << CAM_CTRL_INDEX_SHIFT)));
77 +
78 + b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
79 +
80 + val = br32(B44_CAM_DATA_LO);
81 +
82 + data[2] = (val >> 24) & 0xFF;
83 + data[3] = (val >> 16) & 0xFF;
84 + data[4] = (val >> 8) & 0xFF;
85 + data[5] = (val >> 0) & 0xFF;
86 +
87 + val = br32(B44_CAM_DATA_HI);
88 +
89 + data[0] = (val >> 8) & 0xFF;
90 + data[1] = (val >> 0) & 0xFF;
91 +}
92 +
93 static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
94 {
95 u32 val;
96 @@ -307,6 +347,9 @@
97 {
98 int err;
99
100 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
101 + return 0;
102 +
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) |
106 @@ -321,6 +364,9 @@
107
108 static int b44_writephy(struct b44 *bp, int reg, u32 val)
109 {
110 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
111 + return 0;
112 +
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) |
116 @@ -336,6 +382,9 @@
117 u32 val;
118 int err;
119
120 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
121 + return 0;
122 +
123 err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
124 if (err)
125 return err;
126 @@ -406,6 +455,9 @@
127 u32 val;
128 int err;
129
130 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
131 + return 0;
132 +
133 if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
134 goto out;
135 if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
136 @@ -498,6 +550,19 @@
137 {
138 u32 bmsr, aux;
139
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);
149 + }
150 + return;
151 + }
152 +
153 if (!b44_readphy(bp, MII_BMSR, &bmsr) &&
154 !b44_readphy(bp, B44_MII_AUXCTRL, &aux) &&
155 (bmsr != 0xffff)) {
156 @@ -1092,6 +1157,8 @@
157 /* bp->lock is held. */
158 static void b44_chip_reset(struct b44 *bp)
159 {
160 + unsigned int sb_clock;
161 +
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;
168 } else {
169 - ssb_pci_setup(bp, (bp->core_unit == 0 ?
170 - SBINTVEC_ENET0 :
171 - SBINTVEC_ENET1));
172 + /*if (bp->pdev->device != PCI_DEVICE_ID_BCM4713)*/
173 + ssb_pci_setup(bp, (bp->core_unit == 0 ?
174 + SBINTVEC_ENET0 :
175 + SBINTVEC_ENET1));
176 }
177
178 ssb_core_reset(bp);
179 @@ -1115,6 +1183,11 @@
180 b44_clear_stats(bp);
181
182 /* Make PHY accessible. */
183 + if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
184 + sb_clock = 100000000; /* 100 MHz */
185 + else
186 + sb_clock = 62500000; /* 62.5 MHz */
187 +
188 bw32(B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
189 (0x0d & MDIO_CTRL_MAXF_MASK)));
190 br32(B44_MDIO_CTRL);
191 @@ -1669,20 +1742,42 @@
192 {
193 u8 eeprom[128];
194 int err;
195 + unsigned long flags;
196
197 - err = b44_read_eeprom(bp, &eeprom[0]);
198 - if (err)
199 - goto out;
200 -
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];
207 -
208 - bp->phy_addr = eeprom[90] & 0x1f;
209 - bp->mdc_port = (eeprom[90] >> 14) & 0x1;
210 + if (bp->pdev->device == PCI_DEVICE_ID_BCM4713) {
211 + /*
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.
217 + */
218 + spin_lock_irqsave(&bp->lock, flags);
219 + __b44_cam_read(bp, bp->dev->dev_addr, 0);
220 + spin_unlock_irqrestore(&bp->lock, flags);
221 +
222 + /*
223 + * BCM47xx boards don't have a PHY. Usually there is a switch
224 + * chip with multiple PHYs connected to the PHY port.
225 + */
226 + bp->phy_addr = B44_PHY_ADDR_NO_PHY;
227 + bp->dma_offset = 0;
228 + } else {
229 + err = b44_read_eeprom(bp, &eeprom[0]);
230 + if (err)
231 + return err;
232 +
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];
239 +
240 + bp->phy_addr = eeprom[90] & 0x1f;
241 + bp->dma_offset = SB_PCI_DMA;
242 + bp->mdc_port = (eeprom[90] >> 14) & 0x1;
243 + }
244
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;
249
250 bp->core_unit = ssb_core_unit(bp);
251 - bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0);
252
253 /* XXX - really required?
254 bp->flags |= B44_FLAG_BUGGY_TXPTR;
255 */
256 -out:
257 - return err;
258 +
259 + return 0;
260 }
261
262 static int __devinit b44_init_one(struct pci_dev *pdev,
263 @@ -1819,7 +1913,8 @@
264
265 pci_save_state(bp->pdev, bp->pci_cfg_state);
266
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' : ':');
This page took 0.048806 seconds and 5 git commands to generate.