added polling and transmit. eeprom access still remaining
[people/sha0/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 */
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           0x02    /* Data in */
158 #define EE_DO           0x01    /* Data out */
159
160 /* Offsets within EEPROM (these are word offsets) */
161 #define EE_MAC 7
162
163 static uint32_t SavedClkRun;    
164
165
166
167 static const uint8_t rtl_ee_bits[] = {
168         [SPI_BIT_SCLK]  = EE_SK,
169         [SPI_BIT_MOSI]  = EE_DI,
170         [SPI_BIT_MISO]  = EE_DO,
171         [SPI_BIT_SS(0)] = ( EE_CS | EE_M1 ),
172 };
173
174 static int rtl_spi_read_bit ( struct bit_basher *basher,
175                               unsigned int bit_id ) {
176         struct rtl8139_nic *rtl = container_of ( basher, struct rtl8139_nic,
177                                                  spibit.basher );
178         uint8_t mask = rtl_ee_bits[bit_id];
179         uint8_t eereg;
180
181         eereg = inb ( rtl->ioaddr + Cfg9346 );
182         return ( eereg & mask );
183 }
184
185 static void rtl_spi_write_bit ( struct bit_basher *basher,
186                                 unsigned int bit_id, unsigned long data ) {
187         struct rtl8139_nic *rtl = container_of ( basher, struct rtl8139_nic,
188                                                  spibit.basher );
189         uint8_t mask = rtl_ee_bits[bit_id];
190         uint8_t eereg;
191
192         eereg = inb ( rtl->ioaddr + Cfg9346 );
193         eereg &= ~mask;
194         eereg |= ( data & mask );
195         outb ( eereg, rtl->ioaddr + Cfg9346 );
196 }
197
198 static struct bit_basher_operations rtl_basher_ops = {
199         .read = rtl_spi_read_bit,
200         .write = rtl_spi_write_bit,
201 };
202
203 /** Portion of EEPROM available for non-volatile stored options
204  *
205  * We use offset 0x40 (i.e. address 0x20), length 0x40.  This block is
206  * marked as VPD in the rtl8139 datasheets, so we use it only if we
207  * detect that the card is not supporting VPD.
208  */
209 static struct nvo_fragment rtl_nvo_fragments[] = {
210         { 0x20, 0x40 },
211         { 0, 0 }
212 };
213
214 /**
215  * Set up for EEPROM access
216  *
217  * @v NAT               NATSEMI NIC
218  */
219  void rtl_init_eeprom ( struct natsemi_nic *rtl ) {
220         int ee9356;
221         int vpd;
222
223         /* Initialise three-wire bus */
224         rtl->spibit.basher.op = &rtl_basher_ops;
225         rtl->spibit.bus.mode = SPI_MODE_THREEWIRE;
226         init_spi_bit_basher ( &rtl->spibit );
227
228         /* Detect EEPROM type and initialise three-wire device */
229         ee9356 = ( inw ( rtl->ioaddr + RxConfig ) & Eeprom9356 );
230         if ( ee9356 ) {
231                 DBG ( "EEPROM is an AT93C56\n" );
232                 init_at93c56 ( &rtl->eeprom, 16 );
233         } else {
234                 DBG ( "EEPROM is an AT93C46\n" );
235                 init_at93c46 ( &rtl->eeprom, 16 );
236         }
237         rtl->eeprom.bus = &rtl->spibit.bus;
238
239         /* Initialise space for non-volatile options, if available */
240         vpd = ( inw ( rtl->ioaddr + Config1 ) & VPDEnable );
241         if ( vpd ) {
242                 DBG ( "EEPROM in use for VPD; cannot use for options\n" );
243         } else {
244                 rtl->nvo.nvs = &rtl->eeprom.nvs;
245                 rtl->nvo.fragments = rtl_nvo_fragments;
246         }
247 }
248
249 /**
250  * Reset NIC
251  *
252  * @v           NATSEMI NIC
253  *
254  * Issues a hardware reset and waits for the reset to complete.
255  */
256 static void nat_reset ( struct nat_nic *nat ) {
257
258         int i;
259         /* Reset chip */
260         outb ( ChipReset, nat->ioaddr + ChipCmd );
261         mdelay ( 10 );
262         nat->tx_dirty=0;
263         nat->tx_cur=0;
264         for(i=0;i<TX_RING_SIZE;i++)
265         {
266                 nat->tx[i].link=0;
267                 nat->tx[i].cmdsts=0;
268                 nat->tx[i].bufptr=0;
269         }
270         nat->rx_cur = 0;
271         outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
272         outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
273
274         outl(TxOff|RxOff, nat->ioaddr + ChipCmd);
275
276         /* Restore PME enable bit */
277         outl(SavedClkRun, nat->ioaddr + ClkRun);
278 }
279
280 /**
281  * Open NIC
282  *
283  * @v netdev            Net device
284  * @ret rc              Return status code
285  */
286 static int nat_open ( struct net_device *netdev ) {
287         struct natsemi_nic *nat = netdev->priv;
288         //struct io_buffer *iobuf;
289         int i;
290         
291         /* Disable PME:
292         * The PME bit is initialized from the EEPROM contents.
293         * PCI cards probably have PME disabled, but motherboard
294         * implementations may have PME set to enable WakeOnLan. 
295         * With PME set the chip will scan incoming packets but
296         * nothing will be written to memory. */
297         SavedClkRun = inl(nat->ioaddr + ClkRun);
298         outl(SavedClkRun & ~0x100, nat->ioaddr + ClkRun);
299
300                 
301
302
303         /* Program the MAC address TODO enable this comment */
304         /*
305          for ( i = 0 ; i < ETH_ALEN ; i++ )
306                 outb ( netdev->ll_addr[i], rtl->ioaddr + MAC0 + i );
307         */
308
309
310         /*Set up the Tx Ring */
311         nat->tx_cur=0;
312         nat->tx_dirty=0;
313         for (i=0;i<TX_RING_SIZE;i++)
314         {
315                 nat->tx[i].link   = virt_to_bus((i+1 < TX_RING_SIZE) ? &nat->tx[i+1] : &nat->tx[0]);
316                 nat->tx[i].cmdsts = 0;
317                 nat->tx[i].bufptr = 0;
318         }
319
320
321
322
323
324         /* Set up RX ring */
325         nat->rx_cur=0;
326         for (i=0;i<NUM_RX_DESC;i++)
327         {
328
329                 nat->iobuf[i] = alloc_iob ( RX_BUF_SIZE );
330                 if (!nat->iobuf[i])
331                        return -ENOMEM;  
332                 nat->rx[i].link   = virt_to_bus((i+1 < NUM_RX_DESC) ? &nat->rx[i+1] : &nat->rx[0]);
333                 nat->rx[i].cmdsts = (uint32_t) RX_BUF_SIZE;
334                 nat->rx[i].bufptr = virt_to_bus(nat->iobuf[i]->data);
335         }
336
337
338          /* load Receive Descriptor Register */
339         outl(virt_to_bus(&nat->rx[0]), nat->ioaddr + RxRingPtr);
340         DBG("Natsemi Rx descriptor loaded with: %X\n",inl(nat->ioaddr+RingPtr));                
341
342         /* setup Tx ring */
343         outl(virt_to_bus(&nat->tx[0]),nat->ioaddr+TxRingPtr);
344         DBG("Natsemi Tx descriptor loaded with: %X\n",inl(nat->ioaddr+TxRingPtr));
345
346         /* Enables RX */
347         outl(RxFilterEnable|AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys, nat->ioaddr+RxFilterAddr);
348
349         /* Initialize other registers. */
350         /* Configure the PCI bus bursts and FIFO thresholds. */
351         /* Configure for standard, in-spec Ethernet. */
352         if (inl(nat->ioaddr + ChipConfig) & 0x20000000) {       /* Full duplex */
353                 tx_config = 0xD0801002;
354                 rx_config = 0x10000020;
355         } else {
356                 tx_config = 0x10801002;
357                 rx_config = 0x0020;
358         }
359         outl(tx_config, nat->ioaddr + TxConfig);
360         outl(rx_config, nat->ioaddr + RxConfig);
361
362
363
364         /*start the receiver  */
365         outl(RxOn, nat->ioaddr + ChipCmd);
366
367
368         return 0;
369 }
370
371 /**
372  * Close NIC
373  *
374  * @v netdev            Net device
375  */
376 static void nat_close ( struct net_device *netdev ) {
377         struct natsemi_nic *nat = netdev->priv;
378
379         /* Reset the hardware to disable everything in one go */
380         nat_reset ( nat );
381
382         /* Free RX ring */
383         for (i=0;i<NUM_RX_DESC;i++)
384         {
385                 
386                 free_iob( nat->iobuf[i] );
387         }
388 }
389
390 /** 
391  * Transmit packet
392  *
393  * @v netdev    Network device
394  * @v iobuf     I/O buffer
395  * @ret rc      Return status code
396  */
397 static int natsemi_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
398         struct natsemi_nic *nat = netdev->priv;
399
400        /* check for space in TX ring */
401
402         if (nat->tx[nat->tx_cur].cmdsts !=0)
403         {
404                 printf ( "TX overflow\n" );
405                 return -ENOBUFS;
406         }
407
408
409         /* Pad and align packet */
410         iob_pad ( iobuf, ETH_ZLEN );
411
412         /* Add to TX ring */
413         DBG ( "TX id %d at %lx+%x\n", nat->tx_cur,
414               virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );
415
416         nat->tx[nat->tx_cur].bufptr = virt_to_bus(iobuf->data);
417         nat->tx[nat->tx_cur].cmdsts= (uint32_t) iob_len(iobuf)|OWN;
418
419         nat->tx_cur=(nat->tx_cur+1) % TX_RING_SIZE;
420
421         /*start the transmitter  */
422         outl(TxOn, nat->ioaddr + ChipCmd);
423
424         return 0;
425 }
426
427 /** 
428  * Poll for received packets
429  *
430  * @v netdev    Network device
431  * @v rx_quota  Maximum number of packets to receive
432  */
433 static void nat_poll ( struct net_device *netdev, unsigned int rx_quota ) {
434         struct natsemi_nic *nat = netdev->priv;
435         unsigned int status;
436         unsigned int rx_status;
437         unsigned int rx_len;
438         struct io_buffer *rx_iob;
439         int i;
440
441         
442         /* check the status of packets given to card for transmission */        
443         for ( i = 0 ; i < TX_RING_SIZE ; i++ ) 
444         {
445                 status=bus_to_virt(nat->tx[nat->tx_dirty].cmdsts);
446                 /* check if current packet has been transmitted or not */
447                 if(status & own) 
448                         break;
449                 /* Check if any errors in transmission */
450                 if (! (status & DescPktOK))
451                 {
452                         printf("Error in sending Packet with data: %s\n and status:%X\n",
453                                         bus_to_virt(nat->tx[nat->tx_dirty].bufptr),
454                                         status);
455                 }
456                 else
457                 {
458                         DBG("Success in transmitting Packet with data: %s",
459                                         bus_to_virt(nat->tx[nat->tx_dirty].bufptr));
460                 }
461                 /* setting cmdsts zero, indicating that it can be reused */
462                 nat->tx[nat->tx_dirty].cmdsts=0;
463                 nat->tx_dirty=(nat->tx_dirty +1) % TX_RING_SIZE;
464         }
465                         
466         
467         rx_status=bus_to_virt(nat->rx[nat->rx_cur].cmdsts); 
468         /* Handle received packets */
469         while (rx_quota && (rx_status & OWN))
470         {
471                 rx_len= (rx_status & DSIZE) - CRC_SIZE;
472
473                 /*check for the corrupt packet */
474                 if((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK)
475                 {
476                          printf("natsemi_poll: Corrupted packet received, 
477                                          buffer status = %X\n",rx_status);
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,rxlen);
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         }
494
495
496          /* re-enable the potentially idle receive state machine */
497             outl(RxOn, ioaddr + ChipCmd);       
498 }                               
499
500
501
502
503
504
505 /**
506  * Probe PCI device
507  *
508  * @v pci       PCI device
509  * @v id        PCI ID
510  * @ret rc      Return status code
511  */
512 static int nat_probe ( struct pci_device *pci,
513                        const struct pci_device_id *id __unused ) {
514         struct net_device *netdev;
515         struct natsemi_nic *nat = NULL;
516         int registered_netdev = 0;
517         int rc;
518         uint32_t advertising;
519
520         /* Fix up PCI device */
521         adjust_pci_device ( pci );
522
523         /* Allocate net device */
524         netdev = alloc_etherdev ( sizeof ( *nat ) );
525         if ( ! netdev ) {
526                 rc = -ENOMEM;
527                 goto err;
528         }
529         nat = netdev->priv;
530         pci_set_drvdata ( pci, netdev );
531         netdev->dev = &pci->dev;
532         memset ( nat, 0, sizeof ( *nat ) );
533         nat->ioaddr = pci->ioaddr;
534
535         /* Reset the NIC, set up EEPROM access and read MAC address */
536         nat_reset ( nat );
537         /* commenitng two line below. Have to be included in final natsemi.c TODO*/
538         /*
539         nat_init_eeprom ( rtl );
540         nvs_read ( &nat->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
541         
542         */
543         
544
545         /* mdio routine of etherboot-5.4.0 natsemi driver has been removed and 
546          * statement to read from MII transceiver control section is used directly
547          */
548
549         advertising = inl(nat->ioaddr + 0x80 + (4<<2)) & 0xffff; 
550         {
551                 uint32_t chip_config = inl(ioaddr + ChipConfig);
552                 DBG("%s: Transceiver default autoneg. %s 10 %s %s duplex.\n",
553                 pci->driver_name,
554                 chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
555                 chip_config & 0x4000 ? "0" : "",
556                 chip_config & 0x8000 ? "full" : "half");
557         }
558         DBG("%s: Transceiver status %hX advertising %hX\n",pci->driver_name, (int)inl(nat->ioaddr + 0x84), advertising);
559
560
561
562
563
564         /* Point to NIC specific routines */
565         netdev->open     = nat_open;
566         netdev->close    = nat_close;
567         netdev->transmit = nat_transmit;
568         netdev->poll     = nat_poll;
569
570         /* Register network device */
571         if ( ( rc = register_netdev ( netdev ) ) != 0 )
572                 goto err;
573         registered_netdev = 1;
574
575         /* Register non-volatile storagei
576          * uncomment lines below in final version*/
577         /*
578          if ( rtl->nvo.nvs ) {
579                 if ( ( rc = nvo_register ( &rtl->nvo ) ) != 0 )
580                         goto err;
581         }
582         */
583
584         return 0;
585
586  err:
587         /* Disable NIC */
588         if ( nat )
589                 nat_reset ( nat );
590         if ( registered_netdev )
591                 unregister_netdev ( netdev );
592         /* Free net device */
593         free_netdev ( netdev );
594         return rc;
595 }
596
597 /**
598  * Remove PCI device
599  *
600  * @v pci       PCI device
601  */
602 static void nat_remove ( struct pci_device *pci ) {
603         struct net_device *netdev = pci_get_drvdata ( pci );
604         struct natsemi_nic *nat = netdev->priv;
605 /* TODO 
606         if ( rtl->nvo.nvs )
607                 nvo_unregister ( &rtl->nvo );
608                 */
609         unregister_netdev ( netdev );
610         nat_reset ( nat );
611         free_netdev ( netdev );
612 }
613
614 static struct pci_device_id natsemi_nics[] = {
615         PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
616
617 };
618
619 struct pci_driver natsemi_driver __pci_driver = {
620         .ids = natsemi_nics,
621         .id_count = ( sizeof ( natsemi_nics ) / sizeof ( natsemi_nics[0] ) ),
622         .probe = nat_probe,
623         .remove = nat_remove,
624 };