blob: 3031ed9c4a1a83e384d23875bf55798dff73d65f [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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090016#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#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. */
31static 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 },
Ralf Baechle12755c12005-06-26 17:45:52 -040065 {"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 }},
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 {NULL}};
82
83
84static 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 *
Jeff Garzikf3b197a2006-05-26 21:39:03 -040098 * Some cards like the 3x5 HSC cards (J3514A) do not have a standard
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 * srom and can not be handled under the fixup routine. These cards
Jeff Garzikf3b197a2006-05-26 21:39:03 -0400100 * still need a valid mediatable entry for correct csr12 setup and
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 * mii handling.
Jeff Garzikf3b197a2006-05-26 21:39:03 -0400102 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 * 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 */
107static 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 advertisment */
119 0x00, 0x05, /* fdx bit map */
120 0x00, 0x06 /* ttm bit map */
121 };
122
Joe Perches589be652010-05-31 17:23:13 +0000123 tp->mtable = kmalloc(sizeof(struct mediatable) +
124 sizeof(struct medialeaf), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
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 }
Jeff Garzikf3b197a2006-05-26 21:39:03 -0400142#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143}
144
145void __devinit tulip_parse_eeprom(struct net_device *dev)
146{
Joe Perchesc251c7f2010-03-13 12:26:15 -0800147 /*
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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 /* 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++;
Joe Perchesc251c7f2010-03-13 12:26:15 -0800171 pr_info("%s: Controller %d of multiport board\n",
172 dev->name, controller_index);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 tp->mtable = last_mediatable;
174 ee_data = last_ee_data;
175 goto subsequent_board;
176 } else
Joe Perchesc251c7f2010-03-13 12:26:15 -0800177 pr_info("%s: Missing EEPROM, this interface may not work correctly!\n",
178 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 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++) {
Joe Perches8e95a202009-12-03 07:58:21 +0000183 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)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 i++; /* An Accton EN1207, not an outlaw Maxtech. */
188 memcpy(ee_data + 26, eeprom_fixups[i].newtable,
189 sizeof(eeprom_fixups[i].newtable));
Joe Perchesc251c7f2010-03-13 12:26:15 -0800190 pr_info("%s: Old format EEPROM on '%s' board. Using substitute media control info\n",
191 dev->name, eeprom_fixups[i].name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 break;
193 }
194 }
195 if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
Joe Perchesc251c7f2010-03-13 12:26:15 -0800196 pr_info("%s: Old style EEPROM with no media selection information\n",
197 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 return;
199 }
200 }
201
202 controller_index = 0;
203 if (ee_data[19] > 1) { /* Multiport board. */
204 last_ee_data = ee_data;
205 }
206subsequent_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)
Joe Perchesc251c7f2010-03-13 12:26:15 -0800225 pr_warning("%s: no phy info, aborting mtable build\n",
226 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 return;
228 }
229
Joe Perches589be652010-05-31 17:23:13 +0000230 mtable = kmalloc(sizeof(struct mediatable) +
231 count * sizeof(struct medialeaf),
232 GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 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
Joe Perchesc251c7f2010-03-13 12:26:15 -0800242 pr_info("%s: EEPROM default media type %s\n",
243 dev->name,
244 media & 0x0800 ? "Autosense"
245 : medianame[media & MEDIA_MASK]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 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;
Joe Perchesc251c7f2010-03-13 12:26:15 -0800308 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]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 }
Joe Perchesc251c7f2010-03-13 12:26:15 -0800314 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);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 }
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. */
344int __devinit tulip_read_eeprom(struct net_device *dev, int location, int addr_len)
345{
346 int i;
347 unsigned retval = 0;
Wang Chen8f15ea42008-11-12 23:38:36 -0800348 struct tulip_private *tp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 void __iomem *ee_addr = tp->base_addr + CSR9;
350 int read_cmd = location | (EE_READ_CMD << addr_len);
351
Grant Grundler209261c2008-03-23 23:23:10 -0600352 /* 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 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