diff options
author | Eli Cohen <eli@dev.mellanox.co.il> | 2013-07-18 08:31:08 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-07-31 17:12:24 -0400 |
commit | cd23b14b654769db83c9684ae1ba32c0e066670f (patch) | |
tree | 60270d1f4313fa4938f05ec9773b7994c81be676 /drivers/net/ethernet | |
parent | 11940c8728b8e4bd67d0afacefbb9391ff8f4201 (diff) |
mlx5_core: Implement new initialization sequence
Introduce enbale_hca and disable_hca commands to signify when the
driver starts or ceases to operate on the device.
In addition the driver will use boot and init pages count; boot pages
is required to allow firmware to complete boot commands and the other
to complete init hca. Command interface revision is bumped to 4 to
enforce using supported firmware.
This patch breaks compatibility with old versions of firmware (< 4);
however, the first GA firmware we will publish will support version 4
so this should not be a problem.
Signed-off-by: Eli Cohen <eli@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/main.c | 69 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 20 |
3 files changed, 83 insertions, 14 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index 40374063c01e..c571de85d0f9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include "mlx5_core.h" | 46 | #include "mlx5_core.h" |
47 | 47 | ||
48 | enum { | 48 | enum { |
49 | CMD_IF_REV = 3, | 49 | CMD_IF_REV = 4, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | enum { | 52 | enum { |
@@ -282,6 +282,12 @@ const char *mlx5_command_str(int command) | |||
282 | case MLX5_CMD_OP_TEARDOWN_HCA: | 282 | case MLX5_CMD_OP_TEARDOWN_HCA: |
283 | return "TEARDOWN_HCA"; | 283 | return "TEARDOWN_HCA"; |
284 | 284 | ||
285 | case MLX5_CMD_OP_ENABLE_HCA: | ||
286 | return "MLX5_CMD_OP_ENABLE_HCA"; | ||
287 | |||
288 | case MLX5_CMD_OP_DISABLE_HCA: | ||
289 | return "MLX5_CMD_OP_DISABLE_HCA"; | ||
290 | |||
285 | case MLX5_CMD_OP_QUERY_PAGES: | 291 | case MLX5_CMD_OP_QUERY_PAGES: |
286 | return "QUERY_PAGES"; | 292 | return "QUERY_PAGES"; |
287 | 293 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 12242de2b0e3..b47739b0b5f6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
@@ -249,6 +249,44 @@ static int set_hca_ctrl(struct mlx5_core_dev *dev) | |||
249 | return err; | 249 | return err; |
250 | } | 250 | } |
251 | 251 | ||
252 | static int mlx5_core_enable_hca(struct mlx5_core_dev *dev) | ||
253 | { | ||
254 | int err; | ||
255 | struct mlx5_enable_hca_mbox_in in; | ||
256 | struct mlx5_enable_hca_mbox_out out; | ||
257 | |||
258 | memset(&in, 0, sizeof(in)); | ||
259 | memset(&out, 0, sizeof(out)); | ||
260 | in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ENABLE_HCA); | ||
261 | err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); | ||
262 | if (err) | ||
263 | return err; | ||
264 | |||
265 | if (out.hdr.status) | ||
266 | return mlx5_cmd_status_to_err(&out.hdr); | ||
267 | |||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static int mlx5_core_disable_hca(struct mlx5_core_dev *dev) | ||
272 | { | ||
273 | int err; | ||
274 | struct mlx5_disable_hca_mbox_in in; | ||
275 | struct mlx5_disable_hca_mbox_out out; | ||
276 | |||
277 | memset(&in, 0, sizeof(in)); | ||
278 | memset(&out, 0, sizeof(out)); | ||
279 | in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DISABLE_HCA); | ||
280 | err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); | ||
281 | if (err) | ||
282 | return err; | ||
283 | |||
284 | if (out.hdr.status) | ||
285 | return mlx5_cmd_status_to_err(&out.hdr); | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
252 | int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev) | 290 | int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev) |
253 | { | 291 | { |
254 | struct mlx5_priv *priv = &dev->priv; | 292 | struct mlx5_priv *priv = &dev->priv; |
@@ -304,28 +342,41 @@ int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev) | |||
304 | } | 342 | } |
305 | 343 | ||
306 | mlx5_pagealloc_init(dev); | 344 | mlx5_pagealloc_init(dev); |
345 | |||
346 | err = mlx5_core_enable_hca(dev); | ||
347 | if (err) { | ||
348 | dev_err(&pdev->dev, "enable hca failed\n"); | ||
349 | goto err_pagealloc_cleanup; | ||
350 | } | ||
351 | |||
352 | err = mlx5_satisfy_startup_pages(dev, 1); | ||
353 | if (err) { | ||
354 | dev_err(&pdev->dev, "failed to allocate boot pages\n"); | ||
355 | goto err_disable_hca; | ||
356 | } | ||
357 | |||
307 | err = set_hca_ctrl(dev); | 358 | err = set_hca_ctrl(dev); |
308 | if (err) { | 359 | if (err) { |
309 | dev_err(&pdev->dev, "set_hca_ctrl failed\n"); | 360 | dev_err(&pdev->dev, "set_hca_ctrl failed\n"); |
310 | goto err_pagealloc_cleanup; | 361 | goto reclaim_boot_pages; |
311 | } | 362 | } |
312 | 363 | ||
313 | err = handle_hca_cap(dev); | 364 | err = handle_hca_cap(dev); |
314 | if (err) { | 365 | if (err) { |
315 | dev_err(&pdev->dev, "handle_hca_cap failed\n"); | 366 | dev_err(&pdev->dev, "handle_hca_cap failed\n"); |
316 | goto err_pagealloc_cleanup; | 367 | goto reclaim_boot_pages; |
317 | } | 368 | } |
318 | 369 | ||
319 | err = mlx5_satisfy_startup_pages(dev); | 370 | err = mlx5_satisfy_startup_pages(dev, 0); |
320 | if (err) { | 371 | if (err) { |
321 | dev_err(&pdev->dev, "failed to allocate startup pages\n"); | 372 | dev_err(&pdev->dev, "failed to allocate init pages\n"); |
322 | goto err_pagealloc_cleanup; | 373 | goto reclaim_boot_pages; |
323 | } | 374 | } |
324 | 375 | ||
325 | err = mlx5_pagealloc_start(dev); | 376 | err = mlx5_pagealloc_start(dev); |
326 | if (err) { | 377 | if (err) { |
327 | dev_err(&pdev->dev, "mlx5_pagealloc_start failed\n"); | 378 | dev_err(&pdev->dev, "mlx5_pagealloc_start failed\n"); |
328 | goto err_reclaim_pages; | 379 | goto reclaim_boot_pages; |
329 | } | 380 | } |
330 | 381 | ||
331 | err = mlx5_cmd_init_hca(dev); | 382 | err = mlx5_cmd_init_hca(dev); |
@@ -396,9 +447,12 @@ err_stop_poll: | |||
396 | err_pagealloc_stop: | 447 | err_pagealloc_stop: |
397 | mlx5_pagealloc_stop(dev); | 448 | mlx5_pagealloc_stop(dev); |
398 | 449 | ||
399 | err_reclaim_pages: | 450 | reclaim_boot_pages: |
400 | mlx5_reclaim_startup_pages(dev); | 451 | mlx5_reclaim_startup_pages(dev); |
401 | 452 | ||
453 | err_disable_hca: | ||
454 | mlx5_core_disable_hca(dev); | ||
455 | |||
402 | err_pagealloc_cleanup: | 456 | err_pagealloc_cleanup: |
403 | mlx5_pagealloc_cleanup(dev); | 457 | mlx5_pagealloc_cleanup(dev); |
404 | mlx5_cmd_cleanup(dev); | 458 | mlx5_cmd_cleanup(dev); |
@@ -434,6 +488,7 @@ void mlx5_dev_cleanup(struct mlx5_core_dev *dev) | |||
434 | mlx5_cmd_teardown_hca(dev); | 488 | mlx5_cmd_teardown_hca(dev); |
435 | mlx5_pagealloc_stop(dev); | 489 | mlx5_pagealloc_stop(dev); |
436 | mlx5_reclaim_startup_pages(dev); | 490 | mlx5_reclaim_startup_pages(dev); |
491 | mlx5_core_disable_hca(dev); | ||
437 | mlx5_pagealloc_cleanup(dev); | 492 | mlx5_pagealloc_cleanup(dev); |
438 | mlx5_cmd_cleanup(dev); | 493 | mlx5_cmd_cleanup(dev); |
439 | iounmap(dev->iseg); | 494 | iounmap(dev->iseg); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c index f0bf46339b28..4a3e137931a3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | |||
@@ -64,7 +64,7 @@ struct mlx5_query_pages_inbox { | |||
64 | 64 | ||
65 | struct mlx5_query_pages_outbox { | 65 | struct mlx5_query_pages_outbox { |
66 | struct mlx5_outbox_hdr hdr; | 66 | struct mlx5_outbox_hdr hdr; |
67 | u8 reserved[2]; | 67 | __be16 num_boot_pages; |
68 | __be16 func_id; | 68 | __be16 func_id; |
69 | __be16 init_pages; | 69 | __be16 init_pages; |
70 | __be16 num_pages; | 70 | __be16 num_pages; |
@@ -146,7 +146,7 @@ static struct page *remove_page(struct mlx5_core_dev *dev, u64 addr) | |||
146 | } | 146 | } |
147 | 147 | ||
148 | static int mlx5_cmd_query_pages(struct mlx5_core_dev *dev, u16 *func_id, | 148 | static int mlx5_cmd_query_pages(struct mlx5_core_dev *dev, u16 *func_id, |
149 | s16 *pages, s16 *init_pages) | 149 | s16 *pages, s16 *init_pages, u16 *boot_pages) |
150 | { | 150 | { |
151 | struct mlx5_query_pages_inbox in; | 151 | struct mlx5_query_pages_inbox in; |
152 | struct mlx5_query_pages_outbox out; | 152 | struct mlx5_query_pages_outbox out; |
@@ -164,8 +164,13 @@ static int mlx5_cmd_query_pages(struct mlx5_core_dev *dev, u16 *func_id, | |||
164 | 164 | ||
165 | if (pages) | 165 | if (pages) |
166 | *pages = be16_to_cpu(out.num_pages); | 166 | *pages = be16_to_cpu(out.num_pages); |
167 | |||
167 | if (init_pages) | 168 | if (init_pages) |
168 | *init_pages = be16_to_cpu(out.init_pages); | 169 | *init_pages = be16_to_cpu(out.init_pages); |
170 | |||
171 | if (boot_pages) | ||
172 | *boot_pages = be16_to_cpu(out.num_boot_pages); | ||
173 | |||
169 | *func_id = be16_to_cpu(out.func_id); | 174 | *func_id = be16_to_cpu(out.func_id); |
170 | 175 | ||
171 | return err; | 176 | return err; |
@@ -357,19 +362,22 @@ void mlx5_core_req_pages_handler(struct mlx5_core_dev *dev, u16 func_id, | |||
357 | queue_work(dev->priv.pg_wq, &req->work); | 362 | queue_work(dev->priv.pg_wq, &req->work); |
358 | } | 363 | } |
359 | 364 | ||
360 | int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev) | 365 | int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot) |
361 | { | 366 | { |
367 | u16 uninitialized_var(boot_pages); | ||
362 | s16 uninitialized_var(init_pages); | 368 | s16 uninitialized_var(init_pages); |
363 | u16 uninitialized_var(func_id); | 369 | u16 uninitialized_var(func_id); |
364 | int err; | 370 | int err; |
365 | 371 | ||
366 | err = mlx5_cmd_query_pages(dev, &func_id, NULL, &init_pages); | 372 | err = mlx5_cmd_query_pages(dev, &func_id, NULL, &init_pages, |
373 | &boot_pages); | ||
367 | if (err) | 374 | if (err) |
368 | return err; | 375 | return err; |
369 | 376 | ||
370 | mlx5_core_dbg(dev, "requested %d init pages for func_id 0x%x\n", init_pages, func_id); | ||
371 | 377 | ||
372 | return give_pages(dev, func_id, init_pages, 0); | 378 | mlx5_core_dbg(dev, "requested %d init pages and %d boot pages for func_id 0x%x\n", |
379 | init_pages, boot_pages, func_id); | ||
380 | return give_pages(dev, func_id, boot ? boot_pages : init_pages, 0); | ||
373 | } | 381 | } |
374 | 382 | ||
375 | static int optimal_reclaimed_pages(void) | 383 | static int optimal_reclaimed_pages(void) |