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