iPXE
Functions | Variables
intelxlvf.c File Reference

Intel 40 Gigabit Ethernet virtual function network card driver. More...

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/pci.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include "intelxlvf.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static void intelxlvf_reset_flr (struct intelxl_nic *intelxl, struct pci_device *pci)
 Reset hardware via PCIe function-level reset.
static int intelxlvf_reset_wait_teardown (struct intelxl_nic *intelxl)
 Wait for admin event queue to be torn down.
static int intelxlvf_reset_wait_active (struct intelxl_nic *intelxl)
 Wait for virtual function to be marked as active.
static int intelxlvf_reset_admin (struct intelxl_nic *intelxl)
 Reset hardware via admin queue.
static int intelxlvf_admin_command (struct net_device *netdev)
 Issue admin queue virtual function command.
static void intelxlvf_admin_link (struct net_device *netdev, struct intelxl_admin_vf_status_link *link)
 Handle link status event.
static void intelxlvf_admin_status (struct net_device *netdev, struct intelxl_admin_vf_status_buffer *stat)
 Handle status change event.
void intelxlvf_admin_event (struct net_device *netdev, struct intelxl_admin_descriptor *evt, union intelxl_admin_buffer *buf)
 Handle virtual function event.
static int intelxlvf_admin_get_resources (struct net_device *netdev)
 Get resources.
static int intelxlvf_admin_configure (struct net_device *netdev)
 Configure queues.
static int intelxlvf_admin_irq_map (struct net_device *netdev)
 Configure IRQ mapping.
static int intelxlvf_admin_queues (struct net_device *netdev, int enable)
 Enable/disable queues.
static int intelxlvf_admin_promisc (struct net_device *netdev)
 Configure promiscuous mode.
static int intelxlvf_open (struct net_device *netdev)
 Open network device.
static void intelxlvf_close (struct net_device *netdev)
 Close network device.
static int intelxlvf_probe (struct pci_device *pci)
 Probe PCI device.
static void intelxlvf_remove (struct pci_device *pci)
 Remove PCI device.

Variables

static struct intelxl_admin_offsets intelxlvf_admin_command_offsets
 Admin command queue register offsets.
static struct intelxl_admin_offsets intelxlvf_admin_event_offsets
 Admin event queue register offsets.
static struct net_device_operations intelxlvf_operations
 Network device operations.
static struct pci_device_id intelxlvf_nics []
 PCI device IDs.
struct pci_driver intelxlvf_driver __pci_driver
 PCI driver.

Detailed Description

Intel 40 Gigabit Ethernet virtual function network card driver.

Definition in file intelxlvf.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static void intelxlvf_reset_flr ( struct intelxl_nic intelxl,
struct pci_device pci 
) [static]

Reset hardware via PCIe function-level reset.

Parameters:
intelxlIntel device

Definition at line 53 of file intelxlvf.c.

References control, intelxl_nic::exp, INTELXL_RESET_DELAY_MS, mdelay(), PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR, pci_read_config_word(), and pci_write_config_word().

Referenced by intelxlvf_probe(), and intelxlvf_remove().

                                                           {
        uint16_t control;

        /* Perform a PCIe function-level reset */
        pci_read_config_word ( pci, ( intelxl->exp + PCI_EXP_DEVCTL ),
                               &control );
        pci_write_config_word ( pci, ( intelxl->exp + PCI_EXP_DEVCTL ),
                                ( control | PCI_EXP_DEVCTL_FLR ) );
        mdelay ( INTELXL_RESET_DELAY_MS );
}
static int intelxlvf_reset_wait_teardown ( struct intelxl_nic intelxl) [static]

Wait for admin event queue to be torn down.

Parameters:
intelxlIntel device
Return values:
rcReturn status code

Definition at line 71 of file intelxlvf.c.

References DBGC, ETIMEDOUT, INTELXL_ADMIN_LEN_ENABLE, INTELXLVF_ADMIN, INTELXLVF_ADMIN_EVT_LEN, INTELXLVF_RESET_MAX_WAIT_MS, mdelay(), readl(), and intelxl_nic::regs.

