summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/net/intelvf.c41
-rw-r--r--src/drivers/net/intelvf.h25
-rw-r--r--src/drivers/net/intelxvf.c64
-rw-r--r--src/drivers/net/intelxvf.h6
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 */