summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2021-03-30 14:41:35 +0200
committerAndrew Yourtchenko <ayourtch@gmail.com>2021-04-01 13:51:35 +0000
commita1510f592bf4c91ec68c5e217e112f0c1f756035 (patch)
tree09f5681743351cb50019dee3bef3c825cc2a13ac /src/plugins
parentacc665a9de9ed545cfa0c5b442287fa7ce5c7e9f (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/plugins')
-rw-r--r--src/plugins/avf/avf.h3
-rw-r--r--src/plugins/avf/device.c61
-rw-r--r--src/plugins/avf/format.c78
-rw-r--r--src/plugins/avf/virtchnl.h73
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 */
/*
class="n">ostream& os) { m_db.dump(os); } void interface_span::replay() { if (m_config) { HW::enqueue(new interface_span_cmds::config_cmd( m_config, m_itf_from->handle(), m_itf_to->handle(), m_state)); } } std::string interface_span::to_string() const { std::ostringstream s; s << "Itf Span-config:" << " itf-from:" << m_itf_from->to_string() << " itf-to:" << m_itf_to->to_string() << " state:" << m_state.to_string(); return (s.str()); } void interface_span::update(const interface_span& desired) { if (!m_config) { HW::enqueue(new interface_span_cmds::config_cmd( m_config, m_itf_from->handle(), m_itf_to->handle(), m_state)); } } std::ostream& operator<<(std::ostream& os, const interface_span::key_type_t& key) { os << "[" << key.first << ", " << key.second << "]"; return (os); } std::shared_ptr<interface_span> interface_span::find_or_add(const interface_span& temp) { return (m_db.find_or_add( make_pair(temp.m_itf_from->key(), temp.m_itf_to->key()), temp)); } std::shared_ptr<interface_span> interface_span::singular() const { return find_or_add(*this); } interface_span::event_handler::event_handler() { OM::register_listener(this); inspect::register_handler({ "itf-span" }, "interface span configurations", this); } void interface_span::event_handler::handle_replay() { m_db.replay(); } void interface_span::event_handler::handle_populate(const client_db::key_t& key) { std::shared_ptr<interface_span_cmds::dump_cmd> cmd( new interface_span_cmds::dump_cmd()); HW::enqueue(cmd); HW::write(); for (auto& record : *cmd) { auto& payload = record.get_payload(); std::shared_ptr<interface> itf_from = interface::find(payload.sw_if_index_from); std::shared_ptr<interface> itf_to = interface::find(payload.sw_if_index_to); interface_span itf_span(*itf_from, *itf_to, state_t::from_int(payload.state)); VOM_LOG(log_level_t::DEBUG) << "span-dump: " << itf_from->to_string() << itf_to->to_string() << state_t::from_int(payload.state).to_string(); /* * Write each of the discovered interfaces into the OM, * but disable the HW Command q whilst we do, so that no * commands are sent to VPP */ OM::commit(key, itf_span); } } dependency_t interface_span::event_handler::order() const { return (dependency_t::BINDING); } void interface_span::event_handler::show(std::ostream& os) { m_db.dump(os); } const interface_span::state_t interface_span::state_t::DISABLED(0, "disable"); const interface_span::state_t interface_span::state_t::RX_ENABLED(1, "rx-enable"); const interface_span::state_t interface_span::state_t::TX_ENABLED(2, "tx-enable"); const interface_span::state_t interface_span::state_t::TX_RX_ENABLED( 3, "tx-rx-enable"); interface_span::state_t::state_t(int v, const std::string& s) : enum_base<interface_span::state_t>(v, s) { } interface_span::state_t interface_span::state_t::from_int(uint8_t i) { switch (i) { case 0: return interface_span::state_t::DISABLED; break; case 1: return interface_span::state_t::RX_ENABLED; break; case 2: return interface_span::state_t::TX_ENABLED; break; case 3: default: break; } return interface_span::state_t::TX_RX_ENABLED; } } /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "mozilla") * End: */