Author: hselasky
Date: Mon Oct  7 09:40:57 2019
New Revision: 353236
URL: https://svnweb.freebsd.org/changeset/base/353236

Log:
  MFC r352981:
  Import Linux code to query/set buffer state in mlx5en(4).
  
  Submitted by: kib@
  Sponsored by: Mellanox Technologies

Added:
  stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_port_buffer.c
     - copied unchanged from r352981, 
head/sys/dev/mlx5/mlx5_en/mlx5_en_port_buffer.c
  stable/11/sys/dev/mlx5/mlx5_en/port_buffer.h
     - copied unchanged from r352981, head/sys/dev/mlx5/mlx5_en/port_buffer.h
Modified:
  stable/11/sys/conf/files
  stable/11/sys/dev/mlx5/mlx5_core/mlx5_port.c
  stable/11/sys/dev/mlx5/mlx5_en/en.h
  stable/11/sys/dev/mlx5/port.h
  stable/11/sys/modules/mlx5en/Makefile
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/conf/files
==============================================================================
--- stable/11/sys/conf/files    Mon Oct  7 09:39:05 2019        (r353235)
+++ stable/11/sys/conf/files    Mon Oct  7 09:40:57 2019        (r353236)
@@ -4625,6 +4625,8 @@ dev/mlx5/mlx5_en/mlx5_en_rx.c                     
optional mlx5en pci in
        compile-with "${OFED_C}"
 dev/mlx5/mlx5_en/mlx5_en_txrx.c                        optional mlx5en pci 
inet inet6  \
        compile-with "${OFED_C}"
+dev/mlx5/mlx5_en/mlx5_en_port_buffer.c         optional mlx5en pci inet inet6  
\
+       compile-with "${OFED_C}"
 
 # crypto support
 opencrypto/cast.c              optional crypto | ipsec | ipsec_support

Modified: stable/11/sys/dev/mlx5/mlx5_core/mlx5_port.c
==============================================================================
--- stable/11/sys/dev/mlx5/mlx5_core/mlx5_port.c        Mon Oct  7 09:39:05 
2019        (r353235)
+++ stable/11/sys/dev/mlx5/mlx5_core/mlx5_port.c        Mon Oct  7 09:40:57 
2019        (r353236)
@@ -1236,3 +1236,220 @@ mlx5_set_mfrl_reg(struct mlx5_core_dev *mdev, u8 reset
        return (mlx5_core_access_reg(mdev, mfrl, sz, mfrl, sz, MLX5_REG_MFRL,
            0, 1));
 }
