Author: arybchik
Date: Tue May 17 06:25:00 2016
New Revision: 300008
URL: https://svnweb.freebsd.org/changeset/base/300008

Log:
  sfxge(4): query and use current MTU if setting the MTU fails
  
  This allows the driver to fall back to the largest usable MTU if a
  user attempts to configure an unprivileged function with an MTU higher
  than that of the attached port.
  
  Submitted by:   Mark Spender <mspender at solarflare.com>
  Sponsored by:   Solarflare Communications, Inc.
  MFC after:      1 week
  Differential Revision:  https://reviews.freebsd.org/D6387

Modified:
  head/sys/dev/sfxge/common/ef10_impl.h
  head/sys/dev/sfxge/common/ef10_mac.c
  head/sys/dev/sfxge/common/efx.h
  head/sys/dev/sfxge/common/efx_impl.h
  head/sys/dev/sfxge/common/efx_mac.c
  head/sys/dev/sfxge/common/siena_impl.h
  head/sys/dev/sfxge/common/siena_mac.c

Modified: head/sys/dev/sfxge/common/ef10_impl.h
==============================================================================
--- head/sys/dev/sfxge/common/ef10_impl.h       Tue May 17 06:23:50 2016        
(r300007)
+++ head/sys/dev/sfxge/common/ef10_impl.h       Tue May 17 06:25:00 2016        
(r300008)
@@ -236,6 +236,11 @@ ef10_mac_pdu_set(
        __in    efx_nic_t *enp);
 
 extern __checkReturn   efx_rc_t
+ef10_mac_pdu_get(
+       __in    efx_nic_t *enp,
+       __out   size_t *pdu);
+
+extern __checkReturn   efx_rc_t
 ef10_mac_reconfigure(
        __in    efx_nic_t *enp);
 

Modified: head/sys/dev/sfxge/common/ef10_mac.c
==============================================================================
--- head/sys/dev/sfxge/common/ef10_mac.c        Tue May 17 06:23:50 2016        
(r300007)
+++ head/sys/dev/sfxge/common/ef10_mac.c        Tue May 17 06:25:00 2016        
(r300008)
@@ -199,6 +199,53 @@ fail1:
        return (rc);
 }
 
+static __checkReturn           efx_rc_t
+efx_mcdi_mtu_get(
+       __in            efx_nic_t *enp,
+       __out           size_t *mtu)
+{
+       efx_mcdi_req_t req;
+       uint8_t payload[MAX(MC_CMD_SET_MAC_EXT_IN_LEN,
+                           MC_CMD_SET_MAC_V2_OUT_LEN)];
+       efx_rc_t rc;
+
+       (void) memset(payload, 0, sizeof (payload));
+       req.emr_cmd = MC_CMD_SET_MAC;
+       req.emr_in_buf = payload;
+       req.emr_in_length = MC_CMD_SET_MAC_EXT_IN_LEN;
+       req.emr_out_buf = payload;
+       req.emr_out_length = MC_CMD_SET_MAC_V2_OUT_LEN;
+
+       /*
+        * With MC_CMD_SET_MAC_EXT_IN_CONTROL set to 0, this just queries the
+        * MTU.  This should always be supported on Medford, but it is not
+        * supported on older Huntington firmware.
+        */
+       MCDI_IN_SET_DWORD(req, SET_MAC_EXT_IN_CONTROL, 0);
+
+       efx_mcdi_execute(enp, &req);
+
+       if (req.emr_rc != 0) {
+               rc = req.emr_rc;
+               goto fail1;
+       }
+       if (req.emr_out_length_used < MC_CMD_SET_MAC_V2_OUT_MTU_OFST + 4) {
+               rc = EMSGSIZE;
+               goto fail2;
+       }
+
+       *mtu = MCDI_OUT_DWORD(req, SET_MAC_V2_OUT_MTU);
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
        __checkReturn   efx_rc_t
 ef10_mac_pdu_set(
        __in            efx_nic_t *enp)
@@ -230,6 +277,24 @@ fail1:
        return (rc);
 }
 