Referenced by intelxlvf_reset_admin().

                                                                         {
        uint32_t admin_evt_len;
        unsigned int i;

        /* Wait for admin event queue to be torn down */
        for ( i = 0 ; i < INTELXLVF_RESET_MAX_WAIT_MS ; i++ ) {

                /* Check admin event queue length register */
                admin_evt_len = readl ( intelxl->regs + INTELXLVF_ADMIN +
                                        INTELXLVF_ADMIN_EVT_LEN );
                if ( ! ( admin_evt_len & INTELXL_ADMIN_LEN_ENABLE ) )
                        return 0;

                /* Delay */
                mdelay ( 1 );
        }

        DBGC ( intelxl, "INTELXL %p timed out waiting for teardown (%#08x)\n",
               intelxl, admin_evt_len );
        return -ETIMEDOUT;
}
static int intelxlvf_reset_wait_active ( struct intelxl_nic intelxl) [static]

Wait for virtual function to be marked as active.

Parameters:
intelxlIntel device
Return values:
rcReturn status code

Definition at line 99 of file intelxlvf.c.

References DBGC, ETIMEDOUT, INTELXLVF_RESET_MAX_WAIT_MS, INTELXLVF_VFGEN_RSTAT, INTELXLVF_VFGEN_RSTAT_VFR_STATE, INTELXLVF_VFGEN_RSTAT_VFR_STATE_ACTIVE, mdelay(), readl(), and intelxl_nic::regs.

Referenced by intelxlvf_reset_admin().

                                                                       {
        uint32_t vfgen_rstat;
        unsigned int vfr_state;
        unsigned int i;

        /* Wait for virtual function to be marked as active */
        for ( i = 0 ; i < INTELXLVF_RESET_MAX_WAIT_MS ; i++ ) {

                /* Check status as written by physical function driver */
                vfgen_rstat = readl ( intelxl->regs + INTELXLVF_VFGEN_RSTAT );
                vfr_state = INTELXLVF_VFGEN_RSTAT_VFR_STATE ( vfgen_rstat );
                if ( vfr_state == INTELXLVF_VFGEN_RSTAT_VFR_STATE_ACTIVE )
                        return 0;

                /* Delay */
                mdelay ( 1 );
        }

        DBGC ( intelxl, "INTELXL %p timed out waiting for activation "
               "(%#08x)\n", intelxl, vfgen_rstat );
        return -ETIMEDOUT;
}
static int intelxlvf_reset_admin ( struct intelxl_nic intelxl) [static]

Reset hardware via admin queue.

Parameters:
intelxlIntel device
Return values:
rcReturn status code

Definition at line 128 of file intelxlvf.c.

References cmd, cpu_to_le16, cpu_to_le32, intelxl_admin_command(), intelxl_admin_command_descriptor(), INTELXL_ADMIN_SEND_TO_PF, INTELXL_ADMIN_VF_RESET, intelxl_reopen_admin(), INTELXL_RESET_DELAY_MS, intelxlvf_reset_wait_active(), intelxlvf_reset_wait_teardown(), mdelay(), intelxl_admin_descriptor::opcode, rc, and intelxl_admin_descriptor::vopcode.

Referenced by intelxlvf_probe(), and intelxlvf_remove().

                                                                 {
        struct intelxl_admin_descriptor *cmd;
        int rc;

        /* Populate descriptor */
        cmd = intelxl_admin_command_descriptor ( intelxl );
        cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_SEND_TO_PF );
        cmd->vopcode = cpu_to_le32 ( INTELXL_ADMIN_VF_RESET );

        /* Issue command */
        if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
                goto err_command;

        /* Wait for minimum reset time */
        mdelay ( INTELXL_RESET_DELAY_MS );

        /* Wait for reset to take effect */
        if ( ( rc = intelxlvf_reset_wait_teardown ( intelxl ) ) != 0 )
                goto err_teardown;

        /* Wait for virtual function to become active */
        if ( ( rc = intelxlvf_reset_wait_active ( intelxl ) ) != 0 )
                goto err_active;

 err_active:
 err_teardown:
        intelxl_reopen_admin ( intelxl );
 err_command:
        return rc;
}
static int intelxlvf_admin_command ( struct net_device netdev) [static]

