iPXE
Functions | Variables
jme.c File Reference
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ipxe/io.h>
#include <errno.h>
#include <unistd.h>
#include <byteswap.h>
#include <ipxe/pci.h>
#include <ipxe/if_ether.h>
#include <ipxe/ethernet.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include <ipxe/malloc.h>
#include <mii.h>
#include "jme.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static int jme_mdio_read (struct net_device *netdev, int phy, int reg)
static void jme_mdio_write (struct net_device *netdev, int phy, int reg, int val)
static void jme_reset_phy_processor (struct jme_adapter *jme)
static void jme_phy_init (struct jme_adapter *jme)
static void jme_set_phyfifoa (struct jme_adapter *jme)
static void jme_set_phyfifob (struct jme_adapter *jme)
static void jme_phy_off (struct jme_adapter *jme)
static void jme_restart_an (struct jme_adapter *jme)
static void jme_reset_ghc_speed (struct jme_adapter *jme)
static void jme_start_irq (struct jme_adapter *jme)
static void jme_stop_irq (struct jme_adapter *jme)
static void jme_setup_wakeup_frame (struct jme_adapter *jme, u32 *mask, u32 crc, int fnr)
static void jme_reset_mac_processor (struct jme_adapter *jme)
static void jme_free_tx_buffers (struct jme_adapter *jme)
static void jme_free_tx_resources (struct jme_adapter *jme)
static int jme_alloc_tx_resources (struct jme_adapter *jme)
static void jme_init_tx_ring (struct jme_adapter *jme)
static void jme_enable_tx_engine (struct jme_adapter *jme)
static void jme_disable_tx_engine (struct jme_adapter *jme)
static void jme_set_clean_rxdesc (struct jme_adapter *jme, int i)
static int jme_make_new_rx_buf (struct io_buffer **rxbip)
static void jme_free_rx_buf (struct jme_adapter *jme, int i)
static void jme_free_rx_resources (struct jme_adapter *jme)
static int jme_alloc_rx_resources (struct jme_adapter *jme)
static void jme_init_rx_ring (struct jme_adapter *jme)
static void jme_set_multi (struct jme_adapter *jme)
static void jme_enable_rx_engine (struct jme_adapter *jme)
static void jme_restart_rx_engine (struct jme_adapter *jme)
static void jme_disable_rx_engine (struct jme_adapter *jme)
static void jme_refill_rx_ring (struct jme_adapter *jme, int curhole)
static void jme_alloc_and_feed_iob (struct jme_adapter *jme, int idx)
static void jme_process_receive (struct jme_adapter *jme)
static void jme_set_custom_macaddr (struct net_device *netdev)
static int jme_open (struct net_device *netdev)
 Open NIC.
static void jme_close (struct net_device *netdev)
 Close NIC.
static int jme_alloc_txdesc (struct jme_adapter *jme)
static void jme_fill_tx_desc (struct jme_adapter *jme, struct io_buffer *iob, int idx)
static int jme_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static int jme_check_link (struct net_device *netdev, int testonly)
static void jme_link_change (struct net_device *netdev)
static void jme_tx_clean (struct jme_adapter *jme)
static void jme_poll (struct net_device *netdev)
 Poll for received packets.
static void jme_irq (struct net_device *netdev, int enable)
 Enable/disable interrupts.
static void jme_check_hw_ver (struct jme_adapter *jme)
static int jme_reload_eeprom (struct jme_adapter *jme)
static void jme_load_macaddr (struct net_device *netdev)
static int jme_probe (struct pci_device *pci)
 Probe PCI device.
static void jme_remove (struct pci_device *pci)
 Remove PCI device.

Variables

static struct net_device_operations jme_operations
 JME net device operations.
static struct pci_device_id jm_nics []
struct pci_driver jme_driver __pci_driver

Function Documentation

FILE_LICENCE ( GPL2_OR_LATER  )
static int jme_mdio_read ( struct net_device netdev,
int  phy,
int  reg 
) [static]

Definition at line 41 of file jme.c.

References DBG, MII_BMSR, net_device::priv, udelay(), and val.

Referenced by jme_phy_init(), jme_probe(), jme_reset_phy_processor(), and jme_restart_an().

{
        struct jme_adapter *jme = netdev->priv;
        int i, val, again = (reg == MII_BMSR) ? 1 : 0;

read_again:
        jwrite32(jme, JME_SMI, SMI_OP_REQ |
                                smi_phy_addr(phy) |
                                smi_reg_addr(reg));

        for (i = JME_PHY_TIMEOUT * 50 ; i > 0 ; --i) {
                udelay(20);
                val = jread32(jme, JME_SMI);
                if ((val & SMI_OP_REQ) == 0)
                        break;
        }

        if (i == 0) {
                DBG("phy(%d) read timeout : %d\n", phy, reg);
                return 0;
        }

        if (again--)
                goto read_again;

        return (val & SMI_DATA_MASK) >> SMI_DATA_SHIFT;
}
static void jme_mdio_write ( struct net_device netdev,
int  phy,
int  reg,
int  val 
) [static]

Definition at line 70 of file jme.c.

References DBG, net_device::priv, udelay(), and wmb.

Referenced by jme_phy_init(), jme_phy_off(), jme_probe(), jme_reset_phy_processor(), jme_restart_an(), jme_set_phyfifoa(), and jme_set_phyfifob().

{
        struct jme_adapter *jme = netdev->priv;
        int i;

        jwrite32(jme, JME_SMI, SMI_OP_WRITE | SMI_OP_REQ |
                ((val << SMI_DATA_SHIFT) & SMI_DATA_MASK) |
                smi_phy_addr(phy) | smi_reg_addr(reg));

        wmb();
        for (i = JME_PHY_TIMEOUT * 50 ; i > 0 ; --i) {
                udelay(20);
                if ((jread32(jme, JME_SMI) & SMI_OP_REQ) == 0)
                        break;
        }

        if (i == 0)
                DBG("phy(%d) write timeout : %d\n", phy, reg);

        return;
}
static void jme_reset_phy_processor ( struct jme_adapter *  jme) [static]

Definition at line 94 of file jme.c.

References ADVERTISE_1000FULL, ADVERTISE_1000HALF, ADVERTISE_ALL, ADVERTISE_PAUSE_ASYM, ADVERTISE_PAUSE_CAP, BMCR_RESET, jme_mdio_read(), jme_mdio_write(), MII_ADVERTISE, MII_BMCR, MII_CTRL1000, and val.

