MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / tulip / eeprom.c
blob512debab8b4edf5a92a12443b213adcd5e1ae646
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-user.{pdf,ps,html}
12 for more information on this driver, or visit the project
13 Web page at http://sourceforge.net/projects/tulip/
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.
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
63 { 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 }
65 {NULL}};
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"
78 /**
79 * tulip_build_fake_mediatable - Build a fake mediatable entry.
80 * @tp: Ptr to the tulip private data.
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.
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.
91 static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
93 #ifdef CONFIG_GSC
94 if (tp->flags & NEEDS_FAKE_MEDIA_TABLE) {
95 static unsigned char leafdata[] =
96 { 0x01, /* phy number */
97 0x02, /* gpr setup sequence length */
98 0x02, 0x00, /* gpr setup sequence */
99 0x02, /* phy reset sequence length */
100 0x01, 0x00, /* phy reset sequence */
101 0x00, 0x78, /* media capabilities */
102 0x00, 0xe0, /* nway advertisment */
103 0x00, 0x05, /* fdx bit map */
104 0x00, 0x06 /* ttm bit map */
107 tp->mtable = (struct mediatable *)
108 kmalloc(sizeof(struct mediatable) + sizeof(struct medialeaf), GFP_KERNEL);
110 if (tp->mtable == NULL)
111 return; /* Horrible, impossible failure. */
113 tp->mtable->defaultmedia = 0x800;
114 tp->mtable->leafcount = 1;
115 tp->mtable->csr12dir = 0x3f; /* inputs on bit7 for hsc-pci, bit6 for pci-fx */
116 tp->mtable->has_nonmii = 0;
117 tp->mtable->has_reset = 0;
118 tp->mtable->has_mii = 1;
119 tp->mtable->csr15dir = tp->mtable->csr15val = 0;
120 tp->mtable->mleaf[0].type = 1;
121 tp->mtable->mleaf[0].media = 11;
122 tp->mtable->mleaf[0].leafdata = &leafdata[0];
123 tp->flags |= HAS_PHY_IRQ;
124 tp->csr12_shadow = -1;
126 #endif
129 void __devinit tulip_parse_eeprom(struct net_device *dev)
131 /* The last media info list parsed, for multiport boards. */
132 static struct mediatable *last_mediatable;
133 static unsigned char *last_ee_data;
134 static int controller_index;
135 struct tulip_private *tp = netdev_priv(dev);
136 unsigned char *ee_data = tp->eeprom;
137 int i;
139 tp->mtable = NULL;
140 /* Detect an old-style (SA only) EEPROM layout:
141 memcmp(eedata, eedata+16, 8). */
142 for (i = 0; i < 8; i ++)
143 if (ee_data[i] != ee_data[16+i])
144 break;
145 if (i >= 8) {
146 if (ee_data[0] == 0xff) {
147 if (last_mediatable) {
148 controller_index++;
149 printk(KERN_INFO "%s: Controller %d of multiport board.\n",
150 dev->name, controller_index);
151 tp->mtable = last_mediatable;
152 ee_data = last_ee_data;
153 goto subsequent_board;
154 } else
155 printk(KERN_INFO "%s: Missing EEPROM, this interface may "
156 "not work correctly!\n",
157 dev->name);
158 return;
160 /* Do a fix-up based on the vendor half of the station address prefix. */
161 for (i = 0; eeprom_fixups[i].name; i++) {
162 if (dev->dev_addr[0] == eeprom_fixups[i].addr0
163 && dev->dev_addr[1] == eeprom_fixups[i].addr1
164 && dev->dev_addr[2] == eeprom_fixups[i].addr2) {
165 if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55)
166 i++; /* An Accton EN1207, not an outlaw Maxtech. */
167 memcpy(ee_data + 26, eeprom_fixups[i].newtable,
168 sizeof(eeprom_fixups[i].newtable));
169 printk(KERN_INFO "%s: Old format EEPROM on '%s' board. Using"
170 " substitute media control info.\n",
171 dev->name, eeprom_fixups[i].name);
172 break;
175 if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
176 printk(KERN_INFO "%s: Old style EEPROM with no media selection "
177 "information.\n",
178 dev->name);
179 return;
183 controller_index = 0;
184 if (ee_data[19] > 1) { /* Multiport board. */
185 last_ee_data = ee_data;
187 subsequent_board:
189 if (ee_data[27] == 0) { /* No valid media table. */
190 tulip_build_fake_mediatable(tp);
191 } else {
192 unsigned char *p = (void *)ee_data + ee_data[27];
193 unsigned char csr12dir = 0;
194 int count, new_advertise = 0;
195 struct mediatable *mtable;
196 u16 media = get_u16(p);
198 p += 2;
199 if (tp->flags & CSR12_IN_SROM)
200 csr12dir = *p++;
201 count = *p++;
203 /* there is no phy information, don't even try to build mtable */
204 if (count == 0) {
205 if (tulip_debug > 0)
206 printk(KERN_WARNING "%s: no phy info, aborting mtable build\n", dev->name);
207 return;
210 mtable = (struct mediatable *)
211 kmalloc(sizeof(struct mediatable) + count*sizeof(struct medialeaf),
212 GFP_KERNEL);
213 if (mtable == NULL)
214 return; /* Horrible, impossible failure. */
215 last_mediatable = tp->mtable = mtable;
216 mtable->defaultmedia = media;
217 mtable->leafcount = count;
218 mtable->csr12dir = csr12dir;
219 mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
220 mtable->csr15dir = mtable->csr15val = 0;
222 printk(KERN_INFO "%s: EEPROM default media type %s.\n", dev->name,
223 media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
224 for (i = 0; i < count; i++) {
225 struct medialeaf *leaf = &mtable->mleaf[i];
227 if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
228 leaf->type = 0;
229 leaf->media = p[0] & 0x3f;
230 leaf->leafdata = p;
231 if ((p[2] & 0x61) == 0x01) /* Bogus, but Znyx boards do it. */
232 mtable->has_mii = 1;
233 p += 4;
234 } else {
235 leaf->type = p[1];
236 if (p[1] == 0x05) {
237 mtable->has_reset = i;
238 leaf->media = p[2] & 0x0f;
239 } else if (tp->chip_id == DM910X && p[1] == 0x80) {
240 /* Hack to ignore Davicom delay period block */
241 mtable->leafcount--;
242 count--;
243 i--;
244 leaf->leafdata = p + 2;
245 p += (p[0] & 0x3f) + 1;
246 continue;
247 } else if (p[1] & 1) {
248 int gpr_len, reset_len;
250 mtable->has_mii = 1;
251 leaf->media = 11;
252 gpr_len=p[3]*2;
253 reset_len=p[4+gpr_len]*2;
254 new_advertise |= get_u16(&p[7+gpr_len+reset_len]);
255 } else {
256 mtable->has_nonmii = 1;
257 leaf->media = p[2] & MEDIA_MASK;
258 /* Davicom's media number for 100BaseTX is strange */
259 if (tp->chip_id == DM910X && leaf->media == 1)
260 leaf->media = 3;
261 switch (leaf->media) {
262 case 0: new_advertise |= 0x0020; break;
263 case 4: new_advertise |= 0x0040; break;
264 case 3: new_advertise |= 0x0080; break;
265 case 5: new_advertise |= 0x0100; break;
266 case 6: new_advertise |= 0x0200; break;
268 if (p[1] == 2 && leaf->media == 0) {
269 if (p[2] & 0x40) {
270 u32 base15 = get_unaligned((u16*)&p[7]);
271 mtable->csr15dir =
272 (get_unaligned((u16*)&p[9])<<16) + base15;
273 mtable->csr15val =
274 (get_unaligned((u16*)&p[11])<<16) + base15;
275 } else {
276 mtable->csr15dir = get_unaligned((u16*)&p[3])<<16;
277 mtable->csr15val = get_unaligned((u16*)&p[5])<<16;
281 leaf->leafdata = p + 2;
282 p += (p[0] & 0x3f) + 1;
284 if (tulip_debug > 1 && leaf->media == 11) {
285 unsigned char *bp = leaf->leafdata;
286 printk(KERN_INFO "%s: MII interface PHY %d, setup/reset "
287 "sequences %d/%d long, capabilities %2.2x %2.2x.\n",
288 dev->name, bp[0], bp[1], bp[2 + bp[1]*2],
289 bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
291 printk(KERN_INFO "%s: Index #%d - Media %s (#%d) described "
292 "by a %s (%d) block.\n",
293 dev->name, i, medianame[leaf->media & 15], leaf->media,
294 leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
295 leaf->type);
297 if (new_advertise)
298 tp->sym_advertise = new_advertise;
301 /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
303 /* EEPROM_Ctrl bits. */
304 #define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */
305 #define EE_CS 0x01 /* EEPROM chip select. */
306 #define EE_DATA_WRITE 0x04 /* Data from the Tulip to EEPROM. */
307 #define EE_WRITE_0 0x01
308 #define EE_WRITE_1 0x05
309 #define EE_DATA_READ 0x08 /* Data from the EEPROM chip. */
310 #define EE_ENB (0x4800 | EE_CS)
312 /* Delay between EEPROM clock transitions.
313 Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
314 We add a bus turn-around to insure that this remains true. */
315 #define eeprom_delay() inl(ee_addr)
317 /* The EEPROM commands include the alway-set leading bit. */
318 #define EE_READ_CMD (6)
320 /* Note: this routine returns extra data bits for size detection. */
321 int __devinit tulip_read_eeprom(struct net_device *dev, int location, int addr_len)
323 int i;
324 unsigned retval = 0;
325 struct tulip_private *tp = dev->priv;
326 long ee_addr = tp->base_addr + CSR9;
327 int read_cmd = location | (EE_READ_CMD << addr_len);
329 outl(EE_ENB & ~EE_CS, ee_addr);
330 outl(EE_ENB, ee_addr);
332 /* Shift the read command bits out. */
333 for (i = 4 + addr_len; i >= 0; i--) {
334 short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
335 outl(EE_ENB | dataval, ee_addr);
336 eeprom_delay();
337 outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
338 eeprom_delay();
339 retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
341 outl(EE_ENB, ee_addr);
342 eeprom_delay();
344 for (i = 16; i > 0; i--) {
345 outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
346 eeprom_delay();
347 retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
348 outl(EE_ENB, ee_addr);
349 eeprom_delay();
352 /* Terminate the EEPROM access. */
353 outl(EE_ENB & ~EE_CS, ee_addr);
354 return (tp->flags & HAS_SWAPPED_SEEPROM) ? swab16(retval) : retval;