+
+/* speed in units of 1Mb */
+static const u32 mlx5e_link_speed[/*MLX5E_LINK_MODES_NUMBER*/] = {
+       [MLX5E_1000BASE_CX_SGMII] = 1000,
+       [MLX5E_1000BASE_KX]       = 1000,
+       [MLX5E_10GBASE_CX4]       = 10000,
+       [MLX5E_10GBASE_KX4]       = 10000,
+       [MLX5E_10GBASE_KR]        = 10000,
+       [MLX5E_20GBASE_KR2]       = 20000,
+       [MLX5E_40GBASE_CR4]       = 40000,
+       [MLX5E_40GBASE_KR4]       = 40000,
+       [MLX5E_56GBASE_R4]        = 56000,
+       [MLX5E_10GBASE_CR]        = 10000,
+       [MLX5E_10GBASE_SR]        = 10000,
+       [MLX5E_10GBASE_ER_LR]     = 10000,
+       [MLX5E_40GBASE_SR4]       = 40000,
+       [MLX5E_40GBASE_LR4_ER4]   = 40000,
+       [MLX5E_50GBASE_SR2]       = 50000,
+       [MLX5E_100GBASE_CR4]      = 100000,
+       [MLX5E_100GBASE_SR4]      = 100000,
+       [MLX5E_100GBASE_KR4]      = 100000,
+       [MLX5E_100GBASE_LR4]      = 100000,
+       [MLX5E_100BASE_TX]        = 100,
+       [MLX5E_1000BASE_T]        = 1000,
+       [MLX5E_10GBASE_T]         = 10000,
+       [MLX5E_25GBASE_CR]        = 25000,
+       [MLX5E_25GBASE_KR]        = 25000,
+       [MLX5E_25GBASE_SR]        = 25000,
+       [MLX5E_50GBASE_CR2]       = 50000,
+       [MLX5E_50GBASE_KR2]       = 50000,
+};
+
+static const u32 mlx5e_ext_link_speed[/*MLX5E_EXT_LINK_MODES_NUMBER*/] = {
+       [MLX5E_SGMII_100M]                      = 100,
+       [MLX5E_1000BASE_X_SGMII]                = 1000,
+       [MLX5E_5GBASE_R]                        = 5000,
+       [MLX5E_10GBASE_XFI_XAUI_1]              = 10000,
+       [MLX5E_40GBASE_XLAUI_4_XLPPI_4]         = 40000,
+       [MLX5E_25GAUI_1_25GBASE_CR_KR]          = 25000,
+       [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = 50000,
+       [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR]   = 50000,
+       [MLX5E_CAUI_4_100GBASE_CR4_KR4]         = 100000,
+       [MLX5E_200GAUI_4_200GBASE_CR4_KR4]      = 200000,
+       [MLX5E_400GAUI_8]                       = 400000,
+};
+
+static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev,
+                                    const u32 **arr, u32 *size)
+{
+       bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
+
+       *size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) :
+                     ARRAY_SIZE(mlx5e_link_speed);
+       *arr  = ext ? mlx5e_ext_link_speed : mlx5e_link_speed;
+}
+
+u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper)
+{
+       unsigned long temp = eth_proto_oper;
+       const u32 *table;
+       u32 speed = 0;
+       u32 max_size;
+       int i;
+
+       mlx5e_port_get_speed_arr(mdev, &table, &max_size);
+       i = find_first_bit(&temp, max_size);
+       if (i < max_size)
+               speed = table[i];
+       return speed;
+}
+
+int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
+                             struct mlx5e_port_eth_proto *eproto)
+{
+       u32 out[MLX5_ST_SZ_DW(ptys_reg)];
+       int err;
+
+       if (!eproto)
+               return -EINVAL;
+
+       err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, port);
+       if (err)
+               return err;
+
+       eproto->cap   = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
+                                          eth_proto_capability);
+       eproto->admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_admin);
+       eproto->oper  = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_oper);
+       return 0;
+}
+
+int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
+{
+       struct mlx5e_port_eth_proto eproto;
+       bool ext;
+       int err;
+
+       ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
+       err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
+       if (err)
+               goto out;
+
+       *speed = mlx5e_port_ptys2speed(mdev, eproto.oper);
+       if (!(*speed))
+               err = -EINVAL;
+
+out:
+       return err;
+}
+
+int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out)
+{
+       int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
+       void *in;
+       int err;
+
+       in = kzalloc(sz, GFP_KERNEL);
+       if (!in)
+               return -ENOMEM;
+
+       MLX5_SET(pbmc_reg, in, local_port, 1);
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PBMC, 0, 0);
+
+       kfree(in);
+       return err;
+}
+
+int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in)
+{
+       int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
+       void *out;
+       int err;
+
+       out = kzalloc(sz, GFP_KERNEL);
+       if (!out)
+               return -ENOMEM;
+
+       MLX5_SET(pbmc_reg, in, local_port, 1);
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PBMC, 0, 1);
+
+       kfree(out);
+       return err;
+}
+
+/* buffer[i]: buffer that priority i mapped to */
+int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
+{
+       int sz = MLX5_ST_SZ_BYTES(pptb_reg);
+       u32 prio_x_buff;
+       void *out;
+       void *in;
+       int prio;
+       int err;
+
+       in = kzalloc(sz, GFP_KERNEL);
+       out = kzalloc(sz, GFP_KERNEL);
+       if (!in || !out) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       MLX5_SET(pptb_reg, in, local_port, 1);
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 0);
+       if (err)
+               goto out;
+
+       prio_x_buff = MLX5_GET(pptb_reg, out, prio_x_buff);
+       for (prio = 0; prio < 8; prio++) {
+               buffer[prio] = (u8)(prio_x_buff >> (4 * prio)) & 0xF;
+               mlx5_core_dbg(mdev, "prio %d, buffer %d\n", prio, buffer[prio]);
+       }
+out:
+       kfree(in);
+       kfree(out);
+       return err;
+}
+
+int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
+{
+       int sz = MLX5_ST_SZ_BYTES(pptb_reg);
+       u32 prio_x_buff;
+       void *out;
+       void *in;
+       int prio;
+       int err;
+
+       in = kzalloc(sz, GFP_KERNEL);
+       out = kzalloc(sz, GFP_KERNEL);
+       if (!in || !out) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       /* First query the pptb register */
+       MLX5_SET(pptb_reg, in, local_port, 1);
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 0);
+       if (err)
+               goto out;
+
+       memcpy(in, out, sz);
+       MLX5_SET(pptb_reg, in, local_port, 1);
+
+       /* Update the pm and prio_x_buff */
+       MLX5_SET(pptb_reg, in, pm, 0xFF);
+
+       prio_x_buff = 0;
+       for (prio = 0; prio < 8; prio++)
+               prio_x_buff |= (buffer[prio] << (4 * prio));
+       MLX5_SET(pptb_reg, in, prio_x_buff, prio_x_buff);
+
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 1);
+
+out:
+       kfree(in);
+       kfree(out);
+       return err;
+}

