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
20 FILE_LICENCE ( GPL2_OR_LATER );
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>
38 * Myson Technology network card driver
42 /******************************************************************************
46 ******************************************************************************
50 * Reset controller chip
52 * @v myson Myson device
53 * @ret rc Return status code
55 static int myson_soft_reset ( struct myson_nic *myson ) {
60 bcr = readl ( myson->regs + MYSON_BCR );
61 writel ( ( bcr | MYSON_BCR_SWR ), myson->regs + MYSON_BCR );
63 /* Wait for reset to complete */
64 for ( i = 0 ; i < MYSON_RESET_MAX_WAIT_MS ; i++ ) {
66 /* If reset is not complete, delay 1ms and retry */
67 if ( readl ( myson->regs + MYSON_BCR ) & MYSON_BCR_SWR ) {
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",
84 DBGC ( myson, "MYSON %p timed out waiting for reset\n", myson );
89 * Reload configuration from EEPROM
91 * @v myson Myson device
92 * @ret rc Return status code
94 static int myson_reload_config ( struct myson_nic *myson ) {
98 writel ( MYSON_ROM_AUTOLD, myson->regs + MYSON_ROM_MII );
100 /* Wait for reload to complete */
101 for ( i = 0 ; i < MYSON_AUTOLD_MAX_WAIT_MS ; i++ ) {
103 /* If reload is not complete, delay 1ms and retry */
104 if ( readl ( myson->regs + MYSON_ROM_MII ) & MYSON_ROM_AUTOLD ){
112 DBGC ( myson, "MYSON %p timed out waiting for configuration "
120 * @v myson Myson device
121 * @ret rc Return status code
123 static int myson_reset ( struct myson_nic *myson ) {
126 /* Disable all interrupts */
127 writel ( 0, myson->regs + MYSON_IMR );
129 /* Perform soft reset */
130 if ( ( rc = myson_soft_reset ( myson ) ) != 0 )
133 /* Reload configuration from EEPROM */
134 if ( ( rc = myson_reload_config ( myson ) ) != 0 )
140 /******************************************************************************
142 * Network device interface
144 ******************************************************************************
148 * Create descriptor ring
150 * @v myson Myson device
151 * @v ring Descriptor ring
152 * @ret rc Return status code
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;
163 /* Allocate descriptor ring */
164 ring->desc = malloc_dma ( len, MYSON_RING_ALIGN );
165 if ( ! ring->desc ) {
169 address = virt_to_bus ( ring->desc );
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",
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 ) );
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 ) );
196 free_dma ( ring->desc, len );
203 * Destroy descriptor ring
205 * @v myson Myson device
206 * @v ring Descriptor ring
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] ) );
212 /* Clear ring address */
213 writel ( 0, myson->regs + ring->reg );
215 /* Free descriptor ring */
216 free_dma ( ring->desc, len );
223 * Refill receive descriptor ring
225 * @v netdev Network device
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;
234 while ( ( myson->rx.prod - myson->rx.cons ) < MYSON_NUM_RX_DESC ) {
236 /* Allocate I/O buffer */
237 iobuf = alloc_iob ( MYSON_RX_MAX_LEN );
239 /* Wait for next refill */
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 );
252 /* Get next receive descriptor */
253 rx_idx = ( myson->rx.prod++ % MYSON_NUM_RX_DESC );
254 rx = &myson->rx.desc[rx_idx];
256 /* Populate receive descriptor */
257 rx->address = cpu_to_le32 ( address );
259 cpu_to_le32 ( MYSON_RX_CTRL_RBS ( MYSON_RX_MAX_LEN ) );
261 rx->status = cpu_to_le32 ( MYSON_RX_STAT_OWN );
264 /* Record I/O buffer */
265 assert ( myson->rx_iobuf[rx_idx] == NULL );
266 myson->rx_iobuf[rx_idx] = iobuf;
268 /* Notify card that there are descriptors available */
269 writel ( 0, myson->regs + MYSON_RXPDR );
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 ) );
278 * Open network device
280 * @v netdev Network device
281 * @ret rc Return status code
283 static int myson_open ( struct net_device *netdev ) {
284 struct myson_nic *myson = netdev->priv;
285 union myson_physical_address mac;
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 );
294 /* Create transmit descriptor ring */
295 if ( ( rc = myson_create_ring ( myson, &myson->tx ) ) != 0 )
298 /* Create receive descriptor ring */
299 if ( ( rc = myson_create_ring ( myson, &myson->rx ) ) != 0 )
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 );
307 /* Fill receive ring */
308 myson_refill_rx ( netdev );
312 myson_destroy_ring ( myson, &myson->rx );
314 myson_destroy_ring ( myson, &myson->tx );
320 * Wait for transmit and receive to become idle
322 * @v myson Myson device
323 * @ret rc Return status code
325 static int myson_wait_idle ( struct myson_nic *myson ) {
329 /* Wait for both transmit and receive to be idle */
330 for ( i = 0 ; i < MYSON_IDLE_MAX_WAIT_MS ; i++ ) {
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 ) ) {
342 DBGC ( myson, "MYSON %p timed out waiting for idle state (status "
343 "%08x)\n", myson, tcr_rcr );
348 * Close network device
350 * @v netdev Network device
352 static void myson_close ( struct net_device *netdev ) {
353 struct myson_nic *myson = netdev->priv;
356 /* Disable receiver and transmitter */
357 writel ( 0, myson->regs + MYSON_TCR_RCR );
359 /* Allow time for receiver and transmitter to become idle */
360 myson_wait_idle ( myson );
362 /* Destroy receive descriptor ring */
363 myson_destroy_ring ( myson, &myson->rx );
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;
372 /* Destroy transmit descriptor ring */
373 myson_destroy_ring ( myson, &myson->tx );
379 * @v netdev Network device
380 * @v iobuf I/O buffer
381 * @ret rc Return status code
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;
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 );
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",
404 tx_idx = ( myson->tx.prod++ % MYSON_NUM_TX_DESC );
405 tx = &myson->tx.desc[tx_idx];
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 ) ) );
415 tx->status = cpu_to_le32 ( MYSON_TX_STAT_OWN );
418 /* Notify card that there are packets ready to transmit */
419 writel ( 0, myson->regs + MYSON_TXPDR );
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 ) ) );
429 * Poll for completed packets
431 * @v netdev Network device
433 static void myson_poll_tx ( struct net_device *netdev ) {
434 struct myson_nic *myson = netdev->priv;
435 struct myson_descriptor *tx;
438 /* Check for completed packets */
439 while ( myson->tx.cons != myson->tx.prod ) {
441 /* Get next transmit descriptor */
442 tx_idx = ( myson->tx.cons % MYSON_NUM_TX_DESC );
443 tx = &myson->tx.desc[tx_idx];
445 /* Stop if descriptor is still in use */
446 if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_OWN ) )
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 );
457 DBGC2 ( myson, "MYSON %p TX %d complete\n",
459 netdev_tx_complete_next ( netdev );
466 * Poll for received packets
468 * @v netdev Network device
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;
477 /* Check for received packets */
478 while ( myson->rx.cons != myson->rx.prod ) {
480 /* Get next receive descriptor */
481 rx_idx = ( myson->rx.cons % MYSON_NUM_RX_DESC );
482 rx = &myson->rx.desc[rx_idx];
484 /* Stop if descriptor is still in use */
485 if ( rx->status & MYSON_RX_STAT_OWN )
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 */ );
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 );
501 DBGC2 ( myson, "MYSON %p RX %d complete (length "
502 "%zd)\n", myson, rx_idx, len );
503 netdev_rx ( netdev, iobuf );
510 * Poll for completed and received packets
512 * @v netdev Network device
514 static void myson_poll ( struct net_device *netdev ) {
515 struct myson_nic *myson = netdev->priv;
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.
524 for ( i = 0 ; i < MYSON_ISR_IODELAY_COUNT ; i++ )
527 /* Check for and acknowledge interrupts */
528 isr = readl ( myson->regs + MYSON_ISR );
531 writel ( isr, myson->regs + MYSON_ISR );
533 /* Poll for TX completions, if applicable */
534 if ( isr & MYSON_IRQ_TI )
535 myson_poll_tx ( netdev );
537 /* Poll for RX completionsm, if applicable */
538 if ( isr & MYSON_IRQ_RI )
539 myson_poll_rx ( netdev );
542 myson_refill_rx ( netdev );
546 * Enable or disable interrupts
548 * @v netdev Network device
549 * @v enable Interrupts should be enabled
551 static void myson_irq ( struct net_device *netdev, int enable ) {
552 struct myson_nic *myson = netdev->priv;
555 imr = ( enable ? ( MYSON_IRQ_TI | MYSON_IRQ_RI ) : 0 );
556 writel ( imr, myson->regs + MYSON_IMR );
559 /** Myson network device operations */
560 static struct net_device_operations myson_operations = {
562 .close = myson_close,
563 .transmit = myson_transmit,
568 /******************************************************************************
572 ******************************************************************************
579 * @ret rc Return status code
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;
587 /* Allocate and initialise net device */
588 netdev = alloc_etherdev ( sizeof ( *myson ) );
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 );
601 /* Fix up PCI device */
602 adjust_pci_device ( pci );
605 myson->regs = ioremap ( pci->membase, MYSON_BAR_SIZE );
606 if ( ! myson->regs ) {
612 if ( ( rc = myson_reset ( myson ) ) != 0 )
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 );
620 /* Register network device */
621 if ( ( rc = register_netdev ( netdev ) ) != 0 )
622 goto err_register_netdev;
624 /* Mark as link up; we don't yet handle link state */
625 netdev_link_up ( netdev );
629 unregister_netdev ( netdev );
631 myson_reset ( myson );
633 iounmap ( myson->regs );
635 netdev_nullify ( netdev );
636 netdev_put ( netdev );
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;
650 /* Unregister network device */
651 unregister_netdev ( netdev );
654 myson_reset ( myson );
656 /* Free network device */
657 iounmap ( myson->regs );
658 netdev_nullify ( netdev );
659 netdev_put ( netdev );
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 ),
669 /** Myson PCI driver */
670 struct pci_driver myson_driver __pci_driver = {
672 .id_count = ( sizeof ( myson_nics ) / sizeof ( myson_nics[0] ) ),
673 .probe = myson_probe,
674 .remove = myson_remove,