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