iPXE
Functions | Variables
myson.c File Reference

Myson Technology network card driver. More...

#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/if_ether.h>
#include <ipxe/iobuf.h>
#include <ipxe/malloc.h>
#include <ipxe/pci.h>
#include <ipxe/mii.h>
#include "myson.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int myson_soft_reset (struct myson_nic *myson)
 Reset controller chip.
static int myson_reload_config (struct myson_nic *myson)
 Reload configuration from EEPROM.
static int myson_reset (struct myson_nic *myson)
 Reset hardware.
static int myson_create_ring (struct myson_nic *myson, struct myson_ring *ring)
 Create descriptor ring.
static void myson_destroy_ring (struct myson_nic *myson, struct myson_ring *ring)
 Destroy descriptor ring.
static void myson_refill_rx (struct net_device *netdev)
 Refill receive descriptor ring.
static int myson_open (struct net_device *netdev)
 Open network device.
static int myson_wait_idle (struct myson_nic *myson)
 Wait for transmit and receive to become idle.
static void myson_close (struct net_device *netdev)
 Close network device.
static int myson_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static void myson_poll_tx (struct net_device *netdev)
 Poll for completed packets.
static void myson_poll_rx (struct net_device *netdev)
 Poll for received packets.
static void myson_poll (struct net_device *netdev)
 Poll for completed and received packets.
static void myson_irq (struct net_device *netdev, int enable)
 Enable or disable interrupts.
static int myson_probe (struct pci_device *pci)
 Probe PCI device.
static void myson_remove (struct pci_device *pci)
 Remove PCI device.

Variables

static struct net_device_operations myson_operations
 Myson network device operations.
static struct pci_device_id myson_nics []
 Myson PCI device IDs.
struct pci_driver myson_driver __pci_driver
 Myson PCI driver.

Detailed Description

Myson Technology network card driver.

Definition in file myson.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static int myson_soft_reset ( struct myson_nic *  myson) [static]

Reset controller chip.

Parameters:
mysonMyson device
Return values:
rcReturn status code

Definition at line 59 of file myson.c.

References DBGC, ETIMEDOUT, mdelay(), MYSON_BCR, MYSON_BCR_PBL_DEFAULT, MYSON_BCR_PBL_MASK, MYSON_BCR_RLE, MYSON_BCR_RME, MYSON_BCR_SWR, MYSON_BCR_WIE, MYSON_RESET_MAX_WAIT_MS, readl(), and writel().

Referenced by myson_reset().

                                                        {
        uint32_t bcr;
        unsigned int i;

        /* Initiate reset */
        bcr = readl ( myson->regs + MYSON_BCR );
        writel ( ( bcr | MYSON_BCR_SWR ), myson->regs + MYSON_BCR );

        /* Wait for reset to complete */
        for ( i = 0 ; i < MYSON_RESET_MAX_WAIT_MS ; i++ ) {

                /* If reset is not complete, delay 1ms and retry */
                if ( readl ( myson->regs + MYSON_BCR ) & MYSON_BCR_SWR ) {
                        mdelay ( 1 );
                        continue;
                }

                /* Apply a sensible default bus configuration */
                bcr = readl ( myson->regs + MYSON_BCR );
                bcr &= ~MYSON_BCR_PBL_MASK;
                bcr |= ( MYSON_BCR_RLE | MYSON_BCR_RME | MYSON_BCR_WIE |
                         MYSON_BCR_PBL_DEFAULT );
                writel ( bcr, myson->regs + MYSON_BCR );
                DBGC ( myson, "MYSON %p using configuration %08x\n",
                       myson, bcr );

                return 0;
        }

        DBGC ( myson, "MYSON %p timed out waiting for reset\n", myson );
        return -ETIMEDOUT;
}
static int myson_reload_config ( struct myson_nic *  myson) [static]

Reload configuration from EEPROM.

Parameters:
mysonMyson device
Return values:
rcReturn status code

Definition at line 98 of file myson.c.

References DBGC, ETIMEDOUT, mdelay(), MYSON_AUTOLD_MAX_WAIT_MS, MYSON_ROM_AUTOLD, MYSON_ROM_MII, readl(), and writel().

