Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
0003  *
0004  * This software is available to you under a choice of one of two
0005  * licenses.  You may choose to be licensed under the terms of the GNU
0006  * General Public License (GPL) Version 2, available from the file
0007  * COPYING in the main directory of this source tree, or the
0008  * OpenIB.org BSD license below:
0009  *
0010  *     Redistribution and use in source and binary forms, with or
0011  *     without modification, are permitted provided that the following
0012  *     conditions are met:
0013  *
0014  *      - Redistributions of source code must retain the above
0015  *        copyright notice, this list of conditions and the following
0016  *        disclaimer.
0017  *
0018  *      - Redistributions in binary form must reproduce the above
0019  *        copyright notice, this list of conditions and the following
0020  *        disclaimer in the documentation and/or other materials
0021  *        provided with the distribution.
0022  *
0023  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0024  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0025  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0026  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0027  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0028  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0029  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0030  * SOFTWARE.
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);