vl_api_virtio_pci_create_t *mp;
u8 mac_address[6];
u8 random_mac = 1;
+ u8 gso_enabled = 0;
u32 pci_addr = 0;
u64 features = (u64) ~ (0ULL);
- u32 rx_ring_sz = 0, tx_ring_sz = 0;
int ret;
clib_memset (mac_address, 0, sizeof (mac_address));
;
else if (unformat (i, "features 0x%llx", &features))
;
- else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
- ;
- else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
- ;
+ else if (unformat (i, "gso-enabled"))
+ gso_enabled = 1;
else
break;
}
errmsg ("pci address must be non zero. ");
return -99;
}
- if (!is_pow2 (rx_ring_sz))
- {
- errmsg ("rx ring size must be power of 2. ");
- return -99;
- }
- if (rx_ring_sz > 32768)
- {
- errmsg ("rx ring size must be 32768 or lower. ");
- return -99;
- }
- if (!is_pow2 (tx_ring_sz))
- {
- errmsg ("tx ring size must be power of 2. ");
- return -99;
- }
- if (tx_ring_sz > 32768)
- {
- errmsg ("tx ring size must be 32768 or lower. ");
- return -99;
- }
/* Construct the API message */
M (VIRTIO_PCI_CREATE, mp);
"<vpp-if-name> | sw_if_index <id>") \
_(sw_interface_tap_v2_dump, "") \
_(virtio_pci_create, \
- "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
+ "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
_(virtio_pci_delete, \
"<vpp-if-name> | sw_if_index <id>") \
_(sw_interface_virtio_pci_dump, "") \
;
else if (unformat (line_input, "feature-mask 0x%llx", &feature_mask))
args.features = feature_mask;
+ else if (unformat (line_input, "gso-enabled"))
+ args.gso_enabled = 1;
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);
return status;
}
+static int
+virtio_pci_enable_gso (vlib_main_t * vm, virtio_if_t * vif)
+{
+ virtio_main_t *vim = &virtio_main;
+ struct virtio_ctrl_msg gso_hdr;
+ virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
+
+ gso_hdr.ctrl.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
+ gso_hdr.ctrl.cmd = VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET;
+ gso_hdr.status = VIRTIO_NET_ERR;
+ u64 offloads = VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_UFO);
+ clib_memcpy (gso_hdr.data, &offloads, sizeof (offloads));
+
+ status = virtio_pci_send_ctrl_msg (vm, vif, &gso_hdr, sizeof (offloads));
+ virtio_log_debug (vim, vif, "enable gso");
+ return status;
+}
+
static int
virtio_pci_enable_multiqueue (vlib_main_t * vm, virtio_if_t * vif,
u16 num_queues)
* if features are not requested
* default: all supported features
*/
- u64 supported_features = VIRTIO_FEATURE (VIRTIO_NET_F_MTU)
+ u64 supported_features = VIRTIO_FEATURE (VIRTIO_NET_F_CSUM)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_MTU)
| VIRTIO_FEATURE (VIRTIO_NET_F_MAC)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GSO)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_UFO)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO4)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO6)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_UFO)
| VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF)
| VIRTIO_FEATURE (VIRTIO_NET_F_STATUS)
| VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)
else
vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
- if ((vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) &&
- (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ)))
+ if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ))
{
- if (virtio_pci_enable_multiqueue (vm, vif, vif->max_queue_pairs))
- virtio_log_warning (vim, vif, "multiqueue is not set");
+ if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) &&
+ args->gso_enabled)
+ {
+ if (virtio_pci_enable_gso (vm, vif))
+ {
+ virtio_log_warning (vim, vif, "gso is not enabled");
+ }
+ else
+ {
+ vif->gso_enabled = 1;
+ hw->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO;
+ vnm->interface_main.gso_interface_count++;
+ }
+ }
+ if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ))
+ {
+ if (virtio_pci_enable_multiqueue (vm, vif, vif->max_queue_pairs))
+ virtio_log_warning (vim, vif, "multiqueue is not set");
+ }
}
return;
+
error:
virtio_pci_delete_if (vm, vif);
args->rv = VNET_API_ERROR_INVALID_INTERFACE;
virtio_pci_legacy_reset (vm, vif);
+ if (vif->gso_enabled)
+ vnm->interface_main.gso_interface_count--;
+
if (vif->hw_if_index)
{
vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
* at the end of the used ring. Guest should ignore the used->flags field. */ \
_ (VHOST_USER_F_PROTOCOL_FEATURES, 30)
+#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2
#define VIRTIO_NET_F_MTU 3
#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */
#define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */
+/*
+ * Control network offloads
+ * Reconfigures the network offloads that Guest can handle.
+ * Available with the VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature bit.
+ * Command data format matches the feature bit mask exactly.
+ * See VIRTIO_NET_F_GUEST_* for the list of offloads
+ * that can be enabled/disabled.
+ */
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
+
/* Common configuration */
#define VIRTIO_PCI_CAP_COMMON_CFG 1
/* Notifications */
u8 mac_addr_set;
u8 mac_addr[6];
u64 features;
+ u8 gso_enabled;
clib_error_t *error;
} virtio_pci_create_if_args_t;
0-15 domain, 16-23 bus, 24-28 slot, 29-31 function
@param use_random_mac - let the system generate a unique mac address
@param mac_address - mac addr to assign to the interface if use_radom not set
- @param tx_ring_sz - the number of entries of TX ring
- @param rx_ring_sz - the number of entries of RX ring
+ @param gso_enabled - enable gso feature if available, 1 to enable
@param features - the virtio features which driver should negotiate with device
*/
define virtio_pci_create
u32 pci_addr;
u8 use_random_mac;
u8 mac_address[6];
+ u8 gso_enabled;
u64 features;
};
ap->mac_addr_set = 1;
}
ap->sw_if_index = (u32) ~ 0;
+ if (mp->gso_enabled)
+ ap->gso_enabled = 1;
+ else
+ ap->gso_enabled = 0;
ap->features = clib_net_to_host_u64 (mp->features);
virtio_pci_create_if (vm, ap);
format_ethernet_address, mp->mac_address);
if (mp->features)
s = format (s, "features 0x%llx ", clib_net_to_host_u64 (mp->features));
+ if (mp->gso_enabled)
+ s = format (s, "gso-enabled");
FINISH;
}