Referenced by myson_reset().

                                                           {
        unsigned int i;

        /* Initiate reload */
        writel ( MYSON_ROM_AUTOLD, myson->regs + MYSON_ROM_MII );

        /* Wait for reload to complete */
        for ( i = 0 ; i < MYSON_AUTOLD_MAX_WAIT_MS ; i++ ) {

                /* If reload is not complete, delay 1ms and retry */
                if ( readl ( myson->regs + MYSON_ROM_MII ) & MYSON_ROM_AUTOLD ){
                        mdelay ( 1 );
                        continue;
                }

                return 0;
        }

        DBGC ( myson, "MYSON %p timed out waiting for configuration "
               "reload\n", myson );
        return -ETIMEDOUT;
}
static int myson_reset ( struct myson_nic *  myson) [static]

Reset hardware.

Parameters:
mysonMyson device
Return values:
rcReturn status code

Definition at line 127 of file myson.c.

References MYSON_IMR, myson_reload_config(), myson_soft_reset(), rc, and writel().

Referenced by myson_probe(), and myson_remove().

                                                   {
        int rc;

        /* Disable all interrupts */
        writel ( 0, myson->regs + MYSON_IMR );

        /* Perform soft reset */
        if ( ( rc = myson_soft_reset ( myson ) ) != 0 )
                return rc;

        /* Reload configuration from EEPROM */
        if ( ( rc = myson_reload_config ( myson ) ) != 0 )
                return rc;

        return 0;
}
static int myson_create_ring ( struct myson_nic *  myson,
struct myson_ring ring 
) [static]

Create descriptor ring.

Parameters:
mysonMyson device
ringDescriptor ring
Return values:
rcReturn status code

Definition at line 158 of file myson.c.

References address, myson_ring::count, cpu_to_le32, DBGC, myson_ring::desc, ENOMEM, ENOTSUP, free_dma(), len, malloc_dma(), memset(), MYSON_RING_ALIGN, myson_descriptor::next, next, NULL, rc, myson_ring::reg, virt_to_bus(), and writel().

Referenced by myson_open().

                                                         {
        size_t len = ( ring->count * sizeof ( ring->desc[0] ) );
        struct myson_descriptor *desc;
        struct myson_descriptor *next;
        physaddr_t address;
        unsigned int i;
        int rc;

        /* Allocate descriptor ring */
        ring->desc = malloc_dma ( len, MYSON_RING_ALIGN );
        if ( ! ring->desc ) {
                rc = -ENOMEM;
                goto err_alloc;
        }
        address = virt_to_bus ( ring->desc );

        /* Check address is usable by card */
        if ( ! myson_address_ok ( address + len ) ) {
                DBGC ( myson, "MYSON %p cannot support 64-bit ring address\n",
                       myson );
                rc = -ENOTSUP;
                goto err_64bit;
        }

        /* Initialise descriptor ring */
        memset ( ring->desc, 0, len );
        for ( i = 0 ; i < ring->count ; i++ ) {
                desc = &ring->desc[i];
                next = &ring->desc[ ( i + 1 ) % ring->count ];
                desc->next = cpu_to_le32 ( virt_to_bus ( next ) );
        }

        /* Program ring address */
        writel ( address, myson->regs + ring->reg );
        DBGC ( myson, "MYSON %p ring %02x is at [%08llx,%08llx)\n",
               myson, ring->reg, ( ( unsigned long long ) address ),
               ( ( unsigned long long ) address + len ) );

        return 0;

 err_64bit:
        free_dma ( ring->desc, len );
        ring->desc = NULL;
 err_alloc:
        return rc;
}
static void myson_destroy_ring ( struct myson_nic *  myson,
struct myson_ring ring 
) [static]

Destroy descriptor ring.

Parameters:
mysonMyson device
ringDescriptor ring

Definition at line 212 of file myson.c.

References myson_ring::cons, myson_ring::count, myson_ring::desc, free_dma(), len, NULL, myson_ring::prod, myson_ring::reg, and writel().

