Author: hselasky
Date: Wed Jan 27 14:55:41 2016
New Revision: 294917
URL: https://svnweb.freebsd.org/changeset/base/294917

Log:
  MFC r294314:
  Allow RX and TX pause frames to be set through ifconfig.
  
  Sponsored by: Mellanox Technologies
  Differential Revision:        https://reviews.freebsd.org/D4817

Modified:
  stable/10/sys/dev/mlx5/mlx5_en/en.h
  stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
  stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/mlx5/mlx5_en/en.h
==============================================================================
--- stable/10/sys/dev/mlx5/mlx5_en/en.h Wed Jan 27 14:47:00 2016        
(r294916)
+++ stable/10/sys/dev/mlx5/mlx5_en/en.h Wed Jan 27 14:55:41 2016        
(r294917)
@@ -375,11 +375,11 @@ struct mlx5e_params {
        bool    cqe_zipping_en;
        u32     lro_wqe_sz;
        u16     rx_hash_log_tbl_sz;
+       u32     tx_pauseframe_control;
+       u32     rx_pauseframe_control;
 };
 
 #define        MLX5E_PARAMS(m)                                                 
\
-  m(+1, u64 tx_pauseframe_control, "tx_pauseframe_control", "Set to enable TX 
pause frames. Clear to disable.") \
-  m(+1, u64 rx_pauseframe_control, "rx_pauseframe_control", "Set to enable RX 
pause frames. Clear to disable.") \
   m(+1, u64 tx_queue_size_max, "tx_queue_size_max", "Max send queue size") \
   m(+1, u64 rx_queue_size_max, "rx_queue_size_max", "Max receive queue size") \
   m(+1, u64 tx_queue_size, "tx_queue_size", "Default send queue size") \

Modified: stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
==============================================================================
--- stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c    Wed Jan 27 14:47:00 
2016        (r294916)
+++ stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c    Wed Jan 27 14:55:41 
2016        (r294917)
@@ -113,21 +113,6 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARG
        }
        priv->params.tx_cq_moderation_pkts = 
priv->params_ethtool.tx_coalesce_pkts;
 
-       if (&priv->params_ethtool.arg[arg2] == 
&priv->params_ethtool.rx_pauseframe_control ||
-           &priv->params_ethtool.arg[arg2] == 
&priv->params_ethtool.tx_pauseframe_control) {
-               /* range check parameters */
-               priv->params_ethtool.rx_pauseframe_control =
-                   priv->params_ethtool.rx_pauseframe_control ? 1 : 0;
-               priv->params_ethtool.tx_pauseframe_control =
-                   priv->params_ethtool.tx_pauseframe_control ? 1 : 0;
-
-               /* update firmware */
-               error = -mlx5_set_port_pause(priv->mdev, 1,
-                   priv->params_ethtool.rx_pauseframe_control,
-                   priv->params_ethtool.tx_pauseframe_control);
-               goto done;
-       }
-
        was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
        if (was_opened) {
                u64 *xarg = priv->params_ethtool.arg + arg2;

Modified: stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
==============================================================================
--- stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c       Wed Jan 27 14:47:00 
2016        (r294916)
+++ stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c       Wed Jan 27 14:55:41 
2016        (r294917)
@@ -222,8 +222,8 @@ mlx5e_media_status(struct ifnet *dev, st
 
        ifmr->ifm_status = priv->media_status_last;
        ifmr->ifm_active = priv->media_active_last |
-           (priv->params_ethtool.rx_pauseframe_control ? IFM_ETH_RXPAUSE : 0) |
-           (priv->params_ethtool.tx_pauseframe_control ? IFM_ETH_TXPAUSE : 0);
+           (priv->params.rx_pauseframe_control ? IFM_ETH_RXPAUSE : 0) |
+           (priv->params.tx_pauseframe_control ? IFM_ETH_TXPAUSE : 0);
 
 }
 
@@ -250,6 +250,7 @@ mlx5e_media_change(struct ifnet *dev)
        struct mlx5_core_dev *mdev = priv->mdev;
        u32 eth_proto_cap;
        u32 link_mode;
+       int was_opened;
        int locked;
        int error;
 
@@ -263,24 +264,45 @@ mlx5e_media_change(struct ifnet *dev)
        }
        link_mode = mlx5e_find_link_mode(IFM_SUBTYPE(priv->media.ifm_media));
 
+       /* query supported capabilities */
        error = mlx5_query_port_proto_cap(mdev, &eth_proto_cap, MLX5_PTYS_EN);