Modified: stable/11/sys/dev/mlx5/mlx5_en/en.h
==============================================================================
--- stable/11/sys/dev/mlx5/mlx5_en/en.h Mon Oct  7 09:39:05 2019        
(r353235)
+++ stable/11/sys/dev/mlx5/mlx5_en/en.h Mon Oct  7 09:40:57 2019        
(r353236)
@@ -951,6 +951,11 @@ struct mlx5e_flow_tables {
        struct mlx5e_flow_table inner_rss;
 };
 
+struct mlx5e_dcbx {
+       u32     cable_len;
+       u32     xoff;
+};
+
 struct mlx5e_priv {
        struct mlx5_core_dev *mdev;     /* must be first */
 
@@ -1008,6 +1013,8 @@ struct mlx5e_priv {
        int     media_active_last;
 
        struct callout watchdog;
+
+       struct mlx5e_dcbx dcbx;
 
        struct mlx5e_channel channel[];
 };

Copied: stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_port_buffer.c (from r352981, 
head/sys/dev/mlx5/mlx5_en/mlx5_en_port_buffer.c)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_port_buffer.c        Mon Oct  7 
09:40:57 2019        (r353236, copy of r352981, 
head/sys/dev/mlx5/mlx5_en/mlx5_en_port_buffer.c)
@@ -0,0 +1,328 @@
+/*-
+ * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "port_buffer.h"
+
+#define MLX5E_MAX_PORT_MTU  9216
+
+int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer)
+{
+       struct mlx5_core_dev *mdev = priv->mdev;
+       int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
+       u32 total_used = 0;
+       void *buffer;
+       void *out;
+       int err;
+       int i;
+
+       out = kzalloc(sz, GFP_KERNEL);
+       if (!out)
+               return -ENOMEM;
+
+       err = mlx5e_port_query_pbmc(mdev, out);
+       if (err)
+               goto out;
+
+       for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
+               buffer = MLX5_ADDR_OF(pbmc_reg, out, buffer[i]);
+               port_buffer->buffer[i].lossy =
+                       MLX5_GET(bufferx_reg, buffer, lossy);
+               port_buffer->buffer[i].epsb =
+                       MLX5_GET(bufferx_reg, buffer, epsb);
+               port_buffer->buffer[i].size =
+                       MLX5_GET(bufferx_reg, buffer, size) << 
MLX5E_BUFFER_CELL_SHIFT;
+               port_buffer->buffer[i].xon =
+                       MLX5_GET(bufferx_reg, buffer, xon_threshold) << 
MLX5E_BUFFER_CELL_SHIFT;
+               port_buffer->buffer[i].xoff =
+                       MLX5_GET(bufferx_reg, buffer, xoff_threshold) << 
MLX5E_BUFFER_CELL_SHIFT;
+               total_used += port_buffer->buffer[i].size;
+
+               mlx5e_dbg(HW, priv, "buffer %d: size=%d, xon=%d, xoff=%d, 
epsb=%d, lossy=%d\n", i,
+                         port_buffer->buffer[i].size,
+                         port_buffer->buffer[i].xon,
+                         port_buffer->buffer[i].xoff,
+                         port_buffer->buffer[i].epsb,
+                         port_buffer->buffer[i].lossy);
+       }
+
+       port_buffer->port_buffer_size =
+               MLX5_GET(pbmc_reg, out, port_buffer_size) << 
MLX5E_BUFFER_CELL_SHIFT;
+       port_buffer->spare_buffer_size =
+               port_buffer->port_buffer_size - total_used;
+
+       mlx5e_dbg(HW, priv, "total buffer size=%d, spare buffer size=%d\n",
+                 port_buffer->port_buffer_size,
+                 port_buffer->spare_buffer_size);
+out:
+       kfree(out);
+       return err;
+}
+
+static int port_set_buffer(struct mlx5e_priv *priv,
+                          struct mlx5e_port_buffer *port_buffer)
+{
+       struct mlx5_core_dev *mdev = priv->mdev;
+       int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
+       void *buffer;
+       void *in;
+       int err;
+       int i;
+
+       in = kzalloc(sz, GFP_KERNEL);
+       if (!in)
+               return -ENOMEM;
+
+       err = mlx5e_port_query_pbmc(mdev, in);
+       if (err)
+               goto out;
+
+       for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
+               buffer = MLX5_ADDR_OF(pbmc_reg, in, buffer[i]);
+
+               MLX5_SET(bufferx_reg, buffer, size,
+                        port_buffer->buffer[i].size >> 
MLX5E_BUFFER_CELL_SHIFT);
+               MLX5_SET(bufferx_reg, buffer, lossy,
+                        port_buffer->buffer[i].lossy);
+               MLX5_SET(bufferx_reg, buffer, xoff_threshold,
+                        port_buffer->buffer[i].xoff >> 
MLX5E_BUFFER_CELL_SHIFT);
+               MLX5_SET(bufferx_reg, buffer, xon_threshold,
+                        port_buffer->buffer[i].xon >> MLX5E_BUFFER_CELL_SHIFT);
+       }
+
+       err = mlx5e_port_set_pbmc(mdev, in);
+out:
+       kfree(in);
+       return err;
+}
+
+/* xoff = ((301+2.16 * len [m]) * speed [Gbps] + 2.72 MTU [B]) */
+static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu)
+{
+       u32 speed;
+       u32 xoff;
+       int err;
+
+       err = mlx5e_port_linkspeed(priv->mdev, &speed);
+       if (err) {
+               mlx5_core_warn(priv->mdev, "cannot get port speed\n");
+               speed = SPEED_40000;
+       }
+       speed = max_t(u32, speed, SPEED_40000);
+       xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * 
mtu / 100;
+
+       mlx5e_dbg(HW, priv, "%s: xoff=%d\n", __func__, xoff);
+       return xoff;
+}
+
+static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
+                                u32 xoff)
+{
+       int i;
+
+       for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
+               if (port_buffer->buffer[i].lossy) {
+                       port_buffer->buffer[i].xoff = 0;
+                       port_buffer->buffer[i].xon  = 0;
+                       continue;
+               }
+
+               if (port_buffer->buffer[i].size <
+                   (xoff + MLX5E_MAX_PORT_MTU + (1 << 
MLX5E_BUFFER_CELL_SHIFT)))
+                       return -ENOMEM;
+
+               port_buffer->buffer[i].xoff = port_buffer->buffer[i].size - 
xoff;
+               port_buffer->buffer[i].xon  = 
+                       port_buffer->buffer[i].xoff - MLX5E_MAX_PORT_MTU;
+       }
+
+       return 0;
+}
+
+/**
+ * update_buffer_lossy()
+ *   mtu: device's MTU
+ *   pfc_en: <input> current pfc configuration
+ *   buffer: <input> current prio to buffer mapping
+ *   xoff:   <input> xoff value
+ *   port_buffer: <output> port receive buffer configuration
+ *   change: <output>
+ *
+ *   Update buffer configuration based on pfc configuraiton and priority
+ *   to buffer mapping.
+ *   Buffer's lossy bit is changed to:
+ *     lossless if there is at least one PFC enabled priority mapped to this 
buffer
+ *     lossy if all priorities mapped to this buffer are PFC disabled
+ *
+ *   Return:
+ *     Return 0 if no error.
+ *     Set change to true if buffer configuration is modified.
+ */
+static int update_buffer_lossy(unsigned int mtu,
+                              u8 pfc_en, u8 *buffer, u32 xoff,
+                              struct mlx5e_port_buffer *port_buffer,
+                              bool *change)
+{
+       bool changed = false;
+       u8 lossy_count;
+       u8 prio_count;
+       u8 lossy;
+       int prio;
+       int err;
+       int i;
+
+       for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
+               prio_count = 0;
+               lossy_count = 0;
+
+               for (prio = 0; prio < MLX5E_MAX_PRIORITY; prio++) {
+                       if (buffer[prio] != i)
+                               continue;
+
+                       prio_count++;
+                       lossy_count += !(pfc_en & (1 << prio));
+               }
+
+               if (lossy_count == prio_count)
+                       lossy = 1;
+               else /* lossy_count < prio_count */
+                       lossy = 0;
+
+               if (lossy != port_buffer->buffer[i].lossy) {
+                       port_buffer->buffer[i].lossy = lossy;
+                       changed = true;
+               }
+       }
+
+       if (changed) {
+               err = update_xoff_threshold(port_buffer, xoff);
+               if (err)
+                       return err;
+
+               *change = true;
+       }
+
+       return 0;
+}
+
+int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer)
+{
+       struct mlx5e_port_buffer port_buffer;
+       u32 xoff = calculate_xoff(priv, mtu);
+       bool update_prio2buffer = false;
+       u8 buffer[MLX5E_MAX_PRIORITY];
+       bool update_buffer = false;
+       u32 total_used = 0;
+       u8 curr_pfc_en;
+       int err;
+       int i;
+
+       mlx5e_dbg(HW, priv, "%s: change=%x\n", __func__, change);
+
+       err = mlx5e_port_query_buffer(priv, &port_buffer);
+       if (err)
+               return err;
+
+       if (change & MLX5E_PORT_BUFFER_CABLE_LEN) {
+               update_buffer = true;
+               err = update_xoff_threshold(&port_buffer, xoff);
+               if (err)
+                       return err;
+       }
+
+       if (change & MLX5E_PORT_BUFFER_PFC) {
+               err = mlx5e_port_query_priority2buffer(priv->mdev, buffer);
+               if (err)
+                       return err;
+
+               err = update_buffer_lossy(mtu, pfc->pfc_en, buffer, xoff,
+                                         &port_buffer, &update_buffer);
+               if (err)
+                       return err;
+       }
+
+       if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) {
+               update_prio2buffer = true;
+               err = mlx5_query_port_pfc(priv->mdev, &curr_pfc_en, NULL);
+               if (err)
+                       return err;
+
+               err = update_buffer_lossy(mtu, curr_pfc_en, prio2buffer, xoff,
+                                         &port_buffer, &update_buffer);
+               if (err)
+                       return err;
+       }
+
+       if (change & MLX5E_PORT_BUFFER_SIZE) {
+               for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
+                       mlx5e_dbg(HW, priv, "%s: buffer[%d]=%d\n", __func__, i, 
buffer_size[i]);
+                       if (!port_buffer.buffer[i].lossy && !buffer_size[i]) {
+                               mlx5e_dbg(HW, priv, "%s: lossless buffer[%d] 
size cannot be zero\n",
+                                         __func__, i);
+                               return -EINVAL;
+                       }
+
+                       port_buffer.buffer[i].size = buffer_size[i];
+                       total_used += buffer_size[i];
+               }
+
+               mlx5e_dbg(HW, priv, "%s: total buffer requested=%d\n", 
__func__, total_used);
+
+               if (total_used > port_buffer.port_buffer_size)
+                       return -EINVAL;
+
+               update_buffer = true;
+               err = update_xoff_threshold(&port_buffer, xoff);
+               if (err)
+                       return err;
+       }
+
+       /* Need to update buffer configuration if xoff value is changed */
+       if (!update_buffer && xoff != priv->dcbx.xoff) {
+               update_buffer = true;
+               err = update_xoff_threshold(&port_buffer, xoff);
+               if (err)
+                       return err;
+       }
+       priv->dcbx.xoff = xoff;
+
+       /* Apply the settings */
+       if (update_buffer) {
+               err = port_set_buffer(priv, &port_buffer);
+               if (err)
+                       return err;
+       }
+
+       if (update_prio2buffer)
+               err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+
+       return err;
+}

