2 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
31 #include <ipxe/netdevice.h>
32 #include <ipxe/ethernet.h>
33 #include <ipxe/if_ether.h>
34 #include <ipxe/iobuf.h>
35 #include <ipxe/malloc.h>
42 * Myson Technology network card driver
46 /******************************************************************************
50 ******************************************************************************
54 * Reset controller chip
56 * @v myson Myson device
57 * @ret rc Return status code
59 static int myson_soft_reset ( struct myson_nic *myson ) {
64 bcr = readl ( myson->regs + MYSON_BCR );
65 writel ( ( bcr | MYSON_BCR_SWR ), myson->regs + MYSON_BCR );
67 /* Wait for reset to complete */
68 for ( i = 0 ; i < MYSON_RESET_MAX_WAIT_MS ; i++ ) {
70 /* If reset is not complete, delay 1ms and retry */
71 if ( readl ( myson->regs + MYSON_BCR ) & MYSON_BCR_SWR ) {
76 /* Apply a sensible default bus configuration */
77 bcr = readl ( myson->regs + MYSON_BCR );
78 bcr &= ~MYSON_BCR_PBL_MASK;
79 bcr |= ( MYSON_BCR_RLE | MYSON_BCR_RME | MYSON_BCR_WIE |
80 MYSON_BCR_PBL_DEFAULT );
81 writel ( bcr, myson->regs + MYSON_BCR );
82 DBGC ( myson, "MYSON %p using configuration %08x\n",
88 DBGC ( myson, "MYSON %p timed out waiting for reset\n", myson );
93 * Reload configuration from EEPROM
95 * @v myson Myson device
96 * @ret rc Return status code
98 static int myson_reload_config ( struct myson_nic *myson ) {
101 /* Initiate reload */
102 writel ( MYSON_ROM_AUTOLD, myson->regs + MYSON_ROM_MII );
104 /* Wait for reload to complete */
105 for ( i = 0 ; i < MYSON_AUTOLD_MAX_WAIT_MS ; i++ ) {
107 /* If reload is not complete, delay 1ms and retry */
108 if ( readl ( myson->regs + MYSON_ROM_MII ) & MYSON_ROM_AUTOLD ){
116 DBGC ( myson, "MYSON %p timed out waiting for configuration "
124 * @v myson Myson device
125 * @ret rc Return status code
127 static int myson_reset ( struct myson_nic *myson ) {
130 /* Disable all interrupts */
131 writel ( 0, myson->regs + MYSON_IMR );
133 /* Perform soft reset */
134 if ( ( rc = myson_soft_reset ( myson ) ) != 0 )
137 /* Reload configuration from EEPROM */
138 if ( ( rc = myson_reload_config ( myson ) ) != 0 )
144 /******************************************************************************
146 * Network device interface
148 ******************************************************************************
152 * Create descriptor ring
154 * @v myson Myson device
155 * @v ring Descriptor ring
156 * @ret rc Return status code
158 static int myson_create_ring ( struct myson_nic *myson,
159 struct myson_ring *ring ) {
160 size_t len = ( ring->count * sizeof ( ring->desc[0] ) );
161 struct myson_descriptor *desc;
162 struct myson_descriptor *next;
167 /* Allocate descriptor ring */
168 ring->desc = malloc_dma ( len, MYSON_RING_ALIGN );
169 if ( ! ring->desc ) {
173 address = virt_to_bus ( ring->desc );
175 /* Check address is usable by card */
176 if ( ! myson_address_ok ( address + len ) ) {
177 DBGC ( myson, "MYSON %p cannot support 64-bit ring address\n",
183 /* Initialise descriptor ring */
184 memset ( ring->desc, 0, len );
185 for ( i = 0 ; i < ring->count ; i++ ) {
186 desc = &ring->desc[i];
187 next = &ring->desc[ ( i + 1 ) % ring->count ];
188 desc->next = cpu_to_le32 ( virt_to_bus ( next ) );
191 /* Program ring address */
192 writel ( address, myson->regs + ring->reg );
193 DBGC ( myson, "MYSON %p ring %02x is at [%08llx,%08llx)\n",
194 myson, ring->reg, ( ( unsigned long long ) address ),
195 ( ( unsigned long long ) address + len ) );
200 free_dma ( ring->desc, len );
207 * Destroy descriptor ring
209 * @v myson Myson device
210 * @v ring Descriptor ring
212 static void myson_destroy_ring ( struct myson_nic *myson,
213 struct myson_ring *ring ) {
214 size_t len = ( ring->count * sizeof ( ring->desc[0] ) );
216 /* Clear ring address */
217 writel ( 0, myson->regs + ring->reg );
219 /* Free descriptor ring */
220 free_dma ( ring->desc, len );
227 * Refill receive descriptor ring
229 * @v netdev Network device
231 static void myson_refill_rx ( struct net_device *netdev ) {
232 struct myson_nic *myson = netdev->priv;
233 struct myson_descriptor *rx;
234 struct io_buffer *iobuf;
238 while ( ( myson->rx.prod - myson->rx.cons ) < MYSON_NUM_RX_DESC ) {
240 /* Allocate I/O buffer */
241 iobuf = alloc_iob ( MYSON_RX_MAX_LEN );
243 /* Wait for next refill */
247 /* Check address is usable by card */
248 address = virt_to_bus ( iobuf->data );
249 if ( ! myson_address_ok ( address ) ) {
250 DBGC ( myson, "MYSON %p cannot support 64-bit RX "
251 "buffer address\n", myson );
252 netdev_rx_err ( netdev, iobuf, -ENOTSUP );
256 /* Get next receive descriptor */
257 rx_idx = ( myson->rx.prod++ % MYSON_NUM_RX_DESC );
258 rx = &myson->rx.desc[rx_idx];
260 /* Populate receive descriptor */
261 rx->address = cpu_to_le32 ( address );
263 cpu_to_le32 ( MYSON_RX_CTRL_RBS ( MYSON_RX_MAX_LEN ) );
265 rx->status = cpu_to_le32 ( MYSON_RX_STAT_OWN );
268 /* Record I/O buffer */
269 assert ( myson->rx_iobuf[rx_idx] == NULL );
270 myson->rx_iobuf[rx_idx] = iobuf;
272 /* Notify card that there are descriptors available */
273 writel ( 0, myson->regs + MYSON_RXPDR );
275 DBGC2 ( myson, "MYSON %p RX %d is [%llx,%llx)\n", myson,
276 rx_idx, ( ( unsigned long long ) address ),
277 ( ( unsigned long long ) address + MYSON_RX_MAX_LEN ) );
282 * Open network device
284 * @v netdev Network device
285 * @ret rc Return status code
287 static int myson_open ( struct net_device *netdev ) {
288 struct myson_nic *myson = netdev->priv;
289 union myson_physical_address mac;
292 /* Set MAC address */
293 memset ( &mac, 0, sizeof ( mac ) );
294 memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
295 writel ( le32_to_cpu ( mac.reg.low ), myson->regs + MYSON_PAR0 );
296 writel ( le32_to_cpu ( mac.reg.high ), myson->regs + MYSON_PAR4 );
298 /* Create transmit descriptor ring */
299 if ( ( rc = myson_create_ring ( myson, &myson->tx ) ) != 0 )
302 /* Create receive descriptor ring */
303 if ( ( rc = myson_create_ring ( myson, &myson->rx ) ) != 0 )
306 /* Configure transmitter and receiver */
307 writel ( ( MYSON_TCR_TE | MYSON_RCR_PROM | MYSON_RCR_AB | MYSON_RCR_AM |
308 MYSON_RCR_ARP | MYSON_RCR_ALP | MYSON_RCR_RE ),
309 myson->regs + MYSON_TCR_RCR );
311 /* Fill receive ring */
312 myson_refill_rx ( netdev );
316 myson_destroy_ring ( myson, &myson->rx );
318 myson_destroy_ring ( myson, &myson->tx );
324 * Wait for transmit and receive to become idle
326 * @v myson Myson device
327 * @ret rc Return status code
329 static int myson_wait_idle ( struct myson_nic *myson ) {
333 /* Wait for both transmit and receive to be idle */
334 for ( i = 0 ; i < MYSON_IDLE_MAX_WAIT_MS ; i++ ) {
336 /* If either process is running, delay 1ms and retry */
337 tcr_rcr = readl ( myson->regs + MYSON_TCR_RCR );
338 if ( tcr_rcr & ( MYSON_TCR_TXS | MYSON_RCR_RXS ) ) {
346 DBGC ( myson, "MYSON %p timed out waiting for idle state (status "
347 "%08x)\n", myson, tcr_rcr );
352 * Close network device
354 * @v netdev Network device
356 static void myson_close ( struct net_device *netdev ) {
357 struct myson_nic *myson = netdev->priv;
360 /* Disable receiver and transmitter */
361 writel ( 0, myson->regs + MYSON_TCR_RCR );
363 /* Allow time for receiver and transmitter to become idle */
364 myson_wait_idle ( myson );
366 /* Destroy receive descriptor ring */
367 myson_destroy_ring ( myson, &myson->rx );
369 /* Discard any unused receive buffers */
370 for ( i = 0 ; i < MYSON_NUM_RX_DESC ; i++ ) {
371 if ( myson->rx_iobuf[i] )
372 free_iob ( myson->rx_iobuf[i] );
373 myson->rx_iobuf[i] = NULL;
376 /* Destroy transmit descriptor ring */
377 myson_destroy_ring ( myson, &myson->tx );
383 * @v netdev Network device
384 * @v iobuf I/O buffer
385 * @ret rc Return status code
387 static int myson_transmit ( struct net_device *netdev,
388 struct io_buffer *iobuf ) {
389 struct myson_nic *myson = netdev->priv;
390 struct myson_descriptor *tx;
394 /* Check address is usable by card */
395 address = virt_to_bus ( iobuf->data );
396 if ( ! myson_address_ok ( address ) ) {
397 DBGC ( myson, "MYSON %p cannot support 64-bit TX buffer "
398 "address\n", myson );
402 /* Get next transmit descriptor */
403 if ( ( myson->tx.prod - myson->tx.cons ) >= MYSON_NUM_TX_DESC ) {
404 DBGC ( myson, "MYSON %p out of transmit descriptors\n",
408 tx_idx = ( myson->tx.prod++ % MYSON_NUM_TX_DESC );
409 tx = &myson->tx.desc[tx_idx];
411 /* Populate transmit descriptor */
412 tx->address = cpu_to_le32 ( address );
413 tx->control = cpu_to_le32 ( MYSON_TX_CTRL_IC | MYSON_TX_CTRL_LD |
414 MYSON_TX_CTRL_FD | MYSON_TX_CTRL_CRC |
415 MYSON_TX_CTRL_PAD | MYSON_TX_CTRL_RTLC |
416 MYSON_TX_CTRL_PKTS ( iob_len ( iobuf ) ) |
417 MYSON_TX_CTRL_TBS ( iob_len ( iobuf ) ) );
419 tx->status = cpu_to_le32 ( MYSON_TX_STAT_OWN );
422 /* Notify card that there are packets ready to transmit */
423 writel ( 0, myson->regs + MYSON_TXPDR );
425 DBGC2 ( myson, "MYSON %p TX %d is [%llx,%llx)\n", myson, tx_idx,
426 ( ( unsigned long long ) address ),
427 ( ( unsigned long long ) address + iob_len ( iobuf ) ) );
433 * Poll for completed packets
435 * @v netdev Network device
437 static void myson_poll_tx ( struct net_device *netdev ) {
438 struct myson_nic *myson = netdev->priv;
439 struct myson_descriptor *tx;
442 /* Check for completed packets */
443 while ( myson->tx.cons != myson->tx.prod ) {
445 /* Get next transmit descriptor */
446 tx_idx = ( myson->tx.cons % MYSON_NUM_TX_DESC );
447 tx = &myson->tx.desc[tx_idx];
449 /* Stop if descriptor is still in use */
450 if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_OWN ) )
453 /* Complete TX descriptor */
454 if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_ABORT |
455 MYSON_TX_STAT_CSL ) ) {
456 DBGC ( myson, "MYSON %p TX %d completion error "
457 "(%08x)\n", myson, tx_idx,
458 le32_to_cpu ( tx->status ) );
459 netdev_tx_complete_next_err ( netdev, -EIO );
461 DBGC2 ( myson, "MYSON %p TX %d complete\n",
463 netdev_tx_complete_next ( netdev );
470 * Poll for received packets
472 * @v netdev Network device
474 static void myson_poll_rx ( struct net_device *netdev ) {
475 struct myson_nic *myson = netdev->priv;
476 struct myson_descriptor *rx;
477 struct io_buffer *iobuf;
481 /* Check for received packets */
482 while ( myson->rx.cons != myson->rx.prod ) {
484 /* Get next receive descriptor */
485 rx_idx = ( myson->rx.cons % MYSON_NUM_RX_DESC );
486 rx = &myson->rx.desc[rx_idx];
488 /* Stop if descriptor is still in use */
489 if ( rx->status & MYSON_RX_STAT_OWN )
492 /* Populate I/O buffer */
493 iobuf = myson->rx_iobuf[rx_idx];
494 myson->rx_iobuf[rx_idx] = NULL;
495 len = MYSON_RX_STAT_FLNG ( le32_to_cpu ( rx->status ) );
496 iob_put ( iobuf, len - 4 /* strip CRC */ );
498 /* Hand off to network stack */
499 if ( rx->status & cpu_to_le32 ( MYSON_RX_STAT_ES ) ) {
500 DBGC ( myson, "MYSON %p RX %d error (length %zd, "
501 "status %08x)\n", myson, rx_idx, len,
502 le32_to_cpu ( rx->status ) );
503 netdev_rx_err ( netdev, iobuf, -EIO );
505 DBGC2 ( myson, "MYSON %p RX %d complete (length "
506 "%zd)\n", myson, rx_idx, len );
507 netdev_rx ( netdev, iobuf );
514 * Poll for completed and received packets
516 * @v netdev Network device
518 static void myson_poll ( struct net_device *netdev ) {
519 struct myson_nic *myson = netdev->priv;
523 /* Polling the ISR seems to really upset this card; it ends up
524 * getting no useful PCI transfers done and, for some reason,
525 * flooding the network with invalid packets. Work around
526 * this by introducing deliberate delays between ISR reads.
528 for ( i = 0 ; i < MYSON_ISR_IODELAY_COUNT ; i++ )
531 /* Check for and acknowledge interrupts */
532 isr = readl ( myson->regs + MYSON_ISR );
535 writel ( isr, myson->regs + MYSON_ISR );
537 /* Poll for TX completions, if applicable */
538 if ( isr & MYSON_IRQ_TI )
539 myson_poll_tx ( netdev );
541 /* Poll for RX completionsm, if applicable */
542 if ( isr & MYSON_IRQ_RI )
543 myson_poll_rx ( netdev );
546 myson_refill_rx ( netdev );
550 * Enable or disable interrupts
552 * @v netdev Network device
553 * @v enable Interrupts should be enabled
555 static void myson_irq ( struct net_device *netdev, int enable ) {
556 struct myson_nic *myson = netdev->priv;
559 imr = ( enable ? ( MYSON_IRQ_TI | MYSON_IRQ_RI ) : 0 );
560 writel ( imr, myson->regs + MYSON_IMR );
563 /** Myson network device operations */
564 static struct net_device_operations myson_operations = {
566 .close = myson_close,
567 .transmit = myson_transmit,
572 /******************************************************************************
576 ******************************************************************************
583 * @ret rc Return status code
585 static int myson_probe ( struct pci_device *pci ) {
586 struct net_device *netdev;
587 struct myson_nic *myson;
588 union myson_physical_address mac;
591 /* Allocate and initialise net device */
592 netdev = alloc_etherdev ( sizeof ( *myson ) );
597 netdev_init ( netdev, &myson_operations );
598 myson = netdev->priv;
599 pci_set_drvdata ( pci, netdev );
600 netdev->dev = &pci->dev;
601 memset ( myson, 0, sizeof ( *myson ) );
602 myson_init_ring ( &myson->tx, MYSON_NUM_TX_DESC, MYSON_TXLBA );
603 myson_init_ring ( &myson->rx, MYSON_NUM_RX_DESC, MYSON_RXLBA );
605 /* Fix up PCI device */
606 adjust_pci_device ( pci );
609 myson->regs = ioremap ( pci->membase, MYSON_BAR_SIZE );
610 if ( ! myson->regs ) {
616 if ( ( rc = myson_reset ( myson ) ) != 0 )
619 /* Read MAC address */
620 mac.reg.low = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR0 ) );
621 mac.reg.high = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR4 ) );
622 memcpy ( netdev->hw_addr, mac.raw, ETH_ALEN );
624 /* Register network device */
625 if ( ( rc = register_netdev ( netdev ) ) != 0 )
626 goto err_register_netdev;
628 /* Mark as link up; we don't yet handle link state */
629 netdev_link_up ( netdev );
633 unregister_netdev ( netdev );
635 myson_reset ( myson );
637 iounmap ( myson->regs );
639 netdev_nullify ( netdev );
640 netdev_put ( netdev );
650 static void myson_remove ( struct pci_device *pci ) {
651 struct net_device *netdev = pci_get_drvdata ( pci );
652 struct myson_nic *myson = netdev->priv;
654 /* Unregister network device */
655 unregister_netdev ( netdev );
658 myson_reset ( myson );
660 /* Free network device */
661 iounmap ( myson->regs );
662 netdev_nullify ( netdev );
663 netdev_put ( netdev );
666 /** Myson PCI device IDs */
667 static struct pci_device_id myson_nics[] = {
668 PCI_ROM ( 0x1516, 0x0800, "mtd800", "MTD-8xx", 0 ),
669 PCI_ROM ( 0x1516, 0x0803, "mtd803", "Surecom EP-320X-S", 0 ),
670 PCI_ROM ( 0x1516, 0x0891, "mtd891", "MTD-8xx", 0 ),
673 /** Myson PCI driver */
674 struct pci_driver myson_driver __pci_driver = {
676 .id_count = ( sizeof ( myson_nics ) / sizeof ( myson_nics[0] ) ),
677 .probe = myson_probe,
678 .remove = myson_remove,