Lines Matching +full:stream +full:- +full:match +full:- +full:mask
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright 2020-2022 Xilinx Inc.
29 return -EINVAL; in efx_mae_allocate_mport()
31 return -EINVAL; in efx_mae_allocate_mport()
42 return -EIO; in efx_mae_allocate_mport()
64 MAE_MPORT_SELECTOR_PPORT_ID, efx->port_num); in efx_mae_mport_wire()
115 return -EIO; in efx_mae_fw_lookup_mport()
131 efx->net_dev->mtu); in efx_mae_start_counters()
140 return -EIO; in efx_mae_start_counters()
143 netif_dbg(efx, drv, efx->net_dev, in efx_mae_start_counters()
144 "MAE counter stream uses credits\n"); in efx_mae_start_counters()
145 rx_queue->grant_credits = true; in efx_mae_start_counters()
149 netif_err(efx, drv, efx->net_dev, in efx_mae_start_counters()
150 "MAE counter stream start: unrecognised flags %x\n", in efx_mae_start_counters()
157 return -EOPNOTSUPP; in efx_mae_start_counters()
165 if ((s32)(flush_gen[i] - seen_gen[i]) > 0) in efx_mae_counters_flushed()
185 netif_dbg(efx, drv, efx->net_dev, "Draining counters:\n"); in efx_mae_stop_counters()
188 efx->tc->flush_gen[i] = MCDI_ARRAY_DWORD(outbuf, in efx_mae_stop_counters()
191 netif_dbg(efx, drv, efx->net_dev, in efx_mae_stop_counters()
193 efx->tc->flush_gen[i]); in efx_mae_stop_counters()
196 efx->tc->flush_counters = true; in efx_mae_stop_counters()
198 /* Drain can take up to 2 seconds owing to FWRIVERHD-2884; whatever in efx_mae_stop_counters()
202 if (!wait_event_timeout(efx->tc->flush_wq, in efx_mae_stop_counters()
203 efx_mae_counters_flushed(efx->tc->flush_gen, in efx_mae_stop_counters()
204 efx->tc->seen_gen), in efx_mae_stop_counters()
206 netif_warn(efx, drv, efx->net_dev, in efx_mae_stop_counters()
209 efx->tc->flush_counters = false; in efx_mae_stop_counters()
219 struct efx_nic *efx = rx_queue->efx; in efx_mae_counters_grant_credits()
223 credits = READ_ONCE(rx_queue->notified_count) - rx_queue->granted_count; in efx_mae_counters_grant_credits()
228 rx_queue->granted_count += credits; in efx_mae_counters_grant_credits()
251 rc = -EIO; in efx_mae_table_get_desc()
255 desc->type = MCDI_WORD(outbuf, TABLE_DESCRIPTOR_OUT_TYPE); in efx_mae_table_get_desc()
256 desc->key_width = MCDI_WORD(outbuf, TABLE_DESCRIPTOR_OUT_KEY_WIDTH); in efx_mae_table_get_desc()
257 desc->resp_width = MCDI_WORD(outbuf, TABLE_DESCRIPTOR_OUT_RESP_WIDTH); in efx_mae_table_get_desc()
258 desc->n_keys = MCDI_WORD(outbuf, TABLE_DESCRIPTOR_OUT_N_KEY_FIELDS); in efx_mae_table_get_desc()
259 desc->n_resps = MCDI_WORD(outbuf, TABLE_DESCRIPTOR_OUT_N_RESP_FIELDS); in efx_mae_table_get_desc()
260 desc->n_prios = MCDI_WORD(outbuf, TABLE_DESCRIPTOR_OUT_N_PRIORITIES); in efx_mae_table_get_desc()
261 desc->flags = MCDI_BYTE(outbuf, TABLE_DESCRIPTOR_OUT_FLAGS); in efx_mae_table_get_desc()
262 rc = -EOPNOTSUPP; in efx_mae_table_get_desc()
263 if (desc->flags) in efx_mae_table_get_desc()
265 desc->scheme = MCDI_BYTE(outbuf, TABLE_DESCRIPTOR_OUT_SCHEME); in efx_mae_table_get_desc()
266 if (desc->scheme) in efx_mae_table_get_desc()
268 rc = -ENOMEM; in efx_mae_table_get_desc()
269 desc->keys = kcalloc(desc->n_keys, in efx_mae_table_get_desc()
272 if (!desc->keys) in efx_mae_table_get_desc()
274 desc->resps = kcalloc(desc->n_resps, in efx_mae_table_get_desc()
277 if (!desc->resps) in efx_mae_table_get_desc()
284 for (i = 0; i + offset < desc->n_keys + desc->n_resps; i++) { in efx_mae_table_get_desc()
292 if (i + offset < desc->n_keys) in efx_mae_table_get_desc()
293 field = desc->keys + i + offset; in efx_mae_table_get_desc()
295 field = desc->resps + (i + offset - desc->n_keys); in efx_mae_table_get_desc()
298 field->field_id = MCDI_STRUCT_WORD(fdesc, in efx_mae_table_get_desc()
300 field->lbn = MCDI_STRUCT_WORD(fdesc, TABLE_FIELD_DESCR_LBN); in efx_mae_table_get_desc()
301 field->width = MCDI_STRUCT_WORD(fdesc, TABLE_FIELD_DESCR_WIDTH); in efx_mae_table_get_desc()
302 field->masking = MCDI_STRUCT_BYTE(fdesc, TABLE_FIELD_DESCR_MASK_TYPE); in efx_mae_table_get_desc()
303 field->scheme = MCDI_STRUCT_BYTE(fdesc, TABLE_FIELD_DESCR_SCHEME); in efx_mae_table_get_desc()
308 kfree(desc->keys); in efx_mae_table_get_desc()
309 kfree(desc->resps); in efx_mae_table_get_desc()
323 return -EPROTO; in efx_mae_table_hook_find()
327 efx_mae_table_hook_find((_desc)->n_keys, (_desc)->keys, _id)
329 efx_mae_table_hook_find((_desc)->n_resps, (_desc)->resps, _id)
332 int _rc = TABLE_FIND_KEY(&_meta->desc, TABLE_FIELD_ID_##_mcdi_name); \
335 _rc = -EOPNOTSUPP; \
337 _meta->keys._name##_idx = _rc; \
343 int _rc = TABLE_FIND_RESP(&_meta->desc, TABLE_FIELD_ID_##_mcdi_name); \
346 _rc = -EOPNOTSUPP; \
348 _meta->resps._name##_idx = _rc; \
395 meta_ct->hooked = true; in efx_mae_table_hook_ct()
401 kfree(desc->keys); in efx_mae_table_free_desc()
402 kfree(desc->resps); in efx_mae_table_free_desc()
416 efx->tc->meta_ct.hooked = false; in efx_mae_check_table_exists()
450 efx->tc->meta_ct.hooked = false; in efx_mae_get_tables()
452 rc = efx_mae_table_get_desc(efx, &efx->tc->meta_ct.desc, in efx_mae_get_tables()
455 pci_info(efx->pci_dev, in efx_mae_get_tables()
461 rc = efx_mae_table_hook_ct(efx, &efx->tc->meta_ct); in efx_mae_get_tables()
463 pci_info(efx->pci_dev, in efx_mae_get_tables()
469 pci_info(efx->pci_dev, in efx_mae_get_tables()
477 efx_mae_table_free_desc(&efx->tc->meta_ct.desc); in efx_mae_free_tables()
478 efx->tc->meta_ct.hooked = false; in efx_mae_free_tables()
494 return -EIO; in efx_mae_get_basic_caps()
495 caps->match_field_count = MCDI_DWORD(outbuf, MAE_GET_CAPS_OUT_MATCH_FIELD_COUNT); in efx_mae_get_basic_caps()
496 caps->encap_types = MCDI_DWORD(outbuf, MAE_GET_CAPS_OUT_ENCAP_TYPES_SUPPORTED); in efx_mae_get_basic_caps()
497 caps->action_prios = MCDI_DWORD(outbuf, MAE_GET_CAPS_OUT_ACTION_PRIOS); in efx_mae_get_basic_caps()
545 caps->action_rule_fields); in efx_mae_get_caps()
549 caps->outer_rule_fields); in efx_mae_get_caps()
566 return "all-1s"; in mask_type_name()
568 return "all-0s"; in mask_type_name()
578 /* Checks a (big-endian) bytestring is a bit prefix */
579 static enum mask_type classify_mask(const u8 *mask, size_t len) in classify_mask() argument
588 if (!is_prefix_byte(mask[i])) in classify_mask()
590 } else if (mask[i]) { in classify_mask()
593 if (mask[i] != 0xff) in classify_mask()
595 if (mask[i]) in classify_mask()
614 return -EOPNOTSUPP; in efx_mae_match_check_cap_typ()
622 return -EINVAL; in efx_mae_match_check_cap_typ()
625 return -EOPNOTSUPP; in efx_mae_match_check_cap_typ()
630 return -EIO; in efx_mae_match_check_cap_typ()
634 /* Validate field mask against hardware capabilities. Captures caller's 'rc' */
636 enum mask_type typ = classify_mask((const u8 *)&mask->_field, \
637 sizeof(mask->_field)); \
643 "No support for %s mask in field %s", \
649 enum mask_type typ = mask->_field ? MASK_ONES : MASK_ZEROES; \
655 "No support for %s mask in field %s", \
661 const struct efx_tc_match_fields *mask, in efx_mae_match_check_caps() argument
664 const u8 *supported_fields = efx->tc->caps->action_rule_fields; in efx_mae_match_check_caps()
665 __be32 ingress_port = cpu_to_be32(mask->ingress_port); in efx_mae_match_check_caps()
669 /* Check for _PREFIX assumes big-endian, so we need to convert */ in efx_mae_match_check_caps()
675 NL_SET_ERR_MSG_FMT_MOD(extack, "No support for %s mask in field ingress_port", in efx_mae_match_check_caps()
709 * exact match on Outer Rule ID if any outer field matches are in efx_mae_match_check_caps()
711 * available to the Action Rule match iff the Outer Rule matched in efx_mae_match_check_caps()
714 if (efx_tc_match_is_encap(mask)) { in efx_mae_match_check_caps()
724 } else if (mask->enc_keyid) { in efx_mae_match_check_caps()
725 NL_SET_ERR_MSG_MOD(extack, "Match on enc_keyid requires other encap fields"); in efx_mae_match_check_caps()
726 return -EINVAL; in efx_mae_match_check_caps()
731 /* Checks for match fields not supported in LHS Outer Rules */
733 enum mask_type typ = classify_mask((const u8 *)&mask->_field, \
734 sizeof(mask->_field)); \
737 NL_SET_ERR_MSG_MOD(extack, "Unsupported match field " #_field);\
738 rc = -EOPNOTSUPP; \
743 if (mask->_field) { \
744 NL_SET_ERR_MSG_MOD(extack, "Unsupported match field " #_field);\
745 rc = -EOPNOTSUPP; \
751 * they use ENC_ fields in hardware to match regular (not enc_) fields from
755 const struct efx_tc_match_fields *mask, in efx_mae_match_check_caps_lhs() argument
758 const u8 *supported_fields = efx->tc->caps->outer_rule_fields; in efx_mae_match_check_caps_lhs()
759 __be32 ingress_port = cpu_to_be32(mask->ingress_port); in efx_mae_match_check_caps_lhs()
763 /* Check for _PREFIX assumes big-endian, so we need to convert */ in efx_mae_match_check_caps_lhs()
769 NL_SET_ERR_MSG_FMT_MOD(extack, "No support for %s mask in field %s\n", in efx_mae_match_check_caps_lhs()
797 if (efx_tc_match_is_encap(mask)) { in efx_mae_match_check_caps_lhs()
801 NL_SET_ERR_MSG_MOD(extack, "Unexpected encap match in LHS rule"); in efx_mae_match_check_caps_lhs()
802 return -EOPNOTSUPP; in efx_mae_match_check_caps_lhs()
825 /* Checks that the fields needed for encap-rule matches are supported by the
826 * MAE. All the fields are exact-match, except possibly ENC_IP_TOS.
832 u8 *supported_fields = efx->tc->caps->outer_rule_fields; in efx_mae_check_encap_match_caps()
854 NL_SET_ERR_MSG_FMT_MOD(extack, "No support for %s mask in field %s", in efx_mae_check_encap_match_caps()
862 NL_SET_ERR_MSG_FMT_MOD(extack, "No support for %s mask in field %s", in efx_mae_check_encap_match_caps()
882 return -EOPNOTSUPP; in efx_mae_check_encap_type_supported()
884 if (efx->tc->caps->encap_types & BIT(bit)) in efx_mae_check_encap_type_supported()
886 return -EOPNOTSUPP; in efx_mae_check_encap_type_supported()
897 return -EINVAL; in efx_mae_allocate_counter()
900 MCDI_SET_DWORD(inbuf, MAE_COUNTER_ALLOC_V2_IN_COUNTER_TYPE, cnt->type); in efx_mae_allocate_counter()
907 return -EIO; in efx_mae_allocate_counter()
908 cnt->fw_id = MCDI_DWORD(outbuf, MAE_COUNTER_ALLOC_OUT_COUNTER_ID); in efx_mae_allocate_counter()
909 cnt->gen = MCDI_DWORD(outbuf, MAE_COUNTER_ALLOC_OUT_GENERATION_COUNT); in efx_mae_allocate_counter()
921 MCDI_SET_DWORD(inbuf, MAE_COUNTER_FREE_V2_IN_FREE_COUNTER_ID, cnt->fw_id); in efx_mae_free_counter()
922 MCDI_SET_DWORD(inbuf, MAE_COUNTER_FREE_V2_IN_COUNTER_TYPE, cnt->type); in efx_mae_free_counter()
929 return -EIO; in efx_mae_free_counter()
935 cnt->fw_id)) in efx_mae_free_counter()
936 return -EIO; in efx_mae_free_counter()
950 return -EOPNOTSUPP; in efx_mae_encap_type_to_mae_type()
962 rc = efx_mae_encap_type_to_mae_type(encap->type); in efx_mae_allocate_encap_md()
966 inlen = MC_CMD_MAE_ENCAP_HEADER_ALLOC_IN_LEN(encap->encap_hdr_len); in efx_mae_allocate_encap_md()
968 return -EINVAL; in efx_mae_allocate_encap_md()
970 encap->encap_hdr, in efx_mae_allocate_encap_md()
971 encap->encap_hdr_len); in efx_mae_allocate_encap_md()
977 return -EIO; in efx_mae_allocate_encap_md()
978 encap->fw_id = MCDI_DWORD(outbuf, MAE_ENCAP_HEADER_ALLOC_OUT_ENCAP_HEADER_ID); in efx_mae_allocate_encap_md()
989 rc = efx_mae_encap_type_to_mae_type(encap->type); in efx_mae_update_encap_md()
994 encap->fw_id); in efx_mae_update_encap_md()
995 inlen = MC_CMD_MAE_ENCAP_HEADER_UPDATE_IN_LEN(encap->encap_hdr_len); in efx_mae_update_encap_md()
997 return -EINVAL; in efx_mae_update_encap_md()
999 encap->encap_hdr, in efx_mae_update_encap_md()
1000 encap->encap_hdr_len); in efx_mae_update_encap_md()
1015 MCDI_SET_DWORD(inbuf, MAE_ENCAP_HEADER_FREE_IN_EH_ID, encap->fw_id); in efx_mae_free_encap_md()
1021 return -EIO; in efx_mae_free_encap_md()
1026 if (WARN_ON(MCDI_DWORD(outbuf, MAE_ENCAP_HEADER_FREE_OUT_FREED_EH_ID) != encap->fw_id)) in efx_mae_free_encap_md()
1027 return -EIO; in efx_mae_free_encap_md()
1031 encap->fw_id = MC_CMD_MAE_ENCAP_HEADER_ALLOC_OUT_ENCAP_HEADER_ID_NULL; in efx_mae_free_encap_md()
1037 struct ef100_nic_data *nic_data = efx->nic_data; in efx_mae_lookup_mport()
1038 struct efx_mae *mae = efx->mae; in efx_mae_lookup_mport()
1041 int rc = -ENOENT; in efx_mae_lookup_mport()
1043 rhashtable_walk_enter(&mae->mports_ht, &walk); in efx_mae_lookup_mport()
1046 if (m->mport_type == MAE_MPORT_DESC_MPORT_TYPE_VNIC && in efx_mae_lookup_mport()
1047 m->interface_idx == nic_data->local_mae_intf && in efx_mae_lookup_mport()
1048 m->pf_idx == 0 && in efx_mae_lookup_mport()
1049 m->vf_idx == vf_idx) { in efx_mae_lookup_mport()
1050 *id = m->mport_id; in efx_mae_lookup_mport()
1074 return rhashtable_lookup_fast(&efx->mae->mports_ht, &mport_id, in efx_mae_get_mport()
1080 struct efx_mae *mae = efx->mae; in efx_mae_add_mport()
1083 rc = rhashtable_insert_fast(&mae->mports_ht, &desc->linkage, in efx_mae_add_mport()
1087 pci_err(efx->pci_dev, "Failed to insert MPORT %08x, rc %d\n", in efx_mae_add_mport()
1088 desc->mport_id, rc); in efx_mae_add_mport()
1107 struct ef100_nic_data *nic_data = efx->nic_data; in efx_mae_process_mport()
1110 mport = efx_mae_get_mport(efx, desc->mport_id); in efx_mae_process_mport()
1112 netif_err(efx, drv, efx->net_dev, in efx_mae_process_mport()
1113 "mport with id %u does exist!!!\n", desc->mport_id); in efx_mae_process_mport()
1114 return -EEXIST; in efx_mae_process_mport()
1117 if (nic_data->have_own_mport && in efx_mae_process_mport()
1118 desc->mport_id == nic_data->own_mport) { in efx_mae_process_mport()
1119 WARN_ON(desc->mport_type != MAE_MPORT_DESC_MPORT_TYPE_VNIC); in efx_mae_process_mport()
1120 WARN_ON(desc->vnic_client_type != in efx_mae_process_mport()
1122 nic_data->local_mae_intf = desc->interface_idx; in efx_mae_process_mport()
1123 nic_data->have_local_intf = true; in efx_mae_process_mport()
1124 pci_dbg(efx->pci_dev, "MAE interface_idx is %u\n", in efx_mae_process_mport()
1125 nic_data->local_mae_intf); in efx_mae_process_mport()
1143 return -ENOMEM; in efx_mae_enumerate_mports()
1151 rc = -EIO; in efx_mae_enumerate_mports()
1159 rc = -EIO; in efx_mae_enumerate_mports()
1163 rc = -EIO; in efx_mae_enumerate_mports()
1172 rc = -ENOMEM; in efx_mae_enumerate_mports()
1179 d->mport_id = MCDI_STRUCT_DWORD(desc, MAE_MPORT_DESC_MPORT_ID); in efx_mae_enumerate_mports()
1180 d->flags = MCDI_STRUCT_DWORD(desc, MAE_MPORT_DESC_FLAGS); in efx_mae_enumerate_mports()
1181 d->caller_flags = MCDI_STRUCT_DWORD(desc, in efx_mae_enumerate_mports()
1183 d->mport_type = MCDI_STRUCT_DWORD(desc, in efx_mae_enumerate_mports()
1185 switch (d->mport_type) { in efx_mae_enumerate_mports()
1187 d->port_idx = MCDI_STRUCT_DWORD(desc, in efx_mae_enumerate_mports()
1191 d->alias_mport_id = MCDI_STRUCT_DWORD(desc, in efx_mae_enumerate_mports()
1195 d->vnic_client_type = MCDI_STRUCT_DWORD(desc, in efx_mae_enumerate_mports()
1197 d->interface_idx = MCDI_STRUCT_DWORD(desc, in efx_mae_enumerate_mports()
1199 d->pf_idx = MCDI_STRUCT_WORD(desc, in efx_mae_enumerate_mports()
1201 d->vf_idx = MCDI_STRUCT_WORD(desc, in efx_mae_enumerate_mports()
1223 * efx_mae_allocate_pedit_mac() - allocate pedit MAC address in HW.
1241 sizeof(ped->h_addr)); in efx_mae_allocate_pedit_mac()
1242 memcpy(MCDI_PTR(inbuf, MAE_MAC_ADDR_ALLOC_IN_MAC_ADDR), ped->h_addr, in efx_mae_allocate_pedit_mac()
1243 sizeof(ped->h_addr)); in efx_mae_allocate_pedit_mac()
1249 return -EIO; in efx_mae_allocate_pedit_mac()
1250 ped->fw_id = MCDI_DWORD(outbuf, MAE_MAC_ADDR_ALLOC_OUT_MAC_ID); in efx_mae_allocate_pedit_mac()
1255 * efx_mae_free_pedit_mac() - free pedit MAC address in HW.
1270 MCDI_SET_DWORD(inbuf, MAE_MAC_ADDR_FREE_IN_MAC_ID, ped->fw_id); in efx_mae_free_pedit_mac()
1279 if (WARN_ON(MCDI_DWORD(outbuf, MAE_MAC_ADDR_FREE_OUT_FREED_MAC_ID) != ped->fw_id)) in efx_mae_free_pedit_mac()
1284 ped->fw_id = MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL; in efx_mae_free_pedit_mac()
1295 MAE_ACTION_SET_ALLOC_IN_VLAN_PUSH, act->vlan_push, in efx_mae_alloc_action_set()
1296 MAE_ACTION_SET_ALLOC_IN_VLAN_POP, act->vlan_pop, in efx_mae_alloc_action_set()
1297 MAE_ACTION_SET_ALLOC_IN_DECAP, act->decap, in efx_mae_alloc_action_set()
1299 act->do_ttl_dec); in efx_mae_alloc_action_set()
1301 if (act->src_mac) in efx_mae_alloc_action_set()
1303 act->src_mac->fw_id); in efx_mae_alloc_action_set()
1308 if (act->dst_mac) in efx_mae_alloc_action_set()
1310 act->dst_mac->fw_id); in efx_mae_alloc_action_set()
1315 if (act->count && !WARN_ON(!act->count->cnt)) in efx_mae_alloc_action_set()
1317 act->count->cnt->fw_id); in efx_mae_alloc_action_set()
1323 if (act->vlan_push) { in efx_mae_alloc_action_set()
1325 act->vlan_tci[0]); in efx_mae_alloc_action_set()
1327 act->vlan_proto[0]); in efx_mae_alloc_action_set()
1329 if (act->vlan_push >= 2) { in efx_mae_alloc_action_set()
1331 act->vlan_tci[1]); in efx_mae_alloc_action_set()
1333 act->vlan_proto[1]); in efx_mae_alloc_action_set()
1335 if (act->encap_md) in efx_mae_alloc_action_set()
1337 act->encap_md->fw_id); in efx_mae_alloc_action_set()
1341 if (act->deliver) in efx_mae_alloc_action_set()
1343 act->dest_mport); in efx_mae_alloc_action_set()
1350 return -EIO; in efx_mae_alloc_action_set()
1351 act->fw_id = MCDI_DWORD(outbuf, MAE_ACTION_SET_ALLOC_OUT_AS_ID); in efx_mae_alloc_action_set()
1355 if (WARN_ON_ONCE(efx_mae_asl_id(act->fw_id))) { in efx_mae_alloc_action_set()
1356 efx_mae_free_action_set(efx, act->fw_id); in efx_mae_alloc_action_set()
1357 return -EIO; in efx_mae_alloc_action_set()
1375 return -EIO; in efx_mae_free_action_set()
1378 * what action-sets exist, which could cause mayhem later. in efx_mae_free_action_set()
1381 return -EIO; in efx_mae_free_action_set()
1394 list_for_each_entry(act, &acts->list, list) in efx_mae_alloc_action_set_list()
1397 return -EINVAL; in efx_mae_alloc_action_set_list()
1402 act = list_first_entry(&acts->list, struct efx_tc_action_set, list); in efx_mae_alloc_action_set_list()
1403 acts->fw_id = act->fw_id; in efx_mae_alloc_action_set_list()
1407 return -EOPNOTSUPP; /* Too many actions */ in efx_mae_alloc_action_set_list()
1411 return -ENOMEM; in efx_mae_alloc_action_set_list()
1413 list_for_each_entry(act, &acts->list, list) { in efx_mae_alloc_action_set_list()
1415 i, act->fw_id); in efx_mae_alloc_action_set_list()
1424 rc = -EIO; in efx_mae_alloc_action_set_list()
1427 acts->fw_id = MCDI_DWORD(outbuf, MAE_ACTION_SET_LIST_ALLOC_OUT_ASL_ID); in efx_mae_alloc_action_set_list()
1431 if (WARN_ON_ONCE(!efx_mae_asl_id(acts->fw_id))) { in efx_mae_alloc_action_set_list()
1433 rc = -EIO; in efx_mae_alloc_action_set_list()
1451 if (efx_mae_asl_id(acts->fw_id)) { in efx_mae_free_action_set_list()
1453 acts->fw_id); in efx_mae_free_action_set_list()
1459 return -EIO; in efx_mae_free_action_set_list()
1462 * what action-set-lists exist, which could cause mayhem later. in efx_mae_free_action_set_list()
1464 if (WARN_ON(MCDI_DWORD(outbuf, MAE_ACTION_SET_LIST_FREE_OUT_FREED_ASL_ID) != acts->fw_id)) in efx_mae_free_action_set_list()
1465 return -EIO; in efx_mae_free_action_set_list()
1470 acts->fw_id = MC_CMD_MAE_ACTION_SET_LIST_ALLOC_OUT_ACTION_SET_LIST_ID_NULL; in efx_mae_free_action_set_list()
1483 rc = efx_mae_encap_type_to_mae_type(encap->tun_type); in efx_mae_register_encap_match()
1493 if (encap->src_ip | encap->dst_ip) { in efx_mae_register_encap_match()
1496 encap->src_ip); in efx_mae_register_encap_match()
1500 encap->dst_ip); in efx_mae_register_encap_match()
1508 &encap->src_ip6, sizeof(encap->src_ip6)); in efx_mae_register_encap_match()
1510 0xff, sizeof(encap->src_ip6)); in efx_mae_register_encap_match()
1512 &encap->dst_ip6, sizeof(encap->dst_ip6)); in efx_mae_register_encap_match()
1514 0xff, sizeof(encap->dst_ip6)); in efx_mae_register_encap_match()
1522 encap->udp_dport); in efx_mae_register_encap_match()
1526 encap->udp_sport); in efx_mae_register_encap_match()
1528 encap->udp_sport_mask); in efx_mae_register_encap_match()
1532 encap->ip_tos); in efx_mae_register_encap_match()
1534 encap->ip_tos_mask); in efx_mae_register_encap_match()
1540 return -EIO; in efx_mae_register_encap_match()
1541 encap->fw_id = MCDI_DWORD(outbuf, MAE_OUTER_RULE_INSERT_OUT_OR_ID); in efx_mae_register_encap_match()
1553 MCDI_SET_DWORD(inbuf, MAE_OUTER_RULE_REMOVE_IN_OR_ID, encap->fw_id); in efx_mae_unregister_encap_match()
1559 return -EIO; in efx_mae_unregister_encap_match()
1564 if (WARN_ON(MCDI_DWORD(outbuf, MAE_OUTER_RULE_REMOVE_OUT_REMOVED_OR_ID) != encap->fw_id)) in efx_mae_unregister_encap_match()
1565 return -EIO; in efx_mae_unregister_encap_match()
1569 encap->fw_id = MC_CMD_MAE_OUTER_RULE_INSERT_OUT_OUTER_RULE_ID_NULL; in efx_mae_unregister_encap_match()
1574 const struct efx_tc_match *match) in efx_mae_populate_lhs_match_criteria() argument
1576 if (match->mask.ingress_port) { in efx_mae_populate_lhs_match_criteria()
1577 if (~match->mask.ingress_port) in efx_mae_populate_lhs_match_criteria()
1578 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1581 match->value.ingress_port); in efx_mae_populate_lhs_match_criteria()
1584 match->mask.ingress_port); in efx_mae_populate_lhs_match_criteria()
1586 match->value.eth_proto); in efx_mae_populate_lhs_match_criteria()
1588 match->mask.eth_proto); in efx_mae_populate_lhs_match_criteria()
1590 match->value.vlan_tci[0]); in efx_mae_populate_lhs_match_criteria()
1592 match->mask.vlan_tci[0]); in efx_mae_populate_lhs_match_criteria()
1594 match->value.vlan_proto[0]); in efx_mae_populate_lhs_match_criteria()
1596 match->mask.vlan_proto[0]); in efx_mae_populate_lhs_match_criteria()
1598 match->value.vlan_tci[1]); in efx_mae_populate_lhs_match_criteria()
1600 match->mask.vlan_tci[1]); in efx_mae_populate_lhs_match_criteria()
1602 match->value.vlan_proto[1]); in efx_mae_populate_lhs_match_criteria()
1604 match->mask.vlan_proto[1]); in efx_mae_populate_lhs_match_criteria()
1606 match->value.eth_saddr, ETH_ALEN); in efx_mae_populate_lhs_match_criteria()
1608 match->mask.eth_saddr, ETH_ALEN); in efx_mae_populate_lhs_match_criteria()
1610 match->value.eth_daddr, ETH_ALEN); in efx_mae_populate_lhs_match_criteria()
1612 match->mask.eth_daddr, ETH_ALEN); in efx_mae_populate_lhs_match_criteria()
1614 match->value.ip_proto); in efx_mae_populate_lhs_match_criteria()
1616 match->mask.ip_proto); in efx_mae_populate_lhs_match_criteria()
1618 match->value.ip_tos); in efx_mae_populate_lhs_match_criteria()
1620 match->mask.ip_tos); in efx_mae_populate_lhs_match_criteria()
1622 match->value.ip_ttl); in efx_mae_populate_lhs_match_criteria()
1624 match->mask.ip_ttl); in efx_mae_populate_lhs_match_criteria()
1628 match->value.ip_frag); in efx_mae_populate_lhs_match_criteria()
1632 match->mask.ip_frag); in efx_mae_populate_lhs_match_criteria()
1634 match->value.src_ip); in efx_mae_populate_lhs_match_criteria()
1636 match->mask.src_ip); in efx_mae_populate_lhs_match_criteria()
1638 match->value.dst_ip); in efx_mae_populate_lhs_match_criteria()
1640 match->mask.dst_ip); in efx_mae_populate_lhs_match_criteria()
1643 &match->value.src_ip6, sizeof(struct in6_addr)); in efx_mae_populate_lhs_match_criteria()
1645 &match->mask.src_ip6, sizeof(struct in6_addr)); in efx_mae_populate_lhs_match_criteria()
1647 &match->value.dst_ip6, sizeof(struct in6_addr)); in efx_mae_populate_lhs_match_criteria()
1649 &match->mask.dst_ip6, sizeof(struct in6_addr)); in efx_mae_populate_lhs_match_criteria()
1652 match->value.l4_sport); in efx_mae_populate_lhs_match_criteria()
1654 match->mask.l4_sport); in efx_mae_populate_lhs_match_criteria()
1656 match->value.l4_dport); in efx_mae_populate_lhs_match_criteria()
1658 match->mask.l4_dport); in efx_mae_populate_lhs_match_criteria()
1659 /* No enc-keys in LHS rules. Caps check should have caught this; any in efx_mae_populate_lhs_match_criteria()
1660 * enc-keys from an fLHS should have been translated to regular keys in efx_mae_populate_lhs_match_criteria()
1664 if (WARN_ON_ONCE(match->encap && !match->encap->type)) in efx_mae_populate_lhs_match_criteria()
1665 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1666 if (WARN_ON_ONCE(match->mask.enc_src_ip)) in efx_mae_populate_lhs_match_criteria()
1667 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1668 if (WARN_ON_ONCE(match->mask.enc_dst_ip)) in efx_mae_populate_lhs_match_criteria()
1669 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1671 if (WARN_ON_ONCE(!ipv6_addr_any(&match->mask.enc_src_ip6))) in efx_mae_populate_lhs_match_criteria()
1672 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1673 if (WARN_ON_ONCE(!ipv6_addr_any(&match->mask.enc_dst_ip6))) in efx_mae_populate_lhs_match_criteria()
1674 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1676 if (WARN_ON_ONCE(match->mask.enc_ip_tos)) in efx_mae_populate_lhs_match_criteria()
1677 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1678 if (WARN_ON_ONCE(match->mask.enc_ip_ttl)) in efx_mae_populate_lhs_match_criteria()
1679 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1680 if (WARN_ON_ONCE(match->mask.enc_sport)) in efx_mae_populate_lhs_match_criteria()
1681 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1682 if (WARN_ON_ONCE(match->mask.enc_dport)) in efx_mae_populate_lhs_match_criteria()
1683 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1684 if (WARN_ON_ONCE(match->mask.enc_keyid)) in efx_mae_populate_lhs_match_criteria()
1685 return -EOPNOTSUPP; in efx_mae_populate_lhs_match_criteria()
1700 /* match */ in efx_mae_insert_lhs_outer_rule()
1702 rc = efx_mae_populate_lhs_match_criteria(match_crit, &rule->match); in efx_mae_insert_lhs_outer_rule()
1707 act = &rule->lhs_act; in efx_mae_insert_lhs_outer_rule()
1715 MAE_OUTER_RULE_INSERT_IN_DO_CT, !!act->zone, in efx_mae_insert_lhs_outer_rule()
1718 act->zone ? act->zone->zone : 0, in efx_mae_insert_lhs_outer_rule()
1721 MAE_OUTER_RULE_INSERT_IN_DO_COUNT, !!act->count, in efx_mae_insert_lhs_outer_rule()
1723 act->rid ? act->rid->fw_id : 0); in efx_mae_insert_lhs_outer_rule()
1724 if (act->count) in efx_mae_insert_lhs_outer_rule()
1726 act->count->cnt->fw_id); in efx_mae_insert_lhs_outer_rule()
1732 return -EIO; in efx_mae_insert_lhs_outer_rule()
1733 rule->fw_id = MCDI_DWORD(outbuf, MAE_OUTER_RULE_INSERT_OUT_OR_ID); in efx_mae_insert_lhs_outer_rule()
1751 MCDI_SET_DWORD(inbuf, MAE_OUTER_RULE_REMOVE_IN_OR_ID, rule->fw_id); in efx_mae_remove_lhs_outer_rule()
1757 return -EIO; in efx_mae_remove_lhs_outer_rule()
1762 if (WARN_ON(MCDI_DWORD(outbuf, MAE_OUTER_RULE_REMOVE_OUT_REMOVED_OR_ID) != rule->fw_id)) in efx_mae_remove_lhs_outer_rule()
1763 return -EIO; in efx_mae_remove_lhs_outer_rule()
1767 rule->fw_id = MC_CMD_MAE_OUTER_RULE_INSERT_OUT_OUTER_RULE_ID_NULL; in efx_mae_remove_lhs_outer_rule()
1777 * it in the appropriate bits of @row. @value must be big-endian; we
1778 * convert it to little-endianness as we go.
1791 return -EOPNOTSUPP; in efx_mae_table_populate()
1793 return -EINVAL; in efx_mae_table_populate()
1795 return -EINVAL; in efx_mae_table_populate()
1801 v = ((u8 *)value)[value_size - i - 1]; in efx_mae_table_populate()
1816 return -EINVAL; in efx_mae_table_populate_bool()
1823 /* IPv4 is placed in the first 4 bytes of an IPv6-sized field */ in efx_mae_table_populate_ipv4()
1827 return -EINVAL; in efx_mae_table_populate_ipv4()
1839 * the most significant byte for a big-endian 4-bytes value. in efx_mae_table_populate_u24()
1842 sizeof(v) - 1); in efx_mae_table_populate_u24()
1850 sizeof(_v)) : -EINVAL; \
1853 efx_mae_table_populate_ipv4(efx->tc->meta_##_table.desc.keys \
1854 [efx->tc->meta_##_table.keys._field##_idx],\
1855 dst, efx->tc->meta_##_table.desc.key_width,\
1858 _TABLE_POPULATE(dst, efx->tc->meta_##_table.desc.key_width, \
1859 efx->tc->meta_##_table.desc.keys \
1860 [efx->tc->meta_##_table.keys._field##_idx], \
1864 efx_mae_table_populate_bool(efx->tc->meta_##_table.desc.resps \
1865 [efx->tc->meta_##_table.resps._field##_idx],\
1866 dst, efx->tc->meta_##_table.desc.resp_width,\
1869 _TABLE_POPULATE(dst, efx->tc->meta_##_table.desc.resp_width, \
1870 efx->tc->meta_##_table.desc.resps \
1871 [efx->tc->meta_##_table.resps._field##_idx], \
1875 efx_mae_table_populate_u24(efx->tc->meta_##_table.desc.resps \
1876 [efx->tc->meta_##_table.resps._field##_idx],\
1877 dst, efx->tc->meta_##_table.desc.resp_width,\
1883 bool ipv6 = conn->eth_proto == htons(ETH_P_IPV6); in efx_mae_populate_ct_key()
1886 rc = TABLE_POPULATE_KEY(key, ct, eth_proto, conn->eth_proto); in efx_mae_populate_ct_key()
1889 rc = TABLE_POPULATE_KEY(key, ct, ip_proto, conn->ip_proto); in efx_mae_populate_ct_key()
1893 rc = TABLE_POPULATE_KEY(key, ct, src_ip, conn->src_ip6); in efx_mae_populate_ct_key()
1895 rc = TABLE_POPULATE_KEY_IPV4(key, ct, src_ip, conn->src_ip); in efx_mae_populate_ct_key()
1899 rc = TABLE_POPULATE_KEY(key, ct, dst_ip, conn->dst_ip6); in efx_mae_populate_ct_key()
1901 rc = TABLE_POPULATE_KEY_IPV4(key, ct, dst_ip, conn->dst_ip); in efx_mae_populate_ct_key()
1904 rc = TABLE_POPULATE_KEY(key, ct, l4_sport, conn->l4_sport); in efx_mae_populate_ct_key()
1907 rc = TABLE_POPULATE_KEY(key, ct, l4_dport, conn->l4_dport); in efx_mae_populate_ct_key()
1910 return TABLE_POPULATE_KEY(key, ct, zone, cpu_to_be16(conn->zone->zone)); in efx_mae_populate_ct_key()
1915 bool ipv6 = conn->eth_proto == htons(ETH_P_IPV6); in efx_mae_insert_ct()
1919 int rc = -ENOMEM; in efx_mae_insert_ct()
1922 if (!efx->tc->meta_ct.hooked) in efx_mae_insert_ct()
1923 return -EOPNOTSUPP; in efx_mae_insert_ct()
1926 kw = DIV_ROUND_UP(efx->tc->meta_ct.desc.key_width, 32); in efx_mae_insert_ct()
1927 rw = DIV_ROUND_UP(efx->tc->meta_ct.desc.resp_width, 32); in efx_mae_insert_ct()
1931 return -E2BIG; in efx_mae_insert_ct()
1934 return -ENOMEM; in efx_mae_insert_ct()
1947 rc = TABLE_POPULATE_RESP_BOOL(resp, ct, dnat, conn->dnat); in efx_mae_insert_ct()
1952 rc = TABLE_POPULATE_RESP(resp, ct, nat_ip, conn->nat_ip); in efx_mae_insert_ct()
1955 rc = TABLE_POPULATE_RESP(resp, ct, l4_natport, conn->l4_natport); in efx_mae_insert_ct()
1958 rc = TABLE_POPULATE_RESP(resp, ct, mark, cpu_to_be32(conn->mark)); in efx_mae_insert_ct()
1961 rc = TABLE_POPULATE_RESP_U24(resp, ct, counter_id, conn->cnt->fw_id); in efx_mae_insert_ct()
1967 efx->tc->meta_ct.desc.key_width); in efx_mae_insert_ct()
1970 efx->tc->meta_ct.desc.resp_width); in efx_mae_insert_ct()
1991 int rc = -ENOMEM; in efx_mae_remove_ct()
1994 if (!efx->tc->meta_ct.hooked) in efx_mae_remove_ct()
1995 return -EOPNOTSUPP; in efx_mae_remove_ct()
1998 kw = DIV_ROUND_UP(efx->tc->meta_ct.desc.key_width, 32); in efx_mae_remove_ct()
2002 return -E2BIG; in efx_mae_remove_ct()
2005 return -ENOMEM; in efx_mae_remove_ct()
2017 efx->tc->meta_ct.desc.key_width); in efx_mae_remove_ct()
2033 const struct efx_tc_match *match) in efx_mae_populate_match_criteria() argument
2035 if (match->mask.ingress_port) { in efx_mae_populate_match_criteria()
2036 if (~match->mask.ingress_port) in efx_mae_populate_match_criteria()
2037 return -EOPNOTSUPP; in efx_mae_populate_match_criteria()
2040 match->value.ingress_port); in efx_mae_populate_match_criteria()
2043 match->mask.ingress_port); in efx_mae_populate_match_criteria()
2046 match->value.ct_state_trk, in efx_mae_populate_match_criteria()
2048 match->value.ct_state_est, in efx_mae_populate_match_criteria()
2050 match->value.ip_frag, in efx_mae_populate_match_criteria()
2052 match->value.ip_firstfrag, in efx_mae_populate_match_criteria()
2054 match->value.tcp_syn_fin_rst); in efx_mae_populate_match_criteria()
2057 match->mask.ct_state_trk, in efx_mae_populate_match_criteria()
2059 match->mask.ct_state_est, in efx_mae_populate_match_criteria()
2061 match->mask.ip_frag, in efx_mae_populate_match_criteria()
2063 match->mask.ip_firstfrag, in efx_mae_populate_match_criteria()
2065 match->mask.tcp_syn_fin_rst); in efx_mae_populate_match_criteria()
2067 match->value.recirc_id); in efx_mae_populate_match_criteria()
2069 match->mask.recirc_id); in efx_mae_populate_match_criteria()
2071 match->value.ct_mark); in efx_mae_populate_match_criteria()
2073 match->mask.ct_mark); in efx_mae_populate_match_criteria()
2075 match->value.ct_zone); in efx_mae_populate_match_criteria()
2077 match->mask.ct_zone); in efx_mae_populate_match_criteria()
2079 match->value.eth_proto); in efx_mae_populate_match_criteria()
2081 match->mask.eth_proto); in efx_mae_populate_match_criteria()
2083 match->value.vlan_tci[0]); in efx_mae_populate_match_criteria()
2085 match->mask.vlan_tci[0]); in efx_mae_populate_match_criteria()
2087 match->value.vlan_proto[0]); in efx_mae_populate_match_criteria()
2089 match->mask.vlan_proto[0]); in efx_mae_populate_match_criteria()
2091 match->value.vlan_tci[1]); in efx_mae_populate_match_criteria()
2093 match->mask.vlan_tci[1]); in efx_mae_populate_match_criteria()
2095 match->value.vlan_proto[1]); in efx_mae_populate_match_criteria()
2097 match->mask.vlan_proto[1]); in efx_mae_populate_match_criteria()
2099 match->value.eth_saddr, ETH_ALEN); in efx_mae_populate_match_criteria()
2101 match->mask.eth_saddr, ETH_ALEN); in efx_mae_populate_match_criteria()
2103 match->value.eth_daddr, ETH_ALEN); in efx_mae_populate_match_criteria()
2105 match->mask.eth_daddr, ETH_ALEN); in efx_mae_populate_match_criteria()
2107 match->value.ip_proto); in efx_mae_populate_match_criteria()
2109 match->mask.ip_proto); in efx_mae_populate_match_criteria()
2111 match->value.ip_tos); in efx_mae_populate_match_criteria()
2113 match->mask.ip_tos); in efx_mae_populate_match_criteria()
2115 match->value.ip_ttl); in efx_mae_populate_match_criteria()
2117 match->mask.ip_ttl); in efx_mae_populate_match_criteria()
2119 match->value.src_ip); in efx_mae_populate_match_criteria()
2121 match->mask.src_ip); in efx_mae_populate_match_criteria()
2123 match->value.dst_ip); in efx_mae_populate_match_criteria()
2125 match->mask.dst_ip); in efx_mae_populate_match_criteria()
2128 &match->value.src_ip6, sizeof(struct in6_addr)); in efx_mae_populate_match_criteria()
2130 &match->mask.src_ip6, sizeof(struct in6_addr)); in efx_mae_populate_match_criteria()
2132 &match->value.dst_ip6, sizeof(struct in6_addr)); in efx_mae_populate_match_criteria()
2134 &match->mask.dst_ip6, sizeof(struct in6_addr)); in efx_mae_populate_match_criteria()
2137 match->value.l4_sport); in efx_mae_populate_match_criteria()
2139 match->mask.l4_sport); in efx_mae_populate_match_criteria()
2141 match->value.l4_dport); in efx_mae_populate_match_criteria()
2143 match->mask.l4_dport); in efx_mae_populate_match_criteria()
2145 match->value.tcp_flags); in efx_mae_populate_match_criteria()
2147 match->mask.tcp_flags); in efx_mae_populate_match_criteria()
2148 /* enc-keys are handled indirectly, through encap_match ID */ in efx_mae_populate_match_criteria()
2149 if (match->encap) { in efx_mae_populate_match_criteria()
2151 match->encap->fw_id); in efx_mae_populate_match_criteria()
2156 match->value.enc_keyid); in efx_mae_populate_match_criteria()
2158 match->mask.enc_keyid); in efx_mae_populate_match_criteria()
2159 } else if (WARN_ON_ONCE(match->mask.enc_src_ip) || in efx_mae_populate_match_criteria()
2160 WARN_ON_ONCE(match->mask.enc_dst_ip) || in efx_mae_populate_match_criteria()
2161 WARN_ON_ONCE(!ipv6_addr_any(&match->mask.enc_src_ip6)) || in efx_mae_populate_match_criteria()
2162 WARN_ON_ONCE(!ipv6_addr_any(&match->mask.enc_dst_ip6)) || in efx_mae_populate_match_criteria()
2163 WARN_ON_ONCE(match->mask.enc_ip_tos) || in efx_mae_populate_match_criteria()
2164 WARN_ON_ONCE(match->mask.enc_ip_ttl) || in efx_mae_populate_match_criteria()
2165 WARN_ON_ONCE(match->mask.enc_sport) || in efx_mae_populate_match_criteria()
2166 WARN_ON_ONCE(match->mask.enc_dport) || in efx_mae_populate_match_criteria()
2167 WARN_ON_ONCE(match->mask.enc_keyid)) { in efx_mae_populate_match_criteria()
2168 /* No enc-keys should appear in a rule without an encap_match */ in efx_mae_populate_match_criteria()
2169 return -EOPNOTSUPP; in efx_mae_populate_match_criteria()
2174 int efx_mae_insert_rule(struct efx_nic *efx, const struct efx_tc_match *match, in efx_mae_insert_rule() argument
2185 return -EINVAL; in efx_mae_insert_rule()
2200 rc = efx_mae_populate_match_criteria(match_crit, match); in efx_mae_insert_rule()
2209 return -EIO; in efx_mae_insert_rule()
2250 return -EIO; in efx_mae_delete_rule()
2256 return -EIO; in efx_mae_delete_rule()
2262 struct ef100_nic_data *nic_data = efx->nic_data; in efx_init_mae()
2266 if (!nic_data->have_mport) in efx_init_mae()
2267 return -EINVAL; in efx_init_mae()
2271 return -ENOMEM; in efx_init_mae()
2273 rc = rhashtable_init(&mae->mports_ht, &efx_mae_mports_ht_params); in efx_init_mae()
2278 efx->mae = mae; in efx_init_mae()
2279 mae->efx = efx; in efx_init_mae()
2285 struct efx_mae *mae = efx->mae; in efx_fini_mae()
2288 efx->mae = NULL; in efx_fini_mae()