Referenced by jme_open().

{
        u32 val;

        jme_mdio_write(jme->mii_if.dev,
                        jme->mii_if.phy_id,
                        MII_ADVERTISE, ADVERTISE_ALL |
                        ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);

        if (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC250)
                jme_mdio_write(jme->mii_if.dev,
                                jme->mii_if.phy_id,
                                MII_CTRL1000,
                                ADVERTISE_1000FULL | ADVERTISE_1000HALF);

        val = jme_mdio_read(jme->mii_if.dev,
                                jme->mii_if.phy_id,
                                MII_BMCR);

        jme_mdio_write(jme->mii_if.dev,
                        jme->mii_if.phy_id,
                        MII_BMCR, val | BMCR_RESET);

        return;
}
static void jme_phy_init ( struct jme_adapter *  jme) [static]

Definition at line 121 of file jme.c.

References jme_mdio_read(), and jme_mdio_write().

Referenced by jme_probe().

{
        u16 reg26;

        reg26 = jme_mdio_read(jme->mii_if.dev, jme->mii_if.phy_id, 26);
        jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, 26, reg26 | 0x1000);
}
static void jme_set_phyfifoa ( struct jme_adapter *  jme) [static]

Definition at line 130 of file jme.c.

References jme_mdio_write().

Referenced by jme_check_link(), and jme_probe().

{
        jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, 27, 0x0004);
}
static void jme_set_phyfifob ( struct jme_adapter *  jme) [static]

Definition at line 136 of file jme.c.

References jme_mdio_write().

Referenced by jme_check_link().

{
        jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, 27, 0x0000);
}
static void jme_phy_off ( struct jme_adapter *  jme) [static]

Definition at line 142 of file jme.c.

References BMCR_PDOWN, jme_mdio_write(), and MII_BMCR.

Referenced by jme_close(), and jme_probe().

{
        jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN);
}
static void jme_restart_an ( struct jme_adapter *  jme) [static]

Definition at line 148 of file jme.c.

References BMCR_ANENABLE, BMCR_ANRESTART, jme_mdio_read(), jme_mdio_write(), and MII_BMCR.

Referenced by jme_open().

{
        uint32_t bmcr;

        bmcr = jme_mdio_read(jme->mii_if.dev, jme->mii_if.phy_id, MII_BMCR);
        bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
        jme_mdio_write(jme->mii_if.dev, jme->mii_if.phy_id, MII_BMCR, bmcr);
}
static void jme_reset_ghc_speed ( struct jme_adapter *  jme) [static]

Definition at line 158 of file jme.c.

Referenced by jme_link_change().

{
        jme->reg_ghc &= ~(GHC_SPEED_1000M | GHC_DPX);
        jwrite32(jme, JME_GHC, jme->reg_ghc);
}
static void jme_start_irq ( struct jme_adapter *  jme) [static]

Definition at line 165 of file jme.c.

Referenced by jme_irq().

{
        /*
         * Enable Interrupts
         */
        jwrite32(jme, JME_IENS, INTR_ENABLE);
}
static void jme_stop_irq ( struct jme_adapter *  jme) [static]

Definition at line 174 of file jme.c.

Referenced by jme_irq().

{
        /*
         * Disable Interrupts
         */
        jwrite32f(jme, JME_IENC, INTR_ENABLE);
}
static void jme_setup_wakeup_frame ( struct jme_adapter *  jme,
u32 mask,
u32  crc,
int  fnr 
) [static]

Definition at line 183 of file jme.c.

References wmb.

Referenced by jme_reset_mac_processor().

{
        int i;

        /*
         * Setup CRC pattern
         */
        jwrite32(jme, JME_WFOI, WFOI_CRC_SEL | (fnr & WFOI_FRAME_SEL));
        wmb();
        jwrite32(jme, JME_WFODP, crc);
        wmb();

        /*
         * Setup Mask
         */
        for (i = 0 ; i < WAKEUP_FRAME_MASK_DWNR ; ++i) {
                jwrite32(jme, JME_WFOI,
                                ((i << WFOI_MASK_SHIFT) & WFOI_MASK_SEL) |
                                (fnr & WFOI_FRAME_SEL));
                wmb();
                jwrite32(jme, JME_WFODP, mask[i]);
                wmb();
        }
}
static void jme_reset_mac_processor ( struct jme_adapter *  jme) [static]

Definition at line 210 of file jme.c.

References jme_setup_wakeup_frame(), and udelay().

Referenced by jme_close(), jme_link_change(), and jme_probe().

{
        u32 mask[WAKEUP_FRAME_MASK_DWNR] = {0, 0, 0, 0};
        u32 crc = 0xCDCDCDCD;
        int i;

        jwrite32(jme, JME_GHC, jme->reg_ghc | GHC_SWRST);
        udelay(2);
        jwrite32(jme, JME_GHC, jme->reg_ghc);

        jwrite32(jme, JME_RXDBA_LO, 0x00000000);
        jwrite32(jme, JME_RXDBA_HI, 0x00000000);
        jwrite32(jme, JME_RXQDC, 0x00000000);
        jwrite32(jme, JME_RXNDA, 0x00000000);
        jwrite32(jme, JME_TXDBA_LO, 0x00000000);
        jwrite32(jme, JME_TXDBA_HI, 0x00000000);
        jwrite32(jme, JME_TXQDC, 0x00000000);
        jwrite32(jme, JME_TXNDA, 0x00000000);

        jwrite32(jme, JME_RXMCHT_LO, 0x00000000);
        jwrite32(jme, JME_RXMCHT_HI, 0x00000000);
        for (i = 0 ; i < WAKEUP_FRAME_NR ; ++i)
                jme_setup_wakeup_frame(jme, mask, crc, i);
        jwrite32(jme, JME_GPREG0, GPREG0_DEFAULT);
        jwrite32(jme, JME_GPREG1, GPREG1_DEFAULT);
}
static void jme_free_tx_buffers ( struct jme_adapter *  jme) [static]

Definition at line 238 of file jme.c.

References ENOLINK, netdev_tx_complete_err(), and NULL.

Referenced by jme_init_tx_ring().