Referenced by myson_close(), and myson_open().

                                                           {
        size_t len = ( ring->count * sizeof ( ring->desc[0] ) );

        /* Clear ring address */
        writel ( 0, myson->regs + ring->reg );

        /* Free descriptor ring */
        free_dma ( ring->desc, len );
        ring->desc = NULL;
        ring->prod = 0;
        ring->cons = 0;
}
static void myson_refill_rx ( struct net_device netdev) [static]

Refill receive descriptor ring.

Parameters:
netdevNetwork device

Definition at line 231 of file myson.c.

References myson_descriptor::address, address, alloc_iob(), assert, myson_descriptor::control, cpu_to_le32, io_buffer::data, DBGC, DBGC2, ENOTSUP, MYSON_NUM_RX_DESC, MYSON_RX_CTRL_RBS, MYSON_RX_MAX_LEN, MYSON_RX_STAT_OWN, MYSON_RXPDR, netdev_rx_err(), NULL, net_device::priv, rx, myson_descriptor::status, virt_to_bus(), wmb, and writel().

Referenced by myson_open(), and myson_poll().

                                                          {
        struct myson_nic *myson = netdev->priv;
        struct myson_descriptor *rx;
        struct io_buffer *iobuf;
        unsigned int rx_idx;
        physaddr_t address;

        while ( ( myson->rx.prod - myson->rx.cons ) < MYSON_NUM_RX_DESC ) {

                /* Allocate I/O buffer */
                iobuf = alloc_iob ( MYSON_RX_MAX_LEN );
                if ( ! iobuf ) {
                        /* Wait for next refill */
                        return;
                }

                /* Check address is usable by card */
                address = virt_to_bus ( iobuf->data );
                if ( ! myson_address_ok ( address ) ) {
                        DBGC ( myson, "MYSON %p cannot support 64-bit RX "
                               "buffer address\n", myson );
                        netdev_rx_err ( netdev, iobuf, -ENOTSUP );
                        return;
                }

                /* Get next receive descriptor */
                rx_idx = ( myson->rx.prod++ % MYSON_NUM_RX_DESC );
                rx = &myson->rx.desc[rx_idx];

                /* Populate receive descriptor */
                rx->address = cpu_to_le32 ( address );
                rx->control =
                        cpu_to_le32 ( MYSON_RX_CTRL_RBS ( MYSON_RX_MAX_LEN ) );
                wmb();
                rx->status = cpu_to_le32 ( MYSON_RX_STAT_OWN );
                wmb();

                /* Record I/O buffer */
                assert ( myson->rx_iobuf[rx_idx] == NULL );
                myson->rx_iobuf[rx_idx] = iobuf;

                /* Notify card that there are descriptors available */
                writel ( 0, myson->regs + MYSON_RXPDR );

                DBGC2 ( myson, "MYSON %p RX %d is [%llx,%llx)\n", myson,
                        rx_idx, ( ( unsigned long long ) address ),
                        ( ( unsigned long long ) address + MYSON_RX_MAX_LEN ) );
        }
}
static int myson_open ( struct net_device netdev) [static]

Open network device.

Parameters:
netdevNetwork device
Return values:
rcReturn status code

Definition at line 287 of file myson.c.

References ETH_ALEN, myson_physical_address::high, le32_to_cpu, net_device::ll_addr, myson_physical_address::low, memcpy(), memset(), myson_create_ring(), myson_destroy_ring(), MYSON_PAR0, MYSON_PAR4, MYSON_RCR_AB, MYSON_RCR_ALP, MYSON_RCR_AM, MYSON_RCR_ARP, MYSON_RCR_PROM, MYSON_RCR_RE, myson_refill_rx(), MYSON_TCR_RCR, MYSON_TCR_TE, net_device::priv, myson_physical_address::raw, rc, and writel().

                                                    {
        struct myson_nic *myson = netdev->priv;
        union myson_physical_address mac;
        int rc;

        /* Set MAC address */
        memset ( &mac, 0, sizeof ( mac ) );
        memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
        writel ( le32_to_cpu ( mac.reg.low ), myson->regs + MYSON_PAR0 );
        writel ( le32_to_cpu ( mac.reg.high ), myson->regs + MYSON_PAR4 );

        /* Create transmit descriptor ring */
        if ( ( rc = myson_create_ring ( myson, &myson->tx ) ) != 0 )
                goto err_create_tx;

        /* Create receive descriptor ring */
        if ( ( rc = myson_create_ring ( myson, &myson->rx ) ) != 0 )
                goto err_create_rx;

        /* Configure transmitter and receiver */
        writel ( ( MYSON_TCR_TE | MYSON_RCR_PROM | MYSON_RCR_AB | MYSON_RCR_AM |
                   MYSON_RCR_ARP | MYSON_RCR_ALP | MYSON_RCR_RE ),
                 myson->regs + MYSON_TCR_RCR );

        /* Fill receive ring */
        myson_refill_rx ( netdev );

        return 0;

        myson_destroy_ring ( myson, &myson->rx );
 err_create_rx:
        myson_destroy_ring ( myson, &myson->tx );
 err_create_tx:
        return rc;
}
static int myson_wait_idle ( struct myson_nic *  myson) [static]