Copied: stable/11/sys/dev/mlx5/mlx5_en/port_buffer.h (from r352981, 
head/sys/dev/mlx5/mlx5_en/port_buffer.h)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ stable/11/sys/dev/mlx5/mlx5_en/port_buffer.h        Mon Oct  7 09:40:57 
2019        (r353236, copy of r352981, head/sys/dev/mlx5/mlx5_en/port_buffer.h)
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __MLX5_EN_PORT_BUFFER_H__
+#define __MLX5_EN_PORT_BUFFER_H__
+
+#include "en.h"
+#include <dev/mlx5/port.h>
+
+#define MLX5E_MAX_BUFFER 8
+#define MLX5E_BUFFER_CELL_SHIFT 7
+#define MLX5E_DEFAULT_CABLE_LEN 7 /* 7 meters */
+
+#define MLX5_BUFFER_SUPPORTED(mdev) (MLX5_CAP_GEN(mdev, pcam_reg) && \
+                                    MLX5_CAP_PCAM_REG(mdev, pbmc) && \
+                                    MLX5_CAP_PCAM_REG(mdev, pptb))
+
+enum {
+       MLX5E_PORT_BUFFER_CABLE_LEN   = BIT(0),
+       MLX5E_PORT_BUFFER_PFC         = BIT(1),
+       MLX5E_PORT_BUFFER_PRIO2BUFFER = BIT(2),
+       MLX5E_PORT_BUFFER_SIZE        = BIT(3),
+};
+
+struct mlx5e_bufferx_reg {
+       u8   lossy;
+       u8   epsb;
+       u32  size;
+       u32  xoff;
+       u32  xon;
+};
+
+struct mlx5e_port_buffer {
+       u32                       port_buffer_size;
+       u32                       spare_buffer_size;
+       struct mlx5e_bufferx_reg  buffer[MLX5E_MAX_BUFFER];
+};
+
+#define        IEEE_8021QAZ_MAX_TCS    8
+
+struct ieee_pfc {
+       __u8    pfc_cap;
+       __u8    pfc_en;
+       __u8    mbc;
+       __u16   delay;
+       __u64   requests[IEEE_8021QAZ_MAX_TCS];
+       __u64   indications[IEEE_8021QAZ_MAX_TCS];
+};
+
+int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+                                   u32 change, unsigned int mtu,
+                                   struct ieee_pfc *pfc,
+                                   u32 *buffer_size,
+                                   u8 *prio2buffer);
+
+int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+                           struct mlx5e_port_buffer *port_buffer);
+#endif

