[pci] Add driver_data field to struct pci_device_id
[people/lynusvaz/gpxe.git] / src / drivers / net / natsemi.c
1 /* 
2    natsemi.c - gPXE driver for the NatSemi DP8381x series. 
3  
4    Based on:
5
6    natsemi.c: An Etherboot driver for the NatSemi DP8381x series.
7
8    Copyright (C) 2001 Entity Cyber, Inc.
9    
10    This development of this Etherboot driver was funded by 
11    
12       Sicom Systems: http://www.sicompos.com/
13    
14    Author: Marty Connor <mdc@etherboot.org>
15    Adapted from a Linux driver which was written by Donald Becker
16    
17    This software may be used and distributed according to the terms
18    of the GNU Public License (GPL), incorporated herein by reference.
19    
20    Original Copyright Notice:
21    
22    Written/copyright 1999-2001 by Donald Becker.
23    
24    This software may be used and distributed according to the terms of
25    the GNU General Public License (GPL), incorporated herein by reference.
26    Drivers based on or derived from this code fall under the GPL and must
27    retain the authorship, copyright and license notice.  This file is not
28    a complete program and may only be used when the entire operating
29    system is licensed under the GPL.  License for under other terms may be
30    available.  Contact the original author for details.
31    
32    The original author may be reached as becker@scyld.com, or at
33    Scyld Computing Corporation
34    410 Severn Ave., Suite 210
35    Annapolis MD 21403
36    
37    Support information and updates available at
38    http://www.scyld.com/network/netsemi.html
39    
40    References:
41    
42    http://www.scyld.com/expert/100mbps.html
43    http://www.scyld.com/expert/NWay.html
44    Datasheet is available from:
45    http://www.national.com/pf/DP/DP83815.html
46
47 */
48
49 /* Revision History */
50
51 /*
52   02 Jul 2007  Udayan Kumar      1.2 ported the driver from etherboot to gPXE API.
53                                      Fully rewritten,adapting the old driver.
54                                      Added a circular buffer for transmit and receive.
55                                      transmit routine will not wait for transmission to finish.
56                                      poll routine deals with it.
57   13 Dec 2003  Tim Legge         1.1 Enabled Multicast Support
58   29 May 2001  Marty Connor      1.0 Initial Release. Tested with Netgear FA311 and FA312 boards
59 */
60
61 #include <stdint.h>
62 #include <stdlib.h>
63 #include <stdio.h>
64 #include <string.h>
65 #include <gpxe/io.h>
66 #include <errno.h>
67 #include <byteswap.h>
68 #include <unistd.h>
69 #include <gpxe/pci.h>
70 #include <gpxe/if_ether.h>
71 #include <gpxe/ethernet.h>
72 #include <gpxe/iobuf.h>
73 #include <gpxe/netdevice.h>
74 #include <gpxe/spi_bit.h>
75 #include <gpxe/threewire.h>
76 #include <gpxe/nvo.h>
77 #include "natsemi.h"
78
79 /*  Function Prototypes: */
80  
81 static int natsemi_spi_read_bit ( struct bit_basher *, unsigned int );
82 static void natsemi_spi_write_bit ( struct bit_basher *,unsigned int, unsigned long ); 
83 static void natsemi_init_eeprom ( struct natsemi_private * ); 
84 static int natsemi_probe (struct pci_device *pci, const struct pci_device_id *id);
85 static void natsemi_reset (struct net_device *netdev);
86 static int natsemi_open (struct net_device *netdev);
87 static int natsemi_transmit (struct net_device *netdev, struct io_buffer *iobuf);
88 static void natsemi_poll (struct net_device *netdev);
89 static void natsemi_close (struct net_device *netdev);
90 static void natsemi_irq (struct net_device *netdev, int enable);
91 static void natsemi_remove (struct pci_device *pci);
92
93 /** natsemi net device operations */
94 static struct net_device_operations natsemi_operations = {
95         .open           = natsemi_open,
96         .close          = natsemi_close,
97         .transmit       = natsemi_transmit,
98         .poll           = natsemi_poll,
99         .irq            = natsemi_irq,
100 };
101
102 static int natsemi_spi_read_bit ( struct bit_basher *basher,
103                               unsigned int bit_id ) {
104         struct natsemi_private *np = container_of ( basher, struct natsemi_private,
105                                                  spibit.basher );
106         uint8_t mask = natsemi_ee_bits[bit_id];
107         uint8_t eereg;
108
109         eereg = inb ( np->ioaddr + EE_REG );
110         return ( eereg & mask );
111 }
112
113 static void natsemi_spi_write_bit ( struct bit_basher *basher,
114                                 unsigned int bit_id, unsigned long data ) {
115         struct natsemi_private *np = container_of ( basher, struct natsemi_private,
116                                                  spibit.basher );
117         uint8_t mask = natsemi_ee_bits[bit_id];
118         uint8_t eereg;
119
120         eereg = inb ( np->ioaddr + EE_REG );
121         eereg &= ~mask;
122         eereg |= ( data & mask );
123         outb ( eereg, np->ioaddr + EE_REG );
124 }
125
126 static struct bit_basher_operations natsemi_basher_ops = {
127         .read = natsemi_spi_read_bit,
128         .write = natsemi_spi_write_bit,
129 };
130
131 /* It looks that this portion of EEPROM can be used for 
132  * non-volatile stored options. Data sheet does not talk about this region.
133  * Currently it is not working. But with some efforts it can.
134  */
135 static struct nvo_fragment natsemi_nvo_fragments[] = {
136         { 0x0c, 0x68 },
137         { 0, 0 }
138 };
139
140 /*
141  * Set up for EEPROM access
142  *
143  * @v NAT               NATSEMI NIC
144  */
145 static void natsemi_init_eeprom ( struct natsemi_private *np ) {
146
147         /* Initialise three-wire bus 
148          */
149         np->spibit.basher.op = &natsemi_basher_ops;
150         np->spibit.bus.mode = SPI_MODE_THREEWIRE;
151         np->spibit.endianness = SPI_BIT_LITTLE_ENDIAN;
152         init_spi_bit_basher ( &np->spibit );
153
154         /*natsemi DP 83815 only supports at93c46
155          */
156         init_at93c46 ( &np->eeprom, 16 );
157         np->eeprom.bus = &np->spibit.bus;
158         np->nvo.nvs = &np->eeprom.nvs;
159         np->nvo.fragments = natsemi_nvo_fragments;
160 }
161
162 /**
163  * Probe PCI device
164  *
165  * @v pci       PCI device
166  * @v id        PCI ID
167  * @ret rc      Return status code
168  */
169 static int natsemi_probe (struct pci_device *pci,
170                        const struct pci_device_id *id __unused) {
171         struct net_device *netdev;
172         struct natsemi_private *np = NULL;
173         uint8_t ll_addr_encoded[MAX_LL_ADDR_LEN];
174         uint8_t last=0,last1=0;
175         uint8_t prev_bytes[2];
176         int i;
177         int rc;
178
179         /* Allocate net device 
180          */
181         netdev = alloc_etherdev (sizeof (*np));
182         if (! netdev) 
183                 return -ENOMEM;
184
185         netdev_init (netdev, &natsemi_operations);
186         np = netdev->priv;
187         pci_set_drvdata (pci, netdev);
188         netdev->dev = &pci->dev;
189         memset (np, 0, sizeof (*np));
190         np->ioaddr = pci->ioaddr;
191
192         adjust_pci_device (pci);
193
194         natsemi_reset (netdev);
195         natsemi_init_eeprom ( np );
196         nvs_read ( &np->eeprom.nvs, EE_MAC-1, prev_bytes, 1 );
197         nvs_read ( &np->eeprom.nvs, EE_MAC, ll_addr_encoded, ETH_ALEN );
198
199         /* decoding the MAC address read from NVS 
200          * and save it in netdev->ll_addr
201          */
202         last = prev_bytes[1] >> 7;
203         for ( i = 0 ; i < ETH_ALEN ; i++ ) {
204                 last1 = ll_addr_encoded[i] >> 7;
205                 netdev->ll_addr[i] = ll_addr_encoded[i] << 1 | last;
206                 last = last1;
207         }
208
209         /* Mark as link up; we don't yet handle link state */
210         netdev_link_up ( netdev );
211
212         if ((rc = register_netdev (netdev)) != 0)
213                 goto err_register_netdev;
214
215         return 0;
216
217 err_register_netdev:
218
219         natsemi_reset (netdev);
220         netdev_put (netdev);
221         return rc;
222 }
223
224 /**
225  * Remove PCI device
226  *
227  * @v pci       PCI device
228  */
229 static void natsemi_remove (struct pci_device *pci) {
230         struct net_device *netdev = pci_get_drvdata (pci);
231  
232         unregister_netdev (netdev);
233         natsemi_reset (netdev);
234         netdev_nullify ( netdev );
235         netdev_put (netdev);
236 }
237
238 /**
239  * Reset NIC
240  *
241  * @v           NATSEMI NIC
242  *
243  * Issues a hardware reset and waits for the reset to complete.
244  */
245 static void natsemi_reset (struct net_device *netdev) 
246 {
247         struct natsemi_private *np = netdev->priv;
248         int i;
249         u32 cfg;
250         u32 wcsr;
251         u32 rfcr;
252         u16 pmatch[3];
253         u16 sopass[3];
254
255         natsemi_irq (netdev, 0);
256
257         /*
258          * Resetting the chip causes some registers to be lost.
259          * Natsemi suggests NOT reloading the EEPROM while live, so instead
260          * we save the state that would have been loaded from EEPROM
261          * on a normal power-up (see the spec EEPROM map).
262          */
263
264         /* CFG */
265         cfg = inl (np->ioaddr + ChipConfig) & CFG_RESET_SAVE;
266
267         /* WCSR */
268         wcsr = inl (np->ioaddr + WOLCmd) & WCSR_RESET_SAVE;
269
270         /* RFCR */
271         rfcr = readl (np->ioaddr + RxFilterAddr) & RFCR_RESET_SAVE;
272
273         /* PMATCH */
274         for (i = 0; i < 3; i++) {
275                 outl(i*2, np->ioaddr + RxFilterAddr);
276                 pmatch[i] = inw(np->ioaddr + RxFilterData);
277         }
278
279         /* SOPAS */
280         for (i = 0; i < 3; i++) {
281                 outl(0xa+(i*2), np->ioaddr + RxFilterAddr);
282                 sopass[i] = inw(np->ioaddr + RxFilterData);
283         }
284
285         /* now whack the chip */
286         outl(ChipReset, np->ioaddr + ChipCmd);
287         for (i=0; i<NATSEMI_HW_TIMEOUT; i++) {
288                 if (! (inl (np->ioaddr + ChipCmd) & ChipReset))
289                        break;
290                 udelay(5);
291         }
292         if (i == NATSEMI_HW_TIMEOUT) {
293                 DBG ("natsemi_reset: reset did not complete in %d usec.\n", i*5);
294         }
295
296         /* restore CFG */
297         cfg |= inl(np->ioaddr + ChipConfig) & ~CFG_RESET_SAVE;
298         cfg &= ~(CfgExtPhy | CfgPhyDis);
299         outl (cfg, np->ioaddr + ChipConfig);
300
301         /* restore WCSR */
302         wcsr |= inl (np->ioaddr + WOLCmd) & ~WCSR_RESET_SAVE;
303         outl (wcsr, np->ioaddr + WOLCmd);
304
305         /* read RFCR */
306         rfcr |= inl (np->ioaddr + RxFilterAddr) & ~RFCR_RESET_SAVE;
307
308         /* restore PMATCH */
309         for (i = 0; i < 3; i++) {
310                 outl (i*2, np->ioaddr + RxFilterAddr);
311                 outw (pmatch[i], np->ioaddr + RxFilterData);
312         }
313         for (i = 0; i < 3; i++) {
314                 outl (0xa+(i*2), np->ioaddr + RxFilterAddr);
315                 outw (sopass[i], np->ioaddr + RxFilterData);
316         }
317         /* restore RFCR */
318         outl (rfcr, np->ioaddr + RxFilterAddr);
319 }
320
321 /**
322  * Open NIC
323  *
324  * @v netdev            Net device
325  * @ret rc              Return status code
326  */
327 static int natsemi_open (struct net_device *netdev)
328 {
329         struct natsemi_private *np = netdev->priv;
330         uint32_t tx_config, rx_config;
331         int i;
332         
333         /* Disable PME:
334          * The PME bit is initialized from the EEPROM contents.
335          * PCI cards probably have PME disabled, but motherboard
336          * implementations may have PME set to enable WakeOnLan. 
337          * With PME set the chip will scan incoming packets but
338          * nothing will be written to memory. 
339          */
340         outl (inl (np->ioaddr + ClkRun) & ~0x100, np->ioaddr + ClkRun);
341
342         /* Set MAC address in NIC
343          */
344         for (i = 0 ; i < ETH_ALEN ; i+=2) {
345                 outl (i, np->ioaddr + RxFilterAddr);
346                 outw (netdev->ll_addr[i] + (netdev->ll_addr[i + 1] << 8),
347                        np->ioaddr + RxFilterData);
348         }
349
350         /* Setup Tx Ring 
351          */
352         np->tx_cur = 0;
353         np->tx_dirty = 0;
354         for (i = 0 ; i < TX_RING_SIZE ; i++) {
355                 np->tx[i].link   = virt_to_bus ((i + 1 < TX_RING_SIZE) ? &np->tx[i + 1] : &np->tx[0]);
356                 np->tx[i].cmdsts = 0;
357                 np->tx[i].bufptr = 0;
358         }
359         outl (virt_to_bus (&np->tx[0]),np->ioaddr + TxRingPtr);
360
361         DBG ("Natsemi Tx descriptor loaded with: %#08x\n",
362              inl (np->ioaddr + TxRingPtr));
363
364         /* Setup RX ring
365          */
366         np->rx_cur = 0;
367         for (i = 0 ; i < NUM_RX_DESC ; i++) {
368                 np->iobuf[i] = alloc_iob (RX_BUF_SIZE);
369                 if (! np->iobuf[i])
370                         goto memory_alloc_err;
371                 np->rx[i].link   = virt_to_bus ((i + 1 < NUM_RX_DESC) 
372                                                 ? &np->rx[i + 1] : &np->rx[0]);
373                 np->rx[i].cmdsts = RX_BUF_SIZE;
374                 np->rx[i].bufptr = virt_to_bus (np->iobuf[i]->data);
375                 DBG (" Address of iobuf [%d] = %p and iobuf->data = %p \n", i, 
376                       &np->iobuf[i],  &np->iobuf[i]->data);
377         }
378         outl (virt_to_bus (&np->rx[0]), np->ioaddr + RxRingPtr);
379
380         DBG ("Natsemi Rx descriptor loaded with: %#08x\n",
381               inl (np->ioaddr + RxRingPtr));            
382
383         /* Setup RX Filter 
384          */
385         outl (RxFilterEnable | AcceptBroadcast | AcceptAllMulticast | AcceptMyPhys,
386               np->ioaddr + RxFilterAddr);
387
388         /* Initialize other registers. 
389          * Configure the PCI bus bursts and FIFO thresholds. 
390          * Configure for standard, in-spec Ethernet. 
391          */
392         if (inl (np->ioaddr + ChipConfig) & 0x20000000) {       /* Full duplex */
393                 DBG ("Full duplex\n");
394                 tx_config = 0xD0801002 |  0xC0000000;
395                 rx_config = 0x10000020 |  0x10000000;
396         } else {
397                 DBG ("Half duplex\n");
398                 tx_config = 0x10801002 & ~0xC0000000;
399                 rx_config = 0x00000020 & ~0x10000000;
400         }
401         outl (tx_config, np->ioaddr + TxConfig);
402         outl (rx_config, np->ioaddr + RxConfig);
403
404         DBG ("Tx config register = %#08x Rx config register = %#08x\n", 
405                inl (np->ioaddr + TxConfig),
406                inl (np->ioaddr + RxConfig));
407
408         /*Set the Interrupt Mask register
409          */
410         outl((RxOk|RxErr|TxOk|TxErr),np->ioaddr + IntrMask);
411         /*start the receiver 
412          */
413         outl (RxOn, np->ioaddr + ChipCmd);
414         
415         return 0;
416                        
417 memory_alloc_err:
418
419         /* Frees any allocated buffers when memory
420          * for all buffers requested is not available
421          */
422         i = 0;
423         while (np->rx[i].cmdsts == RX_BUF_SIZE) {
424                 free_iob (np->iobuf[i]);
425                 i++;
426         }
427         return -ENOMEM; 
428 }
429
430 /**
431  * Close NIC
432  *
433  * @v netdev            Net device
434  */
435 static void natsemi_close (struct net_device *netdev) 
436 {
437         struct natsemi_private *np = netdev->priv;
438         int i;
439
440         natsemi_reset (netdev);
441
442         for (i = 0; i < NUM_RX_DESC ; i++) {
443                 free_iob (np->iobuf[i]);
444         }
445 }
446
447 /** 
448  * Transmit packet
449  *
450  * @v netdev    Network device
451  * @v iobuf     I/O buffer
452  * @ret rc      Return status code
453  */
454 static int natsemi_transmit (struct net_device *netdev, struct io_buffer *iobuf)
455 {
456         struct natsemi_private *np = netdev->priv;
457
458         if (np->tx[np->tx_cur].cmdsts != 0) {
459                 DBG ("TX overflow\n");
460                 return -ENOBUFS;
461         }
462
463         /* Used by netdev_tx_complete ()
464          */
465         np->tx_iobuf[np->tx_cur] = iobuf;
466
467         /* Pad and align packet has not been used because its not required 
468          * by the hardware.
469          *      iob_pad (iobuf, ETH_ZLEN); 
470          * can be used to achieve it, if required
471          */
472
473         /* Add the packet to TX ring
474          */
475         np->tx[np->tx_cur].bufptr = virt_to_bus (iobuf->data);
476         np->tx[np->tx_cur].cmdsts = iob_len (iobuf) | OWN;
477
478         DBG ("TX id %d at %#08lx + %#08zx\n", np->tx_cur,
479              virt_to_bus (&iobuf->data), iob_len (iobuf));
480
481         /* increment the circular buffer pointer to the next buffer location
482          */
483         np->tx_cur = (np->tx_cur + 1) % TX_RING_SIZE;
484
485         /*start the transmitter 
486          */
487         outl (TxOn, np->ioaddr + ChipCmd);
488
489         return 0;
490 }
491
492 /** 
493  * Poll for received packets
494  *
495  * @v netdev    Network device
496  */
497 static void natsemi_poll (struct net_device *netdev)
498 {
499         struct natsemi_private *np = netdev->priv;
500         unsigned int tx_status;
501         unsigned int rx_status;
502         unsigned int intr_status;
503         unsigned int rx_len;
504         struct io_buffer *rx_iob;
505         int i;
506         
507         /* read the interrupt register
508          */
509         intr_status = inl (np->ioaddr + IntrStatus);
510
511         if (!intr_status)
512                 goto end;
513
514         DBG ("natsemi_poll: intr_status = %#08x\n", intr_status);
515
516         /* Check status of transmitted packets
517          */
518         i = np->tx_dirty;
519         while (i != np->tx_cur) {
520                 tx_status = np->tx[np->tx_dirty].cmdsts;
521
522                 DBG ("tx_dirty = %d tx_cur=%d tx_status=%#08x\n",
523                      np->tx_dirty, np->tx_cur, tx_status);
524                 
525                 if (tx_status & OWN) 
526                         break;
527
528                 if (! (tx_status & DescPktOK)) {
529                         netdev_tx_complete_err (netdev,np->tx_iobuf[np->tx_dirty],-EINVAL);
530                         DBG ("Error transmitting packet, tx_status: %#08x\n",
531                              tx_status);
532                 } else {
533                         netdev_tx_complete (netdev, np->tx_iobuf[np->tx_dirty]);
534                         DBG ("Success transmitting packet\n");
535                 }
536
537                 np->tx[np->tx_dirty].cmdsts = 0;
538                 np->tx_dirty = (np->tx_dirty + 1) % TX_RING_SIZE;
539                 i = (i + 1) % TX_RING_SIZE;
540         }
541         
542         /* Process received packets 
543          */
544         rx_status = (unsigned int) np->rx[np->rx_cur].cmdsts; 
545         while ((rx_status & OWN)) {
546                 rx_len = (rx_status & DSIZE) - CRC_SIZE;
547
548                 DBG ("Received packet, rx_curr = %d, rx_status = %#08x, rx_len = %d\n",
549                      np->rx_cur, rx_status, rx_len);
550                 
551                 if ((rx_status & (DescMore | DescPktOK | RxTooLong)) != DescPktOK) {
552                         netdev_rx_err (netdev, NULL, -EINVAL);
553
554                         DBG ("natsemi_poll: Corrupted packet received!"
555                              " Status = %#08x\n",
556                               np->rx[np->rx_cur].cmdsts);
557
558                 } else  {
559
560
561                         /* If unable allocate space for this packet,
562                          *  try again next poll
563                          */
564                         rx_iob = alloc_iob (rx_len);
565                         if (! rx_iob) 
566                                 goto end;
567                         memcpy (iob_put (rx_iob, rx_len), 
568                                 np->iobuf[np->rx_cur]->data, rx_len);
569                         /* Add this packet to the receive queue. 
570                          */
571                         netdev_rx (netdev, rx_iob);
572                 }
573                 np->rx[np->rx_cur].cmdsts = RX_BUF_SIZE;
574                 np->rx_cur = (np->rx_cur + 1) % NUM_RX_DESC;
575                 rx_status = np->rx[np->rx_cur].cmdsts; 
576         }
577 end:
578         /* re-enable the potentially idle receive state machine 
579          */
580         outl (RxOn, np->ioaddr + ChipCmd);      
581 }                               
582
583 /**
584  * Enable/disable interrupts
585  *
586  * @v netdev    Network device
587  * @v enable    Non-zero for enable, zero for disable
588  */
589 static void natsemi_irq (struct net_device *netdev, int enable)
590 {
591         struct natsemi_private *np = netdev->priv;
592
593         outl ((enable ? (RxOk | RxErr | TxOk|TxErr) : 0),
594               np->ioaddr + IntrMask); 
595         outl ((enable ? 1 : 0), np->ioaddr + IntrEnable);
596 }
597
598 static struct pci_device_id natsemi_nics[] = {
599         PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815", 0),
600 };
601
602 struct pci_driver natsemi_driver __pci_driver = {
603         .ids = natsemi_nics,
604         .id_count = (sizeof (natsemi_nics) / sizeof (natsemi_nics[0])),
605         .probe = natsemi_probe,
606         .remove = natsemi_remove,
607 };