Wait for transmit and receive to become idle.

Parameters:
mysonMyson device
Return values:
rcReturn status code

Definition at line 329 of file myson.c.

References DBGC, ETIMEDOUT, mdelay(), MYSON_IDLE_MAX_WAIT_MS, MYSON_RCR_RXS, MYSON_TCR_RCR, MYSON_TCR_TXS, and readl().

Referenced by myson_close().

                                                       {
        uint32_t tcr_rcr;
        unsigned int i;

        /* Wait for both transmit and receive to be idle */
        for ( i = 0 ; i < MYSON_IDLE_MAX_WAIT_MS ; i++ ) {

                /* If either process is running, delay 1ms and retry */
                tcr_rcr = readl ( myson->regs + MYSON_TCR_RCR );
                if ( tcr_rcr & ( MYSON_TCR_TXS | MYSON_RCR_RXS ) ) {
                        mdelay ( 1 );
                        continue;
                }

                return 0;
        }

        DBGC ( myson, "MYSON %p timed out waiting for idle state (status "
               "%08x)\n", myson, tcr_rcr );
        return -ETIMEDOUT;
}
static void myson_close ( struct net_device netdev) [static]

Close network device.

Parameters:
netdevNetwork device

Definition at line 356 of file myson.c.

References free_iob(), myson_destroy_ring(), MYSON_NUM_RX_DESC, MYSON_TCR_RCR, myson_wait_idle(), NULL, net_device::priv, and writel().

                                                      {
        struct myson_nic *myson = netdev->priv;
        unsigned int i;

        /* Disable receiver and transmitter */
        writel ( 0, myson->regs + MYSON_TCR_RCR );

        /* Allow time for receiver and transmitter to become idle */
        myson_wait_idle ( myson );

        /* Destroy receive descriptor ring */
        myson_destroy_ring ( myson, &myson->rx );

        /* Discard any unused receive buffers */
        for ( i = 0 ; i < MYSON_NUM_RX_DESC ; i++ ) {
                if ( myson->rx_iobuf[i] )
                        free_iob ( myson->rx_iobuf[i] );
                myson->rx_iobuf[i] = NULL;
        }

        /* Destroy transmit descriptor ring */
        myson_destroy_ring ( myson, &myson->tx );
}
static int myson_transmit ( struct net_device netdev,
struct io_buffer iobuf 
) [static]

Transmit packet.

Parameters:
netdevNetwork device
iobufI/O buffer
Return values:
rcReturn status code

Definition at line 387 of file myson.c.