{
        struct jme_ring *txring = &jme->txring;
        struct io_buffer *txbi;
        unsigned int i;

        for (i = 0; i < jme->tx_ring_size; ++i) {
                txbi = txring->bufinf[i];
                if (txbi) {
                        netdev_tx_complete_err(jme->mii_if.dev,
                                        txbi, -ENOLINK);
                        txring->bufinf[i] = NULL;
                }
        }
}
static void jme_free_tx_resources ( struct jme_adapter *  jme) [static]

Definition at line 255 of file jme.c.

References free, free_dma(), memset(), and NULL.

Referenced by jme_alloc_tx_resources(), and jme_close().

{
        struct jme_ring *txring = &jme->txring;

        if (txring->desc) {
                if (txring->bufinf) {
                        memset(txring->bufinf, 0,
                                sizeof(struct io_buffer *) * jme->tx_ring_size);
                        free(txring->bufinf);
                }
                free_dma(txring->desc, jme->tx_ring_size * TX_DESC_SIZE);
                txring->desc            = NULL;
                txring->dma             = 0;
                txring->bufinf          = NULL;
        }
        txring->next_to_use     = 0;
        txring->next_to_clean   = 0;
        txring->nr_free         = 0;
}
static int jme_alloc_tx_resources ( struct jme_adapter *  jme) [static]

Definition at line 276 of file jme.c.

References DBG, ENOMEM, jme_free_tx_resources(), malloc(), malloc_dma(), memset(), and virt_to_bus().

Referenced by jme_open().

{
        struct jme_ring *txring = &jme->txring;

        txring->desc = malloc_dma(jme->tx_ring_size * TX_DESC_SIZE,
                                        RING_DESC_ALIGN);
        if (!txring->desc) {
                DBG("Can not allocate transmit ring descriptors.\n");
                goto err_out;
        }

        /*
         * 16 Bytes align
         */
        txring->dma             = virt_to_bus(txring->desc);
        txring->bufinf          = malloc(sizeof(struct io_buffer *) *
                                        jme->tx_ring_size);
        if (!(txring->bufinf)) {
                DBG("Can not allocate transmit buffer info.\n");
                goto err_out;
        }

        /*
         * Initialize Transmit Buffer Pointers
         */
        memset(txring->bufinf, 0,
                sizeof(struct io_buffer *) * jme->tx_ring_size);

        return 0;

err_out:
        jme_free_tx_resources(jme);
        return -ENOMEM;
}
static void jme_init_tx_ring ( struct jme_adapter *  jme) [static]

Definition at line 312 of file jme.c.

References jme_free_tx_buffers(), and memset().

Referenced by jme_link_change().

{
        struct jme_ring *txring = &jme->txring;

        txring->next_to_clean   = 0;
        txring->next_to_use     = 0;
        txring->nr_free         = jme->tx_ring_size;

        /*
         * Initialize Transmit Descriptors
         */
        memset(txring->desc, 0, jme->tx_ring_size * TX_DESC_SIZE);
        jme_free_tx_buffers(jme);
}
static void jme_enable_tx_engine ( struct jme_adapter *  jme) [static]

Definition at line 328 of file jme.c.

References wmb.

Referenced by jme_link_change().

{
        /*
         * Select Queue 0
         */
        jwrite32(jme, JME_TXCS, TXCS_DEFAULT | TXCS_SELECT_QUEUE0);
        wmb();

        /*
         * Setup TX Queue 0 DMA Bass Address
         */
        jwrite32(jme, JME_TXDBA_LO, (uint64_t)jme->txring.dma & 0xFFFFFFFFUL);
        jwrite32(jme, JME_TXDBA_HI, (uint64_t)(jme->txring.dma) >> 32);
        jwrite32(jme, JME_TXNDA, (uint64_t)jme->txring.dma & 0xFFFFFFFFUL);

        /*
         * Setup TX Descptor Count
         */
        jwrite32(jme, JME_TXQDC, jme->tx_ring_size);

        /*
         * Enable TX Engine
         */
        wmb();
        jwrite32(jme, JME_TXCS, jme->reg_txcs |
                                TXCS_SELECT_QUEUE0 |
                                TXCS_ENABLE);

}
static void jme_disable_tx_engine ( struct jme_adapter *  jme) [static]

Definition at line 359 of file jme.c.

References DBG, mdelay(), rmb, val, and wmb.

Referenced by jme_link_change().

{
        int i;
        u32 val;

        /*
         * Disable TX Engine
         */
        jwrite32(jme, JME_TXCS, jme->reg_txcs | TXCS_SELECT_QUEUE0);
        wmb();

        val = jread32(jme, JME_TXCS);
        for (i = JME_TX_DISABLE_TIMEOUT ; (val & TXCS_ENABLE) && i > 0 ; --i) {
                mdelay(1);
                val = jread32(jme, JME_TXCS);
                rmb();
        }

        if (!i)
                DBG("Disable TX engine timeout.\n");
}
static void jme_set_clean_rxdesc ( struct jme_adapter *  jme,
int  i 
) [static]

Definition at line 383 of file jme.c.

References cpu_to_le16, cpu_to_le32, io_buffer::data, virt_to_bus(), and wmb.

Referenced by jme_init_rx_ring(), jme_process_receive(), and jme_refill_rx_ring().

{
        struct jme_ring *rxring = &jme->rxring;
        register struct rxdesc *rxdesc = rxring->desc;
        struct io_buffer *rxbi = rxring->bufinf[i];
        uint64_t mapping;

        rxdesc += i;
        mapping = virt_to_bus(rxbi->data);

        rxdesc->dw[0] = 0;
        rxdesc->dw[1] = 0;
        rxdesc->desc1.bufaddrh  = cpu_to_le32(mapping >> 32);
        rxdesc->desc1.bufaddrl  = cpu_to_le32(mapping & 0xFFFFFFFFUL);
        rxdesc->desc1.datalen   = cpu_to_le16(RX_ALLOC_LEN);
        wmb();
        rxdesc->desc1.flags     |= RXFLAG_OWN | RXFLAG_INT;
}
static int jme_make_new_rx_buf ( struct io_buffer **  rxbip) [static]

Definition at line 403 of file jme.c.

References alloc_iob(), DBG, and ENOMEM.

Referenced by jme_alloc_rx_resources(), and jme_refill_rx_ring().

