large target/linux cleanup
[openwrt.git] / target / linux / generic-2.4 / patches / 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