References myson_descriptor::address, address, myson_descriptor::control, cpu_to_le32, io_buffer::data, DBGC, DBGC2, ENOBUFS, ENOTSUP, iob_len(), MYSON_NUM_TX_DESC, MYSON_TX_CTRL_CRC, MYSON_TX_CTRL_FD, MYSON_TX_CTRL_IC, MYSON_TX_CTRL_LD, MYSON_TX_CTRL_PAD, MYSON_TX_CTRL_PKTS, MYSON_TX_CTRL_RTLC, MYSON_TX_CTRL_TBS, MYSON_TX_STAT_OWN, MYSON_TXPDR, net_device::priv, myson_descriptor::status, tx, virt_to_bus(), wmb, and writel().

                                                      {
        struct myson_nic *myson = netdev->priv;
        struct myson_descriptor *tx;
        unsigned int tx_idx;
        physaddr_t address;

        /* Check address is usable by card */
        address = virt_to_bus ( iobuf->data );
        if ( ! myson_address_ok ( address ) ) {
                DBGC ( myson, "MYSON %p cannot support 64-bit TX buffer "
                       "address\n", myson );
                return -ENOTSUP;
        }

        /* Get next transmit descriptor */
        if ( ( myson->tx.prod - myson->tx.cons ) >= MYSON_NUM_TX_DESC ) {
                DBGC ( myson, "MYSON %p out of transmit descriptors\n",
                       myson );
                return -ENOBUFS;
        }
        tx_idx = ( myson->tx.prod++ % MYSON_NUM_TX_DESC );
        tx = &myson->tx.desc[tx_idx];

        /* Populate transmit descriptor */
        tx->address = cpu_to_le32 ( address );
        tx->control = cpu_to_le32 ( MYSON_TX_CTRL_IC | MYSON_TX_CTRL_LD |
                                    MYSON_TX_CTRL_FD | MYSON_TX_CTRL_CRC |
                                    MYSON_TX_CTRL_PAD | MYSON_TX_CTRL_RTLC |
                                    MYSON_TX_CTRL_PKTS ( iob_len ( iobuf ) ) |
                                    MYSON_TX_CTRL_TBS ( iob_len ( iobuf ) ) );
        wmb();
        tx->status = cpu_to_le32 ( MYSON_TX_STAT_OWN );
        wmb();

        /* Notify card that there are packets ready to transmit */
        writel ( 0, myson->regs + MYSON_TXPDR );

        DBGC2 ( myson, "MYSON %p TX %d is [%llx,%llx)\n", myson, tx_idx,
                ( ( unsigned long long ) address ),
                ( ( unsigned long long ) address + iob_len ( iobuf ) ) );

        return 0;
}
static void myson_poll_tx ( struct net_device netdev) [static]

Poll for completed packets.

Parameters:
netdevNetwork device

Definition at line 437 of file myson.c.

References cpu_to_le32, DBGC, DBGC2, EIO, le32_to_cpu, MYSON_NUM_TX_DESC, MYSON_TX_STAT_ABORT, MYSON_TX_STAT_CSL, MYSON_TX_STAT_OWN, netdev_tx_complete_next(), netdev_tx_complete_next_err(), net_device::priv, myson_descriptor::status, and tx.

Referenced by myson_poll().

                                                        {
        struct myson_nic *myson = netdev->priv;
        struct myson_descriptor *tx;
        unsigned int tx_idx;

        /* Check for completed packets */
        while ( myson->tx.cons != myson->tx.prod ) {

                /* Get next transmit descriptor */
                tx_idx = ( myson->tx.cons % MYSON_NUM_TX_DESC );
                tx = &myson->tx.desc[tx_idx];

                /* Stop if descriptor is still in use */
                if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_OWN ) )
                        return;

                /* Complete TX descriptor */
                if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_ABORT |
                                                MYSON_TX_STAT_CSL ) ) {
                        DBGC ( myson, "MYSON %p TX %d completion error "
                               "(%08x)\n", myson, tx_idx,
                               le32_to_cpu ( tx->status ) );
                        netdev_tx_complete_next_err ( netdev, -EIO );
                } else {
                        DBGC2 ( myson, "MYSON %p TX %d complete\n",
                                myson, tx_idx );
                        netdev_tx_complete_next ( netdev );
                }
                myson->tx.cons++;
        }
}
static void myson_poll_rx ( struct net_device netdev) [static]

Poll for received packets.

Parameters:
netdevNetwork device

Definition at line 474 of file myson.c.

References cpu_to_le32, DBGC, DBGC2, EIO, iob_put, le32_to_cpu, len, MYSON_NUM_RX_DESC, MYSON_RX_STAT_ES, MYSON_RX_STAT_FLNG, MYSON_RX_STAT_OWN, netdev_rx(), netdev_rx_err(), NULL, net_device::priv, rx, and myson_descriptor::status.