{
        struct io_buffer *inbuf;

        /*
         * IOB_ALIGN == 2048
         */
        inbuf = alloc_iob(RX_ALLOC_LEN);
        if (!inbuf) {
                DBG("Allocate receive iob error.\n");
                return -ENOMEM;
        }
        *rxbip = inbuf;

        return 0;
}
static void jme_free_rx_buf ( struct jme_adapter *  jme,
int  i 
) [static]

Definition at line 421 of file jme.c.

References free_iob(), and NULL.

Referenced by jme_free_rx_resources().

{
        struct jme_ring *rxring = &jme->rxring;
        struct io_buffer *rxbi = rxring->bufinf[i];

        if (rxbi) {
                free_iob(rxbi);
                rxring->bufinf[i] = NULL;
        }
}
static void jme_free_rx_resources ( struct jme_adapter *  jme) [static]

Definition at line 433 of file jme.c.

References free, free_dma(), jme_free_rx_buf(), and NULL.

Referenced by jme_alloc_rx_resources(), jme_close(), and jme_open().

{
        unsigned int i;
        struct jme_ring *rxring = &jme->rxring;

        if (rxring->desc) {
                if (rxring->bufinf) {
                        for (i = 0 ; i < jme->rx_ring_size ; ++i)
                                jme_free_rx_buf(jme, i);
                        free(rxring->bufinf);
                }

                free_dma(rxring->desc, jme->rx_ring_size * RX_DESC_SIZE);
                rxring->desc     = NULL;
                rxring->dma      = 0;
                rxring->bufinf   = NULL;
        }
        rxring->next_to_fill = 0;
        rxring->next_to_clean = 0;
}
static int jme_alloc_rx_resources ( struct jme_adapter *  jme) [static]

Definition at line 455 of file jme.c.

References DBG, ENOMEM, jme_free_rx_resources(), jme_make_new_rx_buf(), malloc(), malloc_dma(), memset(), and virt_to_bus().

Referenced by jme_open().

{
        unsigned int i;
        struct jme_ring *rxring = &jme->rxring;
        struct io_buffer **bufinf;

        rxring->desc = malloc_dma(jme->rx_ring_size * RX_DESC_SIZE,
                        RING_DESC_ALIGN);
        if (!rxring->desc) {
                DBG("Can not allocate receive ring descriptors.\n");
                goto err_out;
        }

        /*
         * 16 Bytes align
         */
        rxring->dma             = virt_to_bus(rxring->desc);
        rxring->bufinf          = malloc(sizeof(struct io_buffer *) *
                                        jme->rx_ring_size);
        if (!(rxring->bufinf)) {
                DBG("Can not allocate receive buffer info.\n");
                goto err_out;
        }

        /*
         * Initiallize Receive Buffer Pointers
         */
        bufinf = rxring->bufinf;
        memset(bufinf, 0, sizeof(struct io_buffer *) * jme->rx_ring_size);
        for (i = 0 ; i < jme->rx_ring_size ; ++i) {
                if (jme_make_new_rx_buf(bufinf))
                        goto err_out;
                ++bufinf;
        }

        return 0;

err_out:
        jme_free_rx_resources(jme);
        return -ENOMEM;
}
static void jme_init_rx_ring ( struct jme_adapter *  jme) [static]

Definition at line 498 of file jme.c.

References jme_set_clean_rxdesc().

Referenced by jme_link_change().

{
        unsigned int i;
        struct jme_ring *rxring = &jme->rxring;

        for (i = 0 ; i < jme->rx_ring_size ; ++i)
                jme_set_clean_rxdesc(jme, i);

        rxring->next_to_fill = 0;
        rxring->next_to_clean = 0;
}
static void jme_set_multi ( struct jme_adapter *  jme) [static]

Definition at line 511 of file jme.c.

Referenced by jme_enable_rx_engine().

{
        /*
         * Just receive all kind of packet for new.
         */
        jme->reg_rxmcs |= RXMCS_ALLFRAME | RXMCS_BRDFRAME | RXMCS_UNIFRAME;
        jwrite32(jme, JME_RXMCS, jme->reg_rxmcs);
}
static void jme_enable_rx_engine ( struct jme_adapter *  jme) [static]

Definition at line 521 of file jme.c.

References jme_set_multi(), and wmb.

Referenced by jme_link_change().

{
        /*
         * Select Queue 0
         */
        jwrite32(jme, JME_RXCS, jme->reg_rxcs |
                                RXCS_QUEUESEL_Q0);
        wmb();

        /*
         * Setup RX DMA Bass Address
         */
        jwrite32(jme, JME_RXDBA_LO, (uint64_t)(jme->rxring.dma) & 0xFFFFFFFFUL);
        jwrite32(jme, JME_RXDBA_HI, (uint64_t)(jme->rxring.dma) >> 32);
        jwrite32(jme, JME_RXNDA, (uint64_t)(jme->rxring.dma) & 0xFFFFFFFFUL);

        /*
         * Setup RX Descriptor Count
         */
        jwrite32(jme, JME_RXQDC, jme->rx_ring_size);

        /*
         * Setup Unicast Filter
         */
        jme_set_multi(jme);

        /*
         * Enable RX Engine
         */
        wmb();
        jwrite32(jme, JME_RXCS, jme->reg_rxcs |
                                RXCS_QUEUESEL_Q0 |
                                RXCS_ENABLE |
                                RXCS_QST);
}
static void jme_restart_rx_engine ( struct jme_adapter *  jme) [static]

Definition at line 558 of file jme.c.

Referenced by jme_poll().

{
        /*
         * Start RX Engine
         */
        jwrite32(jme, JME_RXCS, jme->reg_rxcs |
                                RXCS_QUEUESEL_Q0 |
                                RXCS_ENABLE |
                                RXCS_QST);
}
static void jme_disable_rx_engine ( struct jme_adapter *  jme) [static]

Definition at line 570 of file jme.c.

References DBG, mdelay(), rmb, val, and wmb.

Referenced by jme_link_change().

{
        int i;
        u32 val;

        /*
         * Disable RX Engine
         */
        jwrite32(jme, JME_RXCS, jme->reg_rxcs);
        wmb();

        val = jread32(jme, JME_RXCS);
        for (i = JME_RX_DISABLE_TIMEOUT ; (val & RXCS_ENABLE) && i > 0 ; --i) {
                mdelay(1);
                val = jread32(jme, JME_RXCS);
                rmb();
        }

        if (!i)
                DBG("Disable RX engine timeout.\n");

}
static void jme_refill_rx_ring ( struct jme_adapter *  jme,
int  curhole 
) [static]

