| .. | .. |
|---|
| 36 | 36 | |
|---|
| 37 | 37 | #include "mlx5_core.h" |
|---|
| 38 | 38 | #include "lib/mlx5.h" |
|---|
| 39 | +#include "lib/eq.h" |
|---|
| 39 | 40 | #include "fpga/core.h" |
|---|
| 40 | 41 | #include "fpga/conn.h" |
|---|
| 41 | 42 | |
|---|
| .. | .. |
|---|
| 80 | 81 | } |
|---|
| 81 | 82 | } |
|---|
| 82 | 83 | |
|---|
| 83 | | -static const char *mlx5_fpga_device_name(u32 device) |
|---|
| 84 | +static const char *mlx5_fpga_name(u32 fpga_id) |
|---|
| 84 | 85 | { |
|---|
| 85 | | - switch (device) { |
|---|
| 86 | | - case MLX5_FPGA_DEVICE_KU040: |
|---|
| 87 | | - return "ku040"; |
|---|
| 88 | | - case MLX5_FPGA_DEVICE_KU060: |
|---|
| 89 | | - return "ku060"; |
|---|
| 90 | | - case MLX5_FPGA_DEVICE_KU060_2: |
|---|
| 91 | | - return "ku060_2"; |
|---|
| 92 | | - case MLX5_FPGA_DEVICE_UNKNOWN: |
|---|
| 93 | | - default: |
|---|
| 94 | | - return "unknown"; |
|---|
| 86 | + static char ret[32]; |
|---|
| 87 | + |
|---|
| 88 | + switch (fpga_id) { |
|---|
| 89 | + case MLX5_FPGA_NEWTON: |
|---|
| 90 | + return "Newton"; |
|---|
| 91 | + case MLX5_FPGA_EDISON: |
|---|
| 92 | + return "Edison"; |
|---|
| 93 | + case MLX5_FPGA_MORSE: |
|---|
| 94 | + return "Morse"; |
|---|
| 95 | + case MLX5_FPGA_MORSEQ: |
|---|
| 96 | + return "MorseQ"; |
|---|
| 95 | 97 | } |
|---|
| 98 | + |
|---|
| 99 | + snprintf(ret, sizeof(ret), "Unknown %d", fpga_id); |
|---|
| 100 | + return ret; |
|---|
| 101 | +} |
|---|
| 102 | + |
|---|
| 103 | +static int mlx5_is_fpga_lookaside(u32 fpga_id) |
|---|
| 104 | +{ |
|---|
| 105 | + return fpga_id != MLX5_FPGA_NEWTON && fpga_id != MLX5_FPGA_EDISON; |
|---|
| 96 | 106 | } |
|---|
| 97 | 107 | |
|---|
| 98 | 108 | static int mlx5_fpga_device_load_check(struct mlx5_fpga_device *fdev) |
|---|
| .. | .. |
|---|
| 109 | 119 | fdev->last_admin_image = query.admin_image; |
|---|
| 110 | 120 | fdev->last_oper_image = query.oper_image; |
|---|
| 111 | 121 | |
|---|
| 112 | | - mlx5_fpga_dbg(fdev, "Status %u; Admin image %u; Oper image %u\n", |
|---|
| 113 | | - query.status, query.admin_image, query.oper_image); |
|---|
| 122 | + mlx5_fpga_info(fdev, "Status %u; Admin image %u; Oper image %u\n", |
|---|
| 123 | + query.status, query.admin_image, query.oper_image); |
|---|
| 124 | + |
|---|
| 125 | + /* for FPGA lookaside projects FPGA load status is not important */ |
|---|
| 126 | + if (mlx5_is_fpga_lookaside(MLX5_CAP_FPGA(fdev->mdev, fpga_id))) |
|---|
| 127 | + return 0; |
|---|
| 114 | 128 | |
|---|
| 115 | 129 | if (query.status != MLX5_FPGA_STATUS_SUCCESS) { |
|---|
| 116 | 130 | mlx5_fpga_err(fdev, "%s image failed to load; status %u\n", |
|---|
| .. | .. |
|---|
| 145 | 159 | return 0; |
|---|
| 146 | 160 | } |
|---|
| 147 | 161 | |
|---|
| 162 | +static int mlx5_fpga_event(struct mlx5_fpga_device *, unsigned long, void *); |
|---|
| 163 | + |
|---|
| 164 | +static int fpga_err_event(struct notifier_block *nb, unsigned long event, void *eqe) |
|---|
| 165 | +{ |
|---|
| 166 | + struct mlx5_fpga_device *fdev = mlx5_nb_cof(nb, struct mlx5_fpga_device, fpga_err_nb); |
|---|
| 167 | + |
|---|
| 168 | + return mlx5_fpga_event(fdev, event, eqe); |
|---|
| 169 | +} |
|---|
| 170 | + |
|---|
| 171 | +static int fpga_qp_err_event(struct notifier_block *nb, unsigned long event, void *eqe) |
|---|
| 172 | +{ |
|---|
| 173 | + struct mlx5_fpga_device *fdev = mlx5_nb_cof(nb, struct mlx5_fpga_device, fpga_qp_err_nb); |
|---|
| 174 | + |
|---|
| 175 | + return mlx5_fpga_event(fdev, event, eqe); |
|---|
| 176 | +} |
|---|
| 177 | + |
|---|
| 148 | 178 | int mlx5_fpga_device_start(struct mlx5_core_dev *mdev) |
|---|
| 149 | 179 | { |
|---|
| 150 | 180 | struct mlx5_fpga_device *fdev = mdev->fpga; |
|---|
| 151 | 181 | unsigned int max_num_qps; |
|---|
| 152 | 182 | unsigned long flags; |
|---|
| 153 | | - u32 fpga_device_id; |
|---|
| 183 | + u32 fpga_id; |
|---|
| 154 | 184 | int err; |
|---|
| 155 | 185 | |
|---|
| 156 | 186 | if (!fdev) |
|---|
| 157 | 187 | return 0; |
|---|
| 158 | 188 | |
|---|
| 159 | | - err = mlx5_fpga_device_load_check(fdev); |
|---|
| 160 | | - if (err) |
|---|
| 161 | | - goto out; |
|---|
| 162 | | - |
|---|
| 163 | 189 | err = mlx5_fpga_caps(fdev->mdev); |
|---|
| 164 | 190 | if (err) |
|---|
| 165 | 191 | goto out; |
|---|
| 166 | 192 | |
|---|
| 167 | | - fpga_device_id = MLX5_CAP_FPGA(fdev->mdev, fpga_device); |
|---|
| 168 | | - mlx5_fpga_info(fdev, "%s:%u; %s image, version %u; SBU %06x:%04x version %d\n", |
|---|
| 169 | | - mlx5_fpga_device_name(fpga_device_id), |
|---|
| 170 | | - fpga_device_id, |
|---|
| 193 | + err = mlx5_fpga_device_load_check(fdev); |
|---|
| 194 | + if (err) |
|---|
| 195 | + goto out; |
|---|
| 196 | + |
|---|
| 197 | + fpga_id = MLX5_CAP_FPGA(fdev->mdev, fpga_id); |
|---|
| 198 | + mlx5_fpga_info(fdev, "FPGA card %s:%u\n", mlx5_fpga_name(fpga_id), fpga_id); |
|---|
| 199 | + |
|---|
| 200 | + /* No QPs if FPGA does not participate in net processing */ |
|---|
| 201 | + if (mlx5_is_fpga_lookaside(fpga_id)) |
|---|
| 202 | + goto out; |
|---|
| 203 | + |
|---|
| 204 | + mlx5_fpga_info(fdev, "%s(%d): image, version %u; SBU %06x:%04x version %d\n", |
|---|
| 171 | 205 | mlx5_fpga_image_name(fdev->last_oper_image), |
|---|
| 206 | + fdev->last_oper_image, |
|---|
| 172 | 207 | MLX5_CAP_FPGA(fdev->mdev, image_version), |
|---|
| 173 | 208 | MLX5_CAP_FPGA(fdev->mdev, ieee_vendor_id), |
|---|
| 174 | 209 | MLX5_CAP_FPGA(fdev->mdev, sandbox_product_id), |
|---|
| .. | .. |
|---|
| 184 | 219 | err = mlx5_core_reserve_gids(mdev, max_num_qps); |
|---|
| 185 | 220 | if (err) |
|---|
| 186 | 221 | goto out; |
|---|
| 222 | + |
|---|
| 223 | + MLX5_NB_INIT(&fdev->fpga_err_nb, fpga_err_event, FPGA_ERROR); |
|---|
| 224 | + MLX5_NB_INIT(&fdev->fpga_qp_err_nb, fpga_qp_err_event, FPGA_QP_ERROR); |
|---|
| 225 | + mlx5_eq_notifier_register(fdev->mdev, &fdev->fpga_err_nb); |
|---|
| 226 | + mlx5_eq_notifier_register(fdev->mdev, &fdev->fpga_qp_err_nb); |
|---|
| 187 | 227 | |
|---|
| 188 | 228 | err = mlx5_fpga_conn_device_init(fdev); |
|---|
| 189 | 229 | if (err) |
|---|
| .. | .. |
|---|
| 201 | 241 | mlx5_fpga_conn_device_cleanup(fdev); |
|---|
| 202 | 242 | |
|---|
| 203 | 243 | err_rsvd_gid: |
|---|
| 244 | + mlx5_eq_notifier_unregister(fdev->mdev, &fdev->fpga_err_nb); |
|---|
| 245 | + mlx5_eq_notifier_unregister(fdev->mdev, &fdev->fpga_qp_err_nb); |
|---|
| 204 | 246 | mlx5_core_unreserve_gids(mdev, max_num_qps); |
|---|
| 205 | 247 | out: |
|---|
| 206 | 248 | spin_lock_irqsave(&fdev->state_lock, flags); |
|---|
| .. | .. |
|---|
| 240 | 282 | if (!fdev) |
|---|
| 241 | 283 | return; |
|---|
| 242 | 284 | |
|---|
| 285 | + if (mlx5_is_fpga_lookaside(MLX5_CAP_FPGA(fdev->mdev, fpga_id))) |
|---|
| 286 | + return; |
|---|
| 287 | + |
|---|
| 243 | 288 | spin_lock_irqsave(&fdev->state_lock, flags); |
|---|
| 244 | 289 | if (fdev->state != MLX5_FPGA_STATUS_SUCCESS) { |
|---|
| 245 | 290 | spin_unlock_irqrestore(&fdev->state_lock, flags); |
|---|
| .. | .. |
|---|
| 256 | 301 | } |
|---|
| 257 | 302 | |
|---|
| 258 | 303 | mlx5_fpga_conn_device_cleanup(fdev); |
|---|
| 304 | + mlx5_eq_notifier_unregister(fdev->mdev, &fdev->fpga_err_nb); |
|---|
| 305 | + mlx5_eq_notifier_unregister(fdev->mdev, &fdev->fpga_qp_err_nb); |
|---|
| 306 | + |
|---|
| 259 | 307 | max_num_qps = MLX5_CAP_FPGA(mdev, shell_caps.max_num_qps); |
|---|
| 260 | 308 | mlx5_core_unreserve_gids(mdev, max_num_qps); |
|---|
| 261 | 309 | } |
|---|
| .. | .. |
|---|
| 283 | 331 | return "Unknown"; |
|---|
| 284 | 332 | } |
|---|
| 285 | 333 | |
|---|
| 286 | | -void mlx5_fpga_event(struct mlx5_core_dev *mdev, u8 event, void *data) |
|---|
| 334 | +static int mlx5_fpga_event(struct mlx5_fpga_device *fdev, |
|---|
| 335 | + unsigned long event, void *eqe) |
|---|
| 287 | 336 | { |
|---|
| 288 | | - struct mlx5_fpga_device *fdev = mdev->fpga; |
|---|
| 337 | + void *data = ((struct mlx5_eqe *)eqe)->data.raw; |
|---|
| 289 | 338 | const char *event_name; |
|---|
| 290 | 339 | bool teardown = false; |
|---|
| 291 | 340 | unsigned long flags; |
|---|
| .. | .. |
|---|
| 301 | 350 | event_name = mlx5_fpga_qp_syndrome_to_string(syndrome); |
|---|
| 302 | 351 | break; |
|---|
| 303 | 352 | default: |
|---|
| 304 | | - mlx5_fpga_warn_ratelimited(fdev, "Unexpected event %u\n", |
|---|
| 305 | | - event); |
|---|
| 306 | | - return; |
|---|
| 353 | + return NOTIFY_DONE; |
|---|
| 307 | 354 | } |
|---|
| 308 | 355 | |
|---|
| 309 | 356 | spin_lock_irqsave(&fdev->state_lock, flags); |
|---|
| .. | .. |
|---|
| 324 | 371 | */ |
|---|
| 325 | 372 | if (teardown) |
|---|
| 326 | 373 | mlx5_trigger_health_work(fdev->mdev); |
|---|
| 374 | + |
|---|
| 375 | + return NOTIFY_OK; |
|---|
| 327 | 376 | } |
|---|