Issue admin queue virtual function command.

Parameters:
netdevNetwork device
Return values:
rcReturn status code

Definition at line 190 of file intelxlvf.c.

References cmd, intelxl_nic::command, cpu_to_le16, DBGC, intelxl_admin::desc, EIO, ETIMEDOUT, intelxl_admin::index, intelxl_admin_command(), INTELXL_ADMIN_NUM_DESC, INTELXL_ADMIN_SEND_TO_PF, intelxl_poll_admin(), INTELXLVF_ADMIN_MAX_WAIT_MS, le32_to_cpu, mdelay(), intelxl_admin_descriptor::opcode, net_device::priv, rc, intelxl_admin_descriptor::vopcode, intelxl_nic::vopcode, and intelxl_nic::vret.

Referenced by intelxlvf_admin_configure(), intelxlvf_admin_get_resources(), intelxlvf_admin_irq_map(), intelxlvf_admin_promisc(), and intelxlvf_admin_queues().

                                                                 {
        struct intelxl_nic *intelxl = netdev->priv;
        struct intelxl_admin *admin = &intelxl->command;
        struct intelxl_admin_descriptor *cmd;
        unsigned int i;
        int rc;

        /* Populate descriptor */
        cmd = &admin->desc[ admin->index % INTELXL_ADMIN_NUM_DESC ];
        cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_SEND_TO_PF );

        /* Record opcode */
        intelxl->vopcode = le32_to_cpu ( cmd->vopcode );

        /* Issue command */
        if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
                goto err_command;

        /* Wait for response */
        for ( i = 0 ; i < INTELXLVF_ADMIN_MAX_WAIT_MS ; i++ ) {

                /* Poll admin event queue */
                intelxl_poll_admin ( netdev );

                /* If response has not arrived, delay 1ms and retry */
                if ( intelxl->vopcode ) {
                        mdelay ( 1 );
                        continue;
                }

                /* Check for errors */
                if ( intelxl->vret != 0 )
                        return -EIO;

                return 0;
        }

        rc = -ETIMEDOUT;
        DBGC ( intelxl, "INTELXL %p timed out waiting for admin VF command "
               "%#x\n", intelxl, intelxl->vopcode );
 err_command:
        intelxl->vopcode = 0;
        return rc;
}
static void intelxlvf_admin_link ( struct net_device netdev,
struct intelxl_admin_vf_status_link link 
) [static]

Handle link status event.

Parameters:
netdevNetwork device
linkLink status

Definition at line 241 of file intelxlvf.c.

References DBGC, netdev_link_down(), netdev_link_up(), net_device::priv, intelxl_admin_vf_status_link::speed, and intelxl_admin_vf_status_link::status.

Referenced by intelxlvf_admin_status().

                                                                               {
        struct intelxl_nic *intelxl = netdev->priv;

        DBGC ( intelxl, "INTELXL %p link %#02x speed %#02x\n", intelxl,
               link->status, link->speed );

        /* Update network device */
        if ( link->status ) {
                netdev_link_up ( netdev );
        } else {
                netdev_link_down ( netdev );
        }
}
static void intelxlvf_admin_status ( struct net_device netdev,
struct intelxl_admin_vf_status_buffer stat 
) [static]

Handle status change event.

Parameters:
netdevNetwork device
statStatus change event

Definition at line 263 of file intelxlvf.c.

References cpu_to_le32, intelxl_admin_vf_status_buffer::data, DBGC, DBGC_HDA, intelxl_admin_vf_status_buffer::event, INTELXL_ADMIN_VF_STATUS_LINK, intelxlvf_admin_link(), le32_to_cpu, intelxl_admin_vf_status_buffer::link, and net_device::priv.