Definition at line 594 of file jme.c.

References jme_make_new_rx_buf(), jme_set_clean_rxdesc(), and limit.

Referenced by jme_alloc_and_feed_iob().

{
        struct jme_ring *rxring = &jme->rxring;
        int i = rxring->next_to_fill;
        struct io_buffer **bufinf = rxring->bufinf;
        int mask = jme->rx_ring_mask;
        int limit = jme->rx_ring_size;

        while (limit--) {
                if (!bufinf[i]) {
                        if (jme_make_new_rx_buf(bufinf + i))
                                break;
                        jme_set_clean_rxdesc(jme, i);
                }
                if (i == curhole)
                        limit = 0;
                i = (i + 1) & mask;
        }
        rxring->next_to_fill = i;
}
static void jme_alloc_and_feed_iob ( struct jme_adapter *  jme,
int  idx 
) [static]

Definition at line 616 of file jme.c.

References net_device::dev, iob_put, jme_refill_rx_ring(), le16_to_cpu, netdev, netdev_rx(), and NULL.

Referenced by jme_process_receive().

{
        struct jme_ring *rxring = &jme->rxring;
        struct rxdesc *rxdesc = rxring->desc;
        struct io_buffer *rxbi = rxring->bufinf[idx];
        struct net_device *netdev = jme->mii_if.dev;
        int framesize;

        rxdesc += idx;

        framesize = le16_to_cpu(rxdesc->descwb.framesize);
        iob_put(rxbi, framesize);
        netdev_rx(netdev, rxbi);

        rxring->bufinf[idx] = NULL;
        jme_refill_rx_ring(jme, idx);
}
static void jme_process_receive ( struct jme_adapter *  jme) [static]

Definition at line 635 of file jme.c.

References cpu_to_le16, DBG, DBG2, net_device::dev, EINVAL, jme_alloc_and_feed_iob(), jme_set_clean_rxdesc(), limit, netdev, netdev_rx_err(), NULL, and rmb.

Referenced by jme_poll().

