* @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;
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;
+}
/** 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
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];
};
*/
#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 */
}
}
+/******************************************************************************
+ *
+ * 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
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",
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;
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 );
/** 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 */