split kernel patches into board dependend and generic
[openwrt/svn-archive/archive.git] / openwrt / target / linux / linux-2.4 / patches / generic / 204-net_b44.patch
1 diff -Nur linux-2.4.30/drivers/net/b44.c linux-2.4.30-b44/drivers/net/b44.c
2 --- linux-2.4.30/drivers/net/b44.c 2004-08-08 01:26:05.000000000 +0200
3 +++ linux-2.4.30-b44/drivers/net/b44.c 2005-05-26 14:08:48.000000000 +0200
4 @@ -1,7 +1,8 @@
5 /* b44.c: Broadcom 4400 device driver.
6 *
7 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
8 - * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
9 + * Copyright (C) 2004 Pekka Pietikainen (pp@ee.oulu.fi)
10 + * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
11 *
12 * Distribute under GPL.
13 */
14 @@ -25,6 +26,16 @@
15
16 #include "b44.h"
17
18 +#include <typedefs.h>
19 +#include <bcmdevs.h>
20 +#include <bcmutils.h>
21 +#include <osl.h>
22 +#include <bcmutils.h>
23 +#include <bcmnvram.h>
24 +#include <sbconfig.h>
25 +#include <sbchipc.h>
26 +#include <sflash.h>
27 +
28 #define DRV_MODULE_NAME "b44"
29 #define PFX DRV_MODULE_NAME ": "
30 #define DRV_MODULE_VERSION "0.93"
31 @@ -75,7 +86,7 @@
32 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
33
34 MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
35 -MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
36 +MODULE_DESCRIPTION("Broadcom 4400/47xx 10/100 PCI ethernet driver");
37 MODULE_LICENSE("GPL");
38 MODULE_PARM(b44_debug, "i");
39 MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
40 @@ -89,6 +100,8 @@
41 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
42 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1,
43 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
44 + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4713,
45 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
46 { } /* terminate list with empty entry */
47 };
48
49 @@ -236,6 +249,8 @@
50 udelay(1);
51 }
52
53 +static int b44_4713_instance;
54 +
55 static int ssb_core_unit(struct b44 *bp)
56 {
57 #if 0
58 @@ -258,6 +273,9 @@
59 break;
60 };
61 #endif
62 + if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
63 + return b44_4713_instance++;
64 + else
65 return 0;
66 }
67
68 @@ -267,6 +285,28 @@
69 == SBTMSLOW_CLOCK);
70 }
71
72 +static void __b44_cam_read(struct b44 *bp, unsigned char *data, int index)
73 +{
74 + u32 val;
75 +
76 + bw32(B44_CAM_CTRL, (CAM_CTRL_READ |
77 + (index << CAM_CTRL_INDEX_SHIFT)));
78 +
79 + b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
80 +
81 + val = br32(B44_CAM_DATA_LO);
82 +
83 + data[2] = (val >> 24) & 0xFF;
84 + data[3] = (val >> 16) & 0xFF;
85 + data[4] = (val >> 8) & 0xFF;
86 + data[5] = (val >> 0) & 0xFF;
87 +
88 + val = br32(B44_CAM_DATA_HI);
89 +
90 + data[0] = (val >> 8) & 0xFF;
91 + data[1] = (val >> 0) & 0xFF;
92 +}
93 +
94 static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
95 {
96 u32 val;
97 @@ -303,14 +343,14 @@
98 bw32(B44_IMASK, bp->imask);
99 }
100
101 -static int b44_readphy(struct b44 *bp, int reg, u32 *val)
102 +static int __b44_readphy(struct b44 *bp, int phy_addr, int reg, u32 *val)
103 {
104 int err;
105
106 bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
107 bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
108 (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
109 - (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
110 + (phy_addr << MDIO_DATA_PMD_SHIFT) |
111 (reg << MDIO_DATA_RA_SHIFT) |
112 (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT)));
113 err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
114 @@ -319,23 +359,42 @@
115 return err;
116 }
117
118 -static int b44_writephy(struct b44 *bp, int reg, u32 val)
119 +static int b44_readphy(struct b44 *bp, int reg, u32 *val)
120 +{
121 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
122 + return 0;
123 +
124 + return __b44_readphy(bp, bp->phy_addr, reg, val);
125 +}
126 +
127 +static int __b44_writephy(struct b44 *bp, int phy_addr, int reg, u32 val)
128 {
129 bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
130 bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
131 (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) |
132 - (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
133 + (phy_addr << MDIO_DATA_PMD_SHIFT) |
134 (reg << MDIO_DATA_RA_SHIFT) |
135 (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT) |
136 (val & MDIO_DATA_DATA)));
137 return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
138 }
139
140 +static int b44_writephy(struct b44 *bp, int reg, u32 val)
141 +{
142 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
143 + return 0;
144 +
145 + return __b44_writephy(bp, bp->phy_addr, reg, val);
146 +}
147 +
148 static int b44_phy_reset(struct b44 *bp)
149 {
150 u32 val;
151 int err;
152
153 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
154 + return 0;
155 +
156 err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
157 if (err)
158 return err;
159 @@ -406,6 +465,9 @@
160 u32 val;
161 int err;
162
163 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
164 + return 0;
165 +
166 if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
167 goto out;
168 if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
169 @@ -498,6 +560,19 @@
170 {
171 u32 bmsr, aux;
172
173 + if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
174 + bp->flags |= B44_FLAG_100_BASE_T;
175 + bp->flags |= B44_FLAG_FULL_DUPLEX;
176 + if (!netif_carrier_ok(bp->dev)) {
177 + u32 val = br32(B44_TX_CTRL);
178 + val |= TX_CTRL_DUPLEX;
179 + bw32(B44_TX_CTRL, val);
180 + netif_carrier_on(bp->dev);
181 + b44_link_report(bp);
182 + }
183 + return;
184 + }
185 +
186 if (!b44_readphy(bp, MII_BMSR, &bmsr) &&
187 !b44_readphy(bp, B44_MII_AUXCTRL, &aux) &&
188 (bmsr != 0xffff)) {
189 @@ -1092,6 +1167,8 @@
190 /* bp->lock is held. */
191 static void b44_chip_reset(struct b44 *bp)
192 {
193 + unsigned int sb_clock;
194 +
195 if (ssb_is_core_up(bp)) {
196 bw32(B44_RCV_LAZY, 0);
197 bw32(B44_ENET_CTRL, ENET_CTRL_DISABLE);
198 @@ -1105,9 +1182,10 @@
199 bw32(B44_DMARX_CTRL, 0);
200 bp->rx_prod = bp->rx_cons = 0;
201 } else {
202 - ssb_pci_setup(bp, (bp->core_unit == 0 ?
203 - SBINTVEC_ENET0 :
204 - SBINTVEC_ENET1));
205 + /*if (bp->pdev->device != PCI_DEVICE_ID_BCM4713)*/
206 + ssb_pci_setup(bp, (bp->core_unit == 0 ?
207 + SBINTVEC_ENET0 :
208 + SBINTVEC_ENET1));
209 }
210
211 ssb_core_reset(bp);
212 @@ -1115,6 +1193,11 @@
213 b44_clear_stats(bp);
214
215 /* Make PHY accessible. */
216 + if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
217 + sb_clock = 100000000; /* 100 MHz */
218 + else
219 + sb_clock = 62500000; /* 62.5 MHz */
220 +
221 bw32(B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
222 (0x0d & MDIO_CTRL_MAXF_MASK)));
223 br32(B44_MDIO_CTRL);
224 @@ -1628,7 +1711,7 @@
225 u32 mii_regval;
226
227 spin_lock_irq(&bp->lock);
228 - err = b44_readphy(bp, data->reg_num & 0x1f, &mii_regval);
229 + err = __b44_readphy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, &mii_regval);
230 spin_unlock_irq(&bp->lock);
231
232 data->val_out = mii_regval;
233 @@ -1641,7 +1724,7 @@
234 return -EPERM;
235
236 spin_lock_irq(&bp->lock);
237 - err = b44_writephy(bp, data->reg_num & 0x1f, data->val_in);
238 + err = __b44_writephy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
239 spin_unlock_irq(&bp->lock);
240
241 return err;
242 @@ -1669,20 +1752,42 @@
243 {
244 u8 eeprom[128];
245 int err;
246 + unsigned long flags;
247
248 - err = b44_read_eeprom(bp, &eeprom[0]);
249 - if (err)
250 - goto out;
251 -
252 - bp->dev->dev_addr[0] = eeprom[79];
253 - bp->dev->dev_addr[1] = eeprom[78];
254 - bp->dev->dev_addr[2] = eeprom[81];
255 - bp->dev->dev_addr[3] = eeprom[80];
256 - bp->dev->dev_addr[4] = eeprom[83];
257 - bp->dev->dev_addr[5] = eeprom[82];
258 -
259 - bp->phy_addr = eeprom[90] & 0x1f;
260 - bp->mdc_port = (eeprom[90] >> 14) & 0x1;
261 + if (bp->pdev->device == PCI_DEVICE_ID_BCM4713) {
262 + /*
263 + * BCM47xx boards don't have a EEPROM. The MAC is stored in
264 + * a NVRAM area somewhere in the flash memory. As we don't
265 + * know the location and/or the format of the NVRAM area
266 + * here, we simply rely on the bootloader to write the
267 + * MAC into the CAM.
268 + */
269 + spin_lock_irqsave(&bp->lock, flags);
270 + __b44_cam_read(bp, bp->dev->dev_addr, 0);
271 + spin_unlock_irqrestore(&bp->lock, flags);
272 +
273 + /*
274 + * BCM47xx boards don't have a PHY. Usually there is a switch
275 + * chip with multiple PHYs connected to the PHY port.
276 + */
277 + bp->phy_addr = B44_PHY_ADDR_NO_PHY;
278 + bp->dma_offset = 0;
279 + } else {
280 + err = b44_read_eeprom(bp, &eeprom[0]);
281 + if (err)
282 + return err;
283 +
284 + bp->dev->dev_addr[0] = eeprom[79];
285 + bp->dev->dev_addr[1] = eeprom[78];
286 + bp->dev->dev_addr[2] = eeprom[81];
287 + bp->dev->dev_addr[3] = eeprom[80];
288 + bp->dev->dev_addr[4] = eeprom[83];
289 + bp->dev->dev_addr[5] = eeprom[82];
290 +
291 + bp->phy_addr = eeprom[90] & 0x1f;
292 + bp->dma_offset = SB_PCI_DMA;
293 + bp->mdc_port = (eeprom[90] >> 14) & 0x1;
294 + }
295
296 /* With this, plus the rx_header prepended to the data by the
297 * hardware, we'll land the ethernet header on a 2-byte boundary.
298 @@ -1692,13 +1797,12 @@
299 bp->imask = IMASK_DEF;
300
301 bp->core_unit = ssb_core_unit(bp);
302 - bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0);
303
304 /* XXX - really required?
305 bp->flags |= B44_FLAG_BUGGY_TXPTR;
306 */
307 -out:
308 - return err;
309 +
310 + return 0;
311 }
312
313 static int __devinit b44_init_one(struct pci_dev *pdev,
314 @@ -1819,11 +1923,17 @@
315
316 pci_save_state(bp->pdev, bp->pci_cfg_state);
317
318 - printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
319 + printk(KERN_INFO "%s: Broadcom %s 10/100BaseT Ethernet ", dev->name,
320 + (pdev->device == PCI_DEVICE_ID_BCM4713) ? "47xx" : "4400");
321 for (i = 0; i < 6; i++)
322 printk("%2.2x%c", dev->dev_addr[i],
323 i == 5 ? '\n' : ':');
324
325 + /* Initialize phy */
326 + spin_lock_irq(&bp->lock);
327 + b44_chip_reset(bp);
328 + spin_unlock_irq(&bp->lock);
329 +
330 return 0;
331
332 err_out_iounmap:
333 diff -Nur linux-2.4.30/drivers/net/b44.h linux-2.4.30-b44/drivers/net/b44.h
334 --- linux-2.4.30/drivers/net/b44.h 2003-08-25 13:44:42.000000000 +0200
335 +++ linux-2.4.30-b44/drivers/net/b44.h 2005-05-26 16:45:10.000000000 +0200
336 @@ -229,8 +229,6 @@
337 #define SBIPSFLAG_IMASK4 0x3f000000 /* Which sbflags --> mips interrupt 4 */
338 #define SBIPSFLAG_ISHIFT4 24
339 #define B44_SBTPSFLAG 0x0F18UL /* SB Target Port OCP Slave Flag */
340 -#define SBTPS_NUM0_MASK 0x0000003f
341 -#define SBTPS_F0EN0 0x00000040
342 #define B44_SBADMATCH3 0x0F60UL /* SB Address Match 3 */
343 #define B44_SBADMATCH2 0x0F68UL /* SB Address Match 2 */
344 #define B44_SBADMATCH1 0x0F70UL /* SB Address Match 1 */
345 @@ -461,6 +459,8 @@
346 };
347
348 #define B44_MCAST_TABLE_SIZE 32
349 +#define B44_PHY_ADDR_NO_PHY 30
350 +#define B44_MDC_RATIO 5000000
351
352 /* SW copy of device statistics, kept up to date by periodic timer
353 * which probes HW values. Must have same relative layout as HW
354 diff -Nur linux-2.4.30/include/linux/pci_ids.h linux-2.4.30-b44/include/linux/pci_ids.h
355 --- linux-2.4.30/include/linux/pci_ids.h 2005-04-04 03:42:20.000000000 +0200
356 +++ linux-2.4.30-b44/include/linux/pci_ids.h 2005-05-26 14:08:41.000000000 +0200
357 @@ -1735,6 +1735,7 @@
358 #define PCI_DEVICE_ID_TIGON3_5901_2 0x170e
359 #define PCI_DEVICE_ID_BCM4401 0x4401
360 #define PCI_DEVICE_ID_BCM4401B0 0x4402
361 +#define PCI_DEVICE_ID_BCM4713 0x4713
362
363 #define PCI_VENDOR_ID_ENE 0x1524
364 #define PCI_DEVICE_ID_ENE_1211 0x1211