debugging 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 #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         { 0x0f, 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          uint8_t last=0;
297          uint8_t last1=0;
298          for ( i = 0 ; i < ETH_ALEN ; i+=2 )
299          {
300         //      DBG("MAC address %d octet :%X %X\n",i,netdev->ll_addr[i],netdev->ll_addr[i+1]);
301         //      DBG("LAst = %d last1 = %d\n",last,last1);
302                 outl(i,nat->ioaddr+RxFilterAddr);
303                 last1=netdev->ll_addr[i]>>7;
304                 netdev->ll_addr[i]=netdev->ll_addr[i]<<1|last;
305                 last=(netdev->ll_addr[i+1]>>7);
306                 netdev->ll_addr[i+1]=(netdev->ll_addr[i+1]<<1)+last1;
307
308                 outw ( netdev->ll_addr[i] + (netdev->ll_addr[i+1]<<8), nat->ioaddr +RxFilterData);
309                 //outw ( (fullbyte>>8)+(fullbyte<<8), nat->ioaddr +RxFilterData);
310         //      DBG("MAC address %d octet :%X %X\n",i,netdev->ll_addr[i],netdev->ll_addr[i+1]);
311         //      DBG("LAst = %d last1 = %d\n",last,last1);
312         }
313        
314
315
316         /*Set up the Tx Ring */
317         nat->tx_cur=0;
318         nat->tx_dirty=0;
319         for (i=0;i<TX_RING_SIZE;i++)
320         {
321                 nat->tx[i].link   = virt_to_bus((i+1 < TX_RING_SIZE) ? &nat->tx[i+1] : &nat->tx[0]);
322                 nat->tx[i].cmdsts = 0;
323                 nat->tx[i].bufptr = 0;
324         }
325
326
327
328
329
330         /* Set up RX ring */
331         nat->rx_cur=0;
332         for (i=0;i<NUM_RX_DESC;i++)
333         {
334
335                 nat->iobuf[i] = alloc_iob ( RX_BUF_SIZE );
336                 if (!nat->iobuf[i])
337                        return -ENOMEM;  
338                 nat->rx[i].link   = virt_to_bus((i+1 < NUM_RX_DESC) ? &nat->rx[i+1] : &nat->rx[0]);
339                 nat->rx[i].cmdsts = (uint32_t) RX_BUF_SIZE;
340                 nat->rx[i].bufptr = virt_to_bus(nat->iobuf[i]->data);
341         }
342
343
344          /* load Receive Descriptor Register */
345         outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
346         DBG("Natsemi Rx descriptor loaded with: %X\n",(unsigned int)inl(nat->ioaddr+RxRingPtr));                
347
348         /* setup Tx ring */
349         outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
350         DBG("Natsemi Tx descriptor loaded with: %X\n",(unsigned int)inl(nat->ioaddr+TxRingPtr));
351
352         /* Enables RX */
353         outl(RxFilterEnable|AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys, nat->ioaddr+RxFilterAddr);
354
355         /* Initialize other registers. */
356         /* Configure the PCI bus bursts and FIFO thresholds. */
357         /* Configure for standard, in-spec Ethernet. */
358         if (inl(nat->ioaddr + ChipConfig) & 0x20000000) {       /* Full duplex */
359                 tx_config = 0xD0801002;
360                 rx_config = 0x10000020;
361         } else {
362                 tx_config = 0x10801002;
363                 rx_config = 0x0020;
364         }
365         outl(tx_config, nat->ioaddr + TxConfig);
366         outl(rx_config, nat->ioaddr + RxConfig);
367
368
369
370         /*start the receiver  */
371         outl(RxOn, nat->ioaddr + ChipCmd);
372
373
374         return 0;
375 }
376
377 /**
378  * Close NIC
379  *
380  * @v netdev            Net device
381  */
382 static void nat_close ( struct net_device *netdev ) {
383         struct natsemi_nic *nat = netdev->priv;
384         int i;
385
386
387         /* Reset the hardware to disable everything in one go */
388         nat_reset ( nat );
389
390         /* Free RX ring */
391         for (i=0;i<NUM_RX_DESC;i++)
392         {
393                 
394                 free_iob( nat->iobuf[i] );
395         }
396 }
397
398 /** 
399  * Transmit packet
400  *
401  * @v netdev    Network device
402  * @v iobuf     I/O buffer
403  * @ret rc      Return status code
404  */
405 static int nat_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
406         struct natsemi_nic *nat = netdev->priv;
407
408        /* check for space in TX ring */
409
410         if (nat->tx[nat->tx_cur].cmdsts !=0)
411         {
412                 printf ( "TX overflow\n" );
413                 return -ENOBUFS;
414         }
415
416         //DBG_HD(iobuf->data,iob_len(iobuf));
417
418         /* Pad and align packet */
419         iob_pad ( iobuf, ETH_ZLEN );
420
421         /* Add to TX ring */
422         DBG ( "TX id %d at %lx+%x\n", nat->tx_cur,
423               virt_to_bus ( &iobuf->data ), iob_len ( iobuf ) );
424
425         nat->tx[nat->tx_cur].bufptr = virt_to_bus(iobuf->data);
426         nat->tx[nat->tx_cur].cmdsts= (uint32_t) iob_len(iobuf)|OWN;
427
428
429         //DBG_HD(bus_to_virt(nat->tx[nat->tx_cur].bufptr), iob_len(iobuf) );
430         nat->tx_cur=(nat->tx_cur+1) % TX_RING_SIZE;
431
432         /*start the transmitter  */
433         outl(TxOn, nat->ioaddr + ChipCmd);
434
435         return 0;
436 }
437
438 /** 
439  * Poll for received packets
440  *
441  * @v netdev    Network device
442  * @v rx_quota  Maximum number of packets to receive
443  */
444 static void nat_poll ( struct net_device *netdev, unsigned int rx_quota ) {
445         struct natsemi_nic *nat = netdev->priv;
446         unsigned int status;
447         unsigned int rx_status;
448         unsigned int rx_len;
449         struct io_buffer *rx_iob;
450         int i;
451         
452         /* check the status of packets given to card for transmission */        
453         i=nat->tx_dirty;
454         while(i!=nat->tx_cur)
455         {
456                 //status=(uint32_t)bus_to_virt(nat->tx[nat->tx_dirty].cmdsts);
457                 status=nat->tx[nat->tx_dirty].cmdsts;
458                 DBG("value of tx_dirty = %d tx_cur=%d status=%X\n",
459                         nat->tx_dirty,nat->tx_cur,status);
460                 
461                 /* check if current packet has been transmitted or not */
462                 if(status & OWN) 
463                         break;
464                 /* Check if any errors in transmission */
465                 if (! (status & DescPktOK))
466                 {
467                         printf("Error in sending Packet status:%X\n",
468                                         (unsigned int)status);
469                 }
470                 else
471                 {
472                         DBG("Success in transmitting Packet with data\n");
473                 //      DBG_HD(&nat->tx[nat->tx_dirty].bufptr,130);
474                 }
475                 /* setting cmdsts zero, indicating that it can be reused */
476                 nat->tx[nat->tx_dirty].cmdsts=0;
477                 nat->tx_dirty=(nat->tx_dirty +1) % TX_RING_SIZE;
478                 i=(i+1) % TX_RING_SIZE;
479
480         }
481                         
482         
483         //rx_status=(unsigned int)bus_to_virt(nat->rx[nat->rx_cur].cmdsts); 
484         rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts; 
485         //DBG ("Receiver Status = %x\n",rx_status);
486         /* Handle received packets */
487         while (rx_quota && (rx_status & OWN))
488         {
489                 rx_len= (rx_status & DSIZE) - CRC_SIZE;
490
491                 /*check for the corrupt packet */
492                 if((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK)
493                 {
494                          printf("natsemi_poll: Corrupted packet received, "
495                                         "buffer status = %X ^ %X \n",rx_status,
496                                         (unsigned int) nat->rx[nat->rx_cur].cmdsts);
497                 }
498                 else
499                 {
500                         rx_iob = alloc_iob(rx_len);
501                         if(!rx_iob) 
502                                 /* leave packet for next call to poll*/
503                                 return;
504                         memcpy(iob_put(rx_iob,rx_len),
505                                         bus_to_virt(nat->rx[nat->rx_cur].bufptr),rx_len);
506                         //DBG_HD(bus_to_virt(nat->rx[nat->rx_cur].bufptr),rx_len);
507
508                         DBG("received packet");
509                         /* add to the receive queue. */
510                         netdev_rx(netdev,rx_iob);
511                         rx_quota--;
512                 }
513                 nat->rx[nat->rx_cur].cmdsts = RX_BUF_SIZE;
514                 nat->rx_cur=(nat->rx_cur+1) % NUM_RX_DESC;
515                 //rx_status=(unsigned int)bus_to_virt(nat->rx[nat->rx_cur].cmdsts); 
516                 rx_status=(unsigned int)nat->rx[nat->rx_cur].cmdsts; 
517         }
518
519
520          /* re-enable the potentially idle receive state machine */
521             outl(RxOn, nat->ioaddr + ChipCmd);  
522 }                               
523
524
525
526
527
528
529 /**
530  * Probe PCI device
531  *
532  * @v pci       PCI device
533  * @v id        PCI ID
534  * @ret rc      Return status code
535  */
536 static int nat_probe ( struct pci_device *pci,
537                        const struct pci_device_id *id __unused ) {
538         struct net_device *netdev;
539         struct natsemi_nic *nat = NULL;
540         int registered_netdev = 0;
541         int rc;
542         uint32_t advertising;
543
544         /* Fix up PCI device */
545         adjust_pci_device ( pci );
546
547         /* Allocate net device */
548         netdev = alloc_etherdev ( sizeof ( *nat ) );
549         if ( ! netdev ) {
550                 rc = -ENOMEM;
551                 goto err;
552         }
553         nat = netdev->priv;
554         pci_set_drvdata ( pci, netdev );
555         netdev->dev = &pci->dev;
556         memset ( nat, 0, sizeof ( *nat ) );
557         nat->ioaddr = pci->ioaddr;
558
559         /* Reset the NIC, set up EEPROM access and read MAC address */
560         nat_reset ( nat );
561         nat_init_eeprom ( nat );
562         nvs_read ( &nat->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
563         uint8_t  eetest[128];   
564         int i;
565         nvs_read ( &nat->eeprom.nvs, 0, eetest,128 );
566         //      DBG_HD(&eetest,128);
567         
568
569         /* mdio routine of etherboot-5.4.0 natsemi driver has been removed and 
570          * statement to read from MII transceiver control section is used directly
571          */
572
573         advertising = inl(nat->ioaddr + 0x80 + (4<<2)) & 0xffff; 
574         {
575                 uint32_t chip_config = inl(nat->ioaddr + ChipConfig);
576                 DBG("%s: Transceiver default autoneg. %s 10 %s %s duplex.\n",
577                 pci->driver_name,
578                 chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
579                 chip_config & 0x4000 ? "0" : "",
580                 chip_config & 0x8000 ? "full" : "half");
581         }
582         DBG("%s: Transceiver status %hX advertising %hX\n",pci->driver_name, (int)inl(nat->ioaddr + 0x84),(unsigned int) advertising);
583
584
585
586
587
588         /* Point to NIC specific routines */
589         netdev->open     = nat_open;
590         netdev->close    = nat_close;
591         netdev->transmit = nat_transmit;
592         netdev->poll     = nat_poll;
593
594         /* Register network device */
595         if ( ( rc = register_netdev ( netdev ) ) != 0 )
596                 goto err;
597         registered_netdev = 1;
598
599         /* Register non-volatile storagei
600          * uncomment lines below in final version*/
601         
602          if ( nat->nvo.nvs ) {
603                 if ( ( rc = nvo_register ( &nat->nvo ) ) != 0 )
604                         goto err;
605         }
606         
607
608         return 0;
609
610  err:
611         /* Disable NIC */
612         if ( nat )
613                 nat_reset ( nat );
614         if ( registered_netdev )
615                 unregister_netdev ( netdev );
616         /* Free net device */
617         free_netdev ( netdev );
618         return rc;
619 }
620
621 /**
622  * Remove PCI device
623  *
624  * @v pci       PCI device
625  */
626 static void nat_remove ( struct pci_device *pci ) {
627         struct net_device *netdev = pci_get_drvdata ( pci );
628         struct natsemi_nic *nat = netdev->priv;
629 /* TODO 
630         if ( rtl->nvo.nvs )
631                 nvo_unregister ( &rtl->nvo );
632                 */
633         unregister_netdev ( netdev );
634         nat_reset ( nat );
635         free_netdev ( netdev );
636 }
637
638 static struct pci_device_id natsemi_nics[] = {
639         PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
640
641 };
642
643 struct pci_driver natsemi_driver __pci_driver = {
644         .ids = natsemi_nics,
645         .id_count = ( sizeof ( natsemi_nics ) / sizeof ( natsemi_nics[0] ) ),
646         .probe = nat_probe,
647         .remove = nat_remove,
648 };