Referenced by myson_poll().

                                                        {
        struct myson_nic *myson = netdev->priv;
        struct myson_descriptor *rx;
        struct io_buffer *iobuf;
        unsigned int rx_idx;
        size_t len;

        /* Check for received packets */
        while ( myson->rx.cons != myson->rx.prod ) {

                /* Get next receive descriptor */
                rx_idx = ( myson->rx.cons % MYSON_NUM_RX_DESC );
                rx = &myson->rx.desc[rx_idx];

                /* Stop if descriptor is still in use */
                if ( rx->status & MYSON_RX_STAT_OWN )
                        return;

                /* Populate I/O buffer */
                iobuf = myson->rx_iobuf[rx_idx];
                myson->rx_iobuf[rx_idx] = NULL;
                len = MYSON_RX_STAT_FLNG ( le32_to_cpu ( rx->status ) );
                iob_put ( iobuf, len - 4 /* strip CRC */ );

                /* Hand off to network stack */
                if ( rx->status & cpu_to_le32 ( MYSON_RX_STAT_ES ) ) {
                        DBGC ( myson, "MYSON %p RX %d error (length %zd, "
                               "status %08x)\n", myson, rx_idx, len,
                               le32_to_cpu ( rx->status ) );
                        netdev_rx_err ( netdev, iobuf, -EIO );
                } else {
                        DBGC2 ( myson, "MYSON %p RX %d complete (length "
                                "%zd)\n", myson, rx_idx, len );
                        netdev_rx ( netdev, iobuf );
                }
                myson->rx.cons++;
        }
}
static void myson_poll ( struct net_device netdev) [static]

Poll for completed and received packets.

Parameters:
netdevNetwork device

Definition at line 518 of file myson.c.

References iodelay(), isr, MYSON_IRQ_RI, MYSON_IRQ_TI, MYSON_ISR, MYSON_ISR_IODELAY_COUNT, myson_poll_rx(), myson_poll_tx(), myson_refill_rx(), net_device::priv, readl(), and writel().

                                                     {
        struct myson_nic *myson = netdev->priv;
        uint32_t isr;
        unsigned int i;

        /* Polling the ISR seems to really upset this card; it ends up
         * getting no useful PCI transfers done and, for some reason,
         * flooding the network with invalid packets.  Work around
         * this by introducing deliberate delays between ISR reads.
         */
        for ( i = 0 ; i < MYSON_ISR_IODELAY_COUNT ; i++ )
                iodelay();

        /* Check for and acknowledge interrupts */
        isr = readl ( myson->regs + MYSON_ISR );
        if ( ! isr )
                return;
        writel ( isr, myson->regs + MYSON_ISR );

        /* Poll for TX completions, if applicable */
        if ( isr & MYSON_IRQ_TI )
                myson_poll_tx ( netdev );

        /* Poll for RX completionsm, if applicable */
        if ( isr & MYSON_IRQ_RI )
                myson_poll_rx ( netdev );

        /* Refill RX ring */
        myson_refill_rx ( netdev );
}
static void myson_irq ( struct net_device netdev,
int  enable 
) [static]

Enable or disable interrupts.

Parameters:
netdevNetwork device
enableInterrupts should be enabled

Definition at line 555 of file myson.c.

References imr, MYSON_IMR, MYSON_IRQ_RI, MYSON_IRQ_TI, net_device::priv, and writel().

                                                                {
        struct myson_nic *myson = netdev->priv;
        uint32_t imr;

        imr = ( enable ? ( MYSON_IRQ_TI | MYSON_IRQ_RI ) : 0 );
        writel ( imr, myson->regs + MYSON_IMR );
}
static int myson_probe ( struct pci_device pci) [static]

Probe PCI device.

Parameters:
pciPCI device
Return values:
rcReturn status code

Definition at line 585 of file myson.c.