Referenced by intelxlvf_admin_event().

                                                                       {
        struct intelxl_nic *intelxl = netdev->priv;

        /* Handle event */
        switch ( stat->event ) {
        case cpu_to_le32 ( INTELXL_ADMIN_VF_STATUS_LINK ):
                intelxlvf_admin_link ( netdev, &stat->data.link );
                break;
        default:
                DBGC ( intelxl, "INTELXL %p unrecognised status change "
                       "event %#x:\n", intelxl, le32_to_cpu ( stat->event ) );
                DBGC_HDA ( intelxl, 0, stat, sizeof ( *stat ) );
                break;
        }
}
void intelxlvf_admin_event ( struct net_device netdev,
struct intelxl_admin_descriptor evt,
union intelxl_admin_buffer buf 
)

Handle virtual function event.

Parameters:
netdevNetwork device
evtAdmin queue event descriptor
bufAdmin queue event data buffer

Definition at line 287 of file intelxlvf.c.

References DBGC, DBGC_HDA, INTELXL_ADMIN_VF_STATUS, intelxlvf_admin_status(), le16_to_cpu, le32_to_cpu, intelxl_admin_descriptor::len, memcpy(), net_device::priv, intelxl_admin_buffer::stat, intelxl_nic::vbuf, virt_to_bus(), intelxl_admin_descriptor::vopcode, intelxl_nic::vopcode, intelxl_admin_descriptor::vret, and intelxl_nic::vret.

                                                               {
        struct intelxl_nic *intelxl = netdev->priv;
        unsigned int vopcode = le32_to_cpu ( evt->vopcode );

        /* Record command response if applicable */
        if ( vopcode == intelxl->vopcode ) {
                memcpy ( &intelxl->vbuf, buf, sizeof ( intelxl->vbuf ) );
                intelxl->vopcode = 0;
                intelxl->vret = le32_to_cpu ( evt->vret );
                if ( intelxl->vret != 0 ) {
                        DBGC ( intelxl, "INTELXL %p admin VF command %#x "
                               "error %d\n", intelxl, vopcode, intelxl->vret );
                        DBGC_HDA ( intelxl, virt_to_bus ( evt ), evt,
                                   sizeof ( *evt ) );
                        DBGC_HDA ( intelxl, virt_to_bus ( buf ), buf,
                                   le16_to_cpu ( evt->len ) );
                }
                return;
        }

        /* Handle unsolicited events */
        switch ( vopcode ) {
        case INTELXL_ADMIN_VF_STATUS:
                intelxlvf_admin_status ( netdev, &buf->stat );
                break;
        default:
                DBGC ( intelxl, "INTELXL %p unrecognised VF event %#x:\n",
                       intelxl, vopcode );
                DBGC_HDA ( intelxl, 0, evt, sizeof ( *evt ) );
                DBGC_HDA ( intelxl, 0, buf, le16_to_cpu ( evt->len ) );
                break;
        }
}
static int intelxlvf_admin_get_resources ( struct net_device netdev) [static]

Get resources.

Parameters:
netdevNetwork device
Return values:
rcReturn status code

Definition at line 329 of file intelxlvf.c.

References cmd, cpu_to_le32, DBGC, ETH_ALEN, net_device::hw_addr, intelxl_admin_command_descriptor(), INTELXL_ADMIN_VF_GET_RESOURCES, intelxlvf_admin_command(), le16_to_cpu, intelxl_admin_vf_get_resources_buffer::mac, memcpy(), net_device::priv, rc, intelxl_admin_buffer::res, intelxl_nic::vbuf, intelxl_admin_descriptor::vopcode, intelxl_admin_vf_get_resources_buffer::vsi, and intelxl_nic::vsi.

Referenced by intelxlvf_probe().

                                                                       {
        struct intelxl_nic *intelxl = netdev->priv;
        struct intelxl_admin_descriptor *cmd;
        struct intelxl_admin_vf_get_resources_buffer *res;
        int rc;

        /* Populate descriptor */
        cmd = intelxl_admin_command_descriptor ( intelxl );
        cmd->vopcode = cpu_to_le32 ( INTELXL_ADMIN_VF_GET_RESOURCES );

        /* Issue command */
        if ( ( rc = intelxlvf_admin_command ( netdev ) ) != 0 )
                return rc;

        /* Parse response */
        res = &intelxl->vbuf.res;
        intelxl->vsi = le16_to_cpu ( res->vsi );
        memcpy ( netdev->hw_addr, res->mac, ETH_ALEN );
        DBGC ( intelxl, "INTELXL %p VSI %#04x\n", intelxl, intelxl->vsi );

        return 0;
}
static int intelxlvf_admin_configure ( struct net_device netdev) [static]