{
        struct jme_ring *rxring = &jme->rxring;
        struct rxdesc *rxdesc = rxring->desc;
        struct net_device *netdev = jme->mii_if.dev;
        int i, j, ccnt, desccnt, mask = jme->rx_ring_mask;
        unsigned int limit = jme->rx_ring_size;

        i = rxring->next_to_clean;
        rxdesc += i;
        while (rxring->bufinf[i] &&
                !(rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) &&
                (rxdesc->descwb.desccnt & RXWBDCNT_WBCPL) &&
                limit--) {

                rmb();
                desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT;
                DBG2("Cleaning rx desc=%d, cnt=%d\n", i, desccnt);

                if (desccnt > 1 || rxdesc->descwb.errstat & RXWBERR_ALLERR) {
                        for (j = i, ccnt = desccnt ; ccnt-- ; ) {
                                jme_set_clean_rxdesc(jme, j);
                                j = (j + 1) & (mask);
                        }
                        DBG("Dropped packet due to ");
                        if (desccnt > 1)
                                DBG("long packet.(%d descriptors)\n", desccnt);
                        else
                                DBG("Packet error.\n");
                        netdev_rx_err(netdev, NULL, -EINVAL);
                } else {
                        jme_alloc_and_feed_iob(jme, i);
                }

                i = (i + desccnt) & (mask);
                rxdesc = rxring->desc;
                rxdesc += i;
        }
        rxring->next_to_clean = i;

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

Definition at line 679 of file jme.c.

References addr, net_device::ll_addr, net_device::priv, and val.

Referenced by jme_open().

{
        struct jme_adapter *jme = netdev->priv;
        uint8_t *addr = netdev->ll_addr;
        u32 val;

        val = (addr[3] & 0xff) << 24 |
              (addr[2] & 0xff) << 16 |
              (addr[1] & 0xff) <<  8 |
              (addr[0] & 0xff);
        jwrite32(jme, JME_RXUMA_LO, val);
        val = (addr[5] & 0xff) << 8 |
              (addr[4] & 0xff);
        jwrite32(jme, JME_RXUMA_HI, val);
}
static int jme_open ( struct net_device netdev) [static]

Open NIC.

Parameters:
netdevNet device
Return values:
rcReturn status code

Definition at line 702 of file jme.c.

References DBG, jme_alloc_rx_resources(), jme_alloc_tx_resources(), jme_free_rx_resources(), jme_reset_phy_processor(), jme_restart_an(), jme_set_custom_macaddr(), net_device::priv, and rc.

{
        struct jme_adapter *jme = netdev->priv;
        int rc;

        /*
         * Allocate receive resources
         */
        rc = jme_alloc_rx_resources(jme);
        if (rc) {
                DBG("Allocate receive resources error.\n");
                goto nomem_out;
        }

        /*
         * Allocate transmit resources
         */
        rc = jme_alloc_tx_resources(jme);
        if (rc) {
                DBG("Allocate transmit resources error.\n");
                goto free_rx_resources_out;
        }

        jme_set_custom_macaddr(netdev);
        jme_reset_phy_processor(jme);
        jme_restart_an(jme);

        return 0;

free_rx_resources_out:
        jme_free_rx_resources(jme);
nomem_out:
        return rc;
}
static void jme_close ( struct net_device netdev) [static]

Close NIC.

Parameters:
netdevNet device

Definition at line 743 of file jme.c.

References jme_free_rx_resources(), jme_free_tx_resources(), jme_phy_off(), jme_reset_mac_processor(), netdev_link_down(), and net_device::priv.

{
        struct jme_adapter *jme = netdev->priv;

        jme_free_tx_resources(jme);
        jme_free_rx_resources(jme);
        jme_reset_mac_processor(jme);
        jme->phylink = 0;
        jme_phy_off(jme);
        netdev_link_down(netdev);
}
static int jme_alloc_txdesc ( struct jme_adapter *  jme) [static]

Definition at line 756 of file jme.c.

Referenced by jme_transmit().

{
        struct jme_ring *txring = &jme->txring;
        int idx;

        idx = txring->next_to_use;
        if (txring->nr_free < 1)
                return -1;
        --(txring->nr_free);
        txring->next_to_use = (txring->next_to_use + 1) & jme->tx_ring_mask;

        return idx;
}
static void jme_fill_tx_desc ( struct jme_adapter *  jme,
struct io_buffer iob,
int  idx 
) [static]

Definition at line 771 of file jme.c.

References cpu_to_le16, cpu_to_le32, io_buffer::data, DBG2, iob_len(), len, virt_to_bus(), and wmb.

Referenced by jme_transmit().

{
        struct jme_ring *txring = &jme->txring;
        struct txdesc *txdesc = txring->desc;
        uint16_t len = iob_len(iob);
        unsigned long int mapping;

        txdesc += idx;
        mapping = virt_to_bus(iob->data);
        DBG2("TX buffer address: %p(%08lx+%x)\n",
                        iob->data, mapping, len);
        txdesc->dw[0] = 0;
        txdesc->dw[1] = 0;
        txdesc->dw[2] = 0;
        txdesc->dw[3] = 0;
        txdesc->desc1.datalen   = cpu_to_le16(len);
        txdesc->desc1.pktsize   = cpu_to_le16(len);
        txdesc->desc1.bufaddr   = cpu_to_le32(mapping);
        /*
         * Set OWN bit at final.
         * When kernel transmit faster than NIC.
         * And NIC trying to send this descriptor before we tell
         * it to start sending this TX queue.
         * Other fields are already filled correctly.
         */
        wmb();
        txdesc->desc1.flags = TXFLAG_OWN | TXFLAG_INT;
        /*
         * Set tx buffer info after telling NIC to send
         * For better tx_clean timing
         */
        wmb();
        txring->bufinf[idx] = iob;
}
static int jme_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 814 of file jme.c.

References DBG, DBG2, EOVERFLOW, jme_alloc_txdesc(), jme_fill_tx_desc(), and net_device::priv.

{
        struct jme_adapter *jme = netdev->priv;
        int idx;

        idx = jme_alloc_txdesc(jme);
        if (idx < 0) {
                /*
                 * Pause transmit queue somehow if possible.
                 */
                DBG("TX ring full!\n");
                return -EOVERFLOW;
        }

        jme_fill_tx_desc(jme, iobuf, idx);

        jwrite32(jme, JME_TXCS, jme->reg_txcs |
                                TXCS_SELECT_QUEUE0 |
                                TXCS_QUEUE0S |
                                TXCS_ENABLE);
        DBG2("xmit: idx=%d\n", idx);

        return 0;
}
static int jme_check_link ( struct net_device netdev,
int  testonly 
) [static]

Definition at line 840 of file jme.c.

References DBG, jme_set_phyfifoa(), jme_set_phyfifob(), netdev_link_down(), netdev_link_up(), out, net_device::priv, rc, and udelay().

Referenced by jme_link_change().

{
        struct jme_adapter *jme = netdev->priv;
        u32 phylink, ghc, cnt = JME_SPDRSV_TIMEOUT, gpreg1;
        int rc = 0;

        phylink = jread32(jme, JME_PHY_LINK);

        if (phylink & PHY_LINK_UP) {
                /*
                 * Keep polling for speed/duplex resolve complete
                 */
                while (!(phylink & PHY_LINK_SPEEDDPU_RESOLVED) &&
                        --cnt) {

                        udelay(1);
                        phylink = jread32(jme, JME_PHY_LINK);
                }
                if (!cnt)
                        DBG("Waiting speed resolve timeout.\n");

                if (jme->phylink == phylink) {
                        rc = 1;
                        goto out;
                }
                if (testonly)
                        goto out;

                jme->phylink = phylink;

                ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX |
                                GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE |
                                GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY);
                switch (phylink & PHY_LINK_SPEED_MASK) {
                case PHY_LINK_SPEED_10M:
                        ghc |= GHC_SPEED_10M |
                                GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE;
                        break;
                case PHY_LINK_SPEED_100M:
                        ghc |= GHC_SPEED_100M |
                                GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE;
                        break;
                case PHY_LINK_SPEED_1000M:
                        ghc |= GHC_SPEED_1000M |
                                GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY;
                        break;
                default:
                        break;
                }

                if (phylink & PHY_LINK_DUPLEX) {
                        jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT);
                        ghc |= GHC_DPX;
                } else {
                        jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT |
                                                TXMCS_BACKOFF |
                                                TXMCS_CARRIERSENSE |
                                                TXMCS_COLLISION);
                        jwrite32(jme, JME_TXTRHD, TXTRHD_TXPEN |
                                ((0x2000 << TXTRHD_TXP_SHIFT) & TXTRHD_TXP) |
                                TXTRHD_TXREN |
                                ((8 << TXTRHD_TXRL_SHIFT) & TXTRHD_TXRL));
                }

                gpreg1 = GPREG1_DEFAULT;
                if (is_buggy250(jme->pdev->device, jme->chiprev)) {
                        if (!(phylink & PHY_LINK_DUPLEX))
                                gpreg1 |= GPREG1_HALFMODEPATCH;
                        switch (phylink & PHY_LINK_SPEED_MASK) {
                        case PHY_LINK_SPEED_10M:
                                jme_set_phyfifoa(jme);
                                gpreg1 |= GPREG1_RSSPATCH;
                                break;
                        case PHY_LINK_SPEED_100M:
                                jme_set_phyfifob(jme);
                                gpreg1 |= GPREG1_RSSPATCH;
                                break;
                        case PHY_LINK_SPEED_1000M:
                                jme_set_phyfifoa(jme);
                                break;
                        default:
                                break;
                        }
                }

                jwrite32(jme, JME_GPREG1, gpreg1);
                jwrite32(jme, JME_GHC, ghc);
                jme->reg_ghc = ghc;

                DBG("Link is up at %d Mbps, %s-Duplex, MDI%s.\n",
                    ((phylink & PHY_LINK_SPEED_MASK)
                             == PHY_LINK_SPEED_1000M) ? 1000 :
                    ((phylink & PHY_LINK_SPEED_MASK)
                             == PHY_LINK_SPEED_100M)  ? 100  : 10,
                    (phylink & PHY_LINK_DUPLEX) ? "Full" : "Half",
                    (phylink & PHY_LINK_MDI_STAT) ? "-X" : "");
                netdev_link_up(netdev);
        } else {
                if (testonly)
                        goto out;

                DBG("Link is down.\n");
                jme->phylink = 0;
                netdev_link_down(netdev);
        }

