0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <linux/mlx5/device.h>
0035
0036 #include "fpga/core.h"
0037 #include "fpga/conn.h"
0038 #include "fpga/sdk.h"
0039
0040 struct mlx5_fpga_conn *
0041 mlx5_fpga_sbu_conn_create(struct mlx5_fpga_device *fdev,
0042 struct mlx5_fpga_conn_attr *attr)
0043 {
0044 return mlx5_fpga_conn_create(fdev, attr, MLX5_FPGA_QPC_QP_TYPE_SANDBOX_QP);
0045 }
0046 EXPORT_SYMBOL(mlx5_fpga_sbu_conn_create);
0047
0048 void mlx5_fpga_sbu_conn_destroy(struct mlx5_fpga_conn *conn)
0049 {
0050 mlx5_fpga_conn_destroy(conn);
0051 }
0052 EXPORT_SYMBOL(mlx5_fpga_sbu_conn_destroy);
0053
0054 int mlx5_fpga_sbu_conn_sendmsg(struct mlx5_fpga_conn *conn,
0055 struct mlx5_fpga_dma_buf *buf)
0056 {
0057 return mlx5_fpga_conn_send(conn, buf);
0058 }
0059 EXPORT_SYMBOL(mlx5_fpga_sbu_conn_sendmsg);
0060
0061 static int mlx5_fpga_mem_read_i2c(struct mlx5_fpga_device *fdev, size_t size,
0062 u64 addr, u8 *buf)
0063 {
0064 size_t max_size = MLX5_FPGA_ACCESS_REG_SIZE_MAX;
0065 size_t bytes_done = 0;
0066 u8 actual_size;
0067 int err;
0068
0069 if (!size)
0070 return -EINVAL;
0071
0072 if (!fdev->mdev)
0073 return -ENOTCONN;
0074
0075 while (bytes_done < size) {
0076 actual_size = min(max_size, (size - bytes_done));
0077
0078 err = mlx5_fpga_access_reg(fdev->mdev, actual_size,
0079 addr + bytes_done,
0080 buf + bytes_done, false);
0081 if (err) {
0082 mlx5_fpga_err(fdev, "Failed to read over I2C: %d\n",
0083 err);
0084 break;
0085 }
0086
0087 bytes_done += actual_size;
0088 }
0089
0090 return err;
0091 }
0092
0093 static int mlx5_fpga_mem_write_i2c(struct mlx5_fpga_device *fdev, size_t size,
0094 u64 addr, u8 *buf)
0095 {
0096 size_t max_size = MLX5_FPGA_ACCESS_REG_SIZE_MAX;
0097 size_t bytes_done = 0;
0098 u8 actual_size;
0099 int err;
0100
0101 if (!size)
0102 return -EINVAL;
0103
0104 if (!fdev->mdev)
0105 return -ENOTCONN;
0106
0107 while (bytes_done < size) {
0108 actual_size = min(max_size, (size - bytes_done));
0109
0110 err = mlx5_fpga_access_reg(fdev->mdev, actual_size,
0111 addr + bytes_done,
0112 buf + bytes_done, true);
0113 if (err) {
0114 mlx5_fpga_err(fdev, "Failed to write FPGA crspace\n");
0115 break;
0116 }
0117
0118 bytes_done += actual_size;
0119 }
0120
0121 return err;
0122 }
0123
0124 int mlx5_fpga_mem_read(struct mlx5_fpga_device *fdev, size_t size, u64 addr,
0125 void *buf, enum mlx5_fpga_access_type access_type)
0126 {
0127 int ret;
0128
0129 switch (access_type) {
0130 case MLX5_FPGA_ACCESS_TYPE_I2C:
0131 ret = mlx5_fpga_mem_read_i2c(fdev, size, addr, buf);
0132 if (ret)
0133 return ret;
0134 break;
0135 default:
0136 mlx5_fpga_warn(fdev, "Unexpected read access_type %u\n",
0137 access_type);
0138 return -EACCES;
0139 }
0140
0141 return size;
0142 }
0143 EXPORT_SYMBOL(mlx5_fpga_mem_read);
0144
0145 int mlx5_fpga_mem_write(struct mlx5_fpga_device *fdev, size_t size, u64 addr,
0146 void *buf, enum mlx5_fpga_access_type access_type)
0147 {
0148 int ret;
0149
0150 switch (access_type) {
0151 case MLX5_FPGA_ACCESS_TYPE_I2C:
0152 ret = mlx5_fpga_mem_write_i2c(fdev, size, addr, buf);
0153 if (ret)
0154 return ret;
0155 break;
0156 default:
0157 mlx5_fpga_warn(fdev, "Unexpected write access_type %u\n",
0158 access_type);
0159 return -EACCES;
0160 }
0161
0162 return size;
0163 }
0164 EXPORT_SYMBOL(mlx5_fpga_mem_write);
0165
0166 int mlx5_fpga_get_sbu_caps(struct mlx5_fpga_device *fdev, int size, void *buf)
0167 {
0168 return mlx5_fpga_sbu_caps(fdev->mdev, buf, size);
0169 }
0170 EXPORT_SYMBOL(mlx5_fpga_get_sbu_caps);