• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2         Driver for the National Semiconductor DP83810 Ethernet controller.
3 
4         Portions Copyright (C) 2001 Inprimis Technologies, Inc.
5         http://www.inprimis.com/
6 
7         This driver is based (heavily) on the Linux driver for this chip
8         which is copyright 1999-2001 by Donald Becker.
9 
10         This software has no warranties expressed or implied for any
11         purpose.
12 
13         This software may be used and distributed according to the terms of
14         the GNU General Public License (GPL), incorporated herein by reference.
15         Drivers based on or derived from this code fall under the GPL and must
16         retain the authorship, copyright and license notice.  This file is not
17         a complete program and may only be used when the entire operating
18         system is licensed under the GPL.  License for under other terms may be
19         available.  Contact the original author for details.
20 
21         The original author may be reached as becker@scyld.com, or at
22         Scyld Computing Corporation
23         410 Severn Ave., Suite 210
24         Annapolis MD 21403
25 */
26 
27 
28 typedef unsigned char  u8;
29 typedef   signed char  s8;
30 typedef unsigned short u16;
31 typedef   signed short s16;
32 typedef unsigned int   u32;
33 typedef   signed int   s32;
34 
35 #include "etherboot.h"
36 #include "nic.h"
37 #include "pci.h"
38 
39 #undef	virt_to_bus
40 #define	virt_to_bus(x)          ((unsigned long)x)
41 #define cpu_to_le32(val)        (val)
42 #define le32_to_cpu(val)        (val)
43 #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
44 #define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
45 
46 #define TX_RING_SIZE 1
47 #define RX_RING_SIZE 4
48 #define TIME_OUT     1000000
49 #define PKT_BUF_SZ   1536
50 
51 /* Offsets to the device registers. */
52 enum register_offsets {
53     ChipCmd=0x00, ChipConfig=0x04, EECtrl=0x08, PCIBusCfg=0x0C,
54     IntrStatus=0x10, IntrMask=0x14, IntrEnable=0x18,
55     TxRingPtr=0x20, TxConfig=0x24,
56     RxRingPtr=0x30, RxConfig=0x34,
57     WOLCmd=0x40, PauseCmd=0x44, RxFilterAddr=0x48, RxFilterData=0x4C,
58     BootRomAddr=0x50, BootRomData=0x54, StatsCtrl=0x5C, StatsData=0x60,
59     RxPktErrs=0x60, RxMissed=0x68, RxCRCErrs=0x64,
60 };
61 
62 /* Bit in ChipCmd. */
63 enum ChipCmdBits {
64     ChipReset=0x100, RxReset=0x20, TxReset=0x10, RxOff=0x08, RxOn=0x04,
65     TxOff=0x02, TxOn=0x01,
66 };
67 
68 /* Bits in the interrupt status/mask registers. */
69 enum intr_status_bits {
70     IntrRxDone=0x0001, IntrRxIntr=0x0002, IntrRxErr=0x0004, IntrRxEarly=0x0008,
71     IntrRxIdle=0x0010, IntrRxOverrun=0x0020,
72     IntrTxDone=0x0040, IntrTxIntr=0x0080, IntrTxErr=0x0100,
73     IntrTxIdle=0x0200, IntrTxUnderrun=0x0400,
74     StatsMax=0x0800, LinkChange=0x4000,	WOLPkt=0x2000,
75     RxResetDone=0x1000000, TxResetDone=0x2000000,
76     IntrPCIErr=0x00f00000, IntrNormalSummary=0x0251, IntrAbnormalSummary=0xED20,
77 };
78 
79 /* Bits in the RxMode register. */
80 enum rx_mode_bits {
81     AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0xC0000000,
82     AcceptMulticast=0x00200000, AcceptAllMulticast=0x20000000,
83     AcceptAllPhys=0x10000000, AcceptMyPhys=0x08000000,
84 };
85 
86 /* Bits in network_desc.status */
87 enum desc_status_bits {
88     DescOwn=0x80000000, DescMore=0x40000000, DescIntr=0x20000000,
89     DescNoCRC=0x10000000,
90     DescPktOK=0x08000000, RxTooLong=0x00400000,
91 };
92 
93 /* The Rx and Tx buffer descriptors. */
94 struct netdev_desc {
95     u32 next_desc;
96     s32 cmd_status;
97     u32 addr;
98 };
99 
100 static struct FA311_DEV {
101     unsigned int    ioaddr;
102     unsigned short  vendor;
103     unsigned short  device;
104     unsigned int    cur_rx;
105     unsigned int    cur_tx;
106     unsigned int    rx_buf_sz;
107     volatile struct netdev_desc *rx_head_desc;
108     volatile struct netdev_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned (4)));
109     volatile struct netdev_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned (4)));
110 } fa311_dev;
111 
112 static int  eeprom_read(long ioaddr, int location);
113 static void init_ring(struct FA311_DEV *dev);
114 static void fa311_reset(struct nic *nic);
115 static int  fa311_poll(struct nic *nic);
116 static void fa311_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
117 static void fa311_disable(struct nic *nic);
118 
119 static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE] __attribute__ ((aligned (4)));
120 static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE] __attribute__ ((aligned (4)));
121 
fa311_probe(struct nic * nic,unsigned short * io_addrs,struct pci_device * pci)122 struct nic * fa311_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
123 {
124 int            prev_eedata;
125 int            i;
126 int            duplex;
127 int            tx_config;
128 int            rx_config;
129 unsigned char  macaddr[6];
130 unsigned char  mactest;
131 unsigned char  pci_bus = 0;
132 struct FA311_DEV* dev = &fa311_dev;
133 
134     if (io_addrs == 0 || *io_addrs == 0)
135         return (0);
136     memset(dev, 0, sizeof(*dev));
137     dev->vendor = pci->vendor;
138     dev->device = pci->dev_id;
139     dev->ioaddr = pci->membase;
140 
141     /* Work around the dropped serial bit. */
142     prev_eedata = eeprom_read(dev->ioaddr, 6);
143     for (i = 0; i < 3; i++) {
144         int eedata = eeprom_read(dev->ioaddr, i + 7);
145         macaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
146         macaddr[i*2+1] = eedata >> 7;
147         prev_eedata = eedata;
148     }
149     mactest = 0;
150     for (i = 0; i < 6; i++)
151         mactest |= macaddr[i];
152     if (mactest == 0)
153         return (0);
154     for (i = 0; i < 6; i++)
155         nic->node_addr[i] = macaddr[i];
156     printf("%! ", nic->node_addr);
157 
158     adjust_pci_device(pci);
159 
160     fa311_reset(nic);
161 
162     nic->reset = fa311_reset;
163     nic->disable = fa311_disable;
164     nic->poll = fa311_poll;
165     nic->transmit = fa311_transmit;
166 
167     init_ring(dev);
168 
169     writel(virt_to_bus(dev->rx_ring), dev->ioaddr + RxRingPtr);
170     writel(virt_to_bus(dev->tx_ring), dev->ioaddr + TxRingPtr);
171 
172     for (i = 0; i < 6; i += 2)
173     {
174         writel(i, dev->ioaddr + RxFilterAddr);
175         writew(macaddr[i] + (macaddr[i+1] << 8),
176                dev->ioaddr + RxFilterData);
177     }
178 
179     /* Initialize other registers. */
180     /* Configure for standard, in-spec Ethernet. */
181     if (readl(dev->ioaddr + ChipConfig) & 0x20000000)
182     {    /* Full duplex */
183         tx_config = 0xD0801002;
184         rx_config = 0x10000020;
185     }
186     else
187     {
188         tx_config = 0x10801002;
189         rx_config = 0x0020;
190     }
191     writel(tx_config, dev->ioaddr + TxConfig);
192     writel(rx_config, dev->ioaddr + RxConfig);
193 
194     duplex = readl(dev->ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
195     if (duplex) {
196         rx_config |= 0x10000000;
197         tx_config |= 0xC0000000;
198     } else {
199         rx_config &= ~0x10000000;
200         tx_config &= ~0xC0000000;
201     }
202     writew(tx_config, dev->ioaddr + TxConfig);
203     writew(rx_config, dev->ioaddr + RxConfig);
204 
205     writel(AcceptBroadcast | AcceptAllMulticast | AcceptMyPhys,
206            dev->ioaddr + RxFilterAddr);
207 
208     writel(RxOn | TxOn, dev->ioaddr + ChipCmd);
209     writel(4, dev->ioaddr + StatsCtrl);              /* Clear Stats */
210     return nic;
211 
212 }
213 
fa311_reset(struct nic * nic)214 static void fa311_reset(struct nic *nic)
215 {
216 u32 chip_config;
217 struct FA311_DEV* dev = &fa311_dev;
218 
219     /* Reset the chip to erase previous misconfiguration. */
220     outl(ChipReset, dev->ioaddr + ChipCmd);
221 
222     if ((readl(dev->ioaddr + ChipConfig) & 0xe000) != 0xe000)
223     {
224         chip_config = readl(dev->ioaddr + ChipConfig);
225     }
226 }
227 
fa311_poll(struct nic * nic)228 static int fa311_poll(struct nic *nic)
229 {
230 s32 desc_status;
231 int to;
232 int entry;
233 int retcode;
234 struct FA311_DEV* dev = &fa311_dev;
235 
236     retcode = 0;
237     entry = dev->cur_rx;
238     to = TIME_OUT;
239     while (to != 0)
240     {
241         desc_status = dev->rx_ring[entry].cmd_status;
242         if ((desc_status & DescOwn) != 0)
243             break;
244         else
245             --to;
246     }
247     if (to != 0)
248     {
249         readl(dev->ioaddr + IntrStatus);         /* clear interrrupt bits */
250         /* driver owns the next entry it's a new packet. Send it up. */
251         if ((desc_status & (DescMore|DescPktOK|RxTooLong)) == DescPktOK)
252         {
253             nic->packetlen = (desc_status & 0x0fff) - 4;    /* Omit CRC size. */
254             memcpy(nic->packet, (char*)(dev->rx_ring[entry].addr), nic->packetlen);
255             retcode = 1;
256         }
257         /* Give the descriptor back to the chip */
258         dev->rx_ring[entry].cmd_status = cpu_to_le32(dev->rx_buf_sz);
259         dev->cur_rx++;
260         if (dev->cur_rx >= RX_RING_SIZE)
261             dev->cur_rx = 0;
262         dev->rx_head_desc = &dev->rx_ring[dev->cur_rx];
263     }
264     /* Restart Rx engine if stopped. */
265     writel(RxOn, dev->ioaddr + ChipCmd);
266     return retcode;
267 }
268 
fa311_transmit(struct nic * nic,const char * destaddr,unsigned int type,unsigned int len,const char * data)269 static void fa311_transmit(struct nic *nic, const char *destaddr, unsigned int type, unsigned int len, const char *data)
270 {
271 unsigned short nstype;
272 s32            desc_status;
273 int            to;
274 int            entry;
275 char*          txp;
276 unsigned char* s;
277 struct FA311_DEV* dev = &fa311_dev;
278 
279     /* Calculate the next Tx descriptor entry. */
280     entry = dev->cur_tx;
281     txp = (char*)(dev->tx_ring[entry].addr);
282 
283     memcpy(txp, destaddr, ETH_ALEN);
284     memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
285     nstype = htons(type);
286     memcpy(txp + 12, (char*)&nstype, 2);
287     memcpy(txp + ETH_HLEN, data, len);
288     len += ETH_HLEN;
289     /* pad frame */
290     if (len <  ETH_ZLEN)
291     {
292         s = (unsigned char*)(txp+len);
293         while (s < (unsigned char*)(txp+ETH_ZLEN))
294             *s++ = 0;
295         len = ETH_ZLEN;
296     }
297     dev->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | len);
298     dev->cur_tx++;
299     if (dev->cur_tx >= TX_RING_SIZE)
300         dev->cur_tx = 0;
301 
302     /* Wake the potentially-idle transmit channel. */
303     writel(TxOn, dev->ioaddr + ChipCmd);
304 
305     /* wait for tranmission to complete */
306     to = TIME_OUT;
307     while (to != 0)
308     {
309         desc_status = dev->tx_ring[entry].cmd_status;
310         if ((desc_status & DescOwn) == 0)
311             break;
312         else
313             --to;
314     }
315 
316     readl(dev->ioaddr + IntrStatus);         /* clear interrrupt bits */
317     return;
318 }
319 
fa311_disable(struct nic * nic)320 static void fa311_disable(struct nic *nic)
321 {
322 struct FA311_DEV* dev = &fa311_dev;
323 
324     /* Stop the chip's Tx and Rx processes. */
325     writel(RxOff | TxOff, dev->ioaddr + ChipCmd);
326 }
327 
328 
329 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
330    The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. */
331 
332 /* Delay between EEPROM clock transitions.
333    No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
334    a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that
335    made udelay() unreliable.
336    The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
337    depricated.
338 */
339 #define eeprom_delay(ee_addr)	inl(ee_addr)
340 
341 enum EEPROM_Ctrl_Bits {
342 	EE_ShiftClk=0x04, EE_DataIn=0x01, EE_ChipSelect=0x08, EE_DataOut=0x02,
343 };
344 #define EE_Write0 (EE_ChipSelect)
345 #define EE_Write1 (EE_ChipSelect | EE_DataIn)
346 
347 /* The EEPROM commands include the alway-set leading bit. */
348 enum EEPROM_Cmds {
349 	EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
350 };
351 
352 
eeprom_read(long addr,int location)353 static int eeprom_read(long addr, int location)
354 {
355 	int i;
356 	int retval = 0;
357 	int ee_addr = addr + EECtrl;
358 	int read_cmd = location | EE_ReadCmd;
359 	writel(EE_Write0, ee_addr);
360 
361 	/* Shift the read command bits out. */
362 	for (i = 10; i >= 0; i--) {
363 		short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
364 		writel(dataval, ee_addr);
365 		eeprom_delay(ee_addr);
366 		writel(dataval | EE_ShiftClk, ee_addr);
367 		eeprom_delay(ee_addr);
368 	}
369 	writel(EE_ChipSelect, ee_addr);
370 	eeprom_delay(ee_addr);
371 
372 	for (i = 0; i < 16; i++) {
373 		writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
374 		eeprom_delay(ee_addr);
375 		retval |= (readl(ee_addr) & EE_DataOut) ? 1 << i : 0;
376 		writel(EE_ChipSelect, ee_addr);
377 		eeprom_delay(ee_addr);
378 	}
379 
380 	/* Terminate the EEPROM access. */
381 	writel(EE_Write0, ee_addr);
382 	writel(0, ee_addr);
383 	return retval;
384 }
385 
386 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
init_ring(struct FA311_DEV * dev)387 static void init_ring(struct FA311_DEV *dev)
388 {
389 	int i;
390 
391 	dev->cur_rx = 0;
392     dev->cur_tx = 0;
393 
394 	dev->rx_buf_sz = PKT_BUF_SZ;
395 	dev->rx_head_desc = &dev->rx_ring[0];
396 
397 	/* Initialize all Rx descriptors. */
398 	for (i = 0; i < RX_RING_SIZE; i++) {
399 		dev->rx_ring[i].next_desc = virt_to_le32desc(&dev->rx_ring[i+1]);
400 		dev->rx_ring[i].cmd_status = DescOwn;
401 	}
402 	/* Mark the last entry as wrapping the ring. */
403 	dev->rx_ring[i-1].next_desc = virt_to_le32desc(&dev->rx_ring[0]);
404 
405 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
406 	for (i = 0; i < RX_RING_SIZE; i++) {
407 		dev->rx_ring[i].addr = (u32)(&rx_packet[PKT_BUF_SZ * i]);
408 	    dev->rx_ring[i].cmd_status = cpu_to_le32(dev->rx_buf_sz);
409 	}
410 
411 	for (i = 0; i < TX_RING_SIZE; i++) {
412 		dev->tx_ring[i].next_desc = virt_to_le32desc(&dev->tx_ring[i+1]);
413 		dev->tx_ring[i].cmd_status = 0;
414 	}
415 	dev->tx_ring[i-1].next_desc = virt_to_le32desc(&dev->tx_ring[0]);
416 
417 	for (i = 0; i < TX_RING_SIZE; i++)
418 		dev->tx_ring[i].addr = (u32)(&tx_packet[PKT_BUF_SZ * i]);
419 	return;
420 }
421 
422