added change log to natsemi.c
[people/holger/gpxe.git] / src / drivers / net / natsemi.c
1 /* natsemi.c - gPXE driver for the NatSemi DP8381x series. */
2
3 /*
4
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@thinguin.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                                  Added a circular buffer for transmit and receive.
54                                  transmit routine will not wait for transmission to finish
55                                  poll routine deals with it.
56
57   13 Dec 2003 timlegge          1.1 Enabled Multicast Support
58   29 May 2001  mdc              1.0
59      Initial Release.           Tested with Netgear FA311 and FA312 boards
60 */
61  
62
63
64
65 #include <stdint.h>
66 #include <stdlib.h>
67 #include <stdio.h>
68 #include <io.h>
69 #include <errno.h>
70 #include <timer.h>
71 #include <byteswap.h>
72 #include <gpxe/pci.h>
73 #include <gpxe/if_ether.h>
74 #include <gpxe/ethernet.h>
75 #include <gpxe/iobuf.h>
76 #include <gpxe/netdevice.h>
77 #include <gpxe/spi_bit.h>
78 #include <gpxe/threewire.h>
79 #include <gpxe/nvo.h>
80
81 #define TX_RING_SIZE 4
82 #define NUM_RX_DESC  4
83 #define RX_BUF_SIZE 1536
84 #define OWN       0x80000000
85 #define DSIZE     0x00000FFF
86 #define CRC_SIZE  4
87
88 struct natsemi_tx {
89         uint32_t link;
90         uint32_t cmdsts;
91         uint32_t bufptr;
92 };
93
94 struct natsemi_rx {
95         uint32_t link;
96         uint32_t cmdsts;
97         uint32_t bufptr;
98 };
99
100 struct natsemi_nic {
101         unsigned short ioaddr;
102         unsigned short tx_cur;
103         unsigned short tx_dirty;
104         unsigned short rx_cur;
105         struct natsemi_tx tx[TX_RING_SIZE];
106         struct natsemi_rx rx[NUM_RX_DESC];
107         /* need to add iobuf as we cannot free iobuf->data in close without this 
108          * alternatively substracting sizeof(head) and sizeof(list_head) can also 
109          * give the same.*/
110         struct io_buffer *iobuf[NUM_RX_DESC];
111         /*netdev_tx_complete needs pointer to the iobuf of the data so as to free 
112           it from the memory.*/
113         struct io_buffer *tx_iobuf[TX_RING_SIZE];
114         struct spi_bit_basher spibit;
115         struct spi_device eeprom;
116         struct nvo_block nvo;
117 };
118
119
120 /* NATSEMI: Offsets to the device registers.
121    Unlike software-only systems, device drivers interact with complex hardware.
122    It's not useful to define symbolic names for every register bit in the
123    device.
124 */
125 enum register_offsets {
126     ChipCmd      = 0x00, 
127     ChipConfig   = 0x04, 
128     EECtrl       = 0x08, 
129     PCIBusCfg    = 0x0C,
130     IntrStatus   = 0x10, 
131     IntrMask     = 0x14, 
132     IntrEnable   = 0x18,
133     TxRingPtr    = 0x20, 
134     TxConfig     = 0x24,
135     RxRingPtr    = 0x30,
136     RxConfig     = 0x34, 
137     ClkRun       = 0x3C,
138     WOLCmd       = 0x40, 
139     PauseCmd     = 0x44,
140     RxFilterAddr = 0x48, 
141     RxFilterData = 0x4C,
142     BootRomAddr  = 0x50, 
143     BootRomData  = 0x54, 
144     SiliconRev   = 0x58, 
145     StatsCtrl    = 0x5C,
146     StatsData    = 0x60, 
147     RxPktErrs    = 0x60, 
148     RxMissed     = 0x68, 
149     RxCRCErrs    = 0x64,
150     PCIPM        = 0x44,
151     PhyStatus    = 0xC0, 
152     MIntrCtrl    = 0xC4, 
153     MIntrStatus  = 0xC8,
154
155     /* These are from the spec, around page 78... on a separate table. */
156     PGSEL        = 0xCC, 
157     PMDCSR       = 0xE4, 
158     TSTDAT       = 0xFC, 
159     DSPCFG       = 0xF4, 
160     SDCFG        = 0x8C,
161     BasicControl = 0x80,        
162     BasicStatus  = 0x84
163             
164 };
165
166
167
168
169 /* Bit in ChipCmd. */
170 enum ChipCmdBits {
171     ChipReset = 0x100, 
172     RxReset   = 0x20, 
173     TxReset   = 0x10, 
174     RxOff     = 0x08, 
175     RxOn      = 0x04,
176     TxOff     = 0x02, 
177     TxOn      = 0x01
178 };
179
180
181 /* Bits in the RxMode register. */
182 enum rx_mode_bits {
183     AcceptErr          = 0x20,
184     AcceptRunt         = 0x10,
185     AcceptBroadcast    = 0xC0000000,
186     AcceptMulticast    = 0x00200000, 
187     AcceptAllMulticast = 0x20000000,
188     AcceptAllPhys      = 0x10000000, 
189     AcceptMyPhys       = 0x08000000,
190     RxFilterEnable     = 0x80000000
191 };
192
193 /* Bits in network_desc.status */
194 enum desc_status_bits {
195     DescOwn   = 0x80000000, 
196     DescMore  = 0x40000000, 
197     DescIntr  = 0x20000000,
198     DescNoCRC = 0x10000000,
199     DescPktOK = 0x08000000, 
200     RxTooLong = 0x00400000
201 };
202
203
204
205 /*  EEPROM access , values are devices specific*/
206 #define EE_CS           0x08    /* EEPROM chip select */
207 #define EE_SK           0x04    /* EEPROM shift clock */
208 #define EE_DI           0x01    /* Data in */
209 #define EE_DO           0x02    /* Data out */
210
211 /* Offsets within EEPROM (these are word offsets) */
212 #define EE_MAC 7
213 #define EE_REG  EECtrl
214 static uint32_t SavedClkRun;    
215
216
217 static const uint8_t nat_ee_bits[] = {
218         [SPI_BIT_SCLK]  = EE_SK,
219         [SPI_BIT_MOSI]  = EE_DI,
220         [SPI_BIT_MISO]  = EE_DO,
221         [SPI_BIT_SS(0)] = EE_CS,
222 };
223
224 static int nat_spi_read_bit ( struct bit_basher *basher,
225                               unsigned int bit_id ) {
226         struct natsemi_nic *nat = container_of ( basher, struct natsemi_nic,
227                                                  spibit.basher );
228         uint8_t mask = nat_ee_bits[bit_id];
229         uint8_t eereg;
230
231         eereg = inb ( nat->ioaddr + EE_REG);
232         return ( eereg & mask );
233 }
234
235 static void nat_spi_write_bit ( struct bit_basher *basher,
236                                 unsigned int bit_id, unsigned long data ) {
237         struct natsemi_nic *nat = container_of ( basher, struct natsemi_nic,
238                                                  spibit.basher );
239         uint8_t mask = nat_ee_bits[bit_id];
240         uint8_t eereg;
241
242         eereg = inb ( nat->ioaddr + EE_REG );
243         eereg &= ~mask;
244         eereg |= ( data & mask );
245         outb ( eereg, nat->ioaddr + EE_REG);
246 }
247
248 static struct bit_basher_operations nat_basher_ops = {
249         .read = nat_spi_read_bit,
250         .write = nat_spi_write_bit,
251 };
252 /** Portion of EEPROM available for non-volatile stored options
253  *
254  * We use offset 0x40 (i.e. address 0x20), length 0x40.  This block is
255  * marked as VPD in the rtl8139 datasheets, so we use it only if we
256  * detect that the card is not supporting VPD.
257  */
258 static struct nvo_fragment nat_nvo_fragments[] = {
259         { 0x0c, 0x40 },
260         { 0, 0 }
261 };
262
263 /**
264  * Set up for EEPROM access
265  *
266  * @v NAT               NATSEMI NIC
267  */
268  void nat_init_eeprom ( struct natsemi_nic *nat ) {
269
270         // Initialise three-wire bus 
271         nat->spibit.basher.op = &nat_basher_ops;
272         nat->spibit.bus.mode = SPI_MODE_THREEWIRE;
273         nat->spibit.endianness = SPI_BIT_LITTLE_ENDIAN;
274         init_spi_bit_basher ( &nat->spibit );
275
276         /*natsemi DP 83815 only supports at93c46 */
277         init_at93c46 ( &nat->eeprom, 16 );
278         nat->eeprom.bus = &nat->spibit.bus;
279
280                 nat->nvo.nvs = &nat->eeprom.nvs;
281                 nat->nvo.fragments = nat_nvo_fragments;
282 }
283
284 /**
285  * Reset NIC
286  *
287  * @v           NATSEMI NIC
288  *
289  * Issues a hardware reset and waits for the reset to complete.
290  */
291 static void nat_reset ( struct natsemi_nic *nat ) {
292
293         int i;
294         /* Reset chip */
295         outl ( ChipReset, nat->ioaddr + ChipCmd );
296         mdelay ( 10 );
297         nat->tx_dirty=0;
298         nat->tx_cur=0;
299         for(i=0;i<TX_RING_SIZE;i++)
300         {
301                 nat->tx[i].link=0;
302                 nat->tx[i].cmdsts=0;
303                 nat->tx[i].bufptr=0;
304         }
305         nat->rx_cur = 0;
306         outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
307         outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
308
309         outl(TxOff|RxOff, nat->ioaddr + ChipCmd);
310
311         /* Restore PME enable bit */
312         outl(SavedClkRun, nat->ioaddr + ClkRun);
313 }
314
315 /**
316  * Open NIC
317  *
318  * @v netdev            Net device
319  * @ret rc              Return status code
320  */
321 static int nat_open ( struct net_device *netdev ) {
322         struct natsemi_nic *nat = netdev->priv;
323         int i;
324         uint32_t tx_config,rx_config;
325         
326         /* Disable PME:
327         * The PME bit is initialized from the EEPROM contents.
328         * PCI cards probably have PME disabled, but motherboard
329         * implementations may have PME set to enable WakeOnLan. 
330         * With PME set the chip will scan incoming packets but
331         * nothing will be written to memory. */
332         SavedClkRun = inl(nat->ioaddr + ClkRun);
333         outl(SavedClkRun & ~0x100, nat->ioaddr + ClkRun);
334
335                 
336
337
338          uint8_t last=0;
339          uint8_t last1=0;
340          for ( i = 0 ; i < ETH_ALEN ; i+=2 )
341          {
342                 outl(i,nat->ioaddr+RxFilterAddr);
343                 last1=netdev->ll_addr[i]>>7;
344                 netdev->ll_addr[i]=netdev->ll_addr[i]<<1|last;
345                 last=(netdev->ll_addr[i+1]>>7);
346                 netdev->ll_addr[i+1]=(netdev->ll_addr[i+1]<<1)+last1;
347
348                 outw ( netdev->ll_addr[i] + (netdev->ll_addr[i+1]<<8), nat->ioaddr +RxFilterData);
349         }
350        
351
352
353         /*Set up the Tx Ring */
354         nat->tx_cur=0;
355         nat->tx_dirty=0;
356         for (i=0;i<TX_RING_SIZE;i++)
357         {
358                 nat->tx[i].link   = virt_to_bus((i+1 < TX_RING_SIZE) ? &nat->tx[i+1] : &nat->tx[0]);
359                 nat->tx[i].cmdsts = 0;
360                 nat->tx[i].bufptr = 0;
361         }
362
363
364
365
366
367         /* Set up RX ring */
368         nat->rx_cur=0;
369         for (i=0;i<NUM_RX_DESC;i++)
370         {
371
372                 nat->iobuf[i] = alloc_iob ( RX_BUF_SIZE );
373                 if (!nat->iobuf[i])
374                        return -ENOMEM;  
375                 nat->rx[i].link   = virt_to_bus((i+1 < NUM_RX_DESC) ? &nat->rx[i+1] : &nat->rx[0]);
376                 nat->rx[i].cmdsts = (uint32_t) RX_BUF_SIZE;
377                 nat->rx[i].bufptr = virt_to_bus(nat->iobuf[i]->data);
378         }
379
380
381          /* load Receive Descriptor Register */
382         outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
383         DBG("Natsemi Rx descriptor loaded with: %X\n",(unsigned int)inl(nat->ioaddr+RxRingPtr));                
384
385         /* setup Tx ring */
386         outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
387         DBG("Natsemi Tx descriptor loaded with: %X\n",(unsigned int)inl(nat->ioaddr+TxRingPtr));
388
389         /* Enables RX */
390         outl(RxFilterEnable|AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys, nat->ioaddr+RxFilterAddr);
391
392         /* Initialize other registers. */
393         /* Configure the PCI bus bursts and FIFO thresholds. */
394         /* Configure for standard, in-spec Ethernet. */
395         if (inl(nat->ioaddr + ChipConfig) & 0x20000000) {       /* Full duplex */
396                 tx_config = 0xD0801002;
397                 rx_config = 0x10000020;
398         } else {
399                 tx_config = 0x10801002;
400                 rx_config = 0x0020;
401         }
402         outl(tx_config, nat->ioaddr + TxConfig);
403         outl(rx_config, nat->ioaddr + RxConfig);
404
405
406
407         /*start the receiver  */
408         outl(RxOn, nat->ioaddr + ChipCmd);
409
410
411         return 0;
412 }
413
414 /**
415  * Close NIC
416  *
417  * @v netdev            Net device
418  */
419 static void nat_close ( struct net_device *netdev ) {
420         struct natsemi_nic *nat = netdev->priv;
421         int i;
422
423
424         /* Reset the hardware to disable everything in one go */
425         nat_reset ( nat );
426
427         /* Free RX ring */
428         for (i=0;i<NUM_RX_DESC;i++)
429         {
430                 
431                 free_iob( nat->iobuf[i] );
432         }
433 }
434
435 /** 
436  * Transmit packet
437  *
438  * @v netdev    Network device
439  * @v iobuf     I/O buffer
440  * @ret rc      Return status code
441  */
442 static int nat_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
443         struct natsemi_nic *nat = netdev->priv;
444
445        /* check for space in TX ring */
446
447         if (nat->tx[nat->tx_cur].cmdsts !=0)
448         {
449                 printf ( "TX overflow\n" );
450                 return -ENOBUFS;
451         }
452
453         /* to be used in netdev_tx_complete*/
454         nat->tx_iobuf[nat->tx_cur]=iobuf;
455
456         /* Pad and align packet */
457         iob_pad ( iobuf, ETH_ZLEN );
458
459         /* Add to TX ring */
460         DBG ( "TX id %d at %lx+%x\n", nat->tx_cur,
461               virt_to_bus ( &iobuf->data ), iob_len ( iobuf ) );
462
463         nat->tx[nat->tx_cur].bufptr = virt_to_bus(iobuf->data);
464         nat->tx[nat->tx_cur].cmdsts= (uint32_t) iob_len(iobuf)|OWN;
465
466
467         nat->tx_cur=(nat->tx_cur+1) % TX_RING_SIZE;
468
469         /*start the transmitter  */
470         outl(TxOn, nat->ioaddr + ChipCmd);
471
472         return 0;
473 }
474
475 /** 
476  * Poll for received packets
477  *
478  * @v netdev    Network device
479  * @v rx_quota  Maximum number of packets to receive
480  */
481 static void nat_poll ( struct net_device *netdev, unsigned int rx_quota ) {
482         struct natsemi_nic *nat = netdev->priv;
483         unsigned int status;
484         unsigned int rx_status;
485         unsigned int rx_len;
486         struct io_buffer *rx_iob;
487         int i;
488         
489         /* check the status of packets given to card for transmission */        
490         i=nat->tx_dirty;
491         while(i!=nat->tx_cur)
492         {
493                 status=nat->tx[nat->tx_dirty].cmdsts;
494                 DBG("value of tx_dirty = %d tx_cur=%d status=%X\n",
495                         nat->tx_dirty,nat->tx_cur,status);
496                 
497                 /* check if current packet has been transmitted or not */
498                 if(status & OWN) 
499                         break;
500                 /* Check if any errors in transmission */
501                 if (! (status & DescPktOK))
502                 {
503                         printf("Error in sending Packet status:%X\n",
504                                         (unsigned int)status);
505                 }
506                 else
507                 {
508                         DBG("Success in transmitting Packet with data\n");
509                 //      DBG_HD(&nat->tx[nat->tx_dirty].bufptr,130);
510                 }
511                 netdev_tx_complete(netdev,nat->tx_iobuf[nat->tx_dirty]);
512                 /* setting cmdsts zero, indicating that it can be reused */
513                 nat->tx[nat->tx_dirty].cmdsts=0;
514                 nat->tx_dirty=(nat->tx_dirty +1) % TX_RING_SIZE;
515                 i=(i+1) % TX_RING_SIZE;
516
517         }
518                         
519         
520         rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts; 
521         /* Handle received packets */
522         while (rx_quota && (rx_status & OWN))
523         {
524                 rx_len= (rx_status & DSIZE) - CRC_SIZE;
525
526                 /*check for the corrupt packet */
527                 if((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK)
528                 {
529                          printf("natsemi_poll: Corrupted packet received, "
530                                         "buffer status = %X ^ %X \n",rx_status,
531                                         (unsigned int) nat->rx[nat->rx_cur].cmdsts);
532                 }
533                 else
534                 {
535                         rx_iob = alloc_iob(rx_len);
536                         if(!rx_iob) 
537                                 /* leave packet for next call to poll*/
538                                 return;
539                         memcpy(iob_put(rx_iob,rx_len),
540                                         bus_to_virt(nat->rx[nat->rx_cur].bufptr),rx_len);
541
542                         DBG("received packet\n");
543                         /* add to the receive queue. */
544                         netdev_rx(netdev,rx_iob);
545                         rx_quota--;
546                 }
547                 nat->rx[nat->rx_cur].cmdsts = RX_BUF_SIZE;
548                 nat->rx_cur=(nat->rx_cur+1) % NUM_RX_DESC;
549                 rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts; 
550         }
551
552
553          /* re-enable the potentially idle receive state machine */
554             outl(RxOn, nat->ioaddr + ChipCmd);  
555 }                               
556
557
558
559
560
561
562 /**
563  * Probe PCI device
564  *
565  * @v pci       PCI device
566  * @v id        PCI ID
567  * @ret rc      Return status code
568  */
569 static int nat_probe ( struct pci_device *pci,
570                        const struct pci_device_id *id __unused ) {
571         struct net_device *netdev;
572         struct natsemi_nic *nat = NULL;
573         int registered_netdev = 0;
574         int rc;
575         uint32_t advertising;
576
577         /* Fix up PCI device */
578         adjust_pci_device ( pci );
579
580         /* Allocate net device */
581         netdev = alloc_etherdev ( sizeof ( *nat ) );
582         if ( ! netdev ) {
583                 rc = -ENOMEM;
584                 goto err;
585         }
586         nat = netdev->priv;
587         pci_set_drvdata ( pci, netdev );
588         netdev->dev = &pci->dev;
589         memset ( nat, 0, sizeof ( *nat ) );
590         nat->ioaddr = pci->ioaddr;
591
592         /* Reset the NIC, set up EEPROM access and read MAC address */
593         nat_reset ( nat );
594         nat_init_eeprom ( nat );
595         nvs_read ( &nat->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
596         uint8_t  eetest[128];   
597         nvs_read ( &nat->eeprom.nvs, 0, eetest,128 );
598         
599
600         /* mdio routine of etherboot-5.4.0 natsemi driver has been removed and 
601          * statement to read from MII transceiver control section is used directly
602          */
603
604         advertising = inl(nat->ioaddr + 0x80 + (4<<2)) & 0xffff; 
605         {
606                 uint32_t chip_config = inl(nat->ioaddr + ChipConfig);
607                 DBG("%s: Transceiver default autoneg. %s 10 %s %s duplex.\n",
608                 pci->driver_name,
609                 chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
610                 chip_config & 0x4000 ? "0" : "",
611                 chip_config & 0x8000 ? "full" : "half");
612         }
613         DBG("%s: Transceiver status %hX advertising %hX\n",pci->driver_name, (int)inl(nat->ioaddr + 0x84),(unsigned int) advertising);
614
615
616
617
618
619         /* Point to NIC specific routines */
620         netdev->open     = nat_open;
621         netdev->close    = nat_close;
622         netdev->transmit = nat_transmit;
623         netdev->poll     = nat_poll;
624
625         /* Register network device */
626         if ( ( rc = register_netdev ( netdev ) ) != 0 )
627                 goto err;
628         registered_netdev = 1;
629
630         /* Register non-volatile storagei
631          * uncomment lines below in final version*/
632         
633          if ( nat->nvo.nvs ) {
634                 if ( ( rc = nvo_register ( &nat->nvo ) ) != 0 )
635                         goto err;
636         }
637         
638
639         return 0;
640
641  err:
642         /* Disable NIC */
643         if ( nat )
644                 nat_reset ( nat );
645         if ( registered_netdev )
646                 unregister_netdev ( netdev );
647         /* Free net device */
648         netdev_put ( netdev );
649         return rc;
650 }
651
652 /**
653  * Remove PCI device
654  *
655  * @v pci       PCI device
656  */
657 static void nat_remove ( struct pci_device *pci ) {
658         struct net_device *netdev = pci_get_drvdata ( pci );
659         struct natsemi_nic *nat = netdev->priv;
660  
661         if ( nat->nvo.nvs )
662                 nvo_unregister ( &nat->nvo );
663                 
664         unregister_netdev ( netdev );
665         nat_reset ( nat );
666         netdev_put ( netdev );
667 }
668
669 static struct pci_device_id natsemi_nics[] = {
670         PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
671
672 };
673
674 struct pci_driver natsemi_driver __pci_driver = {
675         .ids = natsemi_nics,
676         .id_count = ( sizeof ( natsemi_nics ) / sizeof ( natsemi_nics[0] ) ),
677         .probe = nat_probe,
678         .remove = nat_remove,
679 };