debuggers.hg

view xen/drivers/net/tulip/eeprom.c @ 618:4480b471191c

bitkeeper revision 1.259.2.7 (3f0c428fGYxQAV_56B2hOOjYs1PF0A)

Port a bunch of network drivers for low-quality NICS (which will incur extra copying overheads within Xen). But will allow us to work on a wider range of systems at least.
author kaf24@scramble.cl.cam.ac.uk
date Wed Jul 09 16:27:59 2003 +0000 (2003-07-09)
parents
children 125f43340354
line source
1 /*
2 drivers/net/tulip/eeprom.c
4 Maintained by Jeff Garzik <jgarzik@pobox.com>
5 Copyright 2000,2001 The Linux Kernel Team
6 Written/copyright 1994-2001 by Donald Becker.
8 This software may be used and distributed according to the terms
9 of the GNU General Public License, incorporated herein by reference.
11 Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
12 for more information on this driver, or visit the project
13 Web page at http://sourceforge.net/projects/tulip/
15 */
17 #include "tulip.h"
18 #include <linux/init.h>
19 #include <asm/unaligned.h>
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 */
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 {0, 0, 0, 0, {}}};
68 static const char *block_name[] __devinitdata = {
69 "21140 non-MII",
70 "21140 MII PHY",
71 "21142 Serial PHY",
72 "21142 MII PHY",
73 "21143 SYM PHY",
74 "21143 reset method"
75 };
78 /**
79 * tulip_build_fake_mediatable - Build a fake mediatable entry.
80 * @tp: Ptr to the tulip private data.
81 *
82 * Some cards like the 3x5 HSC cards (J3514A) do not have a standard
83 * srom and can not be handled under the fixup routine. These cards
84 * still need a valid mediatable entry for correct csr12 setup and
85 * mii handling.
86 *
87 * Since this is currently a parisc-linux specific function, the
88 * #ifdef __hppa__ should completely optimize this function away for
89 * non-parisc hardware.
90 */
91 static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
92 {
93 #ifdef __hppa__
94 unsigned char *ee_data = tp->eeprom;
96 if (ee_data[0] == 0x3c && ee_data[1] == 0x10 &&
97 (ee_data[2] == 0x63 || ee_data[2] == 0x61) && ee_data[3] == 0x10) {
99 static unsigned char leafdata[] =
100 { 0x01, /* phy number */
101 0x02, /* gpr setup sequence length */
102 0x02, 0x00, /* gpr setup sequence */
103 0x02, /* phy reset sequence length */
104 0x01, 0x00, /* phy reset sequence */
105 0x00, 0x78, /* media capabilities */
106 0x00, 0xe0, /* nway advertisment */
107 0x00, 0x05, /* fdx bit map */
108 0x00, 0x06 /* ttm bit map */
109 };
111 tp->mtable = (struct mediatable *)
112 kmalloc(sizeof(struct mediatable) + sizeof(struct medialeaf), GFP_KERNEL);
114 if (tp->mtable == NULL)
115 return; /* Horrible, impossible failure. */
117 tp->mtable->defaultmedia = 0x800;
118 tp->mtable->leafcount = 1;
119 tp->mtable->csr12dir = 0x3f; /* inputs on bit7 for hsc-pci, bit6 for pci-fx */
120 tp->mtable->has_nonmii = 0;
121 tp->mtable->has_reset = 0;
122 tp->mtable->has_mii = 1;
123 tp->mtable->csr15dir = tp->mtable->csr15val = 0;
124 tp->mtable->mleaf[0].type = 1;
125 tp->mtable->mleaf[0].media = 11;
126 tp->mtable->mleaf[0].leafdata = &leafdata[0];
127 tp->flags |= HAS_PHY_IRQ;
128 tp->csr12_shadow = -1;
129 }
130 #endif
131 }
133 void __devinit tulip_parse_eeprom(struct net_device *dev)
134 {
135 /* The last media info list parsed, for multiport boards. */
136 static struct mediatable *last_mediatable;
137 static unsigned char *last_ee_data;
138 static int controller_index;
139 struct tulip_private *tp = (struct tulip_private *)dev->priv;
140 unsigned char *ee_data = tp->eeprom;
141 int i;
143 tp->mtable = 0;
144 /* Detect an old-style (SA only) EEPROM layout:
145 memcmp(eedata, eedata+16, 8). */
146 for (i = 0; i < 8; i ++)
147 if (ee_data[i] != ee_data[16+i])
148 break;
149 if (i >= 8) {
150 if (ee_data[0] == 0xff) {
151 if (last_mediatable) {
152 controller_index++;
153 printk(KERN_INFO "%s: Controller %d of multiport board.\n",
154 dev->name, controller_index);
155 tp->mtable = last_mediatable;
156 ee_data = last_ee_data;
157 goto subsequent_board;
158 } else
159 printk(KERN_INFO "%s: Missing EEPROM, this interface may "
160 "not work correctly!\n",
161 dev->name);
162 return;
163 }
164 /* Do a fix-up based on the vendor half of the station address prefix. */
165 for (i = 0; eeprom_fixups[i].name; i++) {
166 if (dev->dev_addr[0] == eeprom_fixups[i].addr0
167 && dev->dev_addr[1] == eeprom_fixups[i].addr1
168 && dev->dev_addr[2] == eeprom_fixups[i].addr2) {
169 if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55)
170 i++; /* An Accton EN1207, not an outlaw Maxtech. */
171 memcpy(ee_data + 26, eeprom_fixups[i].newtable,
172 sizeof(eeprom_fixups[i].newtable));
173 printk(KERN_INFO "%s: Old format EEPROM on '%s' board. Using"
174 " substitute media control info.\n",
175 dev->name, eeprom_fixups[i].name);
176 break;
177 }
178 }
179 if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
180 printk(KERN_INFO "%s: Old style EEPROM with no media selection "
181 "information.\n",
182 dev->name);
183 return;
184 }
185 }
187 controller_index = 0;
188 if (ee_data[19] > 1) { /* Multiport board. */
189 last_ee_data = ee_data;
190 }
191 subsequent_board:
193 if (ee_data[27] == 0) { /* No valid media table. */
194 tulip_build_fake_mediatable(tp);
195 } else if (tp->chip_id == DC21041) {
196 unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3];
197 int media = get_u16(p);
198 int count = p[2];
199 p += 3;
201 printk(KERN_INFO "%s: 21041 Media table, default media %4.4x (%s).\n",
202 dev->name, media,
203 media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
204 for (i = 0; i < count; i++) {
205 unsigned char media_block = *p++;
206 int media_code = media_block & MEDIA_MASK;
207 if (media_block & 0x40)
208 p += 6;
209 printk(KERN_INFO "%s: 21041 media #%d, %s.\n",
210 dev->name, media_code, medianame[media_code]);
211 }
212 } else {
213 unsigned char *p = (void *)ee_data + ee_data[27];
214 unsigned char csr12dir = 0;
215 int count, new_advertise = 0;
216 struct mediatable *mtable;
217 u16 media = get_u16(p);
219 p += 2;
220 if (tp->flags & CSR12_IN_SROM)
221 csr12dir = *p++;
222 count = *p++;
224 /* there is no phy information, don't even try to build mtable */
225 if (count == 0) {
226 if (tulip_debug > 0)
227 printk(KERN_WARNING "%s: no phy info, aborting mtable build\n", dev->name);
228 return;
229 }
231 mtable = (struct mediatable *)
232 kmalloc(sizeof(struct mediatable) + count*sizeof(struct medialeaf),
233 GFP_KERNEL);
234 if (mtable == NULL)
235 return; /* Horrible, impossible failure. */
236 last_mediatable = tp->mtable = mtable;
237 mtable->defaultmedia = media;
238 mtable->leafcount = count;
239 mtable->csr12dir = csr12dir;
240 mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
241 mtable->csr15dir = mtable->csr15val = 0;
243 printk(KERN_INFO "%s: EEPROM default media type %s.\n", dev->name,
244 media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
245 for (i = 0; i < count; i++) {
246 struct medialeaf *leaf = &mtable->mleaf[i];
248 if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
249 leaf->type = 0;
250 leaf->media = p[0] & 0x3f;
251 leaf->leafdata = p;
252 if ((p[2] & 0x61) == 0x01) /* Bogus, but Znyx boards do it. */
253 mtable->has_mii = 1;
254 p += 4;
255 } else {
256 leaf->type = p[1];
257 if (p[1] == 0x05) {
258 mtable->has_reset = i;
259 leaf->media = p[2] & 0x0f;
260 } else if (tp->chip_id == DM910X && p[1] == 0x80) {
261 /* Hack to ignore Davicom delay period block */
262 mtable->leafcount--;
263 count--;
264 i--;
265 leaf->leafdata = p + 2;
266 p += (p[0] & 0x3f) + 1;
267 continue;
268 } else if (p[1] & 1) {
269 int gpr_len, reset_len;
271 mtable->has_mii = 1;
272 leaf->media = 11;
273 gpr_len=p[3]*2;
274 reset_len=p[4+gpr_len]*2;
275 new_advertise |= get_u16(&p[7+gpr_len+reset_len]);
276 } else {
277 mtable->has_nonmii = 1;
278 leaf->media = p[2] & MEDIA_MASK;
279 /* Davicom's media number for 100BaseTX is strange */
280 if (tp->chip_id == DM910X && leaf->media == 1)
281 leaf->media = 3;
282 switch (leaf->media) {
283 case 0: new_advertise |= 0x0020; break;
284 case 4: new_advertise |= 0x0040; break;
285 case 3: new_advertise |= 0x0080; break;
286 case 5: new_advertise |= 0x0100; break;
287 case 6: new_advertise |= 0x0200; break;
288 }
289 if (p[1] == 2 && leaf->media == 0) {
290 if (p[2] & 0x40) {
291 u32 base15 = get_unaligned((u16*)&p[7]);
292 mtable->csr15dir =
293 (get_unaligned((u16*)&p[9])<<16) + base15;
294 mtable->csr15val =
295 (get_unaligned((u16*)&p[11])<<16) + base15;
296 } else {
297 mtable->csr15dir = get_unaligned((u16*)&p[3])<<16;
298 mtable->csr15val = get_unaligned((u16*)&p[5])<<16;
299 }
300 }
301 }
302 leaf->leafdata = p + 2;
303 p += (p[0] & 0x3f) + 1;
304 }
305 if (tulip_debug > 1 && leaf->media == 11) {
306 unsigned char *bp = leaf->leafdata;
307 printk(KERN_INFO "%s: MII interface PHY %d, setup/reset "
308 "sequences %d/%d long, capabilities %2.2x %2.2x.\n",
309 dev->name, bp[0], bp[1], bp[2 + bp[1]*2],
310 bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
311 }
312 printk(KERN_INFO "%s: Index #%d - Media %s (#%d) described "
313 "by a %s (%d) block.\n",
314 dev->name, i, medianame[leaf->media & 15], leaf->media,
315 leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
316 leaf->type);
317 }
318 if (new_advertise)
319 tp->sym_advertise = new_advertise;
320 }
321 }
322 /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
324 /* EEPROM_Ctrl bits. */
325 #define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */
326 #define EE_CS 0x01 /* EEPROM chip select. */
327 #define EE_DATA_WRITE 0x04 /* Data from the Tulip to EEPROM. */
328 #define EE_WRITE_0 0x01
329 #define EE_WRITE_1 0x05
330 #define EE_DATA_READ 0x08 /* Data from the EEPROM chip. */
331 #define EE_ENB (0x4800 | EE_CS)
333 /* Delay between EEPROM clock transitions.
334 Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
335 We add a bus turn-around to insure that this remains true. */
336 #define eeprom_delay() inl(ee_addr)
338 /* The EEPROM commands include the alway-set leading bit. */
339 #define EE_READ_CMD (6)
341 /* Note: this routine returns extra data bits for size detection. */
342 int __devinit tulip_read_eeprom(long ioaddr, int location, int addr_len)
343 {
344 int i;
345 unsigned retval = 0;
346 long ee_addr = ioaddr + CSR9;
347 int read_cmd = location | (EE_READ_CMD << addr_len);
349 outl(EE_ENB & ~EE_CS, ee_addr);
350 outl(EE_ENB, ee_addr);
352 /* Shift the read command bits out. */
353 for (i = 4 + addr_len; i >= 0; i--) {
354 short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
355 outl(EE_ENB | dataval, ee_addr);
356 eeprom_delay();
357 outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
358 eeprom_delay();
359 retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
360 }
361 outl(EE_ENB, ee_addr);
362 eeprom_delay();
364 for (i = 16; i > 0; i--) {
365 outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
366 eeprom_delay();
367 retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
368 outl(EE_ENB, ee_addr);
369 eeprom_delay();
370 }
372 /* Terminate the EEPROM access. */
373 outl(EE_ENB & ~EE_CS, ee_addr);
374 return retval;
375 }