Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / myson.c
1 /*
2  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stdint.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <byteswap.h>
27 #include <ipxe/netdevice.h>
28 #include <ipxe/ethernet.h>
29 #include <ipxe/if_ether.h>
30 #include <ipxe/iobuf.h>
31 #include <ipxe/malloc.h>
32 #include <ipxe/pci.h>
33 #include <ipxe/mii.h>
34 #include "myson.h"
35
36 /** @file
37  *
38  * Myson Technology network card driver
39  *
40  */
41
42 /******************************************************************************
43  *
44  * Device reset
45  *
46  ******************************************************************************
47  */
48
49 /**
50  * Reset controller chip
51  *
52  * @v myson             Myson device
53  * @ret rc              Return status code
54  */
55 static int myson_soft_reset ( struct myson_nic *myson ) {
56         uint32_t bcr;
57         unsigned int i;
58
59         /* Initiate reset */
60         bcr = readl ( myson->regs + MYSON_BCR );
61         writel ( ( bcr | MYSON_BCR_SWR ), myson->regs + MYSON_BCR );
62
63         /* Wait for reset to complete */
64         for ( i = 0 ; i < MYSON_RESET_MAX_WAIT_MS ; i++ ) {
65
66                 /* If reset is not complete, delay 1ms and retry */
67                 if ( readl ( myson->regs + MYSON_BCR ) & MYSON_BCR_SWR ) {
68                         mdelay ( 1 );
69                         continue;
70                 }
71
72                 /* Apply a sensible default bus configuration */
73                 bcr = readl ( myson->regs + MYSON_BCR );
74                 bcr &= ~MYSON_BCR_PBL_MASK;
75                 bcr |= ( MYSON_BCR_RLE | MYSON_BCR_RME | MYSON_BCR_WIE |
76                          MYSON_BCR_PBL_DEFAULT );
77                 writel ( bcr, myson->regs + MYSON_BCR );
78                 DBGC ( myson, "MYSON %p using configuration %08x\n",
79                        myson, bcr );
80
81                 return 0;
82         }
83
84         DBGC ( myson, "MYSON %p timed out waiting for reset\n", myson );
85         return -ETIMEDOUT;
86 }
87
88 /**
89  * Reload configuration from EEPROM
90  *
91  * @v myson             Myson device
92  * @ret rc              Return status code
93  */
94 static int myson_reload_config ( struct myson_nic *myson ) {
95         unsigned int i;
96
97         /* Initiate reload */
98         writel ( MYSON_ROM_AUTOLD, myson->regs + MYSON_ROM_MII );
99
100         /* Wait for reload to complete */
101         for ( i = 0 ; i < MYSON_AUTOLD_MAX_WAIT_MS ; i++ ) {
102
103                 /* If reload is not complete, delay 1ms and retry */
104                 if ( readl ( myson->regs + MYSON_ROM_MII ) & MYSON_ROM_AUTOLD ){
105                         mdelay ( 1 );
106                         continue;
107                 }
108
109                 return 0;
110         }
111
112         DBGC ( myson, "MYSON %p timed out waiting for configuration "
113                "reload\n", myson );
114         return -ETIMEDOUT;
115 }
116
117 /**
118  * Reset hardware
119  *
120  * @v myson             Myson device
121  * @ret rc              Return status code
122  */
123 static int myson_reset ( struct myson_nic *myson ) {
124         int rc;
125
126         /* Disable all interrupts */
127         writel ( 0, myson->regs + MYSON_IMR );
128
129         /* Perform soft reset */
130         if ( ( rc = myson_soft_reset ( myson ) ) != 0 )
131                 return rc;
132
133         /* Reload configuration from EEPROM */
134         if ( ( rc = myson_reload_config ( myson ) ) != 0 )
135                 return rc;
136
137         return 0;
138 }
139
140 /******************************************************************************
141  *
142  * Network device interface
143  *
144  ******************************************************************************
145  */
146
147 /**
148  * Create descriptor ring
149  *
150  * @v myson             Myson device
151  * @v ring              Descriptor ring
152  * @ret rc              Return status code
153  */
154 static int myson_create_ring ( struct myson_nic *myson,
155                                struct myson_ring *ring ) {
156         size_t len = ( ring->count * sizeof ( ring->desc[0] ) );
157         struct myson_descriptor *desc;
158         struct myson_descriptor *next;
159         physaddr_t address;
160         unsigned int i;
161         int rc;
162
163         /* Allocate descriptor ring */
164         ring->desc = malloc_dma ( len, MYSON_RING_ALIGN );
165         if ( ! ring->desc ) {
166                 rc = -ENOMEM;
167                 goto err_alloc;
168         }
169         address = virt_to_bus ( ring->desc );
170
171         /* Check address is usable by card */
172         if ( ! myson_address_ok ( address + len ) ) {
173                 DBGC ( myson, "MYSON %p cannot support 64-bit ring address\n",
174                        myson );
175                 rc = -ENOTSUP;
176                 goto err_64bit;
177         }
178
179         /* Initialise descriptor ring */
180         memset ( ring->desc, 0, len );
181         for ( i = 0 ; i < ring->count ; i++ ) {
182                 desc = &ring->desc[i];
183                 next = &ring->desc[ ( i + 1 ) % ring->count ];
184                 desc->next = cpu_to_le32 ( virt_to_bus ( next ) );
185         }
186
187         /* Program ring address */
188         writel ( address, myson->regs + ring->reg );
189         DBGC ( myson, "MYSON %p ring %02x is at [%08llx,%08llx)\n",
190                myson, ring->reg, ( ( unsigned long long ) address ),
191                ( ( unsigned long long ) address + len ) );
192
193         return 0;
194
195  err_64bit:
196         free_dma ( ring->desc, len );
197         ring->desc = NULL;
198  err_alloc:
199         return rc;
200 }
201
202 /**
203  * Destroy descriptor ring
204  *
205  * @v myson             Myson device
206  * @v ring              Descriptor ring
207  */
208 static void myson_destroy_ring ( struct myson_nic *myson,
209                                  struct myson_ring *ring ) {
210         size_t len = ( ring->count * sizeof ( ring->desc[0] ) );
211
212         /* Clear ring address */
213         writel ( 0, myson->regs + ring->reg );
214
215         /* Free descriptor ring */
216         free_dma ( ring->desc, len );
217         ring->desc = NULL;
218         ring->prod = 0;
219         ring->cons = 0;
220 }
221
222 /**
223  * Refill receive descriptor ring
224  *
225  * @v netdev            Network device
226  */
227 static void myson_refill_rx ( struct net_device *netdev ) {
228         struct myson_nic *myson = netdev->priv;
229         struct myson_descriptor *rx;
230         struct io_buffer *iobuf;
231         unsigned int rx_idx;
232         physaddr_t address;
233
234         while ( ( myson->rx.prod - myson->rx.cons ) < MYSON_NUM_RX_DESC ) {
235
236                 /* Allocate I/O buffer */
237                 iobuf = alloc_iob ( MYSON_RX_MAX_LEN );
238                 if ( ! iobuf ) {
239                         /* Wait for next refill */
240                         return;
241                 }
242
243                 /* Check address is usable by card */
244                 address = virt_to_bus ( iobuf->data );
245                 if ( ! myson_address_ok ( address ) ) {
246                         DBGC ( myson, "MYSON %p cannot support 64-bit RX "
247                                "buffer address\n", myson );
248                         netdev_rx_err ( netdev, iobuf, -ENOTSUP );
249                         return;
250                 }
251
252                 /* Get next receive descriptor */
253                 rx_idx = ( myson->rx.prod++ % MYSON_NUM_RX_DESC );
254                 rx = &myson->rx.desc[rx_idx];
255
256                 /* Populate receive descriptor */
257                 rx->address = cpu_to_le32 ( address );
258                 rx->control =
259                         cpu_to_le32 ( MYSON_RX_CTRL_RBS ( MYSON_RX_MAX_LEN ) );
260                 wmb();
261                 rx->status = cpu_to_le32 ( MYSON_RX_STAT_OWN );
262                 wmb();
263
264                 /* Record I/O buffer */
265                 assert ( myson->rx_iobuf[rx_idx] == NULL );
266                 myson->rx_iobuf[rx_idx] = iobuf;
267
268                 /* Notify card that there are descriptors available */
269                 writel ( 0, myson->regs + MYSON_RXPDR );
270
271                 DBGC2 ( myson, "MYSON %p RX %d is [%llx,%llx)\n", myson,
272                         rx_idx, ( ( unsigned long long ) address ),
273                         ( ( unsigned long long ) address + MYSON_RX_MAX_LEN ) );
274         }
275 }
276
277 /**
278  * Open network device
279  *
280  * @v netdev            Network device
281  * @ret rc              Return status code
282  */
283 static int myson_open ( struct net_device *netdev ) {
284         struct myson_nic *myson = netdev->priv;
285         union myson_physical_address mac;
286         int rc;
287
288         /* Set MAC address */
289         memset ( &mac, 0, sizeof ( mac ) );
290         memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
291         writel ( le32_to_cpu ( mac.reg.low ), myson->regs + MYSON_PAR0 );
292         writel ( le32_to_cpu ( mac.reg.high ), myson->regs + MYSON_PAR4 );
293
294         /* Create transmit descriptor ring */
295         if ( ( rc = myson_create_ring ( myson, &myson->tx ) ) != 0 )
296                 goto err_create_tx;
297
298         /* Create receive descriptor ring */
299         if ( ( rc = myson_create_ring ( myson, &myson->rx ) ) != 0 )
300                 goto err_create_rx;
301
302         /* Configure transmitter and receiver */
303         writel ( ( MYSON_TCR_TE | MYSON_RCR_PROM | MYSON_RCR_AB | MYSON_RCR_AM |
304                    MYSON_RCR_ARP | MYSON_RCR_ALP | MYSON_RCR_RE ),
305                  myson->regs + MYSON_TCR_RCR );
306
307         /* Fill receive ring */
308         myson_refill_rx ( netdev );
309
310         return 0;
311
312         myson_destroy_ring ( myson, &myson->rx );
313  err_create_rx:
314         myson_destroy_ring ( myson, &myson->tx );
315  err_create_tx:
316         return rc;
317 }
318
319 /**
320  * Wait for transmit and receive to become idle
321  *
322  * @v myson             Myson device
323  * @ret rc              Return status code
324  */
325 static int myson_wait_idle ( struct myson_nic *myson ) {
326         uint32_t tcr_rcr;
327         unsigned int i;
328
329         /* Wait for both transmit and receive to be idle */
330         for ( i = 0 ; i < MYSON_IDLE_MAX_WAIT_MS ; i++ ) {
331
332                 /* If either process is running, delay 1ms and retry */
333                 tcr_rcr = readl ( myson->regs + MYSON_TCR_RCR );
334                 if ( tcr_rcr & ( MYSON_TCR_TXS | MYSON_RCR_RXS ) ) {
335                         mdelay ( 1 );
336                         continue;
337                 }
338
339                 return 0;
340         }
341
342         DBGC ( myson, "MYSON %p timed out waiting for idle state (status "
343                "%08x)\n", myson, tcr_rcr );
344         return -ETIMEDOUT;
345 }
346
347 /**
348  * Close network device
349  *
350  * @v netdev            Network device
351  */
352 static void myson_close ( struct net_device *netdev ) {
353         struct myson_nic *myson = netdev->priv;
354         unsigned int i;
355
356         /* Disable receiver and transmitter */
357         writel ( 0, myson->regs + MYSON_TCR_RCR );
358
359         /* Allow time for receiver and transmitter to become idle */
360         myson_wait_idle ( myson );
361
362         /* Destroy receive descriptor ring */
363         myson_destroy_ring ( myson, &myson->rx );
364
365         /* Discard any unused receive buffers */
366         for ( i = 0 ; i < MYSON_NUM_RX_DESC ; i++ ) {
367                 if ( myson->rx_iobuf[i] )
368                         free_iob ( myson->rx_iobuf[i] );
369                 myson->rx_iobuf[i] = NULL;
370         }
371
372         /* Destroy transmit descriptor ring */
373         myson_destroy_ring ( myson, &myson->tx );
374 }
375
376 /**
377  * Transmit packet
378  *
379  * @v netdev            Network device
380  * @v iobuf             I/O buffer
381  * @ret rc              Return status code
382  */
383 static int myson_transmit ( struct net_device *netdev,
384                             struct io_buffer *iobuf ) {
385         struct myson_nic *myson = netdev->priv;
386         struct myson_descriptor *tx;
387         unsigned int tx_idx;
388         physaddr_t address;
389
390         /* Check address is usable by card */
391         address = virt_to_bus ( iobuf->data );
392         if ( ! myson_address_ok ( address ) ) {
393                 DBGC ( myson, "MYSON %p cannot support 64-bit TX buffer "
394                        "address\n", myson );
395                 return -ENOTSUP;
396         }
397
398         /* Get next transmit descriptor */
399         if ( ( myson->tx.prod - myson->tx.cons ) >= MYSON_NUM_TX_DESC ) {
400                 DBGC ( myson, "MYSON %p out of transmit descriptors\n",
401                        myson );
402                 return -ENOBUFS;
403         }
404         tx_idx = ( myson->tx.prod++ % MYSON_NUM_TX_DESC );
405         tx = &myson->tx.desc[tx_idx];
406
407         /* Populate transmit descriptor */
408         tx->address = cpu_to_le32 ( address );
409         tx->control = cpu_to_le32 ( MYSON_TX_CTRL_IC | MYSON_TX_CTRL_LD |
410                                     MYSON_TX_CTRL_FD | MYSON_TX_CTRL_CRC |
411                                     MYSON_TX_CTRL_PAD | MYSON_TX_CTRL_RTLC |
412                                     MYSON_TX_CTRL_PKTS ( iob_len ( iobuf ) ) |
413                                     MYSON_TX_CTRL_TBS ( iob_len ( iobuf ) ) );
414         wmb();
415         tx->status = cpu_to_le32 ( MYSON_TX_STAT_OWN );
416         wmb();
417
418         /* Notify card that there are packets ready to transmit */
419         writel ( 0, myson->regs + MYSON_TXPDR );
420
421         DBGC2 ( myson, "MYSON %p TX %d is [%llx,%llx)\n", myson, tx_idx,
422                 ( ( unsigned long long ) address ),
423                 ( ( unsigned long long ) address + iob_len ( iobuf ) ) );
424
425         return 0;
426 }
427
428 /**
429  * Poll for completed packets
430  *
431  * @v netdev            Network device
432  */
433 static void myson_poll_tx ( struct net_device *netdev ) {
434         struct myson_nic *myson = netdev->priv;
435         struct myson_descriptor *tx;
436         unsigned int tx_idx;
437
438         /* Check for completed packets */
439         while ( myson->tx.cons != myson->tx.prod ) {
440
441                 /* Get next transmit descriptor */
442                 tx_idx = ( myson->tx.cons % MYSON_NUM_TX_DESC );
443                 tx = &myson->tx.desc[tx_idx];
444
445                 /* Stop if descriptor is still in use */
446                 if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_OWN ) )
447                         return;
448
449                 /* Complete TX descriptor */
450                 if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_ABORT |
451                                                 MYSON_TX_STAT_CSL ) ) {
452                         DBGC ( myson, "MYSON %p TX %d completion error "
453                                "(%08x)\n", myson, tx_idx,
454                                le32_to_cpu ( tx->status ) );
455                         netdev_tx_complete_next_err ( netdev, -EIO );
456                 } else {
457                         DBGC2 ( myson, "MYSON %p TX %d complete\n",
458                                 myson, tx_idx );
459                         netdev_tx_complete_next ( netdev );
460                 }
461                 myson->tx.cons++;
462         }
463 }
464
465 /**
466  * Poll for received packets
467  *
468  * @v netdev            Network device
469  */
470 static void myson_poll_rx ( struct net_device *netdev ) {
471         struct myson_nic *myson = netdev->priv;
472         struct myson_descriptor *rx;
473         struct io_buffer *iobuf;
474         unsigned int rx_idx;
475         size_t len;
476
477         /* Check for received packets */
478         while ( myson->rx.cons != myson->rx.prod ) {
479
480                 /* Get next receive descriptor */
481                 rx_idx = ( myson->rx.cons % MYSON_NUM_RX_DESC );
482                 rx = &myson->rx.desc[rx_idx];
483
484                 /* Stop if descriptor is still in use */
485                 if ( rx->status & MYSON_RX_STAT_OWN )
486                         return;
487
488                 /* Populate I/O buffer */
489                 iobuf = myson->rx_iobuf[rx_idx];
490                 myson->rx_iobuf[rx_idx] = NULL;
491                 len = MYSON_RX_STAT_FLNG ( le32_to_cpu ( rx->status ) );
492                 iob_put ( iobuf, len - 4 /* strip CRC */ );
493
494                 /* Hand off to network stack */
495                 if ( rx->status & cpu_to_le32 ( MYSON_RX_STAT_ES ) ) {
496                         DBGC ( myson, "MYSON %p RX %d error (length %zd, "
497                                "status %08x)\n", myson, rx_idx, len,
498                                le32_to_cpu ( rx->status ) );
499                         netdev_rx_err ( netdev, iobuf, -EIO );
500                 } else {
501                         DBGC2 ( myson, "MYSON %p RX %d complete (length "
502                                 "%zd)\n", myson, rx_idx, len );
503                         netdev_rx ( netdev, iobuf );
504                 }
505                 myson->rx.cons++;
506         }
507 }
508
509 /**
510  * Poll for completed and received packets
511  *
512  * @v netdev            Network device
513  */
514 static void myson_poll ( struct net_device *netdev ) {
515         struct myson_nic *myson = netdev->priv;
516         uint32_t isr;
517         unsigned int i;
518
519         /* Polling the ISR seems to really upset this card; it ends up
520          * getting no useful PCI transfers done and, for some reason,
521          * flooding the network with invalid packets.  Work around
522          * this by introducing deliberate delays between ISR reads.
523          */
524         for ( i = 0 ; i < MYSON_ISR_IODELAY_COUNT ; i++ )
525                 iodelay();
526
527         /* Check for and acknowledge interrupts */
528         isr = readl ( myson->regs + MYSON_ISR );
529         if ( ! isr )
530                 return;
531         writel ( isr, myson->regs + MYSON_ISR );
532
533         /* Poll for TX completions, if applicable */
534         if ( isr & MYSON_IRQ_TI )
535                 myson_poll_tx ( netdev );
536
537         /* Poll for RX completionsm, if applicable */
538         if ( isr & MYSON_IRQ_RI )
539                 myson_poll_rx ( netdev );
540
541         /* Refill RX ring */
542         myson_refill_rx ( netdev );
543 }
544
545 /**
546  * Enable or disable interrupts
547  *
548  * @v netdev            Network device
549  * @v enable            Interrupts should be enabled
550  */
551 static void myson_irq ( struct net_device *netdev, int enable ) {
552         struct myson_nic *myson = netdev->priv;
553         uint32_t imr;
554
555         imr = ( enable ? ( MYSON_IRQ_TI | MYSON_IRQ_RI ) : 0 );
556         writel ( imr, myson->regs + MYSON_IMR );
557 }
558
559 /** Myson network device operations */
560 static struct net_device_operations myson_operations = {
561         .open           = myson_open,
562         .close          = myson_close,
563         .transmit       = myson_transmit,
564         .poll           = myson_poll,
565         .irq            = myson_irq,
566 };
567
568 /******************************************************************************
569  *
570  * PCI interface
571  *
572  ******************************************************************************
573  */
574
575 /**
576  * Probe PCI device
577  *
578  * @v pci               PCI device
579  * @ret rc              Return status code
580  */
581 static int myson_probe ( struct pci_device *pci ) {
582         struct net_device *netdev;
583         struct myson_nic *myson;
584         union myson_physical_address mac;
585         int rc;
586
587         /* Allocate and initialise net device */
588         netdev = alloc_etherdev ( sizeof ( *myson ) );
589         if ( ! netdev ) {
590                 rc = -ENOMEM;
591                 goto err_alloc;
592         }
593         netdev_init ( netdev, &myson_operations );
594         myson = netdev->priv;
595         pci_set_drvdata ( pci, netdev );
596         netdev->dev = &pci->dev;
597         memset ( myson, 0, sizeof ( *myson ) );
598         myson_init_ring ( &myson->tx, MYSON_NUM_TX_DESC, MYSON_TXLBA );
599         myson_init_ring ( &myson->rx, MYSON_NUM_RX_DESC, MYSON_RXLBA );
600
601         /* Fix up PCI device */
602         adjust_pci_device ( pci );
603
604         /* Map registers */
605         myson->regs = ioremap ( pci->membase, MYSON_BAR_SIZE );
606         if ( ! myson->regs ) {
607                 rc = -ENODEV;
608                 goto err_ioremap;
609         }
610
611         /* Reset the NIC */
612         if ( ( rc = myson_reset ( myson ) ) != 0 )
613                 goto err_reset;
614
615         /* Read MAC address */
616         mac.reg.low = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR0 ) );
617         mac.reg.high = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR4 ) );
618         memcpy ( netdev->hw_addr, mac.raw, ETH_ALEN );
619
620         /* Register network device */
621         if ( ( rc = register_netdev ( netdev ) ) != 0 )
622                 goto err_register_netdev;
623
624         /* Mark as link up; we don't yet handle link state */
625         netdev_link_up ( netdev );
626
627         return 0;
628
629         unregister_netdev ( netdev );
630  err_register_netdev:
631         myson_reset ( myson );
632  err_reset:
633         iounmap ( myson->regs );
634  err_ioremap:
635         netdev_nullify ( netdev );
636         netdev_put ( netdev );
637  err_alloc:
638         return rc;
639 }
640
641 /**
642  * Remove PCI device
643  *
644  * @v pci               PCI device
645  */
646 static void myson_remove ( struct pci_device *pci ) {
647         struct net_device *netdev = pci_get_drvdata ( pci );
648         struct myson_nic *myson = netdev->priv;
649
650         /* Unregister network device */
651         unregister_netdev ( netdev );
652
653         /* Reset card */
654         myson_reset ( myson );
655
656         /* Free network device */
657         iounmap ( myson->regs );
658         netdev_nullify ( netdev );
659         netdev_put ( netdev );
660 }
661
662 /** Myson PCI device IDs */
663 static struct pci_device_id myson_nics[] = {
664         PCI_ROM ( 0x1516, 0x0800, "mtd800", "MTD-8xx", 0 ),
665         PCI_ROM ( 0x1516, 0x0803, "mtd803", "Surecom EP-320X-S", 0 ),
666         PCI_ROM ( 0x1516, 0x0891, "mtd891", "MTD-8xx", 0 ),
667 };
668
669 /** Myson PCI driver */
670 struct pci_driver myson_driver __pci_driver = {
671         .ids = myson_nics,
672         .id_count = ( sizeof ( myson_nics ) / sizeof ( myson_nics[0] ) ),
673         .probe = myson_probe,
674         .remove = myson_remove,
675 };