iPXE
Functions
intelvf.c File Reference

Intel 10/100/1000 virtual function network card driver. More...

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <ipxe/io.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include "intelvf.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static void intelvf_mbox_write (struct intel_nic *intel, const union intelvf_msg *msg)
 Write message to mailbox.
static void intelvf_mbox_read (struct intel_nic *intel, union intelvf_msg *msg)
 Read message from mailbox.
int intelvf_mbox_poll (struct intel_nic *intel)
 Poll mailbox.
int intelvf_mbox_wait (struct intel_nic *intel)
 Wait for PF reset to complete.
int intelvf_mbox_msg (struct intel_nic *intel, union intelvf_msg *msg)
 Send/receive mailbox message.
int intelvf_mbox_reset (struct intel_nic *intel, uint8_t *hw_addr)
 Send reset message and get initial MAC address.
int intelvf_mbox_set_mac (struct intel_nic *intel, const uint8_t *ll_addr)
 Send set MAC address message.
int intelvf_mbox_set_mtu (struct intel_nic *intel, size_t mtu)
 Send set MTU message.

Detailed Description

Intel 10/100/1000 virtual function network card driver.

Definition in file intelvf.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static void intelvf_mbox_write ( struct intel_nic *  intel,
const union intelvf_msg msg 
) [static]

Write message to mailbox.

Parameters:
intelIntel device
msgMessage

Definition at line 53 of file intelvf.c.

References DBGC2, intelvf_msg::dword, and writel().

Referenced by intelvf_mbox_msg().

                                                                {
        unsigned int i;

        /* Write message */
        DBGC2 ( intel, "INTEL %p sending message", intel );
        for ( i = 0 ; i < ( sizeof ( *msg ) / sizeof ( msg->dword[0] ) ) ; i++){
                DBGC2 ( intel, "%c%08x", ( i ? ':' : ' ' ), msg->dword[i] );
                writel ( msg->dword[i], ( intel->regs + intel->mbox.mem +
                                          ( i * sizeof ( msg->dword[0] ) ) ) );
        }
        DBGC2 ( intel, "\n" );
}
static void intelvf_mbox_read ( struct intel_nic *  intel,
union intelvf_msg msg 
) [static]

Read message from mailbox.

Parameters:
intelIntel device
msgMessage

Definition at line 73 of file intelvf.c.

References DBGC2, intelvf_msg::dword, and readl().

Referenced by intelvf_mbox_msg(), and intelvf_mbox_poll().

                                                         {
        unsigned int i;

        /* Read message */
        DBGC2 ( intel, "INTEL %p received message", intel );
        for ( i = 0 ; i < ( sizeof ( *msg ) / sizeof ( msg->dword[0] ) ) ; i++){
                msg->dword[i] = readl ( intel->regs + intel->mbox.mem +
                                        ( i * sizeof ( msg->dword[0] ) ) );
                DBGC2 ( intel, "%c%08x", ( i ? ':' : ' ' ), msg->dword[i] );
        }
        DBGC2 ( intel, "\n" );
}
int intelvf_mbox_poll ( struct intel_nic *  intel)

Poll mailbox.

Parameters:
intelIntel device
Return values:
rcReturn status code

Note that polling the mailbox may fail if the underlying PF is reset.

Definition at line 96 of file intelvf.c.

References intel_mailbox::ctrl, ctrl, EPIPE, INTELVF_MBCTRL_ACK, INTELVF_MBCTRL_PFSTS, INTELVF_MBCTRL_RSTI, intelvf_mbox_read(), readl(), and writel().

Referenced by intelvf_mbox_wait(), and intelxvf_poll().

                                                  {
        struct intel_mailbox *mbox = &intel->mbox;
        union intelvf_msg msg;
        uint32_t ctrl;

        /* Get mailbox status */
        ctrl = readl ( intel->regs + mbox->ctrl );

        /* Fail if a reset is in progress */
        if ( ctrl & INTELVF_MBCTRL_RSTI )
                return -EPIPE;

        /* Acknowledge (and ignore) any received messages */
        if ( ctrl & INTELVF_MBCTRL_PFSTS ) {
                intelvf_mbox_read ( intel, &msg );
                writel ( INTELVF_MBCTRL_ACK, intel->regs + mbox->ctrl );
        }

        return 0;
}
int intelvf_mbox_wait ( struct intel_nic *  intel)

Wait for PF reset to complete.

Parameters:
intelIntel device
Return values:
rcReturn status code

Definition at line 123 of file intelvf.c.

References DBGC, ETIMEDOUT, INTELVF_MBOX_MAX_WAIT_MS, intelvf_mbox_poll(), mdelay(), and rc.

                                                  {
        unsigned int i;
        int rc;

        /* Wait until a poll completes successfully */
        for ( i = 0 ; i < INTELVF_MBOX_MAX_WAIT_MS ; i++ ) {

                /* Check for successful poll */
                if ( ( rc = intelvf_mbox_poll ( intel ) ) == 0 )
                        return 0;

                /* Delay */
                mdelay ( 1 );
        }

        DBGC ( intel, "INTEL %p timed out waiting for reset\n", intel );
        return -ETIMEDOUT;
}
int intelvf_mbox_msg ( struct intel_nic *  intel,
union intelvf_msg msg 
)

