aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/dev/dev.h43
-rw-r--r--src/vnet/dev/format.c77
-rw-r--r--src/vnet/dev/port.c9
3 files changed, 125 insertions, 4 deletions
diff --git a/src/vnet/dev/dev.h b/src/vnet/dev/dev.h
index 59e1003b4a6..951e5054d42 100644
--- a/src/vnet/dev/dev.h
+++ b/src/vnet/dev/dev.h
@@ -28,7 +28,15 @@ typedef enum
#define foreach_vnet_dev_port_caps \
_ (interrupt_mode) \
_ (rss) \
- _ (change_max_rx_frame_size)
+ _ (change_max_rx_frame_size) \
+ _ (mac_filter)
+
+#define foreach_vnet_dev_port_rx_offloads _ (ip4_cksum)
+
+#define foreach_vnet_dev_port_tx_offloads \
+ _ (ip4_cksum) \
+ _ (tcp_gso) \
+ _ (udp_gso)
typedef union
{
@@ -43,6 +51,28 @@ typedef union
typedef union
{
+ struct
+ {
+#define _(n) u8 n : 1;
+ foreach_vnet_dev_port_rx_offloads
+#undef _
+ };
+ u8 as_number;
+} vnet_dev_port_rx_offloads_t;
+
+typedef union
+{
+ struct
+ {
+#define _(n) u8 n : 1;
+ foreach_vnet_dev_port_tx_offloads
+#undef _
+ };
+ u8 as_number;
+} vnet_dev_port_tx_offloads_t;
+
+typedef union
+{
u8 eth_mac[6];
u8 raw[8];
} vnet_dev_hw_addr_t;
@@ -146,6 +176,8 @@ typedef struct
u16 max_supported_rx_frame_size;
vnet_dev_port_type_t type;
vnet_dev_port_caps_t caps;
+ vnet_dev_port_rx_offloads_t rx_offloads;
+ vnet_dev_port_tx_offloads_t tx_offloads;
} vnet_dev_port_attr_t;
typedef enum
@@ -606,17 +638,20 @@ typedef struct
} vnet_dev_format_args_t;
format_function_t format_vnet_dev_addr;
+format_function_t format_vnet_dev_flags;
format_function_t format_vnet_dev_hw_addr;
format_function_t format_vnet_dev_info;
format_function_t format_vnet_dev_interface_info;
format_function_t format_vnet_dev_interface_name;
+format_function_t format_vnet_dev_log;
+format_function_t format_vnet_dev_port_caps;
+format_function_t format_vnet_dev_port_flags;
format_function_t format_vnet_dev_port_info;
+format_function_t format_vnet_dev_port_rx_offloads;
+format_function_t format_vnet_dev_port_tx_offloads;
format_function_t format_vnet_dev_rv;
format_function_t format_vnet_dev_rx_queue_info;
format_function_t format_vnet_dev_tx_queue_info;
-format_function_t format_vnet_dev_flags;
-format_function_t format_vnet_dev_port_flags;
-format_function_t format_vnet_dev_log;
unformat_function_t unformat_vnet_dev_flags;
unformat_function_t unformat_vnet_dev_port_flags;
diff --git a/src/vnet/dev/format.c b/src/vnet/dev/format.c
index 944da0698ea..ff301615e10 100644
--- a/src/vnet/dev/format.c
+++ b/src/vnet/dev/format.c
@@ -122,6 +122,12 @@ format_vnet_dev_port_info (u8 *s, va_list *args)
s = format (s, "\n%UMax RX frame size is %u (max supported %u)",
format_white_space, indent, port->max_rx_frame_size,
port->attr.max_supported_rx_frame_size);
+ s = format (s, "\n%UCaps: %U", format_white_space, indent,
+ format_vnet_dev_port_caps, &port->attr.caps);
+ s = format (s, "\n%URX Offloads: %U", format_white_space, indent,
+ format_vnet_dev_port_rx_offloads, &port->attr.rx_offloads);
+ s = format (s, "\n%UTX Offloads: %U", format_white_space, indent,
+ format_vnet_dev_port_tx_offloads, &port->attr.tx_offloads);
if (port->port_ops.format_status)
s = format (s, "\n%UDevice Specific Port Status:\n%U%U",
format_white_space, indent, format_white_space, indent + 2,
@@ -407,3 +413,74 @@ format_vnet_dev_log (u8 *s, va_list *args)
vec_add1 (s, ' ');
return s;
}
+
+u8 *
+format_vnet_dev_port_caps (u8 *s, va_list *args)
+{
+ vnet_dev_port_caps_t *c = va_arg (*args, vnet_dev_port_caps_t *);
+ u32 line = 0;
+
+ if (c->as_number == 0)
+ return s;
+
+#define _(n) \
+ if (c->n) \
+ { \
+ if (line++) \
+ vec_add1 (s, ' '); \
+ for (char *str = #n; *str; str++) \
+ vec_add1 (s, *str == '_' ? '-' : *str); \
+ }
+ foreach_vnet_dev_port_caps;
+#undef _
+
+ return s;
+}
+
+u8 *
+format_vnet_dev_port_rx_offloads (u8 *s, va_list *args)
+{
+ vnet_dev_port_rx_offloads_t *c =
+ va_arg (*args, vnet_dev_port_rx_offloads_t *);
+ u32 line = 0;
+
+ if (c->as_number == 0)
+ return s;
+
+#define _(n) \
+ if (c->n) \
+ { \
+ if (line++) \
+ vec_add1 (s, ' '); \
+ for (char *str = #n; *str; str++) \
+ vec_add1 (s, *str == '_' ? '-' : *str); \
+ }
+ foreach_vnet_dev_port_rx_offloads;
+#undef _
+
+ return s;
+}
+
+u8 *
+format_vnet_dev_port_tx_offloads (u8 *s, va_list *args)
+{
+ vnet_dev_port_tx_offloads_t *c =
+ va_arg (*args, vnet_dev_port_tx_offloads_t *);
+ u32 line = 0;
+
+ if (c->as_number == 0)
+ return s;
+
+#define _(n) \
+ if (c->n) \
+ { \
+ if (line++) \
+ vec_add1 (s, ' '); \
+ for (char *str = #n; *str; str++) \
+ vec_add1 (s, *str == '_' ? '-' : *str); \
+ }
+ foreach_vnet_dev_port_tx_offloads;
+#undef _
+
+ return s;
+}
diff --git a/src/vnet/dev/port.c b/src/vnet/dev/port.c
index 0363ea41b48..8a6df54cbc8 100644
--- a/src/vnet/dev/port.c
+++ b/src/vnet/dev/port.c
@@ -573,6 +573,7 @@ vnet_dev_port_if_create (vlib_main_t *vm, vnet_dev_port_t *port)
vnet_dev_driver_t *driver;
vnet_sw_interface_t *sw;
vnet_hw_interface_t *hw;
+ vnet_hw_if_caps_t caps = 0;
u32 rx_node_index;
driver = pool_elt_at_index (dm->drivers, dev->driver_index);
@@ -607,6 +608,14 @@ vnet_dev_port_if_create (vlib_main_t *vm, vnet_dev_port_t *port)
port->intf.tx_node_index = hw->tx_node_index;
+ caps |= port->attr.caps.interrupt_mode ? VNET_HW_IF_CAP_INT_MODE : 0;
+ caps |= port->attr.caps.mac_filter ? VNET_HW_IF_CAP_MAC_FILTER : 0;
+ caps |= port->attr.tx_offloads.tcp_gso ? VNET_HW_IF_CAP_TCP_GSO : 0;
+ caps |= port->attr.tx_offloads.ip4_cksum ? VNET_HW_IF_CAP_TX_CKSUM : 0;
+
+ if (caps)
+ vnet_hw_if_set_caps (vnm, port->intf.hw_if_index, caps);
+
/* create / reuse rx node */
if (vec_len (dm->free_rx_node_indices))
{