diff options
author | Damjan Marion <damarion@cisco.com> | 2021-03-30 14:41:35 +0200 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2021-04-01 13:51:35 +0000 |
commit | a1510f592bf4c91ec68c5e217e112f0c1f756035 (patch) | |
tree | 09f5681743351cb50019dee3bef3c825cc2a13ac /src | |
parent | acc665a9de9ed545cfa0c5b442287fa7ce5c7e9f (diff) |
avf: disable VLAN stripping on E810 using V2 VLAN APIs
Type: fix
Change-Id: I9bb19a5c9b5b48825f19a4ac124a3628ceaa081d
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/avf/avf.h | 3 | ||||
-rw-r--r-- | src/plugins/avf/device.c | 61 | ||||
-rw-r--r-- | src/plugins/avf/format.c | 78 | ||||
-rw-r--r-- | src/plugins/avf/virtchnl.h | 73 |
4 files changed, 201 insertions, 14 deletions
diff --git a/src/plugins/avf/avf.h b/src/plugins/avf/avf.h index 2ca31434b8b..6538ff9e41d 100644 --- a/src/plugins/avf/avf.h +++ b/src/plugins/avf/avf.h @@ -349,6 +349,9 @@ format_function_t format_avf_device; format_function_t format_avf_device_name; format_function_t format_avf_input_trace; format_function_t format_avf_vf_cap_flags; +format_function_t format_avf_vlan_supported_caps; +format_function_t format_avf_vlan_caps; +format_function_t format_avf_vlan_support; vnet_flow_dev_ops_function_t avf_flow_ops_fn; static_always_inline avf_device_t * diff --git a/src/plugins/avf/device.c b/src/plugins/avf/device.c index 78a211f5d17..c58b5124e68 100644 --- a/src/plugins/avf/device.c +++ b/src/plugins/avf/device.c @@ -549,11 +549,11 @@ avf_op_get_vf_resources (vlib_main_t * vm, avf_device_t * ad, virtchnl_vf_resource_t * res) { clib_error_t *err = 0; - u32 bitmap = - (VIRTCHNL_VF_OFFLOAD_L2 | VIRTCHNL_VF_OFFLOAD_RSS_PF | - VIRTCHNL_VF_OFFLOAD_WB_ON_ITR | VIRTCHNL_VF_OFFLOAD_VLAN | - VIRTCHNL_VF_OFFLOAD_RX_POLLING | VIRTCHNL_VF_CAP_ADV_LINK_SPEED | - VIRTCHNL_VF_OFFLOAD_FDIR_PF | VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF); + u32 bitmap = (VIRTCHNL_VF_OFFLOAD_L2 | VIRTCHNL_VF_OFFLOAD_RSS_PF | + VIRTCHNL_VF_OFFLOAD_WB_ON_ITR | VIRTCHNL_VF_OFFLOAD_VLAN | + VIRTCHNL_VF_OFFLOAD_RX_POLLING | + VIRTCHNL_VF_CAP_ADV_LINK_SPEED | VIRTCHNL_VF_OFFLOAD_FDIR_PF | + VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF | VIRTCHNL_VF_OFFLOAD_VLAN_V2); avf_log_debug (ad, "get_vf_resources: bitmap 0x%x (%U)", bitmap, format_avf_vf_cap_flags, bitmap); @@ -816,6 +816,39 @@ avf_op_get_stats (vlib_main_t * vm, avf_device_t * ad, } clib_error_t * +avf_op_get_offload_vlan_v2_caps (vlib_main_t *vm, avf_device_t *ad, + virtchnl_vlan_caps_t *vc) +{ + clib_error_t *err; + + err = avf_send_to_pf (vm, ad, VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS, 0, 0, vc, + sizeof (virtchnl_vlan_caps_t)); + + avf_log_debug (ad, "get_offload_vlan_v2_caps:\n%U%U", format_white_space, 16, + format_avf_vlan_caps, vc); + + return err; +} + +clib_error_t * +avf_op_disable_vlan_stripping_v2 (vlib_main_t *vm, avf_device_t *ad, u32 outer, + u32 inner) +{ + virtchnl_vlan_setting_t vs = { + .outer_ethertype_setting = outer, + .inner_ethertype_setting = inner, + .vport_id = ad->vsi_id, + }; + + avf_log_debug (ad, "disable_vlan_stripping_v2: outer: %U, inner %U", + format_avf_vlan_support, outer, format_avf_vlan_support, + inner); + + return avf_send_to_pf (vm, ad, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2, &vs, + sizeof (virtchnl_vlan_setting_t), 0, 0); +} + +clib_error_t * avf_device_reset (vlib_main_t * vm, avf_device_t * ad) { avf_aq_desc_t d = { 0 }; @@ -960,7 +993,23 @@ avf_device_init (vlib_main_t * vm, avf_main_t * am, avf_device_t * ad, /* * Disable VLAN stripping */ - if ((error = avf_op_disable_vlan_stripping (vm, ad))) + if (ad->cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) + { + virtchnl_vlan_caps_t vc = {}; + u32 outer = VIRTCHNL_VLAN_UNSUPPORTED, inner = VIRTCHNL_VLAN_UNSUPPORTED; + u32 mask = VIRTCHNL_VLAN_ETHERTYPE_8100; + + if ((error = avf_op_get_offload_vlan_v2_caps (vm, ad, &vc))) + return error; + + outer = vc.offloads.stripping_support.outer & mask; + inner = vc.offloads.stripping_support.inner & mask; + + if ((outer || inner) && + (error = avf_op_disable_vlan_stripping_v2 (vm, ad, outer, inner))) + return error; + } + else if ((error = avf_op_disable_vlan_stripping (vm, ad))) return error; /* diff --git a/src/plugins/avf/format.c b/src/plugins/avf/format.c index 5dbfae2b378..26157804c77 100644 --- a/src/plugins/avf/format.c +++ b/src/plugins/avf/format.c @@ -168,10 +168,74 @@ format_avf_input_trace (u8 * s, va_list * args) return s; } -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ +u8 * +format_avf_vlan_support (u8 *s, va_list *args) +{ + virtchnl_vlan_support_t v = va_arg (*args, u32); + int not_first = 0; + + char *strs[32] = { +#define _(a, b, c) [a] = c, + foreach_virtchnl_vlan_support_bit +#undef _ + }; + + if (v == VIRTCHNL_VLAN_UNSUPPORTED) + return format (s, "unsupported"); + + for (int i = 0; i < 32; i++) + { + if ((v & (1 << i)) == 0) + continue; + if (not_first) + s = format (s, " "); + if (strs[i]) + s = format (s, "%s", strs[i]); + else + s = format (s, "unknown(%u)", i); + not_first = 1; + } + return s; +} + +u8 * +format_avf_vlan_supported_caps (u8 *s, va_list *args) +{ + virtchnl_vlan_supported_caps_t *sc = + va_arg (*args, virtchnl_vlan_supported_caps_t *); + u32 indent = format_get_indent (s); + + s = format (s, "outer: %U", format_avf_vlan_support, sc->outer); + s = format (s, "\n%Uinner: %U", format_white_space, indent, + format_avf_vlan_support, sc->inner); + return s; +} + +u8 * +format_avf_vlan_caps (u8 *s, va_list *args) +{ + virtchnl_vlan_caps_t *vc = va_arg (*args, virtchnl_vlan_caps_t *); + u32 indent = format_get_indent (s); + + s = format (s, "filtering:"); + s = format (s, "\n%Usupport:", format_white_space, indent + 2); + s = + format (s, "\n%U%U", format_white_space, indent + 4, + format_avf_vlan_supported_caps, &vc->filtering.filtering_support); + s = format (s, "\n%Uethertype-init: 0x%x", format_white_space, indent + 4, + vc->filtering.ethertype_init); + s = format (s, "\n%Umax-filters: %u", format_white_space, indent + 4, + vc->filtering.max_filters); + s = format (s, "\n%Uoffloads:", format_white_space, indent); + s = format (s, "\n%Ustripping support:", format_white_space, indent + 2); + s = format (s, "\n%U%U", format_white_space, indent + 4, + format_avf_vlan_supported_caps, &vc->offloads.stripping_support); + s = format (s, "\n%Uinserion support:", format_white_space, indent + 2); + s = format (s, "\n%U%U", format_white_space, indent + 4, + format_avf_vlan_supported_caps, &vc->offloads.insertion_support); + s = format (s, "\n%Uethertype-init: 0x%x", format_white_space, indent + 4, + vc->offloads.ethertype_init); + s = format (s, "\n%Uethertype-match: 0x%x", format_white_space, indent + 4, + vc->offloads.ethertype_match); + return s; +} diff --git a/src/plugins/avf/virtchnl.h b/src/plugins/avf/virtchnl.h index 01c8510f542..ae4fe4a5e3c 100644 --- a/src/plugins/avf/virtchnl.h +++ b/src/plugins/avf/virtchnl.h @@ -99,7 +99,20 @@ enum _ (33, DEL_CLOUD_FILTER) \ _ (47, ADD_FDIR_FILTER) \ _ (48, DEL_FDIR_FILTER) \ - _ (49, QUERY_FDIR_FILTER) + _ (49, QUERY_FDIR_FILTER) \ + _ (50, GET_MAX_RSS_QREGION) \ + _ (51, GET_OFFLOAD_VLAN_V2_CAPS) \ + _ (52, ADD_VLAN_V2) \ + _ (53, DEL_VLAN_V2) \ + _ (54, ENABLE_VLAN_STRIPPING_V2) \ + _ (55, DISABLE_VLAN_STRIPPING_V2) \ + _ (56, ENABLE_VLAN_INSERTION_V2) \ + _ (57, DISABLE_VLAN_INSERTION_V2) \ + _ (58, ENABLE_VLAN_FILTERING_V2) \ + _ (59, DISABLE_VLAN_FILTERING_V2) \ + _ (107, ENABLE_QUEUES_V2) \ + _ (108, DISABLE_QUEUES_V2) \ + _ (111, MAP_QUEUE_VECTOR) typedef enum { @@ -408,6 +421,64 @@ typedef struct u16 num_queue_pairs; } virtchnl_vf_res_request_t; +typedef struct +{ + u32 outer; + u32 inner; +} virtchnl_vlan_supported_caps_t; + +typedef struct +{ + virtchnl_vlan_supported_caps_t filtering_support; + u32 ethertype_init; + u16 max_filters; + u8 pad[2]; +} virtchnl_vlan_filtering_caps_t; + +typedef struct virtchnl_vlan_offload_caps +{ + virtchnl_vlan_supported_caps_t stripping_support; + virtchnl_vlan_supported_caps_t insertion_support; + u32 ethertype_init; + u8 ethertype_match; + u8 pad[3]; +} virtchnl_vlan_offload_caps_t; + +typedef struct +{ + virtchnl_vlan_filtering_caps_t filtering; + virtchnl_vlan_offload_caps_t offloads; +} virtchnl_vlan_caps_t; + +#define foreach_virtchnl_vlan_support_bit \ + _ (0, ETHERTYPE_8100, "dot1Q") \ + _ (1, ETHERTYPE_88A8, "dot1AD") \ + _ (2, ETHERTYPE_9100, "QinQ") \ + _ (8, TAG_LOCATION_L2TAG1, "l2tag1") \ + _ (9, TAG_LOCATION_L2TAG2, "l2tag2") \ + _ (10, TAG_LOCATION_L2TAG2_2, "l2tag2_2") \ + _ (24, PRIO, "prio") \ + _ (28, FILTER_MASK, "filter-mask") \ + _ (29, ETHERTYPE_AND, "etype-and") \ + _ (30, ETHERTYPE_XOR, "etype-xor") \ + _ (31, TOGGLE, "toggle") + +typedef enum +{ + VIRTCHNL_VLAN_UNSUPPORTED = 0, +#define _(a, b, c) VIRTCHNL_VLAN_##b = (1 << a), + foreach_virtchnl_vlan_support_bit +#undef _ +} virtchnl_vlan_support_t; + +typedef struct +{ + u32 outer_ethertype_setting; + u32 inner_ethertype_setting; + u16 vport_id; + u8 pad[6]; +} virtchnl_vlan_setting_t; + #endif /* AVF_VIRTCHNL_H */ /* |