1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2019-2020 Xilinx, Inc.
4 * Copyright(c) 2019 Solarflare Communications Inc.
6 * This software was jointly developed between OKTET Labs (under contract
7 * for Solarflare) and Solarflare Communications, Inc.
12 #include <rte_common.h>
20 sfc_mae_attach(struct sfc_adapter *sa)
22 const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
23 struct sfc_mae *mae = &sa->mae;
24 efx_mae_limits_t limits;
27 sfc_log_init(sa, "entry");
29 if (!encp->enc_mae_supported) {
30 mae->status = SFC_MAE_STATUS_UNSUPPORTED;
34 sfc_log_init(sa, "init MAE");
35 rc = efx_mae_init(sa->nic);
39 sfc_log_init(sa, "get MAE limits");
40 rc = efx_mae_get_limits(sa->nic, &limits);
42 goto fail_mae_get_limits;
44 mae->status = SFC_MAE_STATUS_SUPPORTED;
45 mae->nb_action_rule_prios_max = limits.eml_max_n_action_prios;
47 sfc_log_init(sa, "done");
52 efx_mae_fini(sa->nic);
55 sfc_log_init(sa, "failed %d", rc);
61 sfc_mae_detach(struct sfc_adapter *sa)
63 struct sfc_mae *mae = &sa->mae;
64 enum sfc_mae_status status_prev = mae->status;
66 sfc_log_init(sa, "entry");
68 mae->nb_action_rule_prios_max = 0;
69 mae->status = SFC_MAE_STATUS_UNKNOWN;
71 if (status_prev != SFC_MAE_STATUS_SUPPORTED)
74 efx_mae_fini(sa->nic);
76 sfc_log_init(sa, "done");
80 sfc_mae_flow_cleanup(struct sfc_adapter *sa,
81 struct rte_flow *flow)
83 struct sfc_flow_spec *spec;
84 struct sfc_flow_spec_mae *spec_mae;
94 spec_mae = &spec->mae;
96 if (spec_mae->match_spec != NULL)
97 efx_mae_match_spec_fini(sa->nic, spec_mae->match_spec);
100 static const struct sfc_flow_item sfc_flow_items[] = {
104 sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
105 const struct rte_flow_item pattern[],
106 struct sfc_flow_spec_mae *spec,
107 struct rte_flow_error *error)
109 struct sfc_mae_parse_ctx ctx_mae;
110 struct sfc_flow_parse_ctx ctx;
113 memset(&ctx_mae, 0, sizeof(ctx_mae));
115 rc = efx_mae_match_spec_init(sa->nic, EFX_MAE_RULE_ACTION,
117 &ctx_mae.match_spec_action);
119 rc = rte_flow_error_set(error, rc,
120 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
121 "Failed to initialise action rule match specification");
122 goto fail_init_match_spec_action;
125 ctx.type = SFC_FLOW_PARSE_CTX_MAE;
128 rc = sfc_flow_parse_pattern(sfc_flow_items, RTE_DIM(sfc_flow_items),
129 pattern, &ctx, error);
131 goto fail_parse_pattern;
133 if (!efx_mae_match_spec_is_valid(sa->nic, ctx_mae.match_spec_action)) {
134 rc = rte_flow_error_set(error, ENOTSUP,
135 RTE_FLOW_ERROR_TYPE_ITEM, NULL,
136 "Inconsistent pattern");
137 goto fail_validate_match_spec_action;
140 spec->match_spec = ctx_mae.match_spec_action;
144 fail_validate_match_spec_action:
146 efx_mae_match_spec_fini(sa->nic, ctx_mae.match_spec_action);
148 fail_init_match_spec_action:
153 sfc_mae_rules_class_cmp(struct sfc_adapter *sa,
154 const efx_mae_match_spec_t *left,
155 const efx_mae_match_spec_t *right)
157 bool have_same_class;
160 rc = efx_mae_match_specs_class_cmp(sa->nic, left, right,
163 return (rc == 0) ? have_same_class : false;
167 sfc_mae_action_rule_class_verify(struct sfc_adapter *sa,
168 struct sfc_flow_spec_mae *spec)
170 const struct rte_flow *entry;
172 TAILQ_FOREACH_REVERSE(entry, &sa->flow_list, sfc_flow_list, entries) {
173 const struct sfc_flow_spec *entry_spec = &entry->spec;
174 const struct sfc_flow_spec_mae *es_mae = &entry_spec->mae;
175 const efx_mae_match_spec_t *left = es_mae->match_spec;
176 const efx_mae_match_spec_t *right = spec->match_spec;
178 switch (entry_spec->type) {
179 case SFC_FLOW_SPEC_FILTER:
180 /* Ignore VNIC-level flows */
182 case SFC_FLOW_SPEC_MAE:
183 if (sfc_mae_rules_class_cmp(sa, left, right))
191 sfc_info(sa, "for now, the HW doesn't support rule validation, and HW "
192 "support for inner frame pattern items is not guaranteed; "
193 "other than that, the items are valid from SW standpoint");
198 * Confirm that a given flow can be accepted by the FW.
201 * Software adapter context
203 * Flow to be verified
205 * Zero on success and non-zero in the case of error.
206 * A special value of EAGAIN indicates that the adapter is
207 * not in started state. This state is compulsory because
208 * it only makes sense to compare the rule class of the flow
209 * being validated with classes of the active rules.
210 * Such classes are wittingly supported by the FW.
213 sfc_mae_flow_verify(struct sfc_adapter *sa,
214 struct rte_flow *flow)
216 struct sfc_flow_spec *spec = &flow->spec;
217 struct sfc_flow_spec_mae *spec_mae = &spec->mae;
219 SFC_ASSERT(sfc_adapter_is_locked(sa));
221 if (sa->state != SFC_ADAPTER_STARTED)
224 return sfc_mae_action_rule_class_verify(sa, spec_mae);