avf: disable VLAN stripping on E810 using V2 VLAN APIs 30/31830/3
authorDamjan Marion <damarion@cisco.com>
Tue, 30 Mar 2021 12:41:35 +0000 (14:41 +0200)
committerAndrew Yourtchenko <ayourtch@gmail.com>
Thu, 1 Apr 2021 13:51:35 +0000 (13:51 +0000)
Type: fix
Change-Id: I9bb19a5c9b5b48825f19a4ac124a3628ceaa081d
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/plugins/avf/avf.h
src/plugins/avf/device.c
src/plugins/avf/format.c
src/plugins/avf/virtchnl.h

index 2ca3143..6538ff9 100644 (file)
@@ -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 *
index 78a211f..c58b512 100644 (file)
@@ -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);
@@ -815,6 +815,39 @@ avf_op_get_stats (vlib_main_t * vm, avf_device_t * ad,
                         es, sizeof (virtchnl_eth_stats_t));
 }
 
+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)
 {
@@ -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;
 
   /*
index 5dbfae2..2615780 100644 (file)
@@ -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;
+}
index 01c8510..ae4fe4a 100644 (file)
@@ -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 */
 
 /*