.. | .. |
---|
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 | } |
---|