cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cmd.c (7245B)


      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
     33#include <linux/etherdevice.h>
     34#include <linux/mlx5/driver.h>
     35#include <linux/mlx5/device.h>
     36
     37#include "mlx5_core.h"
     38#include "fpga/cmd.h"
     39
     40#define MLX5_FPGA_ACCESS_REG_SZ (MLX5_ST_SZ_DW(fpga_access_reg) + \
     41				 MLX5_FPGA_ACCESS_REG_SIZE_MAX)
     42
     43int mlx5_fpga_access_reg(struct mlx5_core_dev *dev, u8 size, u64 addr,
     44			 void *buf, bool write)
     45{
     46	u32 in[MLX5_FPGA_ACCESS_REG_SZ] = {0};
     47	u32 out[MLX5_FPGA_ACCESS_REG_SZ];
     48	int err;
     49
     50	if (size & 3)
     51		return -EINVAL;
     52	if (addr & 3)
     53		return -EINVAL;
     54	if (size > MLX5_FPGA_ACCESS_REG_SIZE_MAX)
     55		return -EINVAL;
     56
     57	MLX5_SET(fpga_access_reg, in, size, size);
     58	MLX5_SET64(fpga_access_reg, in, address, addr);
     59	if (write)
     60		memcpy(MLX5_ADDR_OF(fpga_access_reg, in, data), buf, size);
     61
     62	err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
     63				   MLX5_REG_FPGA_ACCESS_REG, 0, write);
     64	if (err)
     65		return err;
     66
     67	if (!write)
     68		memcpy(buf, MLX5_ADDR_OF(fpga_access_reg, out, data), size);
     69
     70	return 0;
     71}
     72
     73int mlx5_fpga_caps(struct mlx5_core_dev *dev)
     74{
     75	u32 in[MLX5_ST_SZ_DW(fpga_cap)] = {0};
     76
     77	return mlx5_core_access_reg(dev, in, sizeof(in), dev->caps.fpga,
     78				    MLX5_ST_SZ_BYTES(fpga_cap),
     79				    MLX5_REG_FPGA_CAP, 0, 0);
     80}
     81
     82int mlx5_fpga_ctrl_op(struct mlx5_core_dev *dev, u8 op)
     83{
     84	u32 in[MLX5_ST_SZ_DW(fpga_ctrl)] = {0};
     85	u32 out[MLX5_ST_SZ_DW(fpga_ctrl)];
     86
     87	MLX5_SET(fpga_ctrl, in, operation, op);
     88
     89	return mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
     90				    MLX5_REG_FPGA_CTRL, 0, true);
     91}
     92
     93int mlx5_fpga_sbu_caps(struct mlx5_core_dev *dev, void *caps, int size)
     94{
     95	unsigned int cap_size = MLX5_CAP_FPGA(dev, sandbox_extended_caps_len);
     96	u64 addr = MLX5_CAP64_FPGA(dev, sandbox_extended_caps_addr);
     97	unsigned int read;
     98	int ret = 0;
     99
    100	if (cap_size > size) {
    101		mlx5_core_warn(dev, "Not enough buffer %u for FPGA SBU caps %u",
    102			       size, cap_size);
    103		return -EINVAL;
    104	}
    105
    106	while (cap_size > 0) {
    107		read = min_t(unsigned int, cap_size,
    108			     MLX5_FPGA_ACCESS_REG_SIZE_MAX);
    109
    110		ret = mlx5_fpga_access_reg(dev, read, addr, caps, false);
    111		if (ret) {
    112			mlx5_core_warn(dev, "Error reading FPGA SBU caps %u bytes at address 0x%llx: %d",
    113				       read, addr, ret);
    114			return ret;
    115		}
    116
    117		cap_size -= read;
    118		addr += read;
    119		caps += read;
    120	}
    121
    122	return ret;
    123}
    124
    125int mlx5_fpga_query(struct mlx5_core_dev *dev, struct mlx5_fpga_query *query)
    126{
    127	u32 in[MLX5_ST_SZ_DW(fpga_ctrl)] = {0};
    128	u32 out[MLX5_ST_SZ_DW(fpga_ctrl)];
    129	int err;
    130
    131	err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out),
    132				   MLX5_REG_FPGA_CTRL, 0, false);
    133	if (err)
    134		return err;
    135
    136	query->status = MLX5_GET(fpga_ctrl, out, status);
    137	query->admin_image = MLX5_GET(fpga_ctrl, out, flash_select_admin);
    138	query->oper_image = MLX5_GET(fpga_ctrl, out, flash_select_oper);
    139	return 0;
    140}
    141
    142int mlx5_fpga_create_qp(struct mlx5_core_dev *dev, void *fpga_qpc,
    143			u32 *fpga_qpn)
    144{
    145	u32 out[MLX5_ST_SZ_DW(fpga_create_qp_out)] = {};
    146	u32 in[MLX5_ST_SZ_DW(fpga_create_qp_in)] = {};
    147	int ret;
    148
    149	MLX5_SET(fpga_create_qp_in, in, opcode, MLX5_CMD_OP_FPGA_CREATE_QP);
    150	memcpy(MLX5_ADDR_OF(fpga_create_qp_in, in, fpga_qpc), fpga_qpc,
    151	       MLX5_FLD_SZ_BYTES(fpga_create_qp_in, fpga_qpc));
    152
    153	ret = mlx5_cmd_exec_inout(dev, fpga_create_qp, in, out);
    154	if (ret)
    155		return ret;
    156
    157	memcpy(fpga_qpc, MLX5_ADDR_OF(fpga_create_qp_out, out, fpga_qpc),
    158	       MLX5_FLD_SZ_BYTES(fpga_create_qp_out, fpga_qpc));
    159	*fpga_qpn = MLX5_GET(fpga_create_qp_out, out, fpga_qpn);
    160	return ret;
    161}
    162
    163int mlx5_fpga_modify_qp(struct mlx5_core_dev *dev, u32 fpga_qpn,
    164			enum mlx5_fpga_qpc_field_select fields,
    165			void *fpga_qpc)
    166{
    167	u32 in[MLX5_ST_SZ_DW(fpga_modify_qp_in)] = {};
    168
    169	MLX5_SET(fpga_modify_qp_in, in, opcode, MLX5_CMD_OP_FPGA_MODIFY_QP);
    170	MLX5_SET(fpga_modify_qp_in, in, field_select, fields);
    171	MLX5_SET(fpga_modify_qp_in, in, fpga_qpn, fpga_qpn);
    172	memcpy(MLX5_ADDR_OF(fpga_modify_qp_in, in, fpga_qpc), fpga_qpc,
    173	       MLX5_FLD_SZ_BYTES(fpga_modify_qp_in, fpga_qpc));
    174
    175	return mlx5_cmd_exec_in(dev, fpga_modify_qp, in);
    176}
    177
    178int mlx5_fpga_query_qp(struct mlx5_core_dev *dev,
    179		       u32 fpga_qpn, void *fpga_qpc)
    180{
    181	u32 out[MLX5_ST_SZ_DW(fpga_query_qp_out)] = {};
    182	u32 in[MLX5_ST_SZ_DW(fpga_query_qp_in)] = {};
    183	int ret;
    184
    185	MLX5_SET(fpga_query_qp_in, in, opcode, MLX5_CMD_OP_FPGA_QUERY_QP);
    186	MLX5_SET(fpga_query_qp_in, in, fpga_qpn, fpga_qpn);
    187
    188	ret = mlx5_cmd_exec_inout(dev, fpga_query_qp, in, out);
    189	if (ret)
    190		return ret;
    191
    192	memcpy(fpga_qpc, MLX5_ADDR_OF(fpga_query_qp_out, out, fpga_qpc),
    193	       MLX5_FLD_SZ_BYTES(fpga_query_qp_out, fpga_qpc));
    194	return ret;
    195}
    196
    197int mlx5_fpga_destroy_qp(struct mlx5_core_dev *dev, u32 fpga_qpn)
    198{
    199	u32 in[MLX5_ST_SZ_DW(fpga_destroy_qp_in)] = {};
    200
    201	MLX5_SET(fpga_destroy_qp_in, in, opcode, MLX5_CMD_OP_FPGA_DESTROY_QP);
    202	MLX5_SET(fpga_destroy_qp_in, in, fpga_qpn, fpga_qpn);
    203
    204	return mlx5_cmd_exec_in(dev, fpga_destroy_qp, in);
    205}
    206
    207int mlx5_fpga_query_qp_counters(struct mlx5_core_dev *dev, u32 fpga_qpn,
    208				bool clear, struct mlx5_fpga_qp_counters *data)
    209{
    210	u32 out[MLX5_ST_SZ_DW(fpga_query_qp_counters_out)] = {};
    211	u32 in[MLX5_ST_SZ_DW(fpga_query_qp_counters_in)] = {};
    212	int ret;
    213
    214	MLX5_SET(fpga_query_qp_counters_in, in, opcode,
    215		 MLX5_CMD_OP_FPGA_QUERY_QP_COUNTERS);
    216	MLX5_SET(fpga_query_qp_counters_in, in, clear, clear);
    217	MLX5_SET(fpga_query_qp_counters_in, in, fpga_qpn, fpga_qpn);
    218
    219	ret = mlx5_cmd_exec_inout(dev, fpga_query_qp_counters, in, out);
    220	if (ret)
    221		return ret;
    222
    223	data->rx_ack_packets = MLX5_GET64(fpga_query_qp_counters_out, out,
    224					  rx_ack_packets);
    225	data->rx_send_packets = MLX5_GET64(fpga_query_qp_counters_out, out,
    226					   rx_send_packets);
    227	data->tx_ack_packets = MLX5_GET64(fpga_query_qp_counters_out, out,
    228					  tx_ack_packets);
    229	data->tx_send_packets = MLX5_GET64(fpga_query_qp_counters_out, out,
    230					   tx_send_packets);
    231	data->rx_total_drop = MLX5_GET64(fpga_query_qp_counters_out, out,
    232					 rx_total_drop);
    233
    234	return ret;
    235}