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 #ifndef MLX5_FPGA_SDK_H 34 #define MLX5_FPGA_SDK_H 35 36 #include <dev/mlx5/driver.h> 37 #include <linux/types.h> 38 #include <linux/list.h> 39 /* #include <linux/dma-direction.h> */ 40 41 #include <dev/mlx5/mlx5_fpga/cmd.h> 42 #include <dev/mlx5/mlx5io.h> 43 44 /** 45 * DOC: Innova SDK 46 * This header defines the in-kernel API for Innova FPGA client drivers. 47 */ 48 49 #define MLX5_FPGA_CLIENT_NAME_MAX 64 50 51 struct mlx5_fpga_conn; 52 struct mlx5_fpga_device; 53 54 /** 55 * struct mlx5_fpga_client - Describes an Innova client driver 56 */ 57 struct mlx5_fpga_client { 58 /** 59 * @create: Informs the client that an Innova device was created. 60 * The device is not yet operational at this stage 61 * This callback is optional 62 * @fdev: The FPGA device 63 */ 64 void (*create)(struct mlx5_fpga_device *fdev); 65 /** 66 * @add: Informs the client that a core device is ready and operational. 67 * @fdev: The FPGA device 68 * @param vid SBU Vendor ID 69 * @param pid SBU Product ID 70 * Any SBU-specific initialization should happen at this stage 71 * Return: 0 on success, nonzero error value otherwise 72 */ 73 int (*add)(struct mlx5_fpga_device *fdev, u32 vid, u16 pid); 74 /** 75 * @remove: Informs the client that a core device is not operational 76 * anymore. 77 * @fdev: The FPGA device 78 * SBU-specific cleanup should happen at this stage 79 * This callback is called once for every successful call to add() 80 */ 81 void (*remove)(struct mlx5_fpga_device *fdev); 82 /** 83 * @destroy: Informs the client that a core device is being destroyed. 84 * @fdev: The FPGA device 85 * The device is not operational at this stage 86 */ 87 void (*destroy)(struct mlx5_fpga_device *fdev); 88 /** The name of this client driver */ 89 char name[MLX5_FPGA_CLIENT_NAME_MAX]; 90 /** For use by core. A link in the list of client drivers */ 91 struct list_head list; 92 }; 93 94 /** 95 * struct mlx5_fpga_dma_entry - A scatter-gather DMA entry 96 */ 97 struct mlx5_fpga_dma_entry { 98 /** @data: Virtual address pointer to the data */ 99 void *data; 100 /** @size: Size in bytes of the data */ 101 unsigned int size; 102 /** @dma_addr: Private member. Physical DMA-mapped address of the data */ 103 dma_addr_t dma_addr; 104 }; 105 106 /** 107 * struct mlx5_fpga_dma_buf - A packet buffer 108 * May contain up to 2 scatter-gather data entries 109 */ 110 struct mlx5_fpga_dma_buf { 111 /** @dma_dir: DMA direction */ 112 enum dma_data_direction dma_dir; 113 /** @sg: Scatter-gather entries pointing to the data in memory */ 114 struct mlx5_fpga_dma_entry sg[2]; 115 /** @list: Item in SQ backlog, for TX packets */ 116 struct list_head list; 117 /** 118 * @complete: Completion routine, for TX packets 119 * @conn: FPGA Connection this packet was sent to 120 * @fdev: FPGA device this packet was sent to 121 * @buf: The packet buffer 122 * @status: 0 if successful, or an error code otherwise 123 */ 124 void (*complete)(struct mlx5_fpga_conn *conn, 125 struct mlx5_fpga_device *fdev, 126 struct mlx5_fpga_dma_buf *buf, u8 status); 127 }; 128 129 /** 130 * struct mlx5_fpga_conn_attr - FPGA connection attributes 131 * Describes the attributes of a connection 132 */ 133 struct mlx5_fpga_conn_attr { 134 /** @tx_size: Size of connection TX queue, in packets */ 135 unsigned int tx_size; 136 /** @rx_size: Size of connection RX queue, in packets */ 137 unsigned int rx_size; 138 /** 139 * @recv_cb: Callback function which is called for received packets 140 * @cb_arg: The value provided in mlx5_fpga_conn_attr.cb_arg 141 * @buf: A buffer containing a received packet 142 * 143 * buf is guaranteed to only contain a single scatter-gather entry. 144 * The size of the actual packet received is specified in buf.sg[0].size 145 * When this callback returns, the packet buffer may be re-used for 146 * subsequent receives. 147 */ 148 void (*recv_cb)(void *cb_arg, struct mlx5_fpga_dma_buf *buf); 149 void *cb_arg; 150 }; 151 152 /** 153 * mlx5_fpga_client_register() - Register a client driver 154 * @client: The properties of the client driver 155 * 156 * Should be called from a client driver's module init routine. 157 * Note: The core will immediately callback create() and add() for any existing 158 * devices in the system, as well as new ones added later on. 159 */ 160 void mlx5_fpga_client_register(struct mlx5_fpga_client *client); 161 /** 162 * mlx5_fpga_client_unregister() - Unregister a client driver 163 * @client: The client driver to unregister 164 * 165 * Should be called from a client driver's module exit routine. 166 * Note: The core will immediately callback delete() and destroy() for any 167 * created/added devices in the system, to clean up their state. 168 */ 169 void mlx5_fpga_client_unregister(struct mlx5_fpga_client *client); 170 171 /** 172 * mlx5_fpga_device_reload() - Force the FPGA to reload its synthesis from flash 173 * @fdev: The FPGA device 174 * @image: Which flash image to load 175 * 176 * This routine attempts graceful teardown of all device resources before 177 * loading. This includes a callback to client driver delete(). 178 * Calls client driver add() once device is operational again. 179 * Blocks until the new synthesis is loaded, and the device is fully 180 * initialized. 181 * 182 * Return: 0 if successful, or a negative error value otherwise 183 */ 184 int mlx5_fpga_device_reload(struct mlx5_fpga_device *fdev, 185 enum mlx5_fpga_image image); 186 187 /** 188 * mlx5_fpga_flash_select() - Select the current active flash 189 * @fdev: The FPGA device 190 * @image: Which flash image will be active 191 * 192 * This routine selects the active flash by programming the relevant MUX. 193 * Useful prior to burning a new image on flash. 194 * This setting is volatile and is reset upon reboot or power-cycle 195 * 196 * Return: 0 if successful, or a negative error value otherwise 197 */ 198 int mlx5_fpga_flash_select(struct mlx5_fpga_device *fdev, 199 enum mlx5_fpga_image image); 200 201 /** 202 * mlx5_fpga_sbu_conn_create() - Initialize a new FPGA SBU connection 203 * @fdev: The FPGA device 204 * @attr: Attributes of the new connection 205 * 206 * Sets up a new FPGA SBU connection with the specified attributes. 207 * The receive callback function may be called for incoming messages even 208 * before this function returns. 209 * 210 * The caller must eventually destroy the connection by calling 211 * mlx5_fpga_sbu_conn_destroy. 212 * 213 * Return: A new connection, or ERR_PTR() error value otherwise. 214 */ 215 struct mlx5_fpga_conn * 216 mlx5_fpga_sbu_conn_create(struct mlx5_fpga_device *fdev, 217 struct mlx5_fpga_conn_attr *attr); 218 219 /** 220 * mlx5_fpga_sbu_conn_destroy() - Destroy an FPGA SBU connection 221 * @conn: The FPGA SBU connection to destroy 222 * 223 * Cleans up an FPGA SBU connection which was previously created with 224 * mlx5_fpga_sbu_conn_create. 225 */ 226 void mlx5_fpga_sbu_conn_destroy(struct mlx5_fpga_conn *conn); 227 228 /** 229 * mlx5_fpga_sbu_conn_sendmsg() - Queue the transmission of a packet 230 * @fdev: An FPGA SBU connection 231 * @buf: The packet buffer 232 * 233 * Queues a packet for transmission over an FPGA SBU connection. 234 * The buffer should not be modified or freed until completion. 235 * Upon completion, the buf's complete() callback is invoked, indicating the 236 * success or error status of the transmission. 237 * 238 * Return: 0 if successful, or an error value otherwise. 239 */ 240 int mlx5_fpga_sbu_conn_sendmsg(struct mlx5_fpga_conn *conn, 241 struct mlx5_fpga_dma_buf *buf); 242 243 /** 244 * mlx5_fpga_mem_read() - Read from FPGA memory address space 245 * @fdev: The FPGA device 246 * @size: Size of chunk to read, in bytes 247 * @addr: Starting address to read from, in FPGA address space 248 * @buf: Buffer to read into 249 * @access_type: Method for reading 250 * 251 * Reads from the specified address into the specified buffer. 252 * The address may point to configuration space or to DDR. 253 * Large reads may be performed internally as several non-atomic operations. 254 * This function may sleep, so should not be called from atomic contexts. 255 * 256 * Return: 0 if successful, or an error value otherwise. 257 */ 258 int mlx5_fpga_mem_read(struct mlx5_fpga_device *fdev, size_t size, u64 addr, 259 void *buf, enum mlx5_fpga_access_type access_type); 260 261 /** 262 * mlx5_fpga_mem_write() - Write to FPGA memory address space 263 * @fdev: The FPGA device 264 * @size: Size of chunk to write, in bytes 265 * @addr: Starting address to write to, in FPGA address space 266 * @buf: Buffer which contains data to write 267 * @access_type: Method for writing 268 * 269 * Writes the specified buffer data to FPGA memory at the specified address. 270 * The address may point to configuration space or to DDR. 271 * Large writes may be performed internally as several non-atomic operations. 272 * This function may sleep, so should not be called from atomic contexts. 273 * 274 * Return: 0 if successful, or an error value otherwise. 275 */ 276 int mlx5_fpga_mem_write(struct mlx5_fpga_device *fdev, size_t size, u64 addr, 277 void *buf, enum mlx5_fpga_access_type access_type); 278 279 /** 280 * mlx5_fpga_get_sbu_caps() - Read the SBU capabilities 281 * @fdev: The FPGA device 282 * @size: Size of the buffer to read into 283 * @buf: Buffer to read the capabilities into 284 * 285 * Reads the FPGA SBU capabilities into the specified buffer. 286 * The format of the capabilities buffer is SBU-dependent. 287 * 288 * Return: 0 if successful 289 * -EINVAL if the buffer is not large enough to contain SBU caps 290 * or any other error value otherwise. 291 */ 292 int mlx5_fpga_get_sbu_caps(struct mlx5_fpga_device *fdev, int size, void *buf); 293 294 /** 295 * mlx5_fpga_ddr_size_get() - Retrieve the size of FPGA DDR 296 * @fdev: The FPGA device 297 * 298 * Return: Size of DDR avaailable for FPGA, in bytes 299 */ 300 u64 mlx5_fpga_ddr_size_get(struct mlx5_fpga_device *fdev); 301 302 /** 303 * mlx5_fpga_ddr_base_get() - Retrieve the base address of FPGA DDR 304 * @fdev: The FPGA device 305 * 306 * Return: Base address of DDR in FPGA address space 307 */ 308 u64 mlx5_fpga_ddr_base_get(struct mlx5_fpga_device *fdev); 309 310 /** 311 * mlx5_fpga_client_data_set() - Attach client-defined private value to a device 312 * @fdev: The FPGA device 313 * @client: The client driver 314 * @data: Opaque private value 315 * 316 * Client driver may use the private value for storing device-specific 317 * state and configuration information, and may retrieve it with a call to 318 * mlx5_fpga_client_data_get(). 319 */ 320 void mlx5_fpga_client_data_set(struct mlx5_fpga_device *fdev, 321 struct mlx5_fpga_client *client, 322 void *data); 323 324 /** 325 * mlx5_fpga_client_data_get() - Retrieve client-defined private value 326 * @fdev: The FPGA device 327 * @client: The client driver 328 * 329 * Client driver may use the private value for storing device-specific 330 * state and configuration information by calling mlx5_fpga_client_data_set() 331 * 332 * Return: The private value 333 */ 334 void *mlx5_fpga_client_data_get(struct mlx5_fpga_device *fdev, 335 struct mlx5_fpga_client *client); 336 337 /** 338 * mlx5_fpga_device_query() - Query FPGA device state information 339 * @fdev: The FPGA device 340 * @query: Returns the device state 341 * 342 * Queries the device state and returns it in *query 343 */ 344 void mlx5_fpga_device_query(struct mlx5_fpga_device *fdev, 345 struct mlx5_fpga_query *query); 346 347 /** 348 * mlx5_fpga_dev() - Retrieve FPGA device structure 349 * @fdev: The FPGA device 350 351 * Return: A pointer to a struct device, which may be used with dev_* logging, 352 * sysfs extensions, etc. 353 */ 354 struct device *mlx5_fpga_dev(struct mlx5_fpga_device *fdev); 355 356 /** 357 * mlx5_fpga_temperature() - Retrieve FPGA sensor of temperature 358 * @fdev: The FPGA device 359 360 * Return: 0 if successful 361 * or any other error value otherwise. 362 */ 363 int mlx5_fpga_temperature(struct mlx5_fpga_device *fdev, 364 struct mlx5_fpga_temperature *temp); 365 366 /** 367 * mlx5_fpga_connectdisconnect() - Connect/disconnect ConnectX to FPGA 368 * @fdev: The FPGA device 369 370 * Return: 0 if successful 371 * or any other error value otherwise. 372 */ 373 int mlx5_fpga_connectdisconnect(struct mlx5_fpga_device *fdev, 374 enum mlx5_fpga_connect *connect); 375 376 /** 377 * mlx5_fpga_get_cap() - Returns the FPGA cap mailbox from FW without parsing. 378 * @fdev: The FPGA device 379 * @fpga_caps: Is an array with a length of according to the size of 380 * mlx5_ifc_fpga_cap_bits/32 381 * 382 * Returns a copy of the FPGA caps mailbox and returns it in fpga_caps 383 */ 384 void mlx5_fpga_get_cap(struct mlx5_fpga_device *fdev, u32 *fpga_caps); 385 386 #endif /* MLX5_FPGA_SDK_H */ 387