Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2	drivers/net/ethernet/dec/tulip/eeprom.c
  3
  4	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 submit bug reports to http://bugzilla.kernel.org/.
 11*/
 12
 13#include <linux/pci.h>
 14#include <linux/slab.h>
 15#include "tulip.h"
 16#include <asm/unaligned.h>
 17
 18
 19
 20/* Serial EEPROM section. */
 21/* The main routine to parse the very complicated SROM structure.
 22   Search www.digital.com for "21X4 SROM" to get details.
 23   This code is very complex, and will require changes to support
 24   additional cards, so I'll be verbose about what is going on.
 25   */
 26
 27/* Known cards that have old-style EEPROMs. */
 28static struct eeprom_fixup eeprom_fixups[] = {
 29  {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
 30			  0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
 31  {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
 32			   0x0000, 0x009E, /* 10baseT */
 33			   0x0004, 0x009E, /* 10baseT-FD */
 34			   0x0903, 0x006D, /* 100baseTx */
 35			   0x0905, 0x006D, /* 100baseTx-FD */ }},
 36  {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
 37				 0x0107, 0x8021, /* 100baseFx */
 38				 0x0108, 0x8021, /* 100baseFx-FD */
 39				 0x0100, 0x009E, /* 10baseT */
 40				 0x0104, 0x009E, /* 10baseT-FD */
 41				 0x0103, 0x006D, /* 100baseTx */
 42				 0x0105, 0x006D, /* 100baseTx-FD */ }},
 43  {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
 44				   0x1001, 0x009E, /* 10base2, CSR12 0x10*/
 45				   0x0000, 0x009E, /* 10baseT */
 46				   0x0004, 0x009E, /* 10baseT-FD */
 47				   0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
 48				   0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
 49  {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
 50				  0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */
 51				  0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */
 52				  0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
 53				  0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
 54				  0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
 55   }},
 56  {"NetWinder", 0x00, 0x10, 0x57,
 57	/* Default media = MII
 58	 * MII block, reset sequence (3) = 0x0821 0x0000 0x0001, capabilities 0x01e1
 59	 */
 60	{ 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 }
 61  },
 62  {"Cobalt Microserver", 0, 0x10, 0xE0, {0x1e00, /* 0 == controller #, 1e == offset	*/
 63					 0x0000, /* 0 == high offset, 0 == gap		*/
 64					 0x0800, /* Default Autoselect			*/
 65					 0x8001, /* 1 leaf, extended type, bogus len	*/
 66					 0x0003, /* Type 3 (MII), PHY #0		*/
 67					 0x0400, /* 0 init instr, 4 reset instr		*/
 68					 0x0801, /* Set control mode, GP0 output	*/
 69					 0x0000, /* Drive GP0 Low (RST is active low)	*/
 70					 0x0800, /* control mode, GP0 input (undriven)	*/
 71					 0x0000, /* clear control mode			*/
 72					 0x7800, /* 100TX FDX + HDX, 10bT FDX + HDX	*/
 73					 0x01e0, /* Advertise all above			*/
 74					 0x5000, /* FDX all above			*/
 75					 0x1800, /* Set fast TTM in 100bt modes		*/
 76					 0x0000, /* PHY cannot be unplugged		*/
 77  }},
 78  {NULL}};
 79
 80
 81static const char *const block_name[] = {
 82	"21140 non-MII",
 83	"21140 MII PHY",
 84	"21142 Serial PHY",
 85	"21142 MII PHY",
 86	"21143 SYM PHY",
 87	"21143 reset method"
 88};
 89
 90
 91/**
 92 * tulip_build_fake_mediatable - Build a fake mediatable entry.
 93 * @tp: Ptr to the tulip private data.
 94 *
 95 * Some cards like the 3x5 HSC cards (J3514A) do not have a standard
 96 * srom and can not be handled under the fixup routine.  These cards
 97 * still need a valid mediatable entry for correct csr12 setup and
 98 * mii handling.
 99 *
100 * Since this is currently a parisc-linux specific function, the
101 * #ifdef __hppa__ should completely optimize this function away for
102 * non-parisc hardware.
103 */
104static void tulip_build_fake_mediatable(struct tulip_private *tp)
105{
106#ifdef CONFIG_GSC
107	if (tp->flags & NEEDS_FAKE_MEDIA_TABLE) {
108		static unsigned char leafdata[] =
109			{ 0x01,       /* phy number */
110			  0x02,       /* gpr setup sequence length */
111			  0x02, 0x00, /* gpr setup sequence */
112			  0x02,       /* phy reset sequence length */
113			  0x01, 0x00, /* phy reset sequence */
114			  0x00, 0x78, /* media capabilities */
115			  0x00, 0xe0, /* nway advertisement */
116			  0x00, 0x05, /* fdx bit map */
117			  0x00, 0x06  /* ttm bit map */
118			};
119
120		tp->mtable = kmalloc(sizeof(struct mediatable) +
121				     sizeof(struct medialeaf), GFP_KERNEL);
122
123		if (tp->mtable == NULL)
124			return; /* Horrible, impossible failure. */
125
126		tp->mtable->defaultmedia = 0x800;
127		tp->mtable->leafcount = 1;
128		tp->mtable->csr12dir = 0x3f; /* inputs on bit7 for hsc-pci, bit6 for pci-fx */
129		tp->mtable->has_nonmii = 0;
130		tp->mtable->has_reset = 0;
131		tp->mtable->has_mii = 1;
132		tp->mtable->csr15dir = tp->mtable->csr15val = 0;
133		tp->mtable->mleaf[0].type = 1;
134		tp->mtable->mleaf[0].media = 11;
135		tp->mtable->mleaf[0].leafdata = &leafdata[0];
136		tp->flags |= HAS_PHY_IRQ;
137		tp->csr12_shadow = -1;
138	}
139#endif
140}
141
142void tulip_parse_eeprom(struct net_device *dev)
143{
144	/*
145	  dev is not registered at this point, so logging messages can't
146	  use dev_<level> or netdev_<level> but dev->name is good via a
147	  hack in the caller
148	*/
149
150	/* The last media info list parsed, for multiport boards.  */
151	static struct mediatable *last_mediatable;
152	static unsigned char *last_ee_data;
153	static int controller_index;
154	struct tulip_private *tp = netdev_priv(dev);
155	unsigned char *ee_data = tp->eeprom;
156	int i;
157
158	tp->mtable = NULL;
159	/* Detect an old-style (SA only) EEPROM layout:
160	   memcmp(eedata, eedata+16, 8). */
161	for (i = 0; i < 8; i ++)
162		if (ee_data[i] != ee_data[16+i])
163			break;
164	if (i >= 8) {
165		if (ee_data[0] == 0xff) {
166			if (last_mediatable) {
167				controller_index++;
168				pr_info("%s: Controller %d of multiport board\n",
169					dev->name, controller_index);
170				tp->mtable = last_mediatable;
171				ee_data = last_ee_data;
172				goto subsequent_board;
173			} else
174				pr_info("%s: Missing EEPROM, this interface may not work correctly!\n",
175					dev->name);
176			return;
177		}
178	  /* Do a fix-up based on the vendor half of the station address prefix. */
179	  for (i = 0; eeprom_fixups[i].name; i++) {
180		  if (dev->dev_addr[0] == eeprom_fixups[i].addr0 &&
181		      dev->dev_addr[1] == eeprom_fixups[i].addr1 &&
182		      dev->dev_addr[2] == eeprom_fixups[i].addr2) {
183		  if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55)
184			  i++;			/* An Accton EN1207, not an outlaw Maxtech. */
185		  memcpy(ee_data + 26, eeprom_fixups[i].newtable,
186				 sizeof(eeprom_fixups[i].newtable));
187		  pr_info("%s: Old format EEPROM on '%s' board.  Using 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		  pr_info("%s: Old style EEPROM with no media selection information\n",
194			  dev->name);
195		return;
196	  }
197	}
198
199	controller_index = 0;
200	if (ee_data[19] > 1) {		/* Multiport board. */
201		last_ee_data = ee_data;
202	}
203subsequent_board:
204
205	if (ee_data[27] == 0) {		/* No valid media table. */
206		tulip_build_fake_mediatable(tp);
207	} else {
208		unsigned char *p = (void *)ee_data + ee_data[27];
209		unsigned char csr12dir = 0;
210		int count, new_advertise = 0;
211		struct mediatable *mtable;
212		u16 media = get_u16(p);
213
214		p += 2;
215		if (tp->flags & CSR12_IN_SROM)
216			csr12dir = *p++;
217		count = *p++;
218
219	        /* there is no phy information, don't even try to build mtable */
220	        if (count == 0) {
221			if (tulip_debug > 0)
222				pr_warn("%s: no phy info, aborting mtable build\n",
223					dev->name);
224		        return;
225		}
226
227		mtable = kmalloc(struct_size(mtable, mleaf, count), 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		pr_info("%s: EEPROM default media type %s\n",
238			dev->name,
239			media & 0x0800 ? "Autosense"
240				       : 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				pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
304					dev->name,
305					bp[0], bp[1], bp[2 + bp[1]*2],
306					bp[5 + bp[2 + bp[1]*2]*2],
307					bp[4 + bp[2 + bp[1]*2]*2]);
308			}
309			pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n",
310				dev->name,
311				i, medianame[leaf->media & 15], leaf->media,
312				leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
313				leaf->type);
314		}
315		if (new_advertise)
316			tp->sym_advertise = new_advertise;
317	}
318}
319/* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
320
321/*  EEPROM_Ctrl bits. */
322#define EE_SHIFT_CLK	0x02	/* EEPROM shift clock. */
323#define EE_CS		0x01	/* EEPROM chip select. */
324#define EE_DATA_WRITE	0x04	/* Data from the Tulip to EEPROM. */
325#define EE_WRITE_0	0x01
326#define EE_WRITE_1	0x05
327#define EE_DATA_READ	0x08	/* Data from the EEPROM chip. */
328#define EE_ENB		(0x4800 | EE_CS)
329
330/* Delay between EEPROM clock transitions.
331   Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
332   We add a bus turn-around to insure that this remains true. */
333#define eeprom_delay()	ioread32(ee_addr)
334
335/* The EEPROM commands include the alway-set leading bit. */
336#define EE_READ_CMD		(6)
337
338/* Note: this routine returns extra data bits for size detection. */
339int tulip_read_eeprom(struct net_device *dev, int location, int addr_len)
340{
341	int i;
342	unsigned retval = 0;
343	struct tulip_private *tp = netdev_priv(dev);
344	void __iomem *ee_addr = tp->base_addr + CSR9;
345	int read_cmd = location | (EE_READ_CMD << addr_len);
346
347	/* If location is past the end of what we can address, don't
348	 * read some other location (ie truncate). Just return zero.
349	 */
350	if (location > (1 << addr_len) - 1)
351		return 0;
352
353	iowrite32(EE_ENB & ~EE_CS, ee_addr);
354	iowrite32(EE_ENB, ee_addr);
355
356	/* Shift the read command bits out. */
357	for (i = 4 + addr_len; i >= 0; i--) {
358		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
359		iowrite32(EE_ENB | dataval, ee_addr);
360		eeprom_delay();
361		iowrite32(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
362		eeprom_delay();
363		retval = (retval << 1) | ((ioread32(ee_addr) & EE_DATA_READ) ? 1 : 0);
364	}
365	iowrite32(EE_ENB, ee_addr);
366	eeprom_delay();
367
368	for (i = 16; i > 0; i--) {
369		iowrite32(EE_ENB | EE_SHIFT_CLK, ee_addr);
370		eeprom_delay();
371		retval = (retval << 1) | ((ioread32(ee_addr) & EE_DATA_READ) ? 1 : 0);
372		iowrite32(EE_ENB, ee_addr);
373		eeprom_delay();
374	}
375
376	/* Terminate the EEPROM access. */
377	iowrite32(EE_ENB & ~EE_CS, ee_addr);
378	return (tp->flags & HAS_SWAPPED_SEEPROM) ? swab16(retval) : retval;
379}
380