diff options
-rw-r--r-- | src/drivers/net/intelvf.c | 41 | ||||
-rw-r--r-- | src/drivers/net/intelvf.h | 25 | ||||
-rw-r--r-- | src/drivers/net/intelxvf.c | 64 | ||||
-rw-r--r-- | src/drivers/net/intelxvf.h | 6 |
4 files changed, 134 insertions, 2 deletions
diff --git a/src/drivers/net/intelvf.c b/src/drivers/net/intelvf.c index c8d3a4d2..ac6fea74 100644 --- a/src/drivers/net/intelvf.c +++ b/src/drivers/net/intelvf.c @@ -146,8 +146,7 @@ int intelvf_mbox_wait ( struct intel_nic *intel ) { * @v msg Message buffer * @ret rc Return status code */ -static int intelvf_mbox_msg ( struct intel_nic *intel, - union intelvf_msg *msg ) { +int intelvf_mbox_msg ( struct intel_nic *intel, union intelvf_msg *msg ) { struct intel_mailbox *mbox = &intel->mbox; uint32_t ctrl; uint32_t seen = 0; @@ -301,3 +300,41 @@ int intelvf_mbox_set_mac ( struct intel_nic *intel, const uint8_t *ll_addr ) { return 0; } + +/** + * Send set MTU message + * + * @v intel Intel device + * @v mtu Maximum packet size + * @ret rc Return status code + */ +int intelvf_mbox_set_mtu ( struct intel_nic *intel, size_t mtu ) { + 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; +} diff --git a/src/drivers/net/intelvf.h b/src/drivers/net/intelvf.h index d03a7f17..d2f98d87 100644 --- a/src/drivers/net/intelvf.h +++ b/src/drivers/net/intelvf.h @@ -34,6 +34,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** Set MAC address mailbox message */ #define INTELVF_MSG_TYPE_SET_MAC 0x00000002UL +/** Set MTU mailbox message */ +#define INTELVF_MSG_TYPE_SET_MTU 0x00000005UL + /** Control ("ping") mailbox message */ #define INTELVF_MSG_TYPE_CONTROL 0x00000100UL @@ -59,12 +62,32 @@ struct intelvf_msg_mac { uint8_t reserved[ (-ETH_ALEN) & 0x3 ]; } __attribute__ (( packed )); +/** Version number mailbox message */ +struct intelvf_msg_version { + /** Message header */ + uint32_t hdr; + /** API version */ + uint32_t version; +} __attribute__ (( packed )); + +/** MTU mailbox message */ +struct intelvf_msg_mtu { + /** Message header */ + uint32_t hdr; + /** Maximum packet size */ + uint32_t mtu; +} __attribute__ (( packed )); + /** Mailbox message */ union intelvf_msg { /** Message header */ uint32_t hdr; /** MAC address message */ struct intelvf_msg_mac mac; + /** Version number message */ + struct intelvf_msg_version version; + /** MTU message */ + struct intelvf_msg_mtu mtu; /** Raw dwords */ uint32_t dword[0]; }; @@ -75,10 +98,12 @@ union intelvf_msg { */ #define INTELVF_MBOX_MAX_WAIT_MS 500 +extern int intelvf_mbox_msg ( struct intel_nic *intel, union intelvf_msg *msg ); extern int intelvf_mbox_poll ( struct intel_nic *intel ); extern int intelvf_mbox_wait ( struct intel_nic *intel ); extern int intelvf_mbox_reset ( struct intel_nic *intel, uint8_t *hw_addr ); extern int intelvf_mbox_set_mac ( struct intel_nic *intel, const uint8_t *ll_addr ); +extern int intelvf_mbox_set_mtu ( struct intel_nic *intel, size_t mtu ); #endif /* _INTELVF_H */ diff --git a/src/drivers/net/intelxvf.c b/src/drivers/net/intelxvf.c index c03fbe85..05e34c12 100644 --- a/src/drivers/net/intelxvf.c +++ b/src/drivers/net/intelxvf.c @@ -111,6 +111,53 @@ static void intelxvf_check_link ( struct net_device *netdev ) { /****************************************************************************** * + * Mailbox messages + * + ****************************************************************************** + */ + +/** + * Send negotiate API version message + * + * @v intel Intel device + * @v version Requested version + * @ret rc Return status code + */ +static int intelxvf_mbox_version ( struct intel_nic *intel, + unsigned int version ) { + union intelvf_msg msg; + int rc; + + /* Send set MTU message */ + memset ( &msg, 0, sizeof ( msg ) ); + msg.hdr = INTELXVF_MSG_TYPE_VERSION; + msg.version.version = version; + if ( ( rc = intelvf_mbox_msg ( intel, &msg ) ) != 0 ) { + DBGC ( intel, "INTEL %p negotiate API version failed: %s\n", + intel, strerror ( rc ) ); + return rc; + } + + /* Check response */ + if ( ( msg.hdr & INTELVF_MSG_TYPE_MASK ) != INTELXVF_MSG_TYPE_VERSION ){ + DBGC ( intel, "INTEL %p negotiate API version unexpected " + "response:\n", intel ); + DBGC_HDA ( intel, 0, &msg, sizeof ( msg ) ); + return -EPROTO; + } + + /* Check that this version is supported */ + if ( ! ( msg.hdr & INTELVF_MSG_ACK ) ) { + DBGC ( intel, "INTEL %p negotiate API version failed\n", + intel ); + return -EPERM; + } + + return 0; +} + +/****************************************************************************** + * * Network device interface * ****************************************************************************** @@ -138,6 +185,15 @@ static int intelxvf_open ( struct net_device *netdev ) { goto err_mbox_reset; } + /* Negotiate API version 1.1. If we do not negotiate at least + * this version, then the RX datapath will remain disabled if + * the PF has jumbo frames enabled. + * + * Ignore failures, since the host may not actually support + * v1.1. + */ + intelxvf_mbox_version ( intel, INTELXVF_MSG_VERSION_1_1 ); + /* Set MAC address */ if ( ( rc = intelvf_mbox_set_mac ( intel, netdev->ll_addr ) ) != 0 ) { DBGC ( intel, "INTEL %p could not set MAC address: %s\n", @@ -145,6 +201,13 @@ static int intelxvf_open ( struct net_device *netdev ) { goto err_mbox_set_mac; } + /* Set MTU */ + if ( ( rc = intelvf_mbox_set_mtu ( intel, netdev->max_pkt_len ) ) != 0){ + DBGC ( intel, "INTEL %p could not set MTU %zd: %s\n", + intel, netdev->max_pkt_len, strerror ( rc ) ); + goto err_mbox_set_mtu; + } + /* Create transmit descriptor ring */ if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 ) goto err_create_tx; @@ -188,6 +251,7 @@ static int intelxvf_open ( struct net_device *netdev ) { err_create_rx: intel_destroy_ring ( intel, &intel->tx ); err_create_tx: + err_mbox_set_mtu: err_mbox_set_mac: err_mbox_reset: intelxvf_reset ( intel ); diff --git a/src/drivers/net/intelxvf.h b/src/drivers/net/intelxvf.h index aae58c9e..ad046a65 100644 --- a/src/drivers/net/intelxvf.h +++ b/src/drivers/net/intelxvf.h @@ -95,4 +95,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** Good Packets Transmitted Count High */ #define INTELXVF_GOTCH 0x2024 +/** Negotiate API version mailbox message */ +#define INTELXVF_MSG_TYPE_VERSION 0x00000008UL + +/** API version 1.1 */ +#define INTELXVF_MSG_VERSION_1_1 0x00000002UL + #endif /* _INTELXVF_H */ |