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