out:
        return rc;
}
static void jme_link_change ( struct net_device netdev) [static]

Definition at line 951 of file jme.c.

References jme_check_link(), jme_disable_rx_engine(), jme_disable_tx_engine(), jme_enable_rx_engine(), jme_enable_tx_engine(), jme_init_rx_ring(), jme_init_tx_ring(), jme_reset_ghc_speed(), jme_reset_mac_processor(), netdev_link_down(), netdev_link_ok(), and net_device::priv.

Referenced by jme_poll().

{
        struct jme_adapter *jme = netdev->priv;

        /*
         * Do nothing if the link status did not change.
         */
        if (jme_check_link(netdev, 1))
                return;

        if (netdev_link_ok(netdev)) {
                netdev_link_down(netdev);
                jme_disable_rx_engine(jme);
                jme_disable_tx_engine(jme);
                jme_reset_ghc_speed(jme);
                jme_reset_mac_processor(jme);
        }

        jme_check_link(netdev, 0);
        if (netdev_link_ok(netdev)) {
                jme_init_rx_ring(jme);
                jme_enable_rx_engine(jme);
                jme_init_tx_ring(jme);
                jme_enable_tx_engine(jme);
        }

        return;
}
static void jme_tx_clean ( struct jme_adapter *  jme) [static]

Definition at line 981 of file jme.c.

References io_buffer::data, DBG2, net_device::dev, EIO, iob_len(), max, netdev, netdev_tx_complete(), netdev_tx_complete_err(), NULL, and virt_to_bus().

Referenced by jme_poll().

{
        struct jme_ring *txring = &jme->txring;
        struct txdesc *txdesc = txring->desc;
        struct io_buffer *txbi;
        struct net_device *netdev = jme->mii_if.dev;
        int i, cnt = 0, max, err, mask;

        max = jme->tx_ring_size - txring->nr_free;
        mask = jme->tx_ring_mask;

        for (i = txring->next_to_clean ; cnt < max ; ++cnt) {

                txbi = txring->bufinf[i];

                if (txbi && !(txdesc[i].descwb.flags & TXWBFLAG_OWN)) {
                        DBG2("TX clean address: %08lx(%08lx+%zx)\n",
                                        (unsigned long)txbi->data,
                                        virt_to_bus(txbi->data),
                                        iob_len(txbi));
                        err = txdesc[i].descwb.flags & TXWBFLAG_ALLERR;
                        if (err)
                                netdev_tx_complete_err(netdev, txbi, -EIO);
                        else
                                netdev_tx_complete(netdev, txbi);
                        txring->bufinf[i] = NULL;
                } else {
                        break;
                }

                i = (i + 1) & mask;
        }

        DBG2("txclean: next %d\n", i);
        txring->next_to_clean = i;
        txring->nr_free += cnt;
}
static void jme_poll ( struct net_device netdev) [static]

Poll for received packets.

Parameters:
netdevNetwork device

Definition at line 1024 of file jme.c.

References DBG2, jme_link_change(), jme_process_receive(), jme_restart_rx_engine(), jme_tx_clean(), and net_device::priv.

{
        struct jme_adapter *jme = netdev->priv;
        u32 intrstat;

        intrstat = jread32(jme, JME_IEVE);

        /*
         * Check if any actions needs to perform.
         */
        if ((intrstat & INTR_ENABLE) == 0)
                return;

        /*
         * Check if the device still exist
         */
        if (intrstat == ~((typeof(intrstat))0))
                return;

        DBG2("intrstat 0x%08x\n", intrstat);
        if (intrstat & (INTR_LINKCH | INTR_SWINTR)) {
                DBG2("Link changed\n");
                jme_link_change(netdev);

                /*
                 * Clear all interrupt status
                 */
                jwrite32(jme, JME_IEVE, intrstat);

                /*
                 * Link change event is critical
                 * all other events are ignored
                 */
                return;
        }

        /*
         * Process transmission complete first to free more memory.
         */
        if (intrstat & INTR_TX0) {
                DBG2("Packet transmit complete\n");
                jme_tx_clean(jme);
                jwrite32(jme, JME_IEVE, intrstat & INTR_TX0);
        }

        if (intrstat & (INTR_RX0 | INTR_RX0EMP)) {
                DBG2("Packet received\n");
                jme_process_receive(jme);
                jwrite32(jme, JME_IEVE,
                        intrstat & (INTR_RX0 | INTR_RX0EMP));
                if (intrstat & INTR_RX0EMP)
                        jme_restart_rx_engine(jme);
        }

        /*
         * Clean all other interrupt status
         */
        jwrite32(jme, JME_IEVE,
                intrstat & ~(INTR_RX0 | INTR_RX0EMP | INTR_TX0));
}
static void jme_irq ( struct net_device netdev,
int  enable 
) [static]

Enable/disable interrupts.

Parameters:
netdevNetwork device
enableInterrupts should be enabled

Definition at line 1092 of file jme.c.

References DBG, jme_start_irq(), jme_stop_irq(), and net_device::priv.

{
        struct jme_adapter *jme = netdev->priv;

        DBG("jme interrupts %s\n", (enable ? "enabled" : "disabled"));
        if (enable)
                jme_start_irq(jme);
        else
                jme_stop_irq(jme);
}
static void jme_check_hw_ver ( struct jme_adapter *  jme) [static]

Definition at line 1113 of file jme.c.

Referenced by jme_probe().

{
        u32 chipmode;

        chipmode = jread32(jme, JME_CHIPMODE);

        jme->fpgaver = (chipmode & CM_FPGAVER_MASK) >> CM_FPGAVER_SHIFT;
        jme->chiprev = (chipmode & CM_CHIPREV_MASK) >> CM_CHIPREV_SHIFT;
}
static int jme_reload_eeprom ( struct jme_adapter *  jme) [static]

Definition at line 1124 of file jme.c.

References DBG, EIO, mdelay(), and val.

Referenced by jme_probe().

