MATCH_MASK(MC_CMD_FILTER_OP_EXT_IN_MATCH_OUTER_VLAN));
EFX_STATIC_ASSERT(EFX_FILTER_MATCH_IP_PROTO ==
MATCH_MASK(MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_VNI_OR_VSID ==
+ MATCH_MASK(MC_CMD_FILTER_OP_EXT_IN_MATCH_VNI_OR_VSID));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_IFRM_LOC_MAC ==
+ MATCH_MASK(MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_MAC));
EFX_STATIC_ASSERT(EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST ==
MATCH_MASK(MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST));
EFX_STATIC_ASSERT(EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST ==
__inout ef10_filter_handle_t *handle)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FILTER_OP_EXT_IN_LEN,
+ uint8_t payload[MAX(MC_CMD_FILTER_OP_V3_IN_LEN,
MC_CMD_FILTER_OP_EXT_OUT_LEN)];
+ efx_filter_match_flags_t match_flags;
efx_rc_t rc;
memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FILTER_OP;
req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_FILTER_OP_EXT_IN_LEN;
+ req.emr_in_length = MC_CMD_FILTER_OP_V3_IN_LEN;
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_FILTER_OP_EXT_OUT_LEN;
+ /*
+ * Remove match flag for encapsulated filters that does not correspond
+ * to the MCDI match flags
+ */
+ match_flags = spec->efs_match_flags & ~EFX_FILTER_MATCH_ENCAP_TYPE;
+
switch (filter_op) {
case MC_CMD_FILTER_OP_IN_OP_REPLACE:
MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_HANDLE_LO,
MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_PORT_ID,
EVB_PORT_ID_ASSIGNED);
MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_MATCH_FIELDS,
- spec->efs_match_flags);
- MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_RX_DEST,
- MC_CMD_FILTER_OP_EXT_IN_RX_DEST_HOST);
- MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_RX_QUEUE,
- spec->efs_dmaq_id);
+ match_flags);
+ if (spec->efs_dmaq_id == EFX_FILTER_SPEC_RX_DMAQ_ID_DROP) {
+ MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_RX_DEST,
+ MC_CMD_FILTER_OP_EXT_IN_RX_DEST_DROP);
+ } else {
+ MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_RX_DEST,
+ MC_CMD_FILTER_OP_EXT_IN_RX_DEST_HOST);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_RX_QUEUE,
+ spec->efs_dmaq_id);
+ }
#if EFSYS_OPT_RX_SCALE
if (spec->efs_flags & EFX_FILTER_FLAG_RX_RSS) {
rc = EINVAL;
goto fail2;
}
+
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_EXT_IN_VNI_OR_VSID),
+ spec->efs_vni_or_vsid, EFX_VNI_OR_VSID_LEN);
+
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_EXT_IN_IFRM_DST_MAC),
+ spec->efs_ifrm_loc_mac, EFX_MAC_ADDR_LEN);
+ }
+
+ /*
+ * Set the "MARK" or "FLAG" action for all packets matching this filter
+ * if necessary (only useful with equal stride packed stream Rx mode
+ * which provide the information in pseudo-header).
+ * These actions require MC_CMD_FILTER_OP_V3_IN msgrequest.
+ */
+ if ((spec->efs_flags & EFX_FILTER_FLAG_ACTION_MARK) &&
+ (spec->efs_flags & EFX_FILTER_FLAG_ACTION_FLAG)) {
+ rc = EINVAL;
+ goto fail3;
+ }
+ if (spec->efs_flags & EFX_FILTER_FLAG_ACTION_MARK) {
+ MCDI_IN_SET_DWORD(req, FILTER_OP_V3_IN_MATCH_ACTION,
+ MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_MARK);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_V3_IN_MATCH_MARK_VALUE,
+ spec->efs_mark);
+ } else if (spec->efs_flags & EFX_FILTER_FLAG_ACTION_FLAG) {
+ MCDI_IN_SET_DWORD(req, FILTER_OP_V3_IN_MATCH_ACTION,
+ MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_FLAG);
}
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
- goto fail3;
+ goto fail4;
}
if (req.emr_out_length_used < MC_CMD_FILTER_OP_EXT_OUT_LEN) {
rc = EMSGSIZE;
- goto fail4;
+ goto fail5;
}
handle->efh_lo = MCDI_OUT_DWORD(req, FILTER_OP_EXT_OUT_HANDLE_LO);
return (0);
+fail5:
+ EFSYS_PROBE(fail5);
fail4:
EFSYS_PROBE(fail4);
fail3:
return (B_FALSE);
if (left->efs_encap_type != right->efs_encap_type)
return (B_FALSE);
+ if (memcmp(left->efs_vni_or_vsid, right->efs_vni_or_vsid,
+ EFX_VNI_OR_VSID_LEN))
+ return (B_FALSE);
+ if (memcmp(left->efs_ifrm_loc_mac, right->efs_ifrm_loc_mac,
+ EFX_MAC_ADDR_LEN))
+ return (B_FALSE);
return (B_TRUE);
EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_LOC_PORT |
EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_INNER_VID |
EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_VNI_OR_VSID |
+ EFX_FILTER_MATCH_IFRM_LOC_MAC |
EFX_FILTER_MATCH_IFRM_UNKNOWN_MCAST_DST |
EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST |
+ EFX_FILTER_MATCH_ENCAP_TYPE |
EFX_FILTER_MATCH_UNKNOWN_MCAST_DST |
EFX_FILTER_MATCH_UNKNOWN_UCAST_DST);
/*
* Two calls to MC_CMD_GET_PARSER_DISP_INFO are needed: one to get the
* list of supported filters for ordinary packets, and then another to
- * get the list of supported filters for encapsulated packets.
+ * get the list of supported filters for encapsulated packets. To
+ * distinguish the second list from the first, the
+ * EFX_FILTER_MATCH_ENCAP_TYPE flag is added to each filter for
+ * encapsulated packets.
*/
rc = efx_mcdi_get_parser_disp_info(enp, buffer, buffer_length, B_FALSE,
&mcdi_list_length);
no_space = B_TRUE;
else
goto fail2;
+ } else {
+ for (i = next_buf_idx;
+ i < next_buf_idx + mcdi_encap_list_length; i++)
+ buffer[i] |= EFX_FILTER_MATCH_ENCAP_TYPE;
}
} else {
mcdi_encap_list_length = 0;