References adjust_pci_device(), alloc_etherdev(), cpu_to_le32, pci_device::dev, net_device::dev, ENODEV, ENOMEM, ETH_ALEN, myson_physical_address::high, net_device::hw_addr, ioremap(), iounmap(), myson_physical_address::low, pci_device::membase, memcpy(), memset(), MYSON_BAR_SIZE, MYSON_NUM_RX_DESC, MYSON_NUM_TX_DESC, MYSON_PAR0, MYSON_PAR4, myson_reset(), MYSON_RXLBA, MYSON_TXLBA, netdev, netdev_init(), netdev_link_up(), netdev_nullify(), netdev_put(), pci_set_drvdata(), net_device::priv, myson_physical_address::raw, rc, readl(), register_netdev(), and unregister_netdev().

                                                  {
        struct net_device *netdev;
        struct myson_nic *myson;
        union myson_physical_address mac;
        int rc;

        /* Allocate and initialise net device */
        netdev = alloc_etherdev ( sizeof ( *myson ) );
        if ( ! netdev ) {
                rc = -ENOMEM;
                goto err_alloc;
        }
        netdev_init ( netdev, &myson_operations );
        myson = netdev->priv;
        pci_set_drvdata ( pci, netdev );
        netdev->dev = &pci->dev;
        memset ( myson, 0, sizeof ( *myson ) );
        myson_init_ring ( &myson->tx, MYSON_NUM_TX_DESC, MYSON_TXLBA );
        myson_init_ring ( &myson->rx, MYSON_NUM_RX_DESC, MYSON_RXLBA );

        /* Fix up PCI device */
        adjust_pci_device ( pci );

        /* Map registers */
        myson->regs = ioremap ( pci->membase, MYSON_BAR_SIZE );
        if ( ! myson->regs ) {
                rc = -ENODEV;
                goto err_ioremap;
        }

        /* Reset the NIC */
        if ( ( rc = myson_reset ( myson ) ) != 0 )
                goto err_reset;

        /* Read MAC address */
        mac.reg.low = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR0 ) );
        mac.reg.high = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR4 ) );
        memcpy ( netdev->hw_addr, mac.raw, ETH_ALEN );

        /* Register network device */
        if ( ( rc = register_netdev ( netdev ) ) != 0 )
                goto err_register_netdev;

        /* Mark as link up; we don't yet handle link state */
        netdev_link_up ( netdev );

        return 0;

        unregister_netdev ( netdev );
 err_register_netdev:
        myson_reset ( myson );
 err_reset:
        iounmap ( myson->regs );
 err_ioremap:
        netdev_nullify ( netdev );
        netdev_put ( netdev );
 err_alloc:
        return rc;
}
static void myson_remove ( struct pci_device pci) [static]

Remove PCI device.

Parameters:
pciPCI device

Definition at line 650 of file myson.c.

References iounmap(), myson_reset(), netdev, netdev_nullify(), netdev_put(), pci_get_drvdata(), net_device::priv, and unregister_netdev().

                                                    {
        struct net_device *netdev = pci_get_drvdata ( pci );
        struct myson_nic *myson = netdev->priv;

        /* Unregister network device */
        unregister_netdev ( netdev );

        /* Reset card */
        myson_reset ( myson );

        /* Free network device */
        iounmap ( myson->regs );
        netdev_nullify ( netdev );
        netdev_put ( netdev );
}

Variable Documentation

Initial value:
 {
        .open           = myson_open,
        .close          = myson_close,
        .transmit       = myson_transmit,
        .poll           = myson_poll,
        .irq            = myson_irq,
}

Myson network device operations.

Definition at line 564 of file myson.c.

struct pci_device_id myson_nics[] [static]
Initial value:
 {
        PCI_ROM ( 0x1516, 0x0800, "mtd800", "MTD-8xx", 0 ),
        PCI_ROM ( 0x1516, 0x0803, "mtd803", "Surecom EP-320X-S", 0 ),
        PCI_ROM ( 0x1516, 0x0891, "mtd891", "MTD-8xx", 0 ),
}

Myson PCI device IDs.

Definition at line 667 of file myson.c.

struct pci_driver myson_driver __pci_driver
Initial value:
 {
        .ids = myson_nics,
        .id_count = ( sizeof ( myson_nics ) / sizeof ( myson_nics[0] ) ),
        .probe = myson_probe,
        .remove = myson_remove,
}

Myson PCI driver.

Definition at line 674 of file myson.c.