Send/receive mailbox message.

Parameters:
intelIntel device
msgMessage buffer
Return values:
rcReturn status code

Definition at line 149 of file intelvf.c.

References assert, intel_mailbox::ctrl, ctrl, DBGC, EPIPE, ETIMEDOUT, intelvf_msg::hdr, INTELVF_MBCTRL_ACK, INTELVF_MBCTRL_PFACK, INTELVF_MBCTRL_PFSTS, INTELVF_MBCTRL_REQ, INTELVF_MBCTRL_RSTI, INTELVF_MBCTRL_VFU, INTELVF_MBOX_MAX_WAIT_MS, intelvf_mbox_read(), intelvf_mbox_write(), INTELVF_MSG_RESPONSE, mdelay(), readl(), and writel().

Referenced by intelvf_mbox_reset(), intelvf_mbox_set_mac(), intelvf_mbox_set_mtu(), intelxvf_mbox_queues(), and intelxvf_mbox_version().

                                                                         {
        struct intel_mailbox *mbox = &intel->mbox;
        uint32_t ctrl;
        uint32_t seen = 0;
        unsigned int i;

        /* Sanity check */
        assert ( ! ( msg->hdr & INTELVF_MSG_RESPONSE ) );

        /* Handle mailbox */
        for ( i = 0 ; i < INTELVF_MBOX_MAX_WAIT_MS ; i++ ) {

                /* Attempt to claim mailbox, if we have not yet sent
                 * our message.
                 */
                if ( ! ( seen & INTELVF_MBCTRL_VFU ) )
                        writel ( INTELVF_MBCTRL_VFU, intel->regs + mbox->ctrl );

                /* Get mailbox status and record observed flags */
                ctrl = readl ( intel->regs + mbox->ctrl );
                seen |= ctrl;

                /* If a reset is in progress, clear VFU and abort */
                if ( ctrl & INTELVF_MBCTRL_RSTI ) {
                        writel ( 0, intel->regs + mbox->ctrl );
                        return -EPIPE;
                }

                /* Write message to mailbox, if applicable.  This
                 * potentially overwrites a message sent by the PF (if
                 * the PF has simultaneously released PFU (thus
                 * allowing our VFU) and asserted PFSTS), but that
                 * doesn't really matter since there are no
                 * unsolicited PF->VF messages that require the actual
                 * message content to be observed.
                 */
                if ( ctrl & INTELVF_MBCTRL_VFU )
                        intelvf_mbox_write ( intel, msg );

                /* Read message from mailbox, if applicable. */
                if ( ( seen & INTELVF_MBCTRL_VFU ) &&
                     ( seen & INTELVF_MBCTRL_PFACK ) &&
                     ( ctrl & INTELVF_MBCTRL_PFSTS ) )
                        intelvf_mbox_read ( intel, msg );

                /* Acknowledge received message (if applicable),
                 * release VFU lock, and send message (if applicable).
                 */
                ctrl = ( ( ( ctrl & INTELVF_MBCTRL_PFSTS ) ?
                           INTELVF_MBCTRL_ACK : 0 ) |
                         ( ( ctrl & INTELVF_MBCTRL_VFU ) ?
                           INTELVF_MBCTRL_REQ : 0 ) );
                writel ( ctrl, intel->regs + mbox->ctrl );

                /* Exit successfully if we have received a response */
                if ( msg->hdr & INTELVF_MSG_RESPONSE ) {

                        /* Sanity check */
                        assert ( seen & INTELVF_MBCTRL_VFU );
                        assert ( seen & INTELVF_MBCTRL_PFACK );
                        assert ( seen & INTELVF_MBCTRL_PFSTS );

                        return 0;
                }

                /* Delay */
                mdelay ( 1 );
        }

        DBGC ( intel, "INTEL %p timed out waiting for mailbox (seen %08x)\n",
               intel, seen );
        return -ETIMEDOUT;
}
int intelvf_mbox_reset ( struct intel_nic *  intel,
uint8_t hw_addr 
)

Send reset message and get initial MAC address.

Parameters:
intelIntel device
hw_addrHardware address to fill in, or NULL
Return values:
rcReturn status code

Definition at line 230 of file intelvf.c.

References DBGC, DBGC_HDA, EPROTO, eth_ntoa(), eth_random_addr(), intelvf_msg::hdr, intelvf_mbox_msg(), INTELVF_MSG_ACK, INTELVF_MSG_TYPE_MASK, INTELVF_MSG_TYPE_RESET, intelvf_msg_mac::mac, intelvf_msg::mac, memcpy(), memset(), rc, and strerror().

