The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/mlx5/mlx5_fpga/mlx5fpga_cmd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2017, Mellanox Technologies. All rights reserved.
    3  *
    4  * This software is available to you under a choice of one of two
    5  * licenses.  You may choose to be licensed under the terms of the GNU
    6  * General Public License (GPL) Version 2, available from the file
    7  * COPYING in the main directory of this source tree, or the
    8  * OpenIB.org BSD license below:
    9  *
   10  *     Redistribution and use in source and binary forms, with or
   11  *     without modification, are permitted provided that the following
   12  *     conditions are met:
   13  *
   14  *      - Redistributions of source code must retain the above
   15  *        copyright notice, this list of conditions and the following
   16  *        disclaimer.
   17  *
   18  *      - Redistributions in binary form must reproduce the above
   19  *        copyright notice, this list of conditions and the following
   20  *        disclaimer in the documentation and/or other materials
   21  *        provided with the distribution.
   22  *
   23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   30  * SOFTWARE.
   31  *
   32  * $FreeBSD$
   33  */
   34 
   35 #include <dev/mlx5/cmd.h>
   36 #include <dev/mlx5/driver.h>
   37 #include <dev/mlx5/device.h>
   38 #include <dev/mlx5/mlx5_core/mlx5_core.h>
   39 #include <dev/mlx5/mlx5_fpga/cmd.h>
   40 #include <dev/mlx5/mlx5_fpga/core.h>
   41 
   42 #define MLX5_FPGA_ACCESS_REG_SZ (MLX5_ST_SZ_DW(fpga_access_reg) + \
   43                                  MLX5_FPGA_ACCESS_REG_SIZE_MAX)
   44 
   45 int mlx5_fpga_access_reg(struct mlx5_core_dev *dev, u8 size, u64 addr,
   46                          void *buf, bool write)
   47 {
   48         u32 in[MLX5_FPGA_ACCESS_REG_SZ] = {0};
   49         u32 out[MLX5_FPGA_ACCESS_REG_SZ];
   50         int err;
   51 
   52         if (size & 3)
   53                 return -EINVAL;
   54         if (addr & 3)
   55                 return -EINVAL;
   56         if (size > MLX5_FPGA_ACCESS_REG_SIZE_MAX)
   57                 return -EINVAL;
   58 
   59         MLX5_SET(fpga_access_reg, in, size, size);
   60         MLX5_SET64(fpga_access_reg, in, address, addr);
   61         if (write)
   62                 memcpy(MLX5_ADDR_OF(fpga_access_reg, in, data), buf, size);
   63 
   64         err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
   65                                    MLX5_REG_FPGA_ACCESS_REG, 0, write);
   66         if (err)
   67                 return err;
   68 
   69         if (!write)
   70                 memcpy(buf, MLX5_ADDR_OF(fpga_access_reg, out, data), size);
   71 
   72         return 0;
   73 }
   74 
   75 int mlx5_fpga_caps(struct mlx5_core_dev *dev)
   76 {
   77         u32 in[MLX5_ST_SZ_DW(fpga_cap)] = {0};
   78 
   79         return mlx5_core_access_reg(dev, in, sizeof(in), dev->caps.fpga,
   80                                     MLX5_ST_SZ_BYTES(fpga_cap),
   81                                     MLX5_REG_FPGA_CAP, 0, 0);
   82 }
   83 
   84 int mlx5_fpga_ctrl_op(struct mlx5_core_dev *dev, u8 op)
   85 {
   86         u32 in[MLX5_ST_SZ_DW(fpga_ctrl)] = {0};
   87         u32 out[MLX5_ST_SZ_DW(fpga_ctrl)];
   88 
   89         MLX5_SET(fpga_ctrl, in, operation, op);
   90 
   91         return mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
   92                                     MLX5_REG_FPGA_CTRL, 0, true);
   93 }
   94 
   95 int mlx5_fpga_sbu_caps(struct mlx5_core_dev *dev, void *caps, int size)
   96 {
   97         unsigned int cap_size = MLX5_CAP_FPGA(dev, sandbox_extended_caps_len);
   98         u64 addr = MLX5_CAP64_FPGA(dev, sandbox_extended_caps_addr);
   99         unsigned int read;
  100         int ret = 0;
  101 
  102         if (cap_size > size) {
  103                 mlx5_core_warn(dev, "Not enough buffer %u for FPGA SBU caps %u",
  104                                size, cap_size);
  105                 return -EINVAL;
  106         }
  107 
  108         while (cap_size > 0) {
  109                 read = min_t(unsigned int, cap_size,
  110                              MLX5_FPGA_ACCESS_REG_SIZE_MAX);
  111 
  112                 ret = mlx5_fpga_access_reg(dev, read, addr, caps, false);
  113                 if (ret) {
  114                         mlx5_core_warn(dev, "Error reading FPGA SBU caps %u bytes at address %#jx: %d",
  115                                        read, (uintmax_t)addr, ret);
  116                         return ret;
  117                 }
  118 
  119                 cap_size -= read;
  120                 addr += read;
  121                 caps += read;
  122         }
  123 
  124         return ret;
  125 }
  126 
  127 static int mlx5_fpga_ctrl_write(struct mlx5_core_dev *dev, u8 op,
  128                                 enum mlx5_fpga_image image)
  129 {
  130         u32 in[MLX5_ST_SZ_DW(fpga_ctrl)] = {0};
  131         u32 out[MLX5_ST_SZ_DW(fpga_ctrl)];
  132 
  133         MLX5_SET(fpga_ctrl, in, operation, op);
  134         MLX5_SET(fpga_ctrl, in, flash_select_admin, image);
  135 
  136         return mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
  137                                     MLX5_REG_FPGA_CTRL, 0, true);
  138 }
  139 
  140 int mlx5_fpga_load(struct mlx5_core_dev *dev, enum mlx5_fpga_image image)
  141 {
  142         return mlx5_fpga_ctrl_write(dev, MLX5_FPGA_CTRL_OPERATION_LOAD, image);
  143 }
  144 
  145 int mlx5_fpga_image_select(struct mlx5_core_dev *dev,
  146                            enum mlx5_fpga_image image)
  147 {
  148         return mlx5_fpga_ctrl_write(dev, MLX5_FPGA_CTRL_OPERATION_FLASH_SELECT, image);
  149 }
  150 
  151 int mlx5_fpga_query(struct mlx5_core_dev *dev, struct mlx5_fpga_query *query)
  152 {
  153         u32 in[MLX5_ST_SZ_DW(fpga_ctrl)] = {0};
  154         u32 out[MLX5_ST_SZ_DW(fpga_ctrl)];
  155         int err;
  156 
  157         err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
  158                                    MLX5_REG_FPGA_CTRL, 0, false);
  159         if (err)
  160                 return err;
  161 
  162         query->image_status = MLX5_GET(fpga_ctrl, out, status);
  163         query->admin_image = MLX5_GET(fpga_ctrl, out, flash_select_admin);
  164         query->oper_image = MLX5_GET(fpga_ctrl, out, flash_select_oper);
  165         return 0;
  166 }
  167 
  168 int mlx5_fpga_ctrl_connect(struct mlx5_core_dev *dev,
  169                            enum mlx5_fpga_connect *connect)
  170 {
  171         u32 in[MLX5_ST_SZ_DW(fpga_ctrl)] = {0};
  172         u32 out[MLX5_ST_SZ_DW(fpga_ctrl)];
  173         int status;
  174         int err;
  175 
  176         if (*connect == MLX5_FPGA_CONNECT_QUERY) {
  177                 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
  178                                            sizeof(out), MLX5_REG_FPGA_CTRL,
  179                                            0, false);
  180                 if (err)
  181                         return err;
  182                 status = MLX5_GET(fpga_ctrl, out, status);
  183                 *connect = (status == MLX5_FDEV_STATE_DISCONNECTED) ?
  184                         MLX5_FPGA_CONNECT_DISCONNECT :
  185                         MLX5_FPGA_CONNECT_CONNECT;
  186         } else {
  187                 MLX5_SET(fpga_ctrl, in, operation, *connect);
  188                 err = mlx5_core_access_reg(dev, in, sizeof(in), out,
  189                                            sizeof(out), MLX5_REG_FPGA_CTRL,
  190                                            0, true);
  191         }
  192         return err;
  193 }
  194 
  195 int mlx5_fpga_query_mtmp(struct mlx5_core_dev *dev,
  196                          struct mlx5_fpga_temperature *temp)
  197 {
  198         u32 in[MLX5_ST_SZ_DW(mtmp_reg)] = {0};
  199         u32 out[MLX5_ST_SZ_DW(mtmp_reg)] = {0};
  200         int err;
  201 
  202         MLX5_SET(mtmp_reg, in, sensor_index, temp->index);
  203         MLX5_SET(mtmp_reg, in, i,
  204                  ((temp->index < MLX5_FPGA_INTERNAL_SENSORS_LOW) ||
  205                  (temp->index > MLX5_FPGA_INTERNAL_SENSORS_HIGH)) ? 1 : 0);
  206 
  207         err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
  208                                    MLX5_REG_MTMP, 0, false);
  209         if (err)
  210                 return err;
  211 
  212         temp->index = MLX5_GET(mtmp_reg, out, sensor_index);
  213         temp->temperature = MLX5_GET(mtmp_reg, out, temperature);
  214         temp->mte = MLX5_GET(mtmp_reg, out, mte);
  215         temp->max_temperature = MLX5_GET(mtmp_reg, out, max_temperature);
  216         temp->tee = MLX5_GET(mtmp_reg, out, tee);
  217         temp->temperature_threshold_hi = MLX5_GET(mtmp_reg, out,
  218                 temperature_threshold_hi);
  219         temp->temperature_threshold_lo = MLX5_GET(mtmp_reg, out,
  220                 temperature_threshold_lo);
  221         memcpy(temp->sensor_name, MLX5_ADDR_OF(mtmp_reg, out, sensor_name),
  222                MLX5_FLD_SZ_BYTES(mtmp_reg, sensor_name));
  223 
  224         return 0;
  225 }
  226 
  227 int mlx5_fpga_create_qp(struct mlx5_core_dev *dev, void *fpga_qpc,
  228                         u32 *fpga_qpn)
  229 {
  230         u32 in[MLX5_ST_SZ_DW(fpga_create_qp_in)] = {0};
  231         u32 out[MLX5_ST_SZ_DW(fpga_create_qp_out)];
  232         int ret;
  233 
  234         MLX5_SET(fpga_create_qp_in, in, opcode, MLX5_CMD_OP_FPGA_CREATE_QP);
  235         memcpy(MLX5_ADDR_OF(fpga_create_qp_in, in, fpga_qpc), fpga_qpc,
  236                MLX5_FLD_SZ_BYTES(fpga_create_qp_in, fpga_qpc));
  237 
  238         ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  239         if (ret)
  240                 return ret;
  241 
  242         memcpy(fpga_qpc, MLX5_ADDR_OF(fpga_create_qp_out, out, fpga_qpc),
  243                MLX5_FLD_SZ_BYTES(fpga_create_qp_out, fpga_qpc));
  244         *fpga_qpn = MLX5_GET(fpga_create_qp_out, out, fpga_qpn);
  245         return ret;
  246 }
  247 
  248 int mlx5_fpga_modify_qp(struct mlx5_core_dev *dev, u32 fpga_qpn,
  249                         enum mlx5_fpga_qpc_field_select fields,
  250                         void *fpga_qpc)
  251 {
  252         u32 in[MLX5_ST_SZ_DW(fpga_modify_qp_in)] = {0};
  253         u32 out[MLX5_ST_SZ_DW(fpga_modify_qp_out)];
  254 
  255         MLX5_SET(fpga_modify_qp_in, in, opcode, MLX5_CMD_OP_FPGA_MODIFY_QP);
  256         MLX5_SET(fpga_modify_qp_in, in, field_select, fields);
  257         MLX5_SET(fpga_modify_qp_in, in, fpga_qpn, fpga_qpn);
  258         memcpy(MLX5_ADDR_OF(fpga_modify_qp_in, in, fpga_qpc), fpga_qpc,
  259                MLX5_FLD_SZ_BYTES(fpga_modify_qp_in, fpga_qpc));
  260 
  261         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  262 }
  263 
  264 int mlx5_fpga_query_qp(struct mlx5_core_dev *dev,
  265                        u32 fpga_qpn, void *fpga_qpc)
  266 {
  267         u32 in[MLX5_ST_SZ_DW(fpga_query_qp_in)] = {0};
  268         u32 out[MLX5_ST_SZ_DW(fpga_query_qp_out)];
  269         int ret;
  270 
  271         MLX5_SET(fpga_query_qp_in, in, opcode, MLX5_CMD_OP_FPGA_QUERY_QP);
  272         MLX5_SET(fpga_query_qp_in, in, fpga_qpn, fpga_qpn);
  273 
  274         ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  275         if (ret)
  276                 return ret;
  277 
  278         memcpy(fpga_qpc, MLX5_ADDR_OF(fpga_query_qp_out, out, fpga_qpc),
  279                MLX5_FLD_SZ_BYTES(fpga_query_qp_out, fpga_qpc));
  280         return ret;
  281 }
  282 
  283 int mlx5_fpga_destroy_qp(struct mlx5_core_dev *dev, u32 fpga_qpn)
  284 {
  285         u32 in[MLX5_ST_SZ_DW(fpga_destroy_qp_in)] = {0};
  286         u32 out[MLX5_ST_SZ_DW(fpga_destroy_qp_out)];
  287 
  288         MLX5_SET(fpga_destroy_qp_in, in, opcode, MLX5_CMD_OP_FPGA_DESTROY_QP);
  289         MLX5_SET(fpga_destroy_qp_in, in, fpga_qpn, fpga_qpn);
  290 
  291         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  292 }
  293 
  294 int mlx5_fpga_query_qp_counters(struct mlx5_core_dev *dev, u32 fpga_qpn,
  295                                 bool clear, struct mlx5_fpga_qp_counters *data)
  296 {
  297         u32 in[MLX5_ST_SZ_DW(fpga_query_qp_counters_in)] = {0};
  298         u32 out[MLX5_ST_SZ_DW(fpga_query_qp_counters_out)];
  299         int ret;
  300 
  301         MLX5_SET(fpga_query_qp_counters_in, in, opcode,
  302                  MLX5_CMD_OP_FPGA_QUERY_QP_COUNTERS);
  303         MLX5_SET(fpga_query_qp_counters_in, in, clear, clear);
  304         MLX5_SET(fpga_query_qp_counters_in, in, fpga_qpn, fpga_qpn);
  305 
  306         ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  307         if (ret)
  308                 return ret;
  309 
  310         data->rx_ack_packets = MLX5_GET64(fpga_query_qp_counters_out, out,
  311                                           rx_ack_packets);
  312         data->rx_send_packets = MLX5_GET64(fpga_query_qp_counters_out, out,
  313                                            rx_send_packets);
  314         data->tx_ack_packets = MLX5_GET64(fpga_query_qp_counters_out, out,
  315                                           tx_ack_packets);
  316         data->tx_send_packets = MLX5_GET64(fpga_query_qp_counters_out, out,
  317                                            tx_send_packets);
  318         data->rx_total_drop = MLX5_GET64(fpga_query_qp_counters_out, out,
  319                                          rx_total_drop);
  320 
  321         return ret;
  322 }
  323 
  324 int mlx5_fpga_shell_counters(struct mlx5_core_dev *dev, bool clear,
  325                              struct mlx5_fpga_shell_counters *data)
  326 {
  327         u32 in[MLX5_ST_SZ_DW(fpga_shell_counters)] = {0};
  328         u32 out[MLX5_ST_SZ_DW(fpga_shell_counters)];
  329         int err;
  330 
  331         MLX5_SET(fpga_shell_counters, in, clear, clear);
  332         err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
  333                                    MLX5_REG_FPGA_SHELL_CNTR, 0, false);
  334         if (err)
  335                 goto out;
  336         if (data) {
  337                 data->ddr_read_requests = MLX5_GET64(fpga_shell_counters, out,
  338                                                      ddr_read_requests);
  339                 data->ddr_write_requests = MLX5_GET64(fpga_shell_counters, out,
  340                                                       ddr_write_requests);
  341                 data->ddr_read_bytes = MLX5_GET64(fpga_shell_counters, out,
  342                                                   ddr_read_bytes);
  343                 data->ddr_write_bytes = MLX5_GET64(fpga_shell_counters, out,
  344                                                    ddr_write_bytes);
  345         }
  346 
  347 out:
  348         return err;
  349 }

Cache object: 14f99432e25fb0dbb26875634fa386c6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.