Merge remote branch 'kumar/merge' into merge
[pandora-kernel.git] / drivers / net / tulip / eeprom.c
1 /*
2         drivers/net/tulip/eeprom.c
3
4         Copyright 2000,2001  The Linux Kernel Team
5         Written/copyright 1994-2001 by Donald Becker.
6
7         This software may be used and distributed according to the terms
8         of the GNU General Public License, incorporated herein by reference.
9
10         Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
11         for more information on this driver.
12         Please submit bug reports to http://bugzilla.kernel.org/.
13 */
14
15 #include <linux/pci.h>
16 #include <linux/slab.h>
17 #include "tulip.h"
18 #include <linux/init.h>
19 #include <asm/unaligned.h>
20
21
22
23 /* Serial EEPROM section. */
24 /* The main routine to parse the very complicated SROM structure.
25    Search www.digital.com for "21X4 SROM" to get details.
26    This code is very complex, and will require changes to support
27    additional cards, so I'll be verbose about what is going on.
28    */
29
30 /* Known cards that have old-style EEPROMs. */
31 static struct eeprom_fixup eeprom_fixups[] __devinitdata = {
32   {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
33                           0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
34   {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
35                            0x0000, 0x009E, /* 10baseT */
36                            0x0004, 0x009E, /* 10baseT-FD */
37                            0x0903, 0x006D, /* 100baseTx */
38                            0x0905, 0x006D, /* 100baseTx-FD */ }},
39   {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
40                                  0x0107, 0x8021, /* 100baseFx */
41                                  0x0108, 0x8021, /* 100baseFx-FD */
42                                  0x0100, 0x009E, /* 10baseT */
43                                  0x0104, 0x009E, /* 10baseT-FD */
44                                  0x0103, 0x006D, /* 100baseTx */
45                                  0x0105, 0x006D, /* 100baseTx-FD */ }},
46   {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
47                                    0x1001, 0x009E, /* 10base2, CSR12 0x10*/
48                                    0x0000, 0x009E, /* 10baseT */
49                                    0x0004, 0x009E, /* 10baseT-FD */
50                                    0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
51                                    0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
52   {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
53                                   0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */
54                                   0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */
55                                   0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
56                                   0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
57                                   0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
58    }},
59   {"NetWinder", 0x00, 0x10, 0x57,
60         /* Default media = MII
61          * MII block, reset sequence (3) = 0x0821 0x0000 0x0001, capabilities 0x01e1
62          */
63         { 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 }
64   },
65   {"Cobalt Microserver", 0, 0x10, 0xE0, {0x1e00, /* 0 == controller #, 1e == offset     */
66                                          0x0000, /* 0 == high offset, 0 == gap          */
67                                          0x0800, /* Default Autoselect                  */
68                                          0x8001, /* 1 leaf, extended type, bogus len    */
69                                          0x0003, /* Type 3 (MII), PHY #0                */
70                                          0x0400, /* 0 init instr, 4 reset instr         */
71                                          0x0801, /* Set control mode, GP0 output        */
72                                          0x0000, /* Drive GP0 Low (RST is active low)   */
73                                          0x0800, /* control mode, GP0 input (undriven)  */
74                                          0x0000, /* clear control mode                  */
75                                          0x7800, /* 100TX FDX + HDX, 10bT FDX + HDX     */
76                                          0x01e0, /* Advertise all above                 */
77                                          0x5000, /* FDX all above                       */
78                                          0x1800, /* Set fast TTM in 100bt modes         */
79                                          0x0000, /* PHY cannot be unplugged             */
80   }},
81   {NULL}};
82
83
84 static const char *block_name[] __devinitdata = {
85         "21140 non-MII",
86         "21140 MII PHY",
87         "21142 Serial PHY",
88         "21142 MII PHY",
89         "21143 SYM PHY",
90         "21143 reset method"
91 };
92
93
94 /**
95  * tulip_build_fake_mediatable - Build a fake mediatable entry.
96  * @tp: Ptr to the tulip private data.
97  *
98  * Some cards like the 3x5 HSC cards (J3514A) do not have a standard
99  * srom and can not be handled under the fixup routine.  These cards
100  * still need a valid mediatable entry for correct csr12 setup and
101  * mii handling.
102  *
103  * Since this is currently a parisc-linux specific function, the
104  * #ifdef __hppa__ should completely optimize this function away for
105  * non-parisc hardware.
106  */
107 static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
108 {
109 #ifdef CONFIG_GSC
110         if (tp->flags & NEEDS_FAKE_MEDIA_TABLE) {
111                 static unsigned char leafdata[] =
112                         { 0x01,       /* phy number */
113                           0x02,       /* gpr setup sequence length */
114                           0x02, 0x00, /* gpr setup sequence */
115                           0x02,       /* phy reset sequence length */
116                           0x01, 0x00, /* phy reset sequence */
117                           0x00, 0x78, /* media capabilities */
118                           0x00, 0xe0, /* nway advertisement */
119                           0x00, 0x05, /* fdx bit map */
120                           0x00, 0x06  /* ttm bit map */
121                         };
122
123                 tp->mtable = kmalloc(sizeof(struct mediatable) +
124                                      sizeof(struct medialeaf), GFP_KERNEL);
125
126                 if (tp->mtable == NULL)
127                         return; /* Horrible, impossible failure. */
128
129                 tp->mtable->defaultmedia = 0x800;
130                 tp->mtable->leafcount = 1;
131                 tp->mtable->csr12dir = 0x3f; /* inputs on bit7 for hsc-pci, bit6 for pci-fx */
132                 tp->mtable->has_nonmii = 0;
133                 tp->mtable->has_reset = 0;
134                 tp->mtable->has_mii = 1;
135                 tp->mtable->csr15dir = tp->mtable->csr15val = 0;
136                 tp->mtable->mleaf[0].type = 1;
137                 tp->mtable->mleaf[0].media = 11;
138                 tp->mtable->mleaf[0].leafdata = &leafdata[0];
139                 tp->flags |= HAS_PHY_IRQ;
140                 tp->csr12_shadow = -1;
141         }
142 #endif
143 }
144
145 void __devinit tulip_parse_eeprom(struct net_device *dev)
146 {
147         /*
148           dev is not registered at this point, so logging messages can't
149           use dev_<level> or netdev_<level> but dev->name is good via a
150           hack in the caller
151         */
152
153         /* The last media info list parsed, for multiport boards.  */
154         static struct mediatable *last_mediatable;
155         static unsigned char *last_ee_data;
156         static int controller_index;
157         struct tulip_private *tp = netdev_priv(dev);
158         unsigned char *ee_data = tp->eeprom;
159         int i;
160
161         tp->mtable = NULL;
162         /* Detect an old-style (SA only) EEPROM layout:
163            memcmp(eedata, eedata+16, 8). */
164         for (i = 0; i < 8; i ++)
165                 if (ee_data[i] != ee_data[16+i])
166                         break;
167         if (i >= 8) {
168                 if (ee_data[0] == 0xff) {
169                         if (last_mediatable) {
170                                 controller_index++;
171                                 pr_info("%s: Controller %d of multiport board\n",
172                                         dev->name, controller_index);
173                                 tp->mtable = last_mediatable;
174                                 ee_data = last_ee_data;
175                                 goto subsequent_board;
176                         } else
177                                 pr_info("%s: Missing EEPROM, this interface may not work correctly!\n",
178                                         dev->name);
179                         return;
180                 }
181           /* Do a fix-up based on the vendor half of the station address prefix. */
182           for (i = 0; eeprom_fixups[i].name; i++) {
183                   if (dev->dev_addr[0] == eeprom_fixups[i].addr0 &&
184                       dev->dev_addr[1] == eeprom_fixups[i].addr1 &&
185                       dev->dev_addr[2] == eeprom_fixups[i].addr2) {
186                   if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55)
187                           i++;                  /* An Accton EN1207, not an outlaw Maxtech. */
188                   memcpy(ee_data + 26, eeprom_fixups[i].newtable,
189                                  sizeof(eeprom_fixups[i].newtable));
190                   pr_info("%s: Old format EEPROM on '%s' board.  Using substitute media control info\n",
191                           dev->name, eeprom_fixups[i].name);
192                   break;
193                 }
194           }
195           if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
196                   pr_info("%s: Old style EEPROM with no media selection information\n",
197                           dev->name);
198                 return;
199           }
200         }
201
202         controller_index = 0;
203         if (ee_data[19] > 1) {          /* Multiport board. */
204                 last_ee_data = ee_data;
205         }
206 subsequent_board:
207
208         if (ee_data[27] == 0) {         /* No valid media table. */
209                 tulip_build_fake_mediatable(tp);
210         } else {
211                 unsigned char *p = (void *)ee_data + ee_data[27];
212                 unsigned char csr12dir = 0;
213                 int count, new_advertise = 0;
214                 struct mediatable *mtable;
215                 u16 media = get_u16(p);
216
217                 p += 2;
218                 if (tp->flags & CSR12_IN_SROM)
219                         csr12dir = *p++;
220                 count = *p++;
221
222                 /* there is no phy information, don't even try to build mtable */
223                 if (count == 0) {
224                         if (tulip_debug > 0)
225                                 pr_warning("%s: no phy info, aborting mtable build\n",
226                                            dev->name);
227                         return;
228                 }
229
230                 mtable = kmalloc(sizeof(struct mediatable) +
231                                  count * sizeof(struct medialeaf),
232                                  GFP_KERNEL);
233                 if (mtable == NULL)
234                         return;                         /* Horrible, impossible failure. */
235                 last_mediatable = tp->mtable = mtable;
236                 mtable->defaultmedia = media;
237                 mtable->leafcount = count;
238                 mtable->csr12dir = csr12dir;
239                 mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
240                 mtable->csr15dir = mtable->csr15val = 0;
241
242                 pr_info("%s: EEPROM default media type %s\n",
243                         dev->name,
244                         media & 0x0800 ? "Autosense"
245                                        : medianame[media & MEDIA_MASK]);
246                 for (i = 0; i < count; i++) {
247                         struct medialeaf *leaf = &mtable->mleaf[i];
248
249                         if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
250                                 leaf->type = 0;
251                                 leaf->media = p[0] & 0x3f;
252                                 leaf->leafdata = p;
253                                 if ((p[2] & 0x61) == 0x01)      /* Bogus, but Znyx boards do it. */
254                                         mtable->has_mii = 1;
255                                 p += 4;
256                         } else {
257                                 leaf->type = p[1];
258                                 if (p[1] == 0x05) {
259                                         mtable->has_reset = i;
260                                         leaf->media = p[2] & 0x0f;
261                                 } else if (tp->chip_id == DM910X && p[1] == 0x80) {
262                                         /* Hack to ignore Davicom delay period block */
263                                         mtable->leafcount--;
264                                         count--;
265                                         i--;
266                                         leaf->leafdata = p + 2;
267                                         p += (p[0] & 0x3f) + 1;
268                                         continue;
269                                 } else if (p[1] & 1) {
270                                         int gpr_len, reset_len;
271
272                                         mtable->has_mii = 1;
273                                         leaf->media = 11;
274                                         gpr_len=p[3]*2;
275                                         reset_len=p[4+gpr_len]*2;
276                                         new_advertise |= get_u16(&p[7+gpr_len+reset_len]);
277                                 } else {
278                                         mtable->has_nonmii = 1;
279                                         leaf->media = p[2] & MEDIA_MASK;
280                                         /* Davicom's media number for 100BaseTX is strange */
281                                         if (tp->chip_id == DM910X && leaf->media == 1)
282                                                 leaf->media = 3;
283                                         switch (leaf->media) {
284                                         case 0: new_advertise |= 0x0020; break;
285                                         case 4: new_advertise |= 0x0040; break;
286                                         case 3: new_advertise |= 0x0080; break;
287                                         case 5: new_advertise |= 0x0100; break;
288                                         case 6: new_advertise |= 0x0200; break;
289                                         }
290                                         if (p[1] == 2  &&  leaf->media == 0) {
291                                                 if (p[2] & 0x40) {
292                                                         u32 base15 = get_unaligned((u16*)&p[7]);
293                                                         mtable->csr15dir =
294                                                                 (get_unaligned((u16*)&p[9])<<16) + base15;
295                                                         mtable->csr15val =
296                                                                 (get_unaligned((u16*)&p[11])<<16) + base15;
297                                                 } else {
298                                                         mtable->csr15dir = get_unaligned((u16*)&p[3])<<16;
299                                                         mtable->csr15val = get_unaligned((u16*)&p[5])<<16;
300                                                 }
301                                         }
302                                 }
303                                 leaf->leafdata = p + 2;
304                                 p += (p[0] & 0x3f) + 1;
305                         }
306                         if (tulip_debug > 1  &&  leaf->media == 11) {
307                                 unsigned char *bp = leaf->leafdata;
308                                 pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
309                                         dev->name,
310                                         bp[0], bp[1], bp[2 + bp[1]*2],
311                                         bp[5 + bp[2 + bp[1]*2]*2],
312                                         bp[4 + bp[2 + bp[1]*2]*2]);
313                         }
314                         pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n",
315                                 dev->name,
316                                 i, medianame[leaf->media & 15], leaf->media,
317                                 leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
318                                 leaf->type);
319                 }
320                 if (new_advertise)
321                         tp->sym_advertise = new_advertise;
322         }
323 }
324 /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
325
326 /*  EEPROM_Ctrl bits. */
327 #define EE_SHIFT_CLK    0x02    /* EEPROM shift clock. */
328 #define EE_CS           0x01    /* EEPROM chip select. */
329 #define EE_DATA_WRITE   0x04    /* Data from the Tulip to EEPROM. */
330 #define EE_WRITE_0      0x01
331 #define EE_WRITE_1      0x05
332 #define EE_DATA_READ    0x08    /* Data from the EEPROM chip. */
333 #define EE_ENB          (0x4800 | EE_CS)
334
335 /* Delay between EEPROM clock transitions.
336    Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
337    We add a bus turn-around to insure that this remains true. */
338 #define eeprom_delay()  ioread32(ee_addr)
339
340 /* The EEPROM commands include the alway-set leading bit. */
341 #define EE_READ_CMD             (6)
342
343 /* Note: this routine returns extra data bits for size detection. */
344 int __devinit tulip_read_eeprom(struct net_device *dev, int location, int addr_len)
345 {
346         int i;
347         unsigned retval = 0;
348         struct tulip_private *tp = netdev_priv(dev);
349         void __iomem *ee_addr = tp->base_addr + CSR9;
350         int read_cmd = location | (EE_READ_CMD << addr_len);
351
352         /* If location is past the end of what we can address, don't
353          * read some other location (ie truncate). Just return zero.
354          */
355         if (location > (1 << addr_len) - 1)
356                 return 0;
357
358         iowrite32(EE_ENB & ~EE_CS, ee_addr);
359         iowrite32(EE_ENB, ee_addr);
360
361         /* Shift the read command bits out. */
362         for (i = 4 + addr_len; i >= 0; i--) {
363                 short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
364                 iowrite32(EE_ENB | dataval, ee_addr);
365                 eeprom_delay();
366                 iowrite32(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
367                 eeprom_delay();
368                 retval = (retval << 1) | ((ioread32(ee_addr) & EE_DATA_READ) ? 1 : 0);
369         }
370         iowrite32(EE_ENB, ee_addr);
371         eeprom_delay();
372
373         for (i = 16; i > 0; i--) {
374                 iowrite32(EE_ENB | EE_SHIFT_CLK, ee_addr);
375                 eeprom_delay();
376                 retval = (retval << 1) | ((ioread32(ee_addr) & EE_DATA_READ) ? 1 : 0);
377                 iowrite32(EE_ENB, ee_addr);
378                 eeprom_delay();
379         }
380
381         /* Terminate the EEPROM access. */
382         iowrite32(EE_ENB & ~EE_CS, ee_addr);
383         return (tp->flags & HAS_SWAPPED_SEEPROM) ? swab16(retval) : retval;
384 }
385