Configure queues.

Parameters:
netdevNetwork device
Return values:
rcReturn status code

Definition at line 365 of file intelxlvf.c.

References intelxl_admin_vf_configure_buffer::base, intelxl_admin_buffer::cfg, cmd, intelxl_admin_vf_configure_buffer::count, cpu_to_le16, cpu_to_le32, cpu_to_le64, intelxl_ring::desc, intelxl_admin_descriptor::flags, intelxl_admin_command_buffer(), intelxl_admin_command_descriptor(), INTELXL_ADMIN_FL_BUF, INTELXL_ADMIN_FL_RD, INTELXL_ADMIN_VF_CONFIGURE, INTELXL_RX_NUM_DESC, INTELXL_TX_NUM_DESC, intelxlvf_admin_command(), intelxl_admin_vf_configure_buffer::len, intelxl_admin_descriptor::len, intelxl_admin_vf_configure_buffer::mfs, intelxl_nic::mfs, net_device::priv, intelxl_ring::raw, rc, intelxl_admin_vf_configure_buffer::rx, intelxl_nic::rx, intelxl_admin_vf_configure_buffer::tx, intelxl_nic::tx, virt_to_bus(), intelxl_admin_descriptor::vopcode, intelxl_admin_vf_configure_buffer::vsi, and intelxl_nic::vsi.

Referenced by intelxlvf_open().

                                                                   {
        struct intelxl_nic *intelxl = netdev->priv;
        struct intelxl_admin_descriptor *cmd;
        union intelxl_admin_buffer *buf;
        int rc;

        /* Populate descriptor */
        cmd = intelxl_admin_command_descriptor ( intelxl );
        cmd->vopcode = cpu_to_le32 ( INTELXL_ADMIN_VF_CONFIGURE );
        cmd->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_RD | INTELXL_ADMIN_FL_BUF );
        cmd->len = cpu_to_le16 ( sizeof ( buf->cfg ) );
        buf = intelxl_admin_command_buffer ( intelxl );
        buf->cfg.vsi = cpu_to_le16 ( intelxl->vsi );
        buf->cfg.count = cpu_to_le16 ( 1 );
        buf->cfg.tx.vsi = cpu_to_le16 ( intelxl->vsi );
        buf->cfg.tx.count = cpu_to_le16 ( INTELXL_TX_NUM_DESC );
        buf->cfg.tx.base = cpu_to_le64 ( virt_to_bus ( intelxl->tx.desc.raw ) );
        buf->cfg.rx.vsi = cpu_to_le16 ( intelxl->vsi );
        buf->cfg.rx.count = cpu_to_le32 ( INTELXL_RX_NUM_DESC );
        buf->cfg.rx.len = cpu_to_le32 ( intelxl->mfs );
        buf->cfg.rx.mfs = cpu_to_le32 ( intelxl->mfs );
        buf->cfg.rx.base = cpu_to_le64 ( virt_to_bus ( intelxl->rx.desc.raw ) );

        /* Issue command */
        if ( ( rc = intelxlvf_admin_command ( netdev ) ) != 0 )
                return rc;

        return 0;
}
static int intelxlvf_admin_irq_map ( struct net_device netdev) [static]
static int intelxlvf_admin_queues ( struct net_device netdev,
int  enable 
) [static]

Enable/disable queues.

Parameters:
netdevNetwork device
enableEnable queues
Return values:
rcReturn status code

Definition at line 432 of file intelxlvf.c.