+       __checkReturn           efx_rc_t
+ef10_mac_pdu_get(
+       __in            efx_nic_t *enp,
+       __out           size_t *pdu)
+{
+       efx_rc_t rc;
+
+       if ((rc = efx_mcdi_mtu_get(enp, pdu)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
 __checkReturn  efx_rc_t
 ef10_mac_reconfigure(
        __in            efx_nic_t *enp)

Modified: head/sys/dev/sfxge/common/efx.h
==============================================================================
--- head/sys/dev/sfxge/common/efx.h     Tue May 17 06:23:50 2016        
(r300007)
+++ head/sys/dev/sfxge/common/efx.h     Tue May 17 06:25:00 2016        
(r300008)
@@ -442,18 +442,30 @@ typedef enum efx_link_mode_e {
 
 #define        EFX_MAC_SDU_MAX 9202
 
-#define        EFX_MAC_PDU(_sdu)                               \
-       P2ROUNDUP(((_sdu)                               \
-                   + /* EtherII */ 14                  \
-                   + /* VLAN */ 4                      \
-                   + /* CRC */ 4                       \
-                   + /* bug16011 */ 16),               \
-                   (1 << 3))
+#define        EFX_MAC_PDU_ADJUSTMENT                                  \
+       (/* EtherII */ 14                                       \
+           + /* VLAN */ 4                                      \
+           + /* CRC */ 4                                       \
+           + /* bug16011 */ 16)                                \
+
+#define        EFX_MAC_PDU(_sdu)                                       \
+       P2ROUNDUP((_sdu) + EFX_MAC_PDU_ADJUSTMENT, 8)
+
+/*
+ * Due to the P2ROUNDUP in EFX_MAC_PDU(), EFX_MAC_SDU_FROM_PDU() may give
+ * the SDU rounded up slightly.
+ */
+#define        EFX_MAC_SDU_FROM_PDU(_pdu)      ((_pdu) - 
EFX_MAC_PDU_ADJUSTMENT)
 
 #define        EFX_MAC_PDU_MIN 60
 #define        EFX_MAC_PDU_MAX EFX_MAC_PDU(EFX_MAC_SDU_MAX)
 
 extern __checkReturn   efx_rc_t
+efx_mac_pdu_get(
+       __in            efx_nic_t *enp,
+       __out           size_t *pdu);
+
+extern __checkReturn   efx_rc_t
 efx_mac_pdu_set(
        __in            efx_nic_t *enp,
        __in            size_t pdu);

Modified: head/sys/dev/sfxge/common/efx_impl.h
==============================================================================
--- head/sys/dev/sfxge/common/efx_impl.h        Tue May 17 06:23:50 2016        
(r300007)
+++ head/sys/dev/sfxge/common/efx_impl.h        Tue May 17 06:25:00 2016        
(r300008)
@@ -183,6 +183,7 @@ typedef struct efx_mac_ops_s {
        efx_rc_t        (*emo_up)(efx_nic_t *, boolean_t *);
        efx_rc_t        (*emo_addr_set)(efx_nic_t *);
        efx_rc_t        (*emo_pdu_set)(efx_nic_t *);
+       efx_rc_t        (*emo_pdu_get)(efx_nic_t *, size_t *);
        efx_rc_t        (*emo_reconfigure)(efx_nic_t *);
        efx_rc_t        (*emo_multicast_list_set)(efx_nic_t *);
        efx_rc_t        (*emo_filter_default_rxq_set)(efx_nic_t *,

Modified: head/sys/dev/sfxge/common/efx_mac.c
==============================================================================
--- head/sys/dev/sfxge/common/efx_mac.c Tue May 17 06:23:50 2016        
(r300007)
+++ head/sys/dev/sfxge/common/efx_mac.c Tue May 17 06:25:00 2016        
(r300008)
@@ -48,6 +48,7 @@ static const efx_mac_ops_t    __efx_siena_m
        siena_mac_up,                           /* emo_up */
        siena_mac_reconfigure,                  /* emo_addr_set */
        siena_mac_reconfigure,                  /* emo_pdu_set */
+       siena_mac_pdu_get,                      /* emo_pdu_get */
        siena_mac_reconfigure,                  /* emo_reconfigure */
        siena_mac_multicast_list_set,           /* emo_multicast_list_set */
        NULL,                                   /* emo_filter_set_default_rxq */
@@ -69,6 +70,7 @@ static const efx_mac_ops_t    __efx_ef10_ma
        ef10_mac_up,                            /* emo_up */
        ef10_mac_addr_set,                      /* emo_addr_set */
        ef10_mac_pdu_set,                       /* emo_pdu_set */
+       ef10_mac_pdu_get,                       /* emo_pdu_get */
        ef10_mac_reconfigure,                   /* emo_reconfigure */
        ef10_mac_multicast_list_set,            /* emo_multicast_list_set */
        ef10_mac_filter_default_rxq_set,        /* emo_filter_default_rxq_set */
@@ -85,7 +87,6 @@ static const efx_mac_ops_t    __efx_ef10_ma
 };
 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
 
-
        __checkReturn                   efx_rc_t
 efx_mac_pdu_set(
        __in                            efx_nic_t *enp,
@@ -130,6 +131,26 @@ fail1:
        return (rc);
 }
 
+       __checkReturn   efx_rc_t
+efx_mac_pdu_get(
+       __in            efx_nic_t *enp,
+       __out           size_t *pdu)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       efx_rc_t rc;
+
+       if ((rc = emop->emo_pdu_get(enp, pdu)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
        __checkReturn                   efx_rc_t
 efx_mac_addr_set(
        __in                            efx_nic_t *enp,

Modified: head/sys/dev/sfxge/common/siena_impl.h
==============================================================================
--- head/sys/dev/sfxge/common/siena_impl.h      Tue May 17 06:23:50 2016        
(r300007)
+++ head/sys/dev/sfxge/common/siena_impl.h      Tue May 17 06:25:00 2016        
(r300008)
@@ -388,6 +388,11 @@ extern     __checkReturn   efx_rc_t
 siena_mac_reconfigure(
        __in    efx_nic_t *enp);
 
+extern __checkReturn   efx_rc_t
+siena_mac_pdu_get(
+       __in    efx_nic_t *enp,
+       __out   size_t *pdu);
+
 #if EFSYS_OPT_LOOPBACK
 
 extern __checkReturn   efx_rc_t

Modified: head/sys/dev/sfxge/common/siena_mac.c
==============================================================================
--- head/sys/dev/sfxge/common/siena_mac.c       Tue May 17 06:23:50 2016        
(r300007)
+++ head/sys/dev/sfxge/common/siena_mac.c       Tue May 17 06:25:00 2016        
(r300008)
@@ -432,4 +432,12 @@ siena_mac_stats_update(
 
 #endif /* EFSYS_OPT_MAC_STATS */
 
+       __checkReturn           efx_rc_t
+siena_mac_pdu_get(
+       __in            efx_nic_t *enp,
+       __out           size_t *pdu)
+{
+       return (ENOTSUP);
+}
+
 #endif /* EFSYS_OPT_SIENA */
_______________________________________________
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