-       if (error) {
+       if (error != 0) {
                if_printf(dev, "Query port media capability failed\n");
                goto done;
        }
-       if (IFM_SUBTYPE(priv->media.ifm_media) == IFM_AUTO)
+       /* check for autoselect */
+       if (IFM_SUBTYPE(priv->media.ifm_media) == IFM_AUTO) {
                link_mode = eth_proto_cap;
-       else
+               if (link_mode == 0) {
+                       if_printf(dev, "Port media capability is zero\n");
+                       error = EINVAL;
+                       goto done;
+               }
+       } else {
                link_mode = link_mode & eth_proto_cap;
-
-       if (!link_mode) {
-               if_printf(dev, "Not supported link mode requested\n");
-               error = EINVAL;
-               goto done;
+               if (link_mode == 0) {
+                       if_printf(dev, "Not supported link mode requested\n");
+                       error = EINVAL;
+                       goto done;
+               }
        }
+       /* update pauseframe control bits */
+       priv->params.rx_pauseframe_control =
+           (priv->media.ifm_media & IFM_ETH_RXPAUSE) ? 1 : 0;
+       priv->params.tx_pauseframe_control =
+           (priv->media.ifm_media & IFM_ETH_TXPAUSE) ? 1 : 0;
+
+       /* check if device is opened */
+       was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
+
+       /* reconfigure the hardware */
        mlx5_set_port_status(mdev, MLX5_PORT_DOWN);
        mlx5_set_port_proto(mdev, link_mode, MLX5_PTYS_EN);
-       mlx5_set_port_status(mdev, MLX5_PORT_UP);
+       mlx5_set_port_pause(mdev, 1,
+           priv->params.rx_pauseframe_control,
+           priv->params.tx_pauseframe_control);
+       if (was_opened)
+               mlx5_set_port_status(mdev, MLX5_PORT_UP);
 
 done:
        if (!locked)
@@ -2749,6 +2771,56 @@ mlx5e_add_hw_stats(struct mlx5e_priv *pr
            "Board ID");
 }
 
+static void
+mlx5e_setup_pauseframes(struct mlx5e_priv *priv)
+{
+#if (__FreeBSD_version < 1100000)
+       char path[64];
+
+#endif
+       /* Only receiving pauseframes is enabled by default */
+       priv->params.tx_pauseframe_control = 0;
+       priv->params.rx_pauseframe_control = 1;
+
+#if (__FreeBSD_version < 1100000)
+       /* compute path for sysctl */
+       snprintf(path, sizeof(path), "dev.mce.%d.tx_pauseframe_control",
+           device_get_unit(priv->mdev->pdev->dev.bsddev));
+
+       /* try to fetch tunable, if any */
+       TUNABLE_INT_FETCH(path, &priv->params.tx_pauseframe_control);
+
+       /* compute path for sysctl */
+       snprintf(path, sizeof(path), "dev.mce.%d.rx_pauseframe_control",
+           device_get_unit(priv->mdev->pdev->dev.bsddev));
+
+       /* try to fetch tunable, if any */
+       TUNABLE_INT_FETCH(path, &priv->params.rx_pauseframe_control);
+#endif
+
+       /* register pausframe SYSCTLs */
+       SYSCTL_ADD_INT(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
+           OID_AUTO, "tx_pauseframe_control", CTLFLAG_RDTUN,
+           &priv->params.tx_pauseframe_control, 0,
+           "Set to enable TX pause frames. Clear to disable.");
+
+       SYSCTL_ADD_INT(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
+           OID_AUTO, "rx_pauseframe_control", CTLFLAG_RDTUN,
+           &priv->params.rx_pauseframe_control, 0,
+           "Set to enable RX pause frames. Clear to disable.");
+
+       /* range check */
+       priv->params.tx_pauseframe_control =
+           priv->params.tx_pauseframe_control ? 1 : 0;
+       priv->params.rx_pauseframe_control =
+           priv->params.rx_pauseframe_control ? 1 : 0;
+
+       /* update firmware */
+       mlx5_set_port_pause(priv->mdev, 1,
+           priv->params.rx_pauseframe_control,
+           priv->params.tx_pauseframe_control);
+}
+
 static void *
 mlx5e_create_ifp(struct mlx5_core_dev *mdev)
 {
@@ -2874,11 +2946,11 @@ mlx5e_create_ifp(struct mlx5_core_dev *m
 
        /* Set default media status */
        priv->media_status_last = IFM_AVALID;
-       priv->media_active_last = IFM_ETHER | IFM_AUTO;
+       priv->media_active_last = IFM_ETHER | IFM_AUTO |
+           IFM_ETH_RXPAUSE | IFM_FDX;
 
-       /* Pauseframes are enabled by default */
-       priv->params_ethtool.tx_pauseframe_control = 1;
-       priv->params_ethtool.rx_pauseframe_control = 1;
+       /* setup default pauseframes configuration */
+       mlx5e_setup_pauseframes(priv);
 
        err = mlx5_query_port_proto_cap(mdev, &eth_proto_cap, MLX5_PTYS_EN);
        if (err) {
@@ -2894,14 +2966,24 @@ mlx5e_create_ifp(struct mlx5_core_dev *m
        for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
                if (mlx5e_mode_table[i].baudrate == 0)
                        continue;
-               if (MLX5E_PROT_MASK(i) & eth_proto_cap)
+               if (MLX5E_PROT_MASK(i) & eth_proto_cap) {
                        ifmedia_add(&priv->media,
-                           IFM_ETHER | mlx5e_mode_table[i].subtype |
-                           IFM_FDX, 0, NULL);
+                           mlx5e_mode_table[i].subtype |
+                           IFM_ETHER, 0, NULL);
+                       ifmedia_add(&priv->media,
+                           mlx5e_mode_table[i].subtype |
+                           IFM_ETHER | IFM_FDX |
+                           IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE, 0, NULL);
+               }
        }
 
        ifmedia_add(&priv->media, IFM_ETHER | IFM_AUTO, 0, NULL);
-       ifmedia_set(&priv->media, IFM_ETHER | IFM_AUTO);
+       ifmedia_add(&priv->media, IFM_ETHER | IFM_AUTO | IFM_FDX |
+           IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE, 0, NULL);
+
+       /* Set autoselect by default */
+       ifmedia_set(&priv->media, IFM_ETHER | IFM_AUTO | IFM_FDX |
+           IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE);
        ether_ifattach(ifp, dev_addr);
 
        /* Register for VLAN events */
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to