Modified: stable/11/sys/dev/mlx5/port.h
==============================================================================
--- stable/11/sys/dev/mlx5/port.h       Mon Oct  7 09:39:05 2019        
(r353235)
+++ stable/11/sys/dev/mlx5/port.h       Mon Oct  7 09:40:57 2019        
(r353236)
@@ -179,7 +179,16 @@ enum mlx5_qpts_trust_state {
        MLX5_QPTS_TRUST_DSCP = 2,
        MLX5_QPTS_TRUST_BOTH = 3,
 };
+struct mlx5e_port_eth_proto {
+       u32 cap;
+       u32 admin;
+       u32 oper;
+};
 
+#ifndef SPEED_40000
+#define SPEED_40000 40000
+#endif
+
 #define        MLX5E_PROT_MASK(link_mode) (1 << (link_mode))
 
 #define        PORT_MODULE_EVENT_MODULE_STATUS_MASK 0xF
@@ -251,5 +260,15 @@ int mlx5_set_dscp2prio(struct mlx5_core_dev *mdev, con
 int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio);
 
 int mlx5_query_pddr_range_info(struct mlx5_core_dev *mdev, u8 local_port, u8 
*is_er_type);
+
+u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper);
+int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
+int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
+                             struct mlx5e_port_eth_proto *eproto);
+
+int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out);
+int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in);
+int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer);
+int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer);
 
 #endif /* __MLX5_PORT_H__ */

Modified: stable/11/sys/modules/mlx5en/Makefile
==============================================================================
--- stable/11/sys/modules/mlx5en/Makefile       Mon Oct  7 09:39:05 2019        
(r353235)
+++ stable/11/sys/modules/mlx5en/Makefile       Mon Oct  7 09:40:57 2019        
(r353236)
@@ -10,6 +10,7 @@ mlx5_en_tx.c \
 mlx5_en_flow_table.c \
 mlx5_en_rx.c \
 mlx5_en_txrx.c \
+mlx5_en_port_buffer.c \
 device_if.h bus_if.h vnode_if.h pci_if.h \
         opt_inet.h opt_inet6.h opt_rss.h
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to