__in efx_nic_t *enp,
__out_ecount(buffer_length) uint32_t *buffer,
__in size_t buffer_length,
+ __in boolean_t encap,
__out size_t *list_lengthp)
{
efx_mcdi_req_t req;
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX;
- MCDI_IN_SET_DWORD(req, GET_PARSER_DISP_INFO_OUT_OP,
+ MCDI_IN_SET_DWORD(req, GET_PARSER_DISP_INFO_OUT_OP, encap ?
+ MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_ENCAP_RX_MATCHES :
MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES);
efx_mcdi_execute(enp, &req);
__in size_t buffer_length,
__out size_t *list_lengthp)
{
-
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
size_t mcdi_list_length;
+ size_t mcdi_encap_list_length;
size_t list_length;
uint32_t i;
+ uint32_t next_buf_idx;
+ size_t next_buf_length;
efx_rc_t rc;
+ boolean_t no_space = B_FALSE;
efx_filter_match_flags_t all_filter_flags =
(EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_LOC_HOST |
EFX_FILTER_MATCH_REM_MAC | EFX_FILTER_MATCH_REM_PORT |
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_IFRM_UNKNOWN_MCAST_DST |
+ EFX_FILTER_MATCH_IFRM_UNKNOWN_UCAST_DST |
EFX_FILTER_MATCH_UNKNOWN_MCAST_DST |
EFX_FILTER_MATCH_UNKNOWN_UCAST_DST);
- rc = efx_mcdi_get_parser_disp_info(enp, buffer, buffer_length,
- &mcdi_list_length);
+ /*
+ * 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.
+ */
+ rc = efx_mcdi_get_parser_disp_info(enp, buffer, buffer_length, B_FALSE,
+ &mcdi_list_length);
if (rc != 0) {
- if (rc == ENOSPC) {
- /* Pass through mcdi_list_length for the list length */
- *list_lengthp = mcdi_list_length;
+ if (rc == ENOSPC)
+ no_space = B_TRUE;
+ else
+ goto fail1;
+ }
+
+ if (no_space) {
+ next_buf_idx = 0;
+ next_buf_length = 0;
+ } else {
+ EFSYS_ASSERT(mcdi_list_length <= buffer_length);
+ next_buf_idx = mcdi_list_length;
+ next_buf_length = buffer_length - mcdi_list_length;
+ }
+
+ if (encp->enc_tunnel_encapsulations_supported != 0) {
+ rc = efx_mcdi_get_parser_disp_info(enp, &buffer[next_buf_idx],
+ next_buf_length, B_TRUE, &mcdi_encap_list_length);
+ if (rc != 0) {
+ if (rc == ENOSPC)
+ no_space = B_TRUE;
+ else
+ goto fail2;
}
- goto fail1;
+ } else {
+ mcdi_encap_list_length = 0;
+ }
+
+ if (no_space) {
+ *list_lengthp = mcdi_list_length + mcdi_encap_list_length;
+ rc = ENOSPC;
+ goto fail3;
}
/*
* of the matches is preserved as they are ordered from highest to
* lowest priority.
*/
- EFSYS_ASSERT(mcdi_list_length <= buffer_length);
+ EFSYS_ASSERT(mcdi_list_length + mcdi_encap_list_length <=
+ buffer_length);
list_length = 0;
- for (i = 0; i < mcdi_list_length; i++) {
+ for (i = 0; i < mcdi_list_length + mcdi_encap_list_length; i++) {
if ((buffer[i] & ~all_filter_flags) == 0) {
buffer[list_length] = buffer[i];
list_length++;
return (0);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);