{
        u32 val;
        int i;

        val = jread32(jme, JME_SMBCSR);

        if (val & SMBCSR_EEPROMD) {
                val |= SMBCSR_CNACK;
                jwrite32(jme, JME_SMBCSR, val);
                val |= SMBCSR_RELOAD;
                jwrite32(jme, JME_SMBCSR, val);
                mdelay(12);

                for (i = JME_EEPROM_RELOAD_TIMEOUT; i > 0; --i) {
                        mdelay(1);
                        if ((jread32(jme, JME_SMBCSR) & SMBCSR_RELOAD) == 0)
                                break;
                }

                if (i == 0) {
                        DBG("eeprom reload timeout\n");
                        return -EIO;
                }
        }

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

Definition at line 1154 of file jme.c.

References net_device::hw_addr, memcpy(), netdev_priv(), and val.

Referenced by jme_probe().

{
        struct jme_adapter *jme = netdev_priv(netdev);
        unsigned char macaddr[6];
        u32 val;

        val = jread32(jme, JME_RXUMA_LO);
        macaddr[0] = (val >>  0) & 0xFF;
        macaddr[1] = (val >>  8) & 0xFF;
        macaddr[2] = (val >> 16) & 0xFF;
        macaddr[3] = (val >> 24) & 0xFF;
        val = jread32(jme, JME_RXUMA_HI);
        macaddr[4] = (val >>  0) & 0xFF;
        macaddr[5] = (val >>  8) & 0xFF;
        memcpy(netdev->hw_addr, macaddr, 6);
}
static int jme_probe ( struct pci_device pci) [static]

Probe PCI device.

Parameters:
pciPCI device
idPCI ID
Return values:
rcReturn status code

Definition at line 1179 of file jme.c.

References adjust_pci_device(), alloc_etherdev(), DBG, pci_device::dev, net_device::dev, pci_device::device, ENOMEM, ioremap(), iounmap(), jme_check_hw_ver(), jme_load_macaddr(), jme_mdio_read(), jme_mdio_write(), jme_phy_init(), jme_phy_off(), jme_reload_eeprom(), jme_reset_mac_processor(), jme_set_phyfifoa(), pci_device::membase, netdev, netdev_init(), netdev_nullify(), netdev_put(), pci_read_config_byte(), pci_set_drvdata(), net_device::priv, rc, and register_netdev().

{
        struct net_device *netdev;
        struct jme_adapter *jme;
        int rc;
        uint8_t mrrs;

        /* Allocate net device */
        netdev = alloc_etherdev(sizeof(*jme));
        if (!netdev)
                return -ENOMEM;
        netdev_init(netdev, &jme_operations);
        jme = netdev->priv;
        pci_set_drvdata(pci, netdev);
        netdev->dev = &pci->dev;
        jme->regs = ioremap(pci->membase, JME_REGS_SIZE);
        if (!(jme->regs)) {
                DBG("Mapping PCI resource region error.\n");
                rc = -ENOMEM;
                goto err_out;
        }
        jme->reg_ghc = 0;
        jme->reg_rxcs = RXCS_DEFAULT;
        jme->reg_rxmcs = RXMCS_DEFAULT;
        jme->phylink = 0;
        jme->pdev = pci;
        jme->mii_if.dev = netdev;
        jme->mii_if.phy_id = 1;
        jme->mii_if.mdio_read = jme_mdio_read;
        jme->mii_if.mdio_write = jme_mdio_write;
        jme->rx_ring_size = 1 << 4;
        jme->rx_ring_mask = jme->rx_ring_size - 1;
        jme->tx_ring_size = 1 << 4;
        jme->tx_ring_mask = jme->tx_ring_size - 1;

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

        /*
         * Get Max Read Req Size from PCI Config Space
         */
        pci_read_config_byte(pci, PCI_DCSR_MRRS, &mrrs);
        mrrs &= PCI_DCSR_MRRS_MASK;
        switch (mrrs) {
        case MRRS_128B:
                jme->reg_txcs = TXCS_DEFAULT | TXCS_DMASIZE_128B;
                break;
        case MRRS_256B:
                jme->reg_txcs = TXCS_DEFAULT | TXCS_DMASIZE_256B;
                break;
        default:
                jme->reg_txcs = TXCS_DEFAULT | TXCS_DMASIZE_512B;
                break;
        };

        /*
         * Get basic hardware info.
         */
        jme_check_hw_ver(jme);
        if (pci->device == PCI_DEVICE_ID_JMICRON_JMC250)
                jme->mii_if.supports_gmii = 1;
        else
                jme->mii_if.supports_gmii = 0;

        /*
         * Initialize PHY
         */
        jme_set_phyfifoa(jme);
        jme_phy_init(jme);

        /*
         * Bring down phy before interface is opened.
         */
        jme_phy_off(jme);

        /*
         * Reset MAC processor and reload EEPROM for MAC Address
         */
        jme_reset_mac_processor(jme);
        rc = jme_reload_eeprom(jme);
        if (rc) {
                DBG("Reload eeprom for reading MAC Address error.\n");
                goto err_unmap;
        }
        jme_load_macaddr(netdev);

        /* Register network device */
        if ((rc = register_netdev(netdev)) != 0) {
                DBG("Register net_device error.\n");
                goto err_unmap;
        }

        return 0;

err_unmap:
        iounmap(jme->regs);
err_out:
        netdev_nullify(netdev);
        netdev_put(netdev);
        return rc;
}
static void jme_remove ( struct pci_device pci) [static]

Remove PCI device.

Parameters:
pciPCI device

Definition at line 1287 of file jme.c.

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

{
        struct net_device *netdev = pci_get_drvdata(pci);
        struct jme_adapter *jme = netdev->priv;

        iounmap(jme->regs);
        unregister_netdev(netdev);
        netdev_nullify(netdev);
        netdev_put(netdev);
}

Variable Documentation

Initial value:
 {
        .open           = jme_open,
        .close          = jme_close,
        .transmit       = jme_transmit,
        .poll           = jme_poll,
        .irq            = jme_irq,
}

JME net device operations.

Definition at line 1104 of file jme.c.

struct pci_device_id jm_nics[] [static]
Initial value:
 {
PCI_ROM(0x197b, 0x0250, "jme",  "JMicron Gigabit Ethernet", 0),
PCI_ROM(0x197b, 0x0260, "jmfe", "JMicron Fast Ethernet",    0),
}

Definition at line 1298 of file jme.c.

struct pci_driver jme_driver __pci_driver
Initial value:
 {
        .ids = jm_nics,
        .id_count = ( sizeof ( jm_nics ) / sizeof ( jm_nics[0] ) ),
        .probe = jme_probe,
        .remove = jme_remove,
}

Definition at line 1303 of file jme.c.