References cmd, cpu_to_le16, cpu_to_le32, intelxl_admin_descriptor::flags, intelxl_admin_command_buffer(), intelxl_admin_command_descriptor(), INTELXL_ADMIN_FL_BUF, INTELXL_ADMIN_FL_RD, INTELXL_ADMIN_VF_DISABLE, INTELXL_ADMIN_VF_ENABLE, intelxlvf_admin_command(), intelxl_admin_descriptor::len, net_device::priv, intelxl_admin_buffer::queues, rc, intelxl_admin_vf_queues_buffer::rx, intelxl_admin_vf_queues_buffer::tx, intelxl_admin_descriptor::vopcode, intelxl_admin_vf_queues_buffer::vsi, and intelxl_nic::vsi.

Referenced by intelxlvf_close(), and intelxlvf_open().

                                                                            {
        struct intelxl_nic *intelxl = netdev->priv;
        struct intelxl_admin_descriptor *cmd;
        union intelxl_admin_buffer *buf;
        int rc;

        /* Populate descriptor */
        cmd = intelxl_admin_command_descriptor ( intelxl );
        cmd->vopcode = ( enable ? cpu_to_le32 ( INTELXL_ADMIN_VF_ENABLE ) :
                         cpu_to_le32 ( INTELXL_ADMIN_VF_DISABLE ) );
        cmd->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_RD | INTELXL_ADMIN_FL_BUF );
        cmd->len = cpu_to_le16 ( sizeof ( buf->queues ) );
        buf = intelxl_admin_command_buffer ( intelxl );
        buf->queues.vsi = cpu_to_le16 ( intelxl->vsi );
        buf->queues.rx = cpu_to_le32 ( 1 );
        buf->queues.tx = cpu_to_le32 ( 1 );

        /* Issue command */
        if ( ( rc = intelxlvf_admin_command ( netdev ) ) != 0 )
                return rc;

        return 0;
}
static int intelxlvf_admin_promisc ( struct net_device netdev) [static]
static int intelxlvf_open ( struct net_device netdev) [static]

Open network device.

Parameters:
netdevNetwork device
Return values:
rcReturn status code

Definition at line 491 of file intelxlvf.c.

References ETH_HLEN, INTELXL_ADMIN_VF_DISABLE, INTELXL_ALIGN, intelxl_alloc_ring(), intelxl_free_ring(), intelxlvf_admin_configure(), intelxlvf_admin_irq_map(), intelxlvf_admin_promisc(), intelxlvf_admin_queues(), intelxl_nic::mfs, net_device::mtu, net_device::priv, rc, intelxl_nic::rx, and intelxl_nic::tx.

                                                        {
        struct intelxl_nic *intelxl = netdev->priv;
        int rc;

        /* Calculate maximum frame size */
        intelxl->mfs = ( ( ETH_HLEN + netdev->mtu + 4 /* CRC */ +
                           INTELXL_ALIGN - 1 ) & ~( INTELXL_ALIGN - 1 ) );

        /* Allocate transmit descriptor ring */
        if ( ( rc = intelxl_alloc_ring ( intelxl, &intelxl->tx ) ) != 0 )
                goto err_alloc_tx;

        /* Allocate receive descriptor ring */
        if ( ( rc = intelxl_alloc_ring ( intelxl, &intelxl->rx ) ) != 0 )
                goto err_alloc_rx;

        /* Configure queues */
        if ( ( rc = intelxlvf_admin_configure ( netdev ) ) != 0 )
                goto err_configure;

        /* Configure IRQ map */
        if ( ( rc = intelxlvf_admin_irq_map ( netdev ) ) != 0 )
                goto err_irq_map;

        /* Enable queues */
        if ( ( rc = intelxlvf_admin_queues ( netdev, 1 ) ) != 0 )
                goto err_enable;

        /* Configure promiscuous mode */
        if ( ( rc = intelxlvf_admin_promisc ( netdev ) ) != 0 )
                goto err_promisc;

        return 0;

 err_promisc:
        intelxlvf_admin_queues ( netdev, INTELXL_ADMIN_VF_DISABLE );
 err_enable:
 err_irq_map:
 err_configure:
        intelxl_free_ring ( intelxl, &intelxl->rx );
 err_alloc_rx:
        intelxl_free_ring ( intelxl, &intelxl->tx );
 err_alloc_tx:
        return rc;
}
static void intelxlvf_close ( struct net_device netdev) [static]