Referenced by intelxvf_open(), and intelxvf_probe().

                                                                     {
        union intelvf_msg msg;
        int rc;

        /* Send reset message */
        memset ( &msg, 0, sizeof ( msg ) );
        msg.hdr = INTELVF_MSG_TYPE_RESET;
        if ( ( rc = intelvf_mbox_msg ( intel, &msg ) ) != 0 ) {
                DBGC ( intel, "INTEL %p reset failed: %s\n",
                       intel, strerror ( rc ) );
                return rc;
        }

        /* Check response */
        if ( ( msg.hdr & INTELVF_MSG_TYPE_MASK ) != INTELVF_MSG_TYPE_RESET ) {
                DBGC ( intel, "INTEL %p reset unexpected response:\n", intel );
                DBGC_HDA ( intel, 0, &msg, sizeof ( msg ) );
                return -EPROTO;
        }

        /* Fill in MAC address, if applicable */
        if ( hw_addr ) {
                if ( msg.hdr & INTELVF_MSG_ACK ) {
                        memcpy ( hw_addr, msg.mac.mac, sizeof ( msg.mac.mac ) );
                        DBGC ( intel, "INTEL %p reset assigned MAC address "
                               "%s\n", intel, eth_ntoa ( hw_addr ) );
                } else {
                        eth_random_addr ( hw_addr );
                        DBGC ( intel, "INTEL %p reset generated MAC address "
                               "%s\n", intel, eth_ntoa ( hw_addr ) );
                }
        }

        return 0;
}
int intelvf_mbox_set_mac ( struct intel_nic *  intel,
const uint8_t ll_addr 
)

Send set MAC address message.

Parameters:
intelIntel device
ll_addrLink-layer address
Return values:
rcReturn status code

Definition at line 273 of file intelvf.c.

References DBGC, DBGC_HDA, EPERM, EPROTO, intelvf_msg::hdr, intelvf_mbox_msg(), INTELVF_MSG_ACK, INTELVF_MSG_TYPE_MASK, INTELVF_MSG_TYPE_SET_MAC, intelvf_msg_mac::mac, intelvf_msg::mac, memcpy(), memset(), rc, and strerror().

Referenced by intelxvf_open().

                                                                             {
        union intelvf_msg msg;
        int rc;

        /* Send set MAC address message */
        memset ( &msg, 0, sizeof ( msg ) );
        msg.hdr = INTELVF_MSG_TYPE_SET_MAC;
        memcpy ( msg.mac.mac, ll_addr, sizeof ( msg.mac.mac ) );
        if ( ( rc = intelvf_mbox_msg ( intel, &msg ) ) != 0 ) {
                DBGC ( intel, "INTEL %p set MAC address failed: %s\n",
                       intel, strerror ( rc ) );
                return rc;
        }

        /* Check response */
        if ( ( msg.hdr & INTELVF_MSG_TYPE_MASK ) != INTELVF_MSG_TYPE_SET_MAC ) {
                DBGC ( intel, "INTEL %p set MAC address unexpected response:\n",
                       intel );
                DBGC_HDA ( intel, 0, &msg, sizeof ( msg ) );
                return -EPROTO;
        }

        /* Check that we were allowed to set the MAC address */
        if ( ! ( msg.hdr & INTELVF_MSG_ACK ) ) {
                DBGC ( intel, "INTEL %p set MAC address refused\n", intel );
                return -EPERM;
        }

        return 0;
}
int intelvf_mbox_set_mtu ( struct intel_nic *  intel,
size_t  mtu 
)

Send set MTU message.

Parameters:
intelIntel device
mtuMaximum packet size
Return values:
rcReturn status code

Definition at line 311 of file intelvf.c.

References DBGC, DBGC_HDA, EPERM, EPROTO, intelvf_msg::hdr, intelvf_mbox_msg(), INTELVF_MSG_ACK, INTELVF_MSG_TYPE_MASK, INTELVF_MSG_TYPE_SET_MTU, memset(), intelvf_msg_mtu::mtu, intelvf_msg::mtu, mtu, rc, and strerror().

Referenced by intelxvf_open().

                                                                 {
        union intelvf_msg msg;
        int rc;

        /* Send set MTU message */
        memset ( &msg, 0, sizeof ( msg ) );
        msg.hdr = INTELVF_MSG_TYPE_SET_MTU;
        msg.mtu.mtu = mtu;
        if ( ( rc = intelvf_mbox_msg ( intel, &msg ) ) != 0 ) {
                DBGC ( intel, "INTEL %p set MTU failed: %s\n",
                       intel, strerror ( rc ) );
                return rc;
        }

        /* Check response */
        if ( ( msg.hdr & INTELVF_MSG_TYPE_MASK ) != INTELVF_MSG_TYPE_SET_MTU ) {
                DBGC ( intel, "INTEL %p set MTU unexpected response:\n",
                       intel );
                DBGC_HDA ( intel, 0, &msg, sizeof ( msg ) );
                return -EPROTO;
        }

        /* Check that we were allowed to set the MTU */
        if ( ! ( msg.hdr & INTELVF_MSG_ACK ) ) {
                DBGC ( intel, "INTEL %p set MTU refused\n", intel );
                return -EPERM;
        }

        return 0;
}