Author: arybchik
Date: Thu Nov 29 06:42:04 2018
New Revision: 341186
URL: https://svnweb.freebsd.org/changeset/base/341186

Log:
  sfxge(4): support filters for encapsulated packets
  
  This adds filters for encapsulated packets to the list
  returned by ef10_filter_supported_filters().
  
  Submitted by:   Roman Zhukov <roman.zhukov at oktetlabs.ru>
  Sponsored by:   Solarflare Communications, Inc.
  Differential Revision:  https://reviews.freebsd.org/D18217

Modified:
  head/sys/dev/sfxge/common/ef10_filter.c

Modified: head/sys/dev/sfxge/common/ef10_filter.c
==============================================================================
--- head/sys/dev/sfxge/common/ef10_filter.c     Thu Nov 29 06:41:53 2018        
(r341185)
+++ head/sys/dev/sfxge/common/ef10_filter.c     Thu Nov 29 06:42:04 2018        
(r341186)
@@ -922,6 +922,7 @@ efx_mcdi_get_parser_disp_info(
        __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;
@@ -938,7 +939,8 @@ efx_mcdi_get_parser_disp_info(
        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);
@@ -998,30 +1000,68 @@ ef10_filter_supported_filters(
        __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;
+       }
+
        /*
         * The static assertions in ef10_filter_init() ensure that the values of
         * the EFX_FILTER_MATCH flags match those used by MCDI, so they don't
@@ -1032,9 +1072,10 @@ ef10_filter_supported_filters(
         * 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++;
@@ -1045,6 +1086,10 @@ ef10_filter_supported_filters(
 
        return (0);
 
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
 fail1:
        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to