Close network device.

Parameters:
netdevNetwork device

Definition at line 542 of file intelxlvf.c.

References intelxl_empty_rx(), intelxl_free_ring(), intelxlvf_admin_queues(), net_device::priv, rc, intelxl_nic::rx, and intelxl_nic::tx.

                                                          {
        struct intelxl_nic *intelxl = netdev->priv;
        int rc;

        /* Disable queues */
        if ( ( rc = intelxlvf_admin_queues ( netdev, 0 ) ) != 0 ) {
                /* Leak memory; there's nothing else we can do */
                return;
        }

        /* Free receive descriptor ring */
        intelxl_free_ring ( intelxl, &intelxl->rx );

        /* Free transmit descriptor ring */
        intelxl_free_ring ( intelxl, &intelxl->tx );

        /* Discard any unused receive buffers */
        intelxl_empty_rx ( intelxl );
}
static int intelxlvf_probe ( struct pci_device pci) [static]

Probe PCI device.

Parameters:
pciPCI device
Return values:
rcReturn status code

Definition at line 583 of file intelxlvf.c.

References adjust_pci_device(), alloc_etherdev(), intelxl_nic::command, DBGC, intelxl_ring::desc, pci_device::dev, net_device::dev, ENODEV, ENOMEM, ENXIO, intelxl_nic::event, intelxl_nic::exp, intelxl_close_admin(), intelxl_init_admin(), intelxl_msix_disable(), intelxl_msix_enable(), intelxl_open_admin(), INTELXL_RX_NUM_DESC, INTELXL_TX_NUM_DESC, INTELXLVF_ADMIN, intelxlvf_admin_get_resources(), INTELXLVF_BAR_SIZE, intelxlvf_init_ring(), INTELXLVF_QRX_TAIL, INTELXLVF_QTX_TAIL, intelxlvf_reset_admin(), intelxlvf_reset_flr(), INTELXLVF_VFINT_DYN_CTL0, intelxl_nic::intr, ioremap(), iounmap(), pci_device::membase, memset(), netdev, netdev_init(), netdev_nullify(), netdev_put(), PCI_CAP_ID_EXP, pci_find_capability(), pci_set_drvdata(), net_device::priv, rc, register_netdev(), intelxl_nic::regs, intelxl_ring::rx, intelxl_nic::rx, intelxl_ring::tx, intelxl_nic::tx, and unregister_netdev().

                                                      {
        struct net_device *netdev;
        struct intelxl_nic *intelxl;
        int rc;

        /* Allocate and initialise net device */
        netdev = alloc_etherdev ( sizeof ( *intelxl ) );
        if ( ! netdev ) {
                rc = -ENOMEM;
                goto err_alloc;
        }
        netdev_init ( netdev, &intelxlvf_operations );
        intelxl = netdev->priv;
        pci_set_drvdata ( pci, netdev );
        netdev->dev = &pci->dev;
        memset ( intelxl, 0, sizeof ( *intelxl ) );
        intelxl->intr = INTELXLVF_VFINT_DYN_CTL0;
        intelxl_init_admin ( &intelxl->command, INTELXLVF_ADMIN,
                             &intelxlvf_admin_command_offsets );
        intelxl_init_admin ( &intelxl->event, INTELXLVF_ADMIN,
                             &intelxlvf_admin_event_offsets );
        intelxlvf_init_ring ( &intelxl->tx, INTELXL_TX_NUM_DESC,
                              sizeof ( intelxl->tx.desc.tx[0] ),
                              INTELXLVF_QTX_TAIL );
        intelxlvf_init_ring ( &intelxl->rx, INTELXL_RX_NUM_DESC,
                              sizeof ( intelxl->rx.desc.rx[0] ),
                              INTELXLVF_QRX_TAIL );

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

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

        /* Locate PCI Express capability */
        intelxl->exp = pci_find_capability ( pci, PCI_CAP_ID_EXP );
        if ( ! intelxl->exp ) {
                DBGC ( intelxl, "INTELXL %p missing PCIe capability\n",
                       intelxl );
                rc = -ENXIO;
                goto err_exp;
        }

        /* Reset the function via PCIe FLR */
        intelxlvf_reset_flr ( intelxl, pci );

        /* Enable MSI-X dummy interrupt */
        if ( ( rc = intelxl_msix_enable ( intelxl, pci ) ) != 0 )
                goto err_msix;

        /* Open admin queues */
        if ( ( rc = intelxl_open_admin ( intelxl ) ) != 0 )
                goto err_open_admin;

        /* Reset the function via admin queue */
        if ( ( rc = intelxlvf_reset_admin ( intelxl ) ) != 0 )
                goto err_reset_admin;

        /* Get MAC address */
        if ( ( rc = intelxlvf_admin_get_resources ( netdev ) ) != 0 )
                goto err_get_resources;

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

        return 0;

        unregister_netdev ( netdev );
 err_register_netdev:
 err_get_resources:
 err_reset_admin:
        intelxl_close_admin ( intelxl );
 err_open_admin:
        intelxl_msix_disable ( intelxl, pci );
 err_msix:
        intelxlvf_reset_flr ( intelxl, pci );
 err_exp:
        iounmap ( intelxl->regs );
 err_ioremap:
        netdev_nullify ( netdev );
        netdev_put ( netdev );
 err_alloc:
        return rc;
}
static void intelxlvf_remove ( struct pci_device pci) [static]

