1e9dcd831SSlava Shwartsman /*- 2e9dcd831SSlava Shwartsman * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 3e9dcd831SSlava Shwartsman * 4e9dcd831SSlava Shwartsman * This software is available to you under a choice of one of two 5e9dcd831SSlava Shwartsman * licenses. You may choose to be licensed under the terms of the GNU 6e9dcd831SSlava Shwartsman * General Public License (GPL) Version 2, available from the file 7e9dcd831SSlava Shwartsman * COPYING in the main directory of this source tree, or the 8e9dcd831SSlava Shwartsman * OpenIB.org BSD license below: 9e9dcd831SSlava Shwartsman * 10e9dcd831SSlava Shwartsman * Redistribution and use in source and binary forms, with or 11e9dcd831SSlava Shwartsman * without modification, are permitted provided that the following 12e9dcd831SSlava Shwartsman * conditions are met: 13e9dcd831SSlava Shwartsman * 14e9dcd831SSlava Shwartsman * - Redistributions of source code must retain the above 15e9dcd831SSlava Shwartsman * copyright notice, this list of conditions and the following 16e9dcd831SSlava Shwartsman * disclaimer. 17e9dcd831SSlava Shwartsman * 18e9dcd831SSlava Shwartsman * - Redistributions in binary form must reproduce the above 19e9dcd831SSlava Shwartsman * copyright notice, this list of conditions and the following 20e9dcd831SSlava Shwartsman * disclaimer in the documentation and/or other materials 21e9dcd831SSlava Shwartsman * provided with the distribution. 22e9dcd831SSlava Shwartsman * 23e9dcd831SSlava Shwartsman * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24e9dcd831SSlava Shwartsman * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25e9dcd831SSlava Shwartsman * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26e9dcd831SSlava Shwartsman * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27e9dcd831SSlava Shwartsman * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28e9dcd831SSlava Shwartsman * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29e9dcd831SSlava Shwartsman * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30e9dcd831SSlava Shwartsman * SOFTWARE. 31e9dcd831SSlava Shwartsman * 32e9dcd831SSlava Shwartsman * $FreeBSD$ 33e9dcd831SSlava Shwartsman */ 34e9dcd831SSlava Shwartsman 35e9dcd831SSlava Shwartsman #include <linux/errno.h> 36e9dcd831SSlava Shwartsman #include <linux/err.h> 37e9dcd831SSlava Shwartsman #include <linux/completion.h> 38e9dcd831SSlava Shwartsman #include <dev/mlx5/device.h> 39e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/core.h> 40e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/conn.h> 41e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/sdk.h> 42e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/xfer.h> 43e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_core/mlx5_core.h> 44e9dcd831SSlava Shwartsman /* #include "accel/ipsec.h" */ 45e9dcd831SSlava Shwartsman 46e9dcd831SSlava Shwartsman #define MLX5_FPGA_LOAD_TIMEOUT 25000 /* msec */ 47e9dcd831SSlava Shwartsman 48e9dcd831SSlava Shwartsman struct mem_transfer { 49e9dcd831SSlava Shwartsman struct mlx5_fpga_transaction t; 50e9dcd831SSlava Shwartsman struct completion comp; 51e9dcd831SSlava Shwartsman u8 status; 52e9dcd831SSlava Shwartsman }; 53e9dcd831SSlava Shwartsman 54e9dcd831SSlava Shwartsman struct mlx5_fpga_conn * 55e9dcd831SSlava Shwartsman mlx5_fpga_sbu_conn_create(struct mlx5_fpga_device *fdev, 56e9dcd831SSlava Shwartsman struct mlx5_fpga_conn_attr *attr) 57e9dcd831SSlava Shwartsman { 58e9dcd831SSlava Shwartsman #ifdef NOT_YET 59e9dcd831SSlava Shwartsman /* XXXKIB */ 60e9dcd831SSlava Shwartsman return mlx5_fpga_conn_create(fdev, attr, MLX5_FPGA_QPC_QP_TYPE_SANDBOX_QP); 61e9dcd831SSlava Shwartsman #else 62e9dcd831SSlava Shwartsman return (NULL); 63e9dcd831SSlava Shwartsman #endif 64e9dcd831SSlava Shwartsman } 65e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_sbu_conn_create); 66e9dcd831SSlava Shwartsman 67e9dcd831SSlava Shwartsman void mlx5_fpga_sbu_conn_destroy(struct mlx5_fpga_conn *conn) 68e9dcd831SSlava Shwartsman { 69e9dcd831SSlava Shwartsman #ifdef NOT_YET 70e9dcd831SSlava Shwartsman /* XXXKIB */ 71e9dcd831SSlava Shwartsman mlx5_fpga_conn_destroy(conn); 72e9dcd831SSlava Shwartsman #endif 73e9dcd831SSlava Shwartsman } 74e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_sbu_conn_destroy); 75e9dcd831SSlava Shwartsman 76e9dcd831SSlava Shwartsman int mlx5_fpga_sbu_conn_sendmsg(struct mlx5_fpga_conn *conn, 77e9dcd831SSlava Shwartsman struct mlx5_fpga_dma_buf *buf) 78e9dcd831SSlava Shwartsman { 79e9dcd831SSlava Shwartsman #ifdef NOT_YET 80e9dcd831SSlava Shwartsman /* XXXKIB */ 81e9dcd831SSlava Shwartsman return mlx5_fpga_conn_send(conn, buf); 82e9dcd831SSlava Shwartsman #else 83e9dcd831SSlava Shwartsman return (0); 84e9dcd831SSlava Shwartsman #endif 85e9dcd831SSlava Shwartsman } 86e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_sbu_conn_sendmsg); 87e9dcd831SSlava Shwartsman 88e9dcd831SSlava Shwartsman static void mem_complete(const struct mlx5_fpga_transaction *complete, 89e9dcd831SSlava Shwartsman u8 status) 90e9dcd831SSlava Shwartsman { 91e9dcd831SSlava Shwartsman struct mem_transfer *xfer; 92e9dcd831SSlava Shwartsman 93e9dcd831SSlava Shwartsman mlx5_fpga_dbg(complete->conn->fdev, 94e9dcd831SSlava Shwartsman "transaction %p complete status %u", complete, status); 95e9dcd831SSlava Shwartsman 96e9dcd831SSlava Shwartsman xfer = container_of(complete, struct mem_transfer, t); 97e9dcd831SSlava Shwartsman xfer->status = status; 98e9dcd831SSlava Shwartsman complete_all(&xfer->comp); 99e9dcd831SSlava Shwartsman } 100e9dcd831SSlava Shwartsman 101e9dcd831SSlava Shwartsman static int mem_transaction(struct mlx5_fpga_device *fdev, size_t size, u64 addr, 102e9dcd831SSlava Shwartsman void *buf, enum mlx5_fpga_direction direction) 103e9dcd831SSlava Shwartsman { 104e9dcd831SSlava Shwartsman int ret; 105e9dcd831SSlava Shwartsman struct mem_transfer xfer; 106e9dcd831SSlava Shwartsman 107e9dcd831SSlava Shwartsman if (!fdev->shell_conn) { 108e9dcd831SSlava Shwartsman ret = -ENOTCONN; 109e9dcd831SSlava Shwartsman goto out; 110e9dcd831SSlava Shwartsman } 111e9dcd831SSlava Shwartsman 112e9dcd831SSlava Shwartsman xfer.t.data = buf; 113e9dcd831SSlava Shwartsman xfer.t.size = size; 114e9dcd831SSlava Shwartsman xfer.t.addr = addr; 115e9dcd831SSlava Shwartsman xfer.t.conn = fdev->shell_conn; 116e9dcd831SSlava Shwartsman xfer.t.direction = direction; 117e9dcd831SSlava Shwartsman xfer.t.complete1 = mem_complete; 118e9dcd831SSlava Shwartsman init_completion(&xfer.comp); 119e9dcd831SSlava Shwartsman ret = mlx5_fpga_xfer_exec(&xfer.t); 120e9dcd831SSlava Shwartsman if (ret) { 121e9dcd831SSlava Shwartsman mlx5_fpga_dbg(fdev, "Transfer execution failed: %d\n", ret); 122e9dcd831SSlava Shwartsman goto out; 123e9dcd831SSlava Shwartsman } 124e9dcd831SSlava Shwartsman wait_for_completion(&xfer.comp); 125e9dcd831SSlava Shwartsman if (xfer.status != 0) 126e9dcd831SSlava Shwartsman ret = -EIO; 127e9dcd831SSlava Shwartsman 128e9dcd831SSlava Shwartsman out: 129e9dcd831SSlava Shwartsman return ret; 130e9dcd831SSlava Shwartsman } 131e9dcd831SSlava Shwartsman 132e9dcd831SSlava Shwartsman static int mlx5_fpga_mem_read_i2c(struct mlx5_fpga_device *fdev, size_t size, 133e9dcd831SSlava Shwartsman u64 addr, u8 *buf) 134e9dcd831SSlava Shwartsman { 135e9dcd831SSlava Shwartsman size_t max_size = MLX5_FPGA_ACCESS_REG_SIZE_MAX; 136e9dcd831SSlava Shwartsman size_t bytes_done = 0; 137e9dcd831SSlava Shwartsman u8 actual_size; 138e9dcd831SSlava Shwartsman int err = 0; 139e9dcd831SSlava Shwartsman 140e9dcd831SSlava Shwartsman if (!size) 141e9dcd831SSlava Shwartsman return -EINVAL; 142e9dcd831SSlava Shwartsman 143e9dcd831SSlava Shwartsman if (!fdev->mdev) 144e9dcd831SSlava Shwartsman return -ENOTCONN; 145e9dcd831SSlava Shwartsman 146e9dcd831SSlava Shwartsman while (bytes_done < size) { 147e9dcd831SSlava Shwartsman actual_size = min(max_size, (size - bytes_done)); 148e9dcd831SSlava Shwartsman 149e9dcd831SSlava Shwartsman err = mlx5_fpga_access_reg(fdev->mdev, actual_size, 150e9dcd831SSlava Shwartsman addr + bytes_done, 151e9dcd831SSlava Shwartsman buf + bytes_done, false); 152e9dcd831SSlava Shwartsman if (err) { 153e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to read over I2C: %d\n", 154e9dcd831SSlava Shwartsman err); 155e9dcd831SSlava Shwartsman break; 156e9dcd831SSlava Shwartsman } 157e9dcd831SSlava Shwartsman 158e9dcd831SSlava Shwartsman bytes_done += actual_size; 159e9dcd831SSlava Shwartsman } 160e9dcd831SSlava Shwartsman 161e9dcd831SSlava Shwartsman return err; 162e9dcd831SSlava Shwartsman } 163e9dcd831SSlava Shwartsman 164e9dcd831SSlava Shwartsman static int mlx5_fpga_mem_write_i2c(struct mlx5_fpga_device *fdev, size_t size, 165e9dcd831SSlava Shwartsman u64 addr, u8 *buf) 166e9dcd831SSlava Shwartsman { 167e9dcd831SSlava Shwartsman size_t max_size = MLX5_FPGA_ACCESS_REG_SIZE_MAX; 168e9dcd831SSlava Shwartsman size_t bytes_done = 0; 169e9dcd831SSlava Shwartsman u8 actual_size; 170e9dcd831SSlava Shwartsman int err = 0; 171e9dcd831SSlava Shwartsman 172e9dcd831SSlava Shwartsman if (!size) 173e9dcd831SSlava Shwartsman return -EINVAL; 174e9dcd831SSlava Shwartsman 175e9dcd831SSlava Shwartsman if (!fdev->mdev) 176e9dcd831SSlava Shwartsman return -ENOTCONN; 177e9dcd831SSlava Shwartsman 178e9dcd831SSlava Shwartsman while (bytes_done < size) { 179e9dcd831SSlava Shwartsman actual_size = min(max_size, (size - bytes_done)); 180e9dcd831SSlava Shwartsman 181e9dcd831SSlava Shwartsman err = mlx5_fpga_access_reg(fdev->mdev, actual_size, 182e9dcd831SSlava Shwartsman addr + bytes_done, 183e9dcd831SSlava Shwartsman buf + bytes_done, true); 184e9dcd831SSlava Shwartsman if (err) { 185e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to write FPGA crspace\n"); 186e9dcd831SSlava Shwartsman break; 187e9dcd831SSlava Shwartsman } 188e9dcd831SSlava Shwartsman 189e9dcd831SSlava Shwartsman bytes_done += actual_size; 190e9dcd831SSlava Shwartsman } 191e9dcd831SSlava Shwartsman 192e9dcd831SSlava Shwartsman return err; 193e9dcd831SSlava Shwartsman } 194e9dcd831SSlava Shwartsman 195e9dcd831SSlava Shwartsman int mlx5_fpga_mem_read(struct mlx5_fpga_device *fdev, size_t size, u64 addr, 196e9dcd831SSlava Shwartsman void *buf, enum mlx5_fpga_access_type access_type) 197e9dcd831SSlava Shwartsman { 198e9dcd831SSlava Shwartsman int ret; 199e9dcd831SSlava Shwartsman 200e9dcd831SSlava Shwartsman if (access_type == MLX5_FPGA_ACCESS_TYPE_DONTCARE) 201e9dcd831SSlava Shwartsman access_type = fdev->shell_conn ? MLX5_FPGA_ACCESS_TYPE_RDMA : 202e9dcd831SSlava Shwartsman MLX5_FPGA_ACCESS_TYPE_I2C; 203e9dcd831SSlava Shwartsman 204e9dcd831SSlava Shwartsman mlx5_fpga_dbg(fdev, "Reading %zu bytes at 0x%jx over %s", 205e9dcd831SSlava Shwartsman size, (uintmax_t)addr, access_type ? "RDMA" : "I2C"); 206e9dcd831SSlava Shwartsman 207e9dcd831SSlava Shwartsman switch (access_type) { 208e9dcd831SSlava Shwartsman case MLX5_FPGA_ACCESS_TYPE_RDMA: 209e9dcd831SSlava Shwartsman ret = mem_transaction(fdev, size, addr, buf, MLX5_FPGA_READ); 210e9dcd831SSlava Shwartsman if (ret) 211e9dcd831SSlava Shwartsman return ret; 212e9dcd831SSlava Shwartsman break; 213e9dcd831SSlava Shwartsman case MLX5_FPGA_ACCESS_TYPE_I2C: 214e9dcd831SSlava Shwartsman ret = mlx5_fpga_mem_read_i2c(fdev, size, addr, buf); 215e9dcd831SSlava Shwartsman if (ret) 216e9dcd831SSlava Shwartsman return ret; 217e9dcd831SSlava Shwartsman break; 218e9dcd831SSlava Shwartsman default: 219e9dcd831SSlava Shwartsman mlx5_fpga_warn(fdev, "Unexpected read access_type %u\n", 220e9dcd831SSlava Shwartsman access_type); 221e9dcd831SSlava Shwartsman return -EACCES; 222e9dcd831SSlava Shwartsman } 223e9dcd831SSlava Shwartsman 224e9dcd831SSlava Shwartsman return size; 225e9dcd831SSlava Shwartsman } 226e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_mem_read); 227e9dcd831SSlava Shwartsman 228e9dcd831SSlava Shwartsman int mlx5_fpga_mem_write(struct mlx5_fpga_device *fdev, size_t size, u64 addr, 229e9dcd831SSlava Shwartsman void *buf, enum mlx5_fpga_access_type access_type) 230e9dcd831SSlava Shwartsman { 231e9dcd831SSlava Shwartsman int ret; 232e9dcd831SSlava Shwartsman 233e9dcd831SSlava Shwartsman if (access_type == MLX5_FPGA_ACCESS_TYPE_DONTCARE) 234e9dcd831SSlava Shwartsman access_type = fdev->shell_conn ? MLX5_FPGA_ACCESS_TYPE_RDMA : 235e9dcd831SSlava Shwartsman MLX5_FPGA_ACCESS_TYPE_I2C; 236e9dcd831SSlava Shwartsman 237e9dcd831SSlava Shwartsman mlx5_fpga_dbg(fdev, "Writing %zu bytes at 0x%jx over %s", 238e9dcd831SSlava Shwartsman size, (uintmax_t)addr, access_type ? "RDMA" : "I2C"); 239e9dcd831SSlava Shwartsman 240e9dcd831SSlava Shwartsman switch (access_type) { 241e9dcd831SSlava Shwartsman case MLX5_FPGA_ACCESS_TYPE_RDMA: 242e9dcd831SSlava Shwartsman ret = mem_transaction(fdev, size, addr, buf, MLX5_FPGA_WRITE); 243e9dcd831SSlava Shwartsman if (ret) 244e9dcd831SSlava Shwartsman return ret; 245e9dcd831SSlava Shwartsman break; 246e9dcd831SSlava Shwartsman case MLX5_FPGA_ACCESS_TYPE_I2C: 247e9dcd831SSlava Shwartsman ret = mlx5_fpga_mem_write_i2c(fdev, size, addr, buf); 248e9dcd831SSlava Shwartsman if (ret) 249e9dcd831SSlava Shwartsman return ret; 250e9dcd831SSlava Shwartsman break; 251e9dcd831SSlava Shwartsman default: 252e9dcd831SSlava Shwartsman mlx5_fpga_warn(fdev, "Unexpected write access_type %u\n", 253e9dcd831SSlava Shwartsman access_type); 254e9dcd831SSlava Shwartsman return -EACCES; 255e9dcd831SSlava Shwartsman } 256e9dcd831SSlava Shwartsman 257e9dcd831SSlava Shwartsman return size; 258e9dcd831SSlava Shwartsman } 259e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_mem_write); 260e9dcd831SSlava Shwartsman 261e9dcd831SSlava Shwartsman int mlx5_fpga_get_sbu_caps(struct mlx5_fpga_device *fdev, int size, void *buf) 262e9dcd831SSlava Shwartsman { 263e9dcd831SSlava Shwartsman return mlx5_fpga_sbu_caps(fdev->mdev, buf, size); 264e9dcd831SSlava Shwartsman } 265e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_get_sbu_caps); 266e9dcd831SSlava Shwartsman 267e9dcd831SSlava Shwartsman u64 mlx5_fpga_ddr_size_get(struct mlx5_fpga_device *fdev) 268e9dcd831SSlava Shwartsman { 269e9dcd831SSlava Shwartsman return (u64)MLX5_CAP_FPGA(fdev->mdev, fpga_ddr_size) << 10; 270e9dcd831SSlava Shwartsman } 271e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_ddr_size_get); 272e9dcd831SSlava Shwartsman 273e9dcd831SSlava Shwartsman u64 mlx5_fpga_ddr_base_get(struct mlx5_fpga_device *fdev) 274e9dcd831SSlava Shwartsman { 275e9dcd831SSlava Shwartsman return MLX5_CAP64_FPGA(fdev->mdev, fpga_ddr_start_addr); 276e9dcd831SSlava Shwartsman } 277e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_ddr_base_get); 278e9dcd831SSlava Shwartsman 279e9dcd831SSlava Shwartsman void mlx5_fpga_client_data_set(struct mlx5_fpga_device *fdev, 280e9dcd831SSlava Shwartsman struct mlx5_fpga_client *client, void *data) 281e9dcd831SSlava Shwartsman { 282e9dcd831SSlava Shwartsman struct mlx5_fpga_client_data *context; 283e9dcd831SSlava Shwartsman 284e9dcd831SSlava Shwartsman list_for_each_entry(context, &fdev->client_data_list, list) { 285e9dcd831SSlava Shwartsman if (context->client != client) 286e9dcd831SSlava Shwartsman continue; 287e9dcd831SSlava Shwartsman context->data = data; 288e9dcd831SSlava Shwartsman return; 289e9dcd831SSlava Shwartsman } 290e9dcd831SSlava Shwartsman 291e9dcd831SSlava Shwartsman mlx5_fpga_warn(fdev, "No client context found for %s\n", client->name); 292e9dcd831SSlava Shwartsman } 293e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_client_data_set); 294e9dcd831SSlava Shwartsman 295e9dcd831SSlava Shwartsman void *mlx5_fpga_client_data_get(struct mlx5_fpga_device *fdev, 296e9dcd831SSlava Shwartsman struct mlx5_fpga_client *client) 297e9dcd831SSlava Shwartsman { 298e9dcd831SSlava Shwartsman struct mlx5_fpga_client_data *context; 299e9dcd831SSlava Shwartsman void *ret = NULL; 300e9dcd831SSlava Shwartsman 301e9dcd831SSlava Shwartsman list_for_each_entry(context, &fdev->client_data_list, list) { 302e9dcd831SSlava Shwartsman if (context->client != client) 303e9dcd831SSlava Shwartsman continue; 304e9dcd831SSlava Shwartsman ret = context->data; 305e9dcd831SSlava Shwartsman goto out; 306e9dcd831SSlava Shwartsman } 307e9dcd831SSlava Shwartsman mlx5_fpga_warn(fdev, "No client context found for %s\n", client->name); 308e9dcd831SSlava Shwartsman 309e9dcd831SSlava Shwartsman out: 310e9dcd831SSlava Shwartsman return ret; 311e9dcd831SSlava Shwartsman } 312e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_client_data_get); 313e9dcd831SSlava Shwartsman 314e9dcd831SSlava Shwartsman void mlx5_fpga_device_query(struct mlx5_fpga_device *fdev, 315e9dcd831SSlava Shwartsman struct mlx5_fpga_query *query) 316e9dcd831SSlava Shwartsman { 317e9dcd831SSlava Shwartsman unsigned long flags; 318e9dcd831SSlava Shwartsman 319e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags); 320e9dcd831SSlava Shwartsman query->image_status = fdev->image_status; 321e9dcd831SSlava Shwartsman query->admin_image = fdev->last_admin_image; 322e9dcd831SSlava Shwartsman query->oper_image = fdev->last_oper_image; 323e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 324e9dcd831SSlava Shwartsman } 325e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_device_query); 326e9dcd831SSlava Shwartsman 327e9dcd831SSlava Shwartsman int mlx5_fpga_device_reload(struct mlx5_fpga_device *fdev, 328e9dcd831SSlava Shwartsman enum mlx5_fpga_image image) 329e9dcd831SSlava Shwartsman { 330e9dcd831SSlava Shwartsman struct mlx5_core_dev *mdev = fdev->mdev; 331e9dcd831SSlava Shwartsman unsigned long timeout; 332e9dcd831SSlava Shwartsman unsigned long flags; 333e9dcd831SSlava Shwartsman int err = 0; 334e9dcd831SSlava Shwartsman 335e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags); 336e9dcd831SSlava Shwartsman switch (fdev->fdev_state) { 337e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_NONE: 338e9dcd831SSlava Shwartsman err = -ENODEV; 339e9dcd831SSlava Shwartsman break; 340e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_IN_PROGRESS: 341e9dcd831SSlava Shwartsman err = -EBUSY; 342e9dcd831SSlava Shwartsman break; 343e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_SUCCESS: 344e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_FAILURE: 345e9dcd831SSlava Shwartsman break; 346e9dcd831SSlava Shwartsman } 347e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 348e9dcd831SSlava Shwartsman if (err) 349e9dcd831SSlava Shwartsman return err; 350e9dcd831SSlava Shwartsman 351e9dcd831SSlava Shwartsman mutex_lock(&mdev->intf_state_mutex); 352e9dcd831SSlava Shwartsman clear_bit(MLX5_INTERFACE_STATE_UP, &mdev->intf_state); 353e9dcd831SSlava Shwartsman 354e9dcd831SSlava Shwartsman mlx5_unregister_device(mdev); 355e9dcd831SSlava Shwartsman /* XXXKIB mlx5_accel_ipsec_cleanup(mdev); */ 356e9dcd831SSlava Shwartsman mlx5_fpga_device_stop(mdev); 357e9dcd831SSlava Shwartsman 358e9dcd831SSlava Shwartsman fdev->fdev_state = MLX5_FDEV_STATE_IN_PROGRESS; 359e9dcd831SSlava Shwartsman reinit_completion(&fdev->load_event); 360e9dcd831SSlava Shwartsman 361e9dcd831SSlava Shwartsman if (image <= MLX5_FPGA_IMAGE_MAX) { 362e9dcd831SSlava Shwartsman mlx5_fpga_info(fdev, "Loading from flash\n"); 363e9dcd831SSlava Shwartsman err = mlx5_fpga_load(mdev, image); 364e9dcd831SSlava Shwartsman if (err) { 365e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to request load: %d\n", 366e9dcd831SSlava Shwartsman err); 367e9dcd831SSlava Shwartsman goto out; 368e9dcd831SSlava Shwartsman } 369e9dcd831SSlava Shwartsman } else { 370e9dcd831SSlava Shwartsman mlx5_fpga_info(fdev, "Resetting\n"); 371e9dcd831SSlava Shwartsman err = mlx5_fpga_ctrl_op(mdev, MLX5_FPGA_CTRL_OPERATION_RESET); 372e9dcd831SSlava Shwartsman if (err) { 373e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to request reset: %d\n", 374e9dcd831SSlava Shwartsman err); 375e9dcd831SSlava Shwartsman goto out; 376e9dcd831SSlava Shwartsman } 377e9dcd831SSlava Shwartsman } 378e9dcd831SSlava Shwartsman 379e9dcd831SSlava Shwartsman timeout = jiffies + msecs_to_jiffies(MLX5_FPGA_LOAD_TIMEOUT); 380e9dcd831SSlava Shwartsman err = wait_for_completion_timeout(&fdev->load_event, timeout - jiffies); 381e9dcd831SSlava Shwartsman if (err < 0) { 382e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed waiting for FPGA load: %d\n", err); 383e9dcd831SSlava Shwartsman fdev->fdev_state = MLX5_FDEV_STATE_FAILURE; 384e9dcd831SSlava Shwartsman goto out; 385e9dcd831SSlava Shwartsman } 386e9dcd831SSlava Shwartsman 387e9dcd831SSlava Shwartsman err = mlx5_fpga_device_start(mdev); 388e9dcd831SSlava Shwartsman if (err) { 389e9dcd831SSlava Shwartsman mlx5_core_err(mdev, "fpga device start failed %d\n", err); 390e9dcd831SSlava Shwartsman goto out; 391e9dcd831SSlava Shwartsman } 392e9dcd831SSlava Shwartsman /* XXXKIB err = mlx5_accel_ipsec_init(mdev); */ 393e9dcd831SSlava Shwartsman if (err) { 394e9dcd831SSlava Shwartsman mlx5_core_err(mdev, "IPSec device start failed %d\n", err); 395e9dcd831SSlava Shwartsman goto err_fpga; 396e9dcd831SSlava Shwartsman } 397e9dcd831SSlava Shwartsman 398e9dcd831SSlava Shwartsman err = mlx5_register_device(mdev); 399e9dcd831SSlava Shwartsman if (err) { 400e9dcd831SSlava Shwartsman mlx5_core_err(mdev, "mlx5_register_device failed %d\n", err); 401e9dcd831SSlava Shwartsman fdev->fdev_state = MLX5_FDEV_STATE_FAILURE; 402e9dcd831SSlava Shwartsman goto err_ipsec; 403e9dcd831SSlava Shwartsman } 404e9dcd831SSlava Shwartsman 405e9dcd831SSlava Shwartsman set_bit(MLX5_INTERFACE_STATE_UP, &mdev->intf_state); 406e9dcd831SSlava Shwartsman goto out; 407e9dcd831SSlava Shwartsman 408e9dcd831SSlava Shwartsman err_ipsec: 409e9dcd831SSlava Shwartsman /* XXXKIB mlx5_accel_ipsec_cleanup(mdev); */ 410e9dcd831SSlava Shwartsman err_fpga: 411e9dcd831SSlava Shwartsman mlx5_fpga_device_stop(mdev); 412e9dcd831SSlava Shwartsman out: 413e9dcd831SSlava Shwartsman mutex_unlock(&mdev->intf_state_mutex); 414e9dcd831SSlava Shwartsman return err; 415e9dcd831SSlava Shwartsman } 416e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_device_reload); 417e9dcd831SSlava Shwartsman 418e9dcd831SSlava Shwartsman int mlx5_fpga_flash_select(struct mlx5_fpga_device *fdev, 419e9dcd831SSlava Shwartsman enum mlx5_fpga_image image) 420e9dcd831SSlava Shwartsman { 421e9dcd831SSlava Shwartsman unsigned long flags; 422e9dcd831SSlava Shwartsman int err; 423e9dcd831SSlava Shwartsman 424e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags); 425e9dcd831SSlava Shwartsman switch (fdev->fdev_state) { 426e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_NONE: 427e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 428e9dcd831SSlava Shwartsman return -ENODEV; 429e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_IN_PROGRESS: 430e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_SUCCESS: 431e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_FAILURE: 432e9dcd831SSlava Shwartsman break; 433e9dcd831SSlava Shwartsman } 434e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 435e9dcd831SSlava Shwartsman 436e9dcd831SSlava Shwartsman err = mlx5_fpga_image_select(fdev->mdev, image); 437e9dcd831SSlava Shwartsman if (err) 438e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to select flash image: %d\n", err); 439e9dcd831SSlava Shwartsman else 440e9dcd831SSlava Shwartsman fdev->last_admin_image = image; 441e9dcd831SSlava Shwartsman return err; 442e9dcd831SSlava Shwartsman } 443e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_flash_select); 444e9dcd831SSlava Shwartsman 445*085b35bbSSlava Shwartsman int mlx5_fpga_temperature(struct mlx5_fpga_device *fdev, 446*085b35bbSSlava Shwartsman struct mlx5_fpga_temperature *temp) 447*085b35bbSSlava Shwartsman { 448*085b35bbSSlava Shwartsman return mlx5_fpga_query_mtmp(fdev->mdev, temp); 449*085b35bbSSlava Shwartsman } 450*085b35bbSSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_temperature); 451*085b35bbSSlava Shwartsman 452e9dcd831SSlava Shwartsman struct device *mlx5_fpga_dev(struct mlx5_fpga_device *fdev) 453e9dcd831SSlava Shwartsman { 454e9dcd831SSlava Shwartsman return &fdev->mdev->pdev->dev; 455e9dcd831SSlava Shwartsman } 456e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_dev); 457e9dcd831SSlava Shwartsman 458e9dcd831SSlava Shwartsman void mlx5_fpga_get_cap(struct mlx5_fpga_device *fdev, u32 *fpga_caps) 459e9dcd831SSlava Shwartsman { 460e9dcd831SSlava Shwartsman unsigned long flags; 461e9dcd831SSlava Shwartsman 462e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags); 463e9dcd831SSlava Shwartsman memcpy(fpga_caps, &fdev->mdev->caps.fpga, sizeof(fdev->mdev->caps.fpga)); 464e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 465e9dcd831SSlava Shwartsman } 466e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_get_cap); 467