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 327*c322dbafSHans Petter Selasky static int mlx5_fpga_device_reload_cmd(struct mlx5_fpga_device *fdev) 328*c322dbafSHans Petter Selasky { 329*c322dbafSHans Petter Selasky struct mlx5_core_dev *mdev = fdev->mdev; 330*c322dbafSHans Petter Selasky unsigned long timeout; 331*c322dbafSHans Petter Selasky unsigned long flags; 332*c322dbafSHans Petter Selasky int err = 0; 333*c322dbafSHans Petter Selasky 334*c322dbafSHans Petter Selasky mlx5_fpga_info(fdev, "mlx5/fpga - reload started\n"); 335*c322dbafSHans Petter Selasky fdev->fdev_state = MLX5_FDEV_STATE_IN_PROGRESS; 336*c322dbafSHans Petter Selasky reinit_completion(&fdev->load_event); 337*c322dbafSHans Petter Selasky err = mlx5_fpga_ctrl_op(mdev, MLX5_FPGA_CTRL_OPERATION_RELOAD); 338*c322dbafSHans Petter Selasky if (err) { 339*c322dbafSHans Petter Selasky mlx5_fpga_err(fdev, "Failed to request reload: %d\n", 340*c322dbafSHans Petter Selasky err); 341*c322dbafSHans Petter Selasky goto out; 342*c322dbafSHans Petter Selasky } 343*c322dbafSHans Petter Selasky timeout = jiffies + msecs_to_jiffies(MLX5_FPGA_LOAD_TIMEOUT); 344*c322dbafSHans Petter Selasky err = wait_for_completion_timeout(&fdev->load_event, 345*c322dbafSHans Petter Selasky timeout - jiffies); 346*c322dbafSHans Petter Selasky if (err < 0) { 347*c322dbafSHans Petter Selasky mlx5_fpga_err(fdev, "Failed waiting for reload: %d\n", err); 348*c322dbafSHans Petter Selasky fdev->fdev_state = MLX5_FDEV_STATE_FAILURE; 349*c322dbafSHans Petter Selasky goto out; 350*c322dbafSHans Petter Selasky } 351*c322dbafSHans Petter Selasky /* Check device loaded successful */ 352*c322dbafSHans Petter Selasky err = mlx5_fpga_device_start(mdev); 353*c322dbafSHans Petter Selasky if (err) { 354*c322dbafSHans Petter Selasky mlx5_fpga_err(fdev, "Failed load check for reload: %d\n", err); 355*c322dbafSHans Petter Selasky fdev->fdev_state = MLX5_FDEV_STATE_FAILURE; 356*c322dbafSHans Petter Selasky goto out; 357*c322dbafSHans Petter Selasky } 358*c322dbafSHans Petter Selasky spin_lock_irqsave(&fdev->state_lock, flags); 359*c322dbafSHans Petter Selasky fdev->fdev_state = MLX5_FDEV_STATE_SUCCESS; 360*c322dbafSHans Petter Selasky spin_unlock_irqrestore(&fdev->state_lock, flags); 361*c322dbafSHans Petter Selasky mlx5_fpga_info(fdev, "mlx5/fpga - reload ended\n"); 362*c322dbafSHans Petter Selasky out: 363*c322dbafSHans Petter Selasky return err; 364*c322dbafSHans Petter Selasky } 365*c322dbafSHans Petter Selasky 366e9dcd831SSlava Shwartsman int mlx5_fpga_device_reload(struct mlx5_fpga_device *fdev, 367e9dcd831SSlava Shwartsman enum mlx5_fpga_image image) 368e9dcd831SSlava Shwartsman { 369e9dcd831SSlava Shwartsman struct mlx5_core_dev *mdev = fdev->mdev; 370e9dcd831SSlava Shwartsman unsigned long timeout; 371e9dcd831SSlava Shwartsman unsigned long flags; 372e9dcd831SSlava Shwartsman int err = 0; 373e9dcd831SSlava Shwartsman 374e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags); 375e9dcd831SSlava Shwartsman switch (fdev->fdev_state) { 376e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_NONE: 377e9dcd831SSlava Shwartsman err = -ENODEV; 378e9dcd831SSlava Shwartsman break; 379e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_IN_PROGRESS: 380e9dcd831SSlava Shwartsman err = -EBUSY; 381e9dcd831SSlava Shwartsman break; 382e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_SUCCESS: 383e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_FAILURE: 384d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_DISCONNECTED: 385e9dcd831SSlava Shwartsman break; 386e9dcd831SSlava Shwartsman } 387e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 388e9dcd831SSlava Shwartsman if (err) 389e9dcd831SSlava Shwartsman return err; 390e9dcd831SSlava Shwartsman 391e9dcd831SSlava Shwartsman mutex_lock(&mdev->intf_state_mutex); 392*c322dbafSHans Petter Selasky 393*c322dbafSHans Petter Selasky if (image == MLX5_FPGA_IMAGE_RELOAD) { 394*c322dbafSHans Petter Selasky err = mlx5_fpga_device_reload_cmd(fdev); 395*c322dbafSHans Petter Selasky goto out; 396*c322dbafSHans Petter Selasky } 397*c322dbafSHans Petter Selasky 398e9dcd831SSlava Shwartsman clear_bit(MLX5_INTERFACE_STATE_UP, &mdev->intf_state); 399e9dcd831SSlava Shwartsman 400e9dcd831SSlava Shwartsman mlx5_unregister_device(mdev); 401e9dcd831SSlava Shwartsman /* XXXKIB mlx5_accel_ipsec_cleanup(mdev); */ 402e9dcd831SSlava Shwartsman mlx5_fpga_device_stop(mdev); 403e9dcd831SSlava Shwartsman 404e9dcd831SSlava Shwartsman fdev->fdev_state = MLX5_FDEV_STATE_IN_PROGRESS; 405e9dcd831SSlava Shwartsman reinit_completion(&fdev->load_event); 406e9dcd831SSlava Shwartsman 407*c322dbafSHans Petter Selasky if (image <= MLX5_FPGA_IMAGE_FACTORY) { 408e9dcd831SSlava Shwartsman mlx5_fpga_info(fdev, "Loading from flash\n"); 409e9dcd831SSlava Shwartsman err = mlx5_fpga_load(mdev, image); 410e9dcd831SSlava Shwartsman if (err) { 411e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to request load: %d\n", 412e9dcd831SSlava Shwartsman err); 413e9dcd831SSlava Shwartsman goto out; 414e9dcd831SSlava Shwartsman } 415*c322dbafSHans Petter Selasky } else if (image == MLX5_FPGA_IMAGE_RESET) { 416e9dcd831SSlava Shwartsman mlx5_fpga_info(fdev, "Resetting\n"); 417e9dcd831SSlava Shwartsman err = mlx5_fpga_ctrl_op(mdev, MLX5_FPGA_CTRL_OPERATION_RESET); 418e9dcd831SSlava Shwartsman if (err) { 419e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to request reset: %d\n", 420e9dcd831SSlava Shwartsman err); 421e9dcd831SSlava Shwartsman goto out; 422e9dcd831SSlava Shwartsman } 423*c322dbafSHans Petter Selasky } else { 424*c322dbafSHans Petter Selasky mlx5_fpga_err(fdev, "Unknown command: %d\n", 425*c322dbafSHans Petter Selasky image); 426*c322dbafSHans Petter Selasky goto out; 427e9dcd831SSlava Shwartsman } 428e9dcd831SSlava Shwartsman 429e9dcd831SSlava Shwartsman timeout = jiffies + msecs_to_jiffies(MLX5_FPGA_LOAD_TIMEOUT); 430e9dcd831SSlava Shwartsman err = wait_for_completion_timeout(&fdev->load_event, timeout - jiffies); 431e9dcd831SSlava Shwartsman if (err < 0) { 432e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed waiting for FPGA load: %d\n", err); 433e9dcd831SSlava Shwartsman fdev->fdev_state = MLX5_FDEV_STATE_FAILURE; 434e9dcd831SSlava Shwartsman goto out; 435e9dcd831SSlava Shwartsman } 436e9dcd831SSlava Shwartsman 437e9dcd831SSlava Shwartsman err = mlx5_fpga_device_start(mdev); 438e9dcd831SSlava Shwartsman if (err) { 439e9dcd831SSlava Shwartsman mlx5_core_err(mdev, "fpga device start failed %d\n", err); 440e9dcd831SSlava Shwartsman goto out; 441e9dcd831SSlava Shwartsman } 442e9dcd831SSlava Shwartsman /* XXXKIB err = mlx5_accel_ipsec_init(mdev); */ 443e9dcd831SSlava Shwartsman if (err) { 444e9dcd831SSlava Shwartsman mlx5_core_err(mdev, "IPSec device start failed %d\n", err); 445e9dcd831SSlava Shwartsman goto err_fpga; 446e9dcd831SSlava Shwartsman } 447e9dcd831SSlava Shwartsman 448e9dcd831SSlava Shwartsman err = mlx5_register_device(mdev); 449e9dcd831SSlava Shwartsman if (err) { 450e9dcd831SSlava Shwartsman mlx5_core_err(mdev, "mlx5_register_device failed %d\n", err); 451e9dcd831SSlava Shwartsman fdev->fdev_state = MLX5_FDEV_STATE_FAILURE; 452e9dcd831SSlava Shwartsman goto err_ipsec; 453e9dcd831SSlava Shwartsman } 454e9dcd831SSlava Shwartsman 455e9dcd831SSlava Shwartsman set_bit(MLX5_INTERFACE_STATE_UP, &mdev->intf_state); 456e9dcd831SSlava Shwartsman goto out; 457e9dcd831SSlava Shwartsman 458e9dcd831SSlava Shwartsman err_ipsec: 459e9dcd831SSlava Shwartsman /* XXXKIB mlx5_accel_ipsec_cleanup(mdev); */ 460e9dcd831SSlava Shwartsman err_fpga: 461e9dcd831SSlava Shwartsman mlx5_fpga_device_stop(mdev); 462e9dcd831SSlava Shwartsman out: 463e9dcd831SSlava Shwartsman mutex_unlock(&mdev->intf_state_mutex); 464e9dcd831SSlava Shwartsman return err; 465e9dcd831SSlava Shwartsman } 466e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_device_reload); 467e9dcd831SSlava Shwartsman 468e9dcd831SSlava Shwartsman int mlx5_fpga_flash_select(struct mlx5_fpga_device *fdev, 469e9dcd831SSlava Shwartsman enum mlx5_fpga_image image) 470e9dcd831SSlava Shwartsman { 471e9dcd831SSlava Shwartsman unsigned long flags; 472e9dcd831SSlava Shwartsman int err; 473e9dcd831SSlava Shwartsman 474e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags); 475e9dcd831SSlava Shwartsman switch (fdev->fdev_state) { 476e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_NONE: 477e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 478e9dcd831SSlava Shwartsman return -ENODEV; 479d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_DISCONNECTED: 480e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_IN_PROGRESS: 481e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_SUCCESS: 482e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_FAILURE: 483e9dcd831SSlava Shwartsman break; 484e9dcd831SSlava Shwartsman } 485e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 486e9dcd831SSlava Shwartsman 487e9dcd831SSlava Shwartsman err = mlx5_fpga_image_select(fdev->mdev, image); 488e9dcd831SSlava Shwartsman if (err) 489e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to select flash image: %d\n", err); 490e9dcd831SSlava Shwartsman else 491e9dcd831SSlava Shwartsman fdev->last_admin_image = image; 492e9dcd831SSlava Shwartsman return err; 493e9dcd831SSlava Shwartsman } 494e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_flash_select); 495e9dcd831SSlava Shwartsman 496d82f1c13SSlava Shwartsman int mlx5_fpga_connectdisconnect(struct mlx5_fpga_device *fdev, 497d82f1c13SSlava Shwartsman enum mlx5_fpga_connect *connect) 498d82f1c13SSlava Shwartsman { 499d82f1c13SSlava Shwartsman unsigned long flags; 500d82f1c13SSlava Shwartsman int err; 501d82f1c13SSlava Shwartsman 502d82f1c13SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags); 503d82f1c13SSlava Shwartsman switch (fdev->fdev_state) { 504d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_NONE: 505d82f1c13SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 506d82f1c13SSlava Shwartsman return -ENODEV; 507d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_IN_PROGRESS: 508d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_SUCCESS: 509d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_FAILURE: 510d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_DISCONNECTED: 511d82f1c13SSlava Shwartsman break; 512d82f1c13SSlava Shwartsman } 513d82f1c13SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 514d82f1c13SSlava Shwartsman 515d82f1c13SSlava Shwartsman err = mlx5_fpga_ctrl_connect(fdev->mdev, connect); 516d82f1c13SSlava Shwartsman if (err) 517d82f1c13SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to connect/disconnect: %d\n", err); 518d82f1c13SSlava Shwartsman return err; 519d82f1c13SSlava Shwartsman } 520d82f1c13SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_connectdisconnect); 521d82f1c13SSlava Shwartsman 522085b35bbSSlava Shwartsman int mlx5_fpga_temperature(struct mlx5_fpga_device *fdev, 523085b35bbSSlava Shwartsman struct mlx5_fpga_temperature *temp) 524085b35bbSSlava Shwartsman { 525085b35bbSSlava Shwartsman return mlx5_fpga_query_mtmp(fdev->mdev, temp); 526085b35bbSSlava Shwartsman } 527085b35bbSSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_temperature); 528085b35bbSSlava Shwartsman 529e9dcd831SSlava Shwartsman struct device *mlx5_fpga_dev(struct mlx5_fpga_device *fdev) 530e9dcd831SSlava Shwartsman { 531e9dcd831SSlava Shwartsman return &fdev->mdev->pdev->dev; 532e9dcd831SSlava Shwartsman } 533e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_dev); 534e9dcd831SSlava Shwartsman 535e9dcd831SSlava Shwartsman void mlx5_fpga_get_cap(struct mlx5_fpga_device *fdev, u32 *fpga_caps) 536e9dcd831SSlava Shwartsman { 537e9dcd831SSlava Shwartsman unsigned long flags; 538e9dcd831SSlava Shwartsman 539e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags); 540e9dcd831SSlava Shwartsman memcpy(fpga_caps, &fdev->mdev->caps.fpga, sizeof(fdev->mdev->caps.fpga)); 541e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags); 542e9dcd831SSlava Shwartsman } 543e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_get_cap); 544