Remove PCI device.

Parameters:
pciPCI device

Definition at line 678 of file intelxlvf.c.

References intelxl_close_admin(), intelxl_msix_disable(), intelxlvf_reset_admin(), intelxlvf_reset_flr(), iounmap(), netdev, netdev_nullify(), netdev_put(), pci_get_drvdata(), net_device::priv, intelxl_nic::regs, and unregister_netdev().

                                                        {
        struct net_device *netdev = pci_get_drvdata ( pci );
        struct intelxl_nic *intelxl = netdev->priv;

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

        /* Reset the function via admin queue */
        intelxlvf_reset_admin ( intelxl );

        /* Close admin queues */
        intelxl_close_admin ( intelxl );

        /* Disable MSI-X dummy interrupt */
        intelxl_msix_disable ( intelxl, pci );

        /* Reset the function via PCIe FLR */
        intelxlvf_reset_flr ( intelxl, pci );

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

Variable Documentation

Initial value:

Admin command queue register offsets.

Definition at line 167 of file intelxlvf.c.

Initial value:

Admin event queue register offsets.

Definition at line 176 of file intelxlvf.c.

Initial value:
 {
        .open           = intelxlvf_open,
        .close          = intelxlvf_close,
        .transmit       = intelxl_transmit,
        .poll           = intelxl_poll,
}

Network device operations.

Definition at line 563 of file intelxlvf.c.

struct pci_device_id intelxlvf_nics[] [static]
Initial value:
 {
        PCI_ROM ( 0x8086, 0x154c, "xl710-vf", "XL710 VF", 0 ),
        PCI_ROM ( 0x8086, 0x1571, "xl710-vf-hv", "XL710 VF (Hyper-V)", 0 ),
        PCI_ROM ( 0x8086, 0x1889, "xl710-vf-ad", "XL710 VF (adaptive)", 0 ),
        PCI_ROM ( 0x8086, 0x37cd, "x722-vf", "X722 VF", 0 ),
        PCI_ROM ( 0x8086, 0x37d9, "x722-vf-hv", "X722 VF (Hyper-V)", 0 ),
}

PCI device IDs.

Definition at line 704 of file intelxlvf.c.

struct pci_driver intelxlvf_driver __pci_driver
Initial value:
 {
        .ids = intelxlvf_nics,
        .id_count = ( sizeof ( intelxlvf_nics ) /
                      sizeof ( intelxlvf_nics[0] ) ),
        .probe = intelxlvf_probe,
        .remove = intelxlvf_remove,
}

PCI driver.

Definition at line 713 of file intelxlvf.c.