.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Huawei HiNIC PCI Express Linux driver |
---|
3 | 4 | * Copyright(c) 2017 Huawei Technologies Co., Ltd |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms and conditions of the GNU General Public License, |
---|
7 | | - * version 2, as published by the Free Software Foundation. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
---|
12 | | - * for more details. |
---|
13 | | - * |
---|
14 | 5 | */ |
---|
15 | 6 | |
---|
16 | 7 | #include <linux/kernel.h> |
---|
.. | .. |
---|
24 | 15 | #include <linux/jiffies.h> |
---|
25 | 16 | #include <linux/log2.h> |
---|
26 | 17 | #include <linux/err.h> |
---|
| 18 | +#include <linux/netdevice.h> |
---|
| 19 | +#include <net/devlink.h> |
---|
27 | 20 | |
---|
| 21 | +#include "hinic_devlink.h" |
---|
| 22 | +#include "hinic_sriov.h" |
---|
| 23 | +#include "hinic_dev.h" |
---|
28 | 24 | #include "hinic_hw_if.h" |
---|
29 | 25 | #include "hinic_hw_eqs.h" |
---|
30 | 26 | #include "hinic_hw_mgmt.h" |
---|
.. | .. |
---|
51 | 47 | IO_RUNNING = 1, |
---|
52 | 48 | }; |
---|
53 | 49 | |
---|
54 | | -enum hw_ioctxt_set_cmdq_depth { |
---|
55 | | - HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT, |
---|
56 | | -}; |
---|
57 | | - |
---|
58 | | -/* HW struct */ |
---|
59 | | -struct hinic_dev_cap { |
---|
60 | | - u8 status; |
---|
61 | | - u8 version; |
---|
62 | | - u8 rsvd0[6]; |
---|
63 | | - |
---|
64 | | - u8 rsvd1[5]; |
---|
65 | | - u8 intr_type; |
---|
66 | | - u8 rsvd2[66]; |
---|
67 | | - u16 max_sqs; |
---|
68 | | - u16 max_rqs; |
---|
69 | | - u8 rsvd3[208]; |
---|
70 | | -}; |
---|
71 | | - |
---|
72 | 50 | /** |
---|
73 | 51 | * get_capability - convert device capabilities to NIC capabilities |
---|
74 | 52 | * @hwdev: the HW device to set and convert device capabilities for |
---|
.. | .. |
---|
76 | 54 | * |
---|
77 | 55 | * Return 0 - Success, negative - Failure |
---|
78 | 56 | **/ |
---|
79 | | -static int get_capability(struct hinic_hwdev *hwdev, |
---|
80 | | - struct hinic_dev_cap *dev_cap) |
---|
| 57 | +static int parse_capability(struct hinic_hwdev *hwdev, |
---|
| 58 | + struct hinic_dev_cap *dev_cap) |
---|
81 | 59 | { |
---|
82 | 60 | struct hinic_cap *nic_cap = &hwdev->nic_cap; |
---|
83 | 61 | int num_aeqs, num_ceqs, num_irqs; |
---|
84 | 62 | |
---|
85 | | - if (!HINIC_IS_PF(hwdev->hwif) && !HINIC_IS_PPF(hwdev->hwif)) |
---|
86 | | - return -EINVAL; |
---|
87 | | - |
---|
88 | | - if (dev_cap->intr_type != INTR_MSIX_TYPE) |
---|
| 63 | + if (!HINIC_IS_VF(hwdev->hwif) && dev_cap->intr_type != INTR_MSIX_TYPE) |
---|
89 | 64 | return -EFAULT; |
---|
90 | 65 | |
---|
91 | 66 | num_aeqs = HINIC_HWIF_NUM_AEQS(hwdev->hwif); |
---|
.. | .. |
---|
98 | 73 | if (nic_cap->num_qps > HINIC_Q_CTXT_MAX) |
---|
99 | 74 | nic_cap->num_qps = HINIC_Q_CTXT_MAX; |
---|
100 | 75 | |
---|
101 | | - /* num_qps must be power of 2 */ |
---|
102 | | - nic_cap->num_qps = BIT(fls(nic_cap->num_qps) - 1); |
---|
103 | | - |
---|
104 | | - nic_cap->max_qps = dev_cap->max_sqs + 1; |
---|
105 | | - if (nic_cap->max_qps != (dev_cap->max_rqs + 1)) |
---|
106 | | - return -EFAULT; |
---|
| 76 | + if (!HINIC_IS_VF(hwdev->hwif)) |
---|
| 77 | + nic_cap->max_qps = dev_cap->max_sqs + 1; |
---|
| 78 | + else |
---|
| 79 | + nic_cap->max_qps = dev_cap->max_sqs; |
---|
107 | 80 | |
---|
108 | 81 | if (nic_cap->num_qps > nic_cap->max_qps) |
---|
109 | 82 | nic_cap->num_qps = nic_cap->max_qps; |
---|
| 83 | + |
---|
| 84 | + if (!HINIC_IS_VF(hwdev->hwif)) { |
---|
| 85 | + nic_cap->max_vf = dev_cap->max_vf; |
---|
| 86 | + nic_cap->max_vf_qps = dev_cap->max_vf_sqs + 1; |
---|
| 87 | + } |
---|
| 88 | + |
---|
| 89 | + hwdev->port_id = dev_cap->port_id; |
---|
110 | 90 | |
---|
111 | 91 | return 0; |
---|
112 | 92 | } |
---|
.. | .. |
---|
117 | 97 | * |
---|
118 | 98 | * Return 0 - Success, negative - Failure |
---|
119 | 99 | **/ |
---|
120 | | -static int get_cap_from_fw(struct hinic_pfhwdev *pfhwdev) |
---|
| 100 | +static int get_capability(struct hinic_pfhwdev *pfhwdev) |
---|
121 | 101 | { |
---|
122 | 102 | struct hinic_hwdev *hwdev = &pfhwdev->hwdev; |
---|
123 | 103 | struct hinic_hwif *hwif = hwdev->hwif; |
---|
124 | 104 | struct pci_dev *pdev = hwif->pdev; |
---|
125 | 105 | struct hinic_dev_cap dev_cap; |
---|
126 | | - u16 in_len, out_len; |
---|
| 106 | + u16 out_len; |
---|
127 | 107 | int err; |
---|
128 | 108 | |
---|
129 | | - in_len = 0; |
---|
130 | 109 | out_len = sizeof(dev_cap); |
---|
131 | 110 | |
---|
132 | 111 | err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_CFGM, |
---|
133 | | - HINIC_CFG_NIC_CAP, &dev_cap, in_len, &dev_cap, |
---|
134 | | - &out_len, HINIC_MGMT_MSG_SYNC); |
---|
| 112 | + HINIC_CFG_NIC_CAP, &dev_cap, sizeof(dev_cap), |
---|
| 113 | + &dev_cap, &out_len, HINIC_MGMT_MSG_SYNC); |
---|
135 | 114 | if (err) { |
---|
136 | 115 | dev_err(&pdev->dev, "Failed to get capability from FW\n"); |
---|
137 | 116 | return err; |
---|
138 | 117 | } |
---|
139 | 118 | |
---|
140 | | - return get_capability(hwdev, &dev_cap); |
---|
| 119 | + return parse_capability(hwdev, &dev_cap); |
---|
141 | 120 | } |
---|
142 | 121 | |
---|
143 | 122 | /** |
---|
.. | .. |
---|
156 | 135 | switch (HINIC_FUNC_TYPE(hwif)) { |
---|
157 | 136 | case HINIC_PPF: |
---|
158 | 137 | case HINIC_PF: |
---|
| 138 | + case HINIC_VF: |
---|
159 | 139 | pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
---|
160 | | - |
---|
161 | | - err = get_cap_from_fw(pfhwdev); |
---|
| 140 | + err = get_capability(pfhwdev); |
---|
162 | 141 | if (err) { |
---|
163 | | - dev_err(&pdev->dev, "Failed to get capability from FW\n"); |
---|
| 142 | + dev_err(&pdev->dev, "Failed to get capability\n"); |
---|
164 | 143 | return err; |
---|
165 | 144 | } |
---|
166 | 145 | break; |
---|
167 | | - |
---|
168 | 146 | default: |
---|
169 | 147 | dev_err(&pdev->dev, "Unsupported PCI Function type\n"); |
---|
170 | 148 | return -EINVAL; |
---|
.. | .. |
---|
184 | 162 | struct hinic_hwif *hwif = hwdev->hwif; |
---|
185 | 163 | struct pci_dev *pdev = hwif->pdev; |
---|
186 | 164 | int nr_irqs, num_aeqs, num_ceqs; |
---|
187 | | - size_t msix_entries_size; |
---|
188 | 165 | int i, err; |
---|
189 | 166 | |
---|
190 | 167 | num_aeqs = HINIC_HWIF_NUM_AEQS(hwif); |
---|
.. | .. |
---|
193 | 170 | if (nr_irqs > HINIC_HWIF_NUM_IRQS(hwif)) |
---|
194 | 171 | nr_irqs = HINIC_HWIF_NUM_IRQS(hwif); |
---|
195 | 172 | |
---|
196 | | - msix_entries_size = nr_irqs * sizeof(*hwdev->msix_entries); |
---|
197 | | - hwdev->msix_entries = devm_kzalloc(&pdev->dev, msix_entries_size, |
---|
| 173 | + hwdev->msix_entries = devm_kcalloc(&pdev->dev, nr_irqs, |
---|
| 174 | + sizeof(*hwdev->msix_entries), |
---|
198 | 175 | GFP_KERNEL); |
---|
199 | 176 | if (!hwdev->msix_entries) |
---|
200 | 177 | return -ENOMEM; |
---|
.. | .. |
---|
237 | 214 | int hinic_port_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_port_cmd cmd, |
---|
238 | 215 | void *buf_in, u16 in_size, void *buf_out, u16 *out_size) |
---|
239 | 216 | { |
---|
240 | | - struct hinic_hwif *hwif = hwdev->hwif; |
---|
241 | | - struct pci_dev *pdev = hwif->pdev; |
---|
242 | 217 | struct hinic_pfhwdev *pfhwdev; |
---|
243 | | - |
---|
244 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
---|
245 | | - dev_err(&pdev->dev, "unsupported PCI Function type\n"); |
---|
246 | | - return -EINVAL; |
---|
247 | | - } |
---|
248 | 218 | |
---|
249 | 219 | pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
---|
250 | 220 | |
---|
251 | 221 | return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC, cmd, |
---|
| 222 | + buf_in, in_size, buf_out, out_size, |
---|
| 223 | + HINIC_MGMT_MSG_SYNC); |
---|
| 224 | +} |
---|
| 225 | + |
---|
| 226 | +int hinic_hilink_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_hilink_cmd cmd, |
---|
| 227 | + void *buf_in, u16 in_size, void *buf_out, |
---|
| 228 | + u16 *out_size) |
---|
| 229 | +{ |
---|
| 230 | + struct hinic_pfhwdev *pfhwdev; |
---|
| 231 | + |
---|
| 232 | + pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
---|
| 233 | + |
---|
| 234 | + return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_HILINK, cmd, |
---|
252 | 235 | buf_in, in_size, buf_out, out_size, |
---|
253 | 236 | HINIC_MGMT_MSG_SYNC); |
---|
254 | 237 | } |
---|
.. | .. |
---|
264 | 247 | struct hinic_hwif *hwif = hwdev->hwif; |
---|
265 | 248 | struct pci_dev *pdev = hwif->pdev; |
---|
266 | 249 | struct hinic_cmd_fw_ctxt fw_ctxt; |
---|
267 | | - u16 out_size; |
---|
| 250 | + u16 out_size = sizeof(fw_ctxt); |
---|
268 | 251 | int err; |
---|
269 | | - |
---|
270 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
---|
271 | | - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); |
---|
272 | | - return -EINVAL; |
---|
273 | | - } |
---|
274 | 252 | |
---|
275 | 253 | fw_ctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); |
---|
276 | 254 | fw_ctxt.rx_buf_sz = HINIC_RX_BUF_SZ; |
---|
.. | .. |
---|
279 | 257 | &fw_ctxt, sizeof(fw_ctxt), |
---|
280 | 258 | &fw_ctxt, &out_size); |
---|
281 | 259 | if (err || (out_size != sizeof(fw_ctxt)) || fw_ctxt.status) { |
---|
282 | | - dev_err(&pdev->dev, "Failed to init FW ctxt, ret = %d\n", |
---|
283 | | - fw_ctxt.status); |
---|
284 | | - return -EFAULT; |
---|
| 260 | + dev_err(&pdev->dev, "Failed to init FW ctxt, err: %d, status: 0x%x, out size: 0x%x\n", |
---|
| 261 | + err, fw_ctxt.status, out_size); |
---|
| 262 | + return -EIO; |
---|
285 | 263 | } |
---|
286 | 264 | |
---|
287 | 265 | return 0; |
---|
.. | .. |
---|
295 | 273 | * |
---|
296 | 274 | * Return 0 - Success, negative - Failure |
---|
297 | 275 | **/ |
---|
298 | | -static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth, |
---|
299 | | - unsigned int sq_depth) |
---|
| 276 | +static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int sq_depth, |
---|
| 277 | + unsigned int rq_depth) |
---|
300 | 278 | { |
---|
301 | 279 | struct hinic_hwif *hwif = hwdev->hwif; |
---|
302 | 280 | struct hinic_cmd_hw_ioctxt hw_ioctxt; |
---|
303 | | - struct pci_dev *pdev = hwif->pdev; |
---|
304 | 281 | struct hinic_pfhwdev *pfhwdev; |
---|
305 | | - |
---|
306 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
---|
307 | | - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); |
---|
308 | | - return -EINVAL; |
---|
309 | | - } |
---|
310 | 282 | |
---|
311 | 283 | hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); |
---|
312 | 284 | hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); |
---|
313 | 285 | |
---|
314 | 286 | hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT; |
---|
315 | 287 | hw_ioctxt.cmdq_depth = 0; |
---|
| 288 | + |
---|
| 289 | + hw_ioctxt.lro_en = 1; |
---|
316 | 290 | |
---|
317 | 291 | hw_ioctxt.rq_depth = ilog2(rq_depth); |
---|
318 | 292 | |
---|
.. | .. |
---|
384 | 358 | struct hinic_pfhwdev *pfhwdev; |
---|
385 | 359 | int err; |
---|
386 | 360 | |
---|
387 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
---|
388 | | - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); |
---|
389 | | - return -EINVAL; |
---|
390 | | - } |
---|
391 | | - |
---|
392 | 361 | /* sleep 100ms to wait for firmware stopping I/O */ |
---|
393 | 362 | msleep(100); |
---|
394 | 363 | |
---|
.. | .. |
---|
420 | 389 | { |
---|
421 | 390 | struct hinic_cmd_set_res_state res_state; |
---|
422 | 391 | struct hinic_hwif *hwif = hwdev->hwif; |
---|
423 | | - struct pci_dev *pdev = hwif->pdev; |
---|
424 | 392 | struct hinic_pfhwdev *pfhwdev; |
---|
425 | | - |
---|
426 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
---|
427 | | - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); |
---|
428 | | - return -EINVAL; |
---|
429 | | - } |
---|
430 | 393 | |
---|
431 | 394 | res_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif); |
---|
432 | 395 | res_state.state = state; |
---|
.. | .. |
---|
451 | 414 | { |
---|
452 | 415 | struct hinic_cmd_base_qpn cmd_base_qpn; |
---|
453 | 416 | struct hinic_hwif *hwif = hwdev->hwif; |
---|
| 417 | + u16 out_size = sizeof(cmd_base_qpn); |
---|
454 | 418 | struct pci_dev *pdev = hwif->pdev; |
---|
455 | | - u16 out_size; |
---|
456 | 419 | int err; |
---|
457 | 420 | |
---|
458 | 421 | cmd_base_qpn.func_idx = HINIC_HWIF_FUNC_IDX(hwif); |
---|
.. | .. |
---|
461 | 424 | &cmd_base_qpn, sizeof(cmd_base_qpn), |
---|
462 | 425 | &cmd_base_qpn, &out_size); |
---|
463 | 426 | if (err || (out_size != sizeof(cmd_base_qpn)) || cmd_base_qpn.status) { |
---|
464 | | - dev_err(&pdev->dev, "Failed to get base qpn, status = %d\n", |
---|
465 | | - cmd_base_qpn.status); |
---|
466 | | - return -EFAULT; |
---|
| 427 | + dev_err(&pdev->dev, "Failed to get base qpn, err: %d, status: 0x%x, out size: 0x%x\n", |
---|
| 428 | + err, cmd_base_qpn.status, out_size); |
---|
| 429 | + return -EIO; |
---|
467 | 430 | } |
---|
468 | 431 | |
---|
469 | 432 | *base_qpn = cmd_base_qpn.qpn; |
---|
.. | .. |
---|
473 | 436 | /** |
---|
474 | 437 | * hinic_hwdev_ifup - Preparing the HW for passing IO |
---|
475 | 438 | * @hwdev: the NIC HW device |
---|
| 439 | + * @sq_depth: the send queue depth |
---|
| 440 | + * @rq_depth: the receive queue depth |
---|
476 | 441 | * |
---|
477 | 442 | * Return 0 - Success, negative - Failure |
---|
478 | 443 | **/ |
---|
479 | | -int hinic_hwdev_ifup(struct hinic_hwdev *hwdev) |
---|
| 444 | +int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth) |
---|
480 | 445 | { |
---|
481 | 446 | struct hinic_func_to_io *func_to_io = &hwdev->func_to_io; |
---|
482 | 447 | struct hinic_cap *nic_cap = &hwdev->nic_cap; |
---|
.. | .. |
---|
498 | 463 | num_ceqs = HINIC_HWIF_NUM_CEQS(hwif); |
---|
499 | 464 | |
---|
500 | 465 | ceq_msix_entries = &hwdev->msix_entries[num_aeqs]; |
---|
| 466 | + func_to_io->hwdev = hwdev; |
---|
| 467 | + func_to_io->sq_depth = sq_depth; |
---|
| 468 | + func_to_io->rq_depth = rq_depth; |
---|
| 469 | + func_to_io->global_qpn = base_qpn; |
---|
501 | 470 | |
---|
502 | 471 | err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs, |
---|
503 | 472 | ceq_msix_entries); |
---|
.. | .. |
---|
523 | 492 | hinic_db_state_set(hwif, HINIC_DB_ENABLE); |
---|
524 | 493 | } |
---|
525 | 494 | |
---|
526 | | - err = set_hw_ioctxt(hwdev, HINIC_SQ_DEPTH, HINIC_RQ_DEPTH); |
---|
| 495 | + err = set_hw_ioctxt(hwdev, sq_depth, rq_depth); |
---|
527 | 496 | if (err) { |
---|
528 | 497 | dev_err(&pdev->dev, "Failed to set HW IO ctxt\n"); |
---|
529 | 498 | goto err_hw_ioctxt; |
---|
.. | .. |
---|
568 | 537 | u16 in_size, void *buf_out, |
---|
569 | 538 | u16 *out_size)) |
---|
570 | 539 | { |
---|
571 | | - struct hinic_hwif *hwif = hwdev->hwif; |
---|
572 | | - struct pci_dev *pdev = hwif->pdev; |
---|
573 | 540 | struct hinic_pfhwdev *pfhwdev; |
---|
574 | 541 | struct hinic_nic_cb *nic_cb; |
---|
575 | 542 | u8 cmd_cb; |
---|
576 | | - |
---|
577 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
---|
578 | | - dev_err(&pdev->dev, "unsupported PCI Function type\n"); |
---|
579 | | - return; |
---|
580 | | - } |
---|
581 | 543 | |
---|
582 | 544 | pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
---|
583 | 545 | |
---|
.. | .. |
---|
598 | 560 | enum hinic_mgmt_msg_cmd cmd) |
---|
599 | 561 | { |
---|
600 | 562 | struct hinic_hwif *hwif = hwdev->hwif; |
---|
601 | | - struct pci_dev *pdev = hwif->pdev; |
---|
602 | 563 | struct hinic_pfhwdev *pfhwdev; |
---|
603 | 564 | struct hinic_nic_cb *nic_cb; |
---|
604 | 565 | u8 cmd_cb; |
---|
605 | 566 | |
---|
606 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
---|
607 | | - dev_err(&pdev->dev, "unsupported PCI Function type\n"); |
---|
| 567 | + if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) |
---|
608 | 568 | return; |
---|
609 | | - } |
---|
610 | 569 | |
---|
611 | 570 | pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
---|
612 | 571 | |
---|
.. | .. |
---|
624 | 583 | /** |
---|
625 | 584 | * nic_mgmt_msg_handler - nic mgmt event handler |
---|
626 | 585 | * @handle: private data for the handler |
---|
| 586 | + * @cmd: message command |
---|
627 | 587 | * @buf_in: input buffer |
---|
628 | 588 | * @in_size: input size |
---|
629 | 589 | * @buf_out: output buffer |
---|
.. | .. |
---|
667 | 627 | nic_cb->cb_state &= ~HINIC_CB_RUNNING; |
---|
668 | 628 | } |
---|
669 | 629 | |
---|
| 630 | +static void hinic_comm_recv_mgmt_self_cmd_reg(struct hinic_pfhwdev *pfhwdev, |
---|
| 631 | + u8 cmd, |
---|
| 632 | + comm_mgmt_self_msg_proc proc) |
---|
| 633 | +{ |
---|
| 634 | + u8 cmd_idx; |
---|
| 635 | + |
---|
| 636 | + cmd_idx = pfhwdev->proc.cmd_num; |
---|
| 637 | + if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) { |
---|
| 638 | + dev_err(&pfhwdev->hwdev.hwif->pdev->dev, |
---|
| 639 | + "Register recv mgmt process failed, cmd: 0x%x\n", cmd); |
---|
| 640 | + return; |
---|
| 641 | + } |
---|
| 642 | + |
---|
| 643 | + pfhwdev->proc.info[cmd_idx].cmd = cmd; |
---|
| 644 | + pfhwdev->proc.info[cmd_idx].proc = proc; |
---|
| 645 | + pfhwdev->proc.cmd_num++; |
---|
| 646 | +} |
---|
| 647 | + |
---|
| 648 | +static void hinic_comm_recv_mgmt_self_cmd_unreg(struct hinic_pfhwdev *pfhwdev, |
---|
| 649 | + u8 cmd) |
---|
| 650 | +{ |
---|
| 651 | + u8 cmd_idx; |
---|
| 652 | + |
---|
| 653 | + cmd_idx = pfhwdev->proc.cmd_num; |
---|
| 654 | + if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) { |
---|
| 655 | + dev_err(&pfhwdev->hwdev.hwif->pdev->dev, "Unregister recv mgmt process failed, cmd: 0x%x\n", |
---|
| 656 | + cmd); |
---|
| 657 | + return; |
---|
| 658 | + } |
---|
| 659 | + |
---|
| 660 | + for (cmd_idx = 0; cmd_idx < HINIC_COMM_SELF_CMD_MAX; cmd_idx++) { |
---|
| 661 | + if (cmd == pfhwdev->proc.info[cmd_idx].cmd) { |
---|
| 662 | + pfhwdev->proc.info[cmd_idx].cmd = 0; |
---|
| 663 | + pfhwdev->proc.info[cmd_idx].proc = NULL; |
---|
| 664 | + pfhwdev->proc.cmd_num--; |
---|
| 665 | + } |
---|
| 666 | + } |
---|
| 667 | +} |
---|
| 668 | + |
---|
| 669 | +static void comm_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in, |
---|
| 670 | + u16 in_size, void *buf_out, u16 *out_size) |
---|
| 671 | +{ |
---|
| 672 | + struct hinic_pfhwdev *pfhwdev = handle; |
---|
| 673 | + u8 cmd_idx; |
---|
| 674 | + |
---|
| 675 | + for (cmd_idx = 0; cmd_idx < pfhwdev->proc.cmd_num; cmd_idx++) { |
---|
| 676 | + if (cmd == pfhwdev->proc.info[cmd_idx].cmd) { |
---|
| 677 | + if (!pfhwdev->proc.info[cmd_idx].proc) { |
---|
| 678 | + dev_warn(&pfhwdev->hwdev.hwif->pdev->dev, |
---|
| 679 | + "PF recv mgmt comm msg handle null, cmd: 0x%x\n", |
---|
| 680 | + cmd); |
---|
| 681 | + } else { |
---|
| 682 | + pfhwdev->proc.info[cmd_idx].proc |
---|
| 683 | + (&pfhwdev->hwdev, buf_in, in_size, |
---|
| 684 | + buf_out, out_size); |
---|
| 685 | + } |
---|
| 686 | + |
---|
| 687 | + return; |
---|
| 688 | + } |
---|
| 689 | + } |
---|
| 690 | + |
---|
| 691 | + dev_warn(&pfhwdev->hwdev.hwif->pdev->dev, "Received unknown mgmt cpu event: 0x%x\n", |
---|
| 692 | + cmd); |
---|
| 693 | + |
---|
| 694 | + *out_size = 0; |
---|
| 695 | +} |
---|
| 696 | + |
---|
| 697 | +/* pf fault report event */ |
---|
| 698 | +static void pf_fault_event_handler(void *dev, void *buf_in, u16 in_size, |
---|
| 699 | + void *buf_out, u16 *out_size) |
---|
| 700 | +{ |
---|
| 701 | + struct hinic_cmd_fault_event *fault_event = buf_in; |
---|
| 702 | + struct hinic_hwdev *hwdev = dev; |
---|
| 703 | + |
---|
| 704 | + if (in_size != sizeof(*fault_event)) { |
---|
| 705 | + dev_err(&hwdev->hwif->pdev->dev, "Invalid fault event report, length: %d, should be %zu\n", |
---|
| 706 | + in_size, sizeof(*fault_event)); |
---|
| 707 | + return; |
---|
| 708 | + } |
---|
| 709 | + |
---|
| 710 | + if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->hw_fault_reporter)) |
---|
| 711 | + return; |
---|
| 712 | + |
---|
| 713 | + devlink_health_report(hwdev->devlink_dev->hw_fault_reporter, |
---|
| 714 | + "HW fatal error reported", &fault_event->event); |
---|
| 715 | +} |
---|
| 716 | + |
---|
| 717 | +static void mgmt_watchdog_timeout_event_handler(void *dev, |
---|
| 718 | + void *buf_in, u16 in_size, |
---|
| 719 | + void *buf_out, u16 *out_size) |
---|
| 720 | +{ |
---|
| 721 | + struct hinic_mgmt_watchdog_info *watchdog_info = buf_in; |
---|
| 722 | + struct hinic_hwdev *hwdev = dev; |
---|
| 723 | + |
---|
| 724 | + if (in_size != sizeof(*watchdog_info)) { |
---|
| 725 | + dev_err(&hwdev->hwif->pdev->dev, "Invalid mgmt watchdog report, length: %d, should be %zu\n", |
---|
| 726 | + in_size, sizeof(*watchdog_info)); |
---|
| 727 | + return; |
---|
| 728 | + } |
---|
| 729 | + |
---|
| 730 | + if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->fw_fault_reporter)) |
---|
| 731 | + return; |
---|
| 732 | + |
---|
| 733 | + devlink_health_report(hwdev->devlink_dev->fw_fault_reporter, |
---|
| 734 | + "FW fatal error reported", watchdog_info); |
---|
| 735 | +} |
---|
| 736 | + |
---|
670 | 737 | /** |
---|
671 | 738 | * init_pfhwdev - Initialize the extended components of PF |
---|
672 | 739 | * @pfhwdev: the HW device for PF |
---|
.. | .. |
---|
686 | 753 | return err; |
---|
687 | 754 | } |
---|
688 | 755 | |
---|
689 | | - hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC, |
---|
690 | | - pfhwdev, nic_mgmt_msg_handler); |
---|
| 756 | + err = hinic_devlink_register(hwdev->devlink_dev, &pdev->dev); |
---|
| 757 | + if (err) { |
---|
| 758 | + dev_err(&hwif->pdev->dev, "Failed to register devlink\n"); |
---|
| 759 | + hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); |
---|
| 760 | + return err; |
---|
| 761 | + } |
---|
| 762 | + |
---|
| 763 | + err = hinic_func_to_func_init(hwdev); |
---|
| 764 | + if (err) { |
---|
| 765 | + dev_err(&hwif->pdev->dev, "Failed to init mailbox\n"); |
---|
| 766 | + hinic_devlink_unregister(hwdev->devlink_dev); |
---|
| 767 | + hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); |
---|
| 768 | + return err; |
---|
| 769 | + } |
---|
| 770 | + |
---|
| 771 | + if (!HINIC_IS_VF(hwif)) { |
---|
| 772 | + hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, |
---|
| 773 | + HINIC_MOD_L2NIC, pfhwdev, |
---|
| 774 | + nic_mgmt_msg_handler); |
---|
| 775 | + hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, |
---|
| 776 | + pfhwdev, comm_mgmt_msg_handler); |
---|
| 777 | + hinic_comm_recv_mgmt_self_cmd_reg(pfhwdev, |
---|
| 778 | + HINIC_COMM_CMD_FAULT_REPORT, |
---|
| 779 | + pf_fault_event_handler); |
---|
| 780 | + hinic_comm_recv_mgmt_self_cmd_reg |
---|
| 781 | + (pfhwdev, HINIC_COMM_CMD_WATCHDOG_INFO, |
---|
| 782 | + mgmt_watchdog_timeout_event_handler); |
---|
| 783 | + } else { |
---|
| 784 | + hinic_register_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC, |
---|
| 785 | + nic_mgmt_msg_handler); |
---|
| 786 | + } |
---|
691 | 787 | |
---|
692 | 788 | hinic_set_pf_action(hwif, HINIC_PF_MGMT_ACTIVE); |
---|
| 789 | + |
---|
693 | 790 | return 0; |
---|
694 | 791 | } |
---|
695 | 792 | |
---|
.. | .. |
---|
703 | 800 | |
---|
704 | 801 | hinic_set_pf_action(hwdev->hwif, HINIC_PF_MGMT_INIT); |
---|
705 | 802 | |
---|
706 | | - hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC); |
---|
| 803 | + if (!HINIC_IS_VF(hwdev->hwif)) { |
---|
| 804 | + hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev, |
---|
| 805 | + HINIC_COMM_CMD_WATCHDOG_INFO); |
---|
| 806 | + hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev, |
---|
| 807 | + HINIC_COMM_CMD_FAULT_REPORT); |
---|
| 808 | + hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, |
---|
| 809 | + HINIC_MOD_COMM); |
---|
| 810 | + hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, |
---|
| 811 | + HINIC_MOD_L2NIC); |
---|
| 812 | + } else { |
---|
| 813 | + hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC); |
---|
| 814 | + } |
---|
| 815 | + |
---|
| 816 | + hinic_func_to_func_free(hwdev); |
---|
| 817 | + |
---|
| 818 | + hinic_devlink_unregister(hwdev->devlink_dev); |
---|
707 | 819 | |
---|
708 | 820 | hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); |
---|
| 821 | +} |
---|
| 822 | + |
---|
| 823 | +static int hinic_l2nic_reset(struct hinic_hwdev *hwdev) |
---|
| 824 | +{ |
---|
| 825 | + struct hinic_cmd_l2nic_reset l2nic_reset = {0}; |
---|
| 826 | + u16 out_size = sizeof(l2nic_reset); |
---|
| 827 | + struct hinic_pfhwdev *pfhwdev; |
---|
| 828 | + int err; |
---|
| 829 | + |
---|
| 830 | + pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
---|
| 831 | + |
---|
| 832 | + l2nic_reset.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); |
---|
| 833 | + /* 0 represents standard l2nic reset flow */ |
---|
| 834 | + l2nic_reset.reset_flag = 0; |
---|
| 835 | + |
---|
| 836 | + err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, |
---|
| 837 | + HINIC_COMM_CMD_L2NIC_RESET, &l2nic_reset, |
---|
| 838 | + sizeof(l2nic_reset), &l2nic_reset, |
---|
| 839 | + &out_size, HINIC_MGMT_MSG_SYNC); |
---|
| 840 | + if (err || !out_size || l2nic_reset.status) { |
---|
| 841 | + dev_err(&hwdev->hwif->pdev->dev, "Failed to reset L2NIC resources, err: %d, status: 0x%x, out_size: 0x%x\n", |
---|
| 842 | + err, l2nic_reset.status, out_size); |
---|
| 843 | + return -EIO; |
---|
| 844 | + } |
---|
| 845 | + |
---|
| 846 | + return 0; |
---|
| 847 | +} |
---|
| 848 | + |
---|
| 849 | +int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev, |
---|
| 850 | + struct hinic_msix_config *interrupt_info) |
---|
| 851 | +{ |
---|
| 852 | + u16 out_size = sizeof(*interrupt_info); |
---|
| 853 | + struct hinic_pfhwdev *pfhwdev; |
---|
| 854 | + int err; |
---|
| 855 | + |
---|
| 856 | + if (!hwdev || !interrupt_info) |
---|
| 857 | + return -EINVAL; |
---|
| 858 | + |
---|
| 859 | + pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
---|
| 860 | + |
---|
| 861 | + interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); |
---|
| 862 | + |
---|
| 863 | + err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, |
---|
| 864 | + HINIC_COMM_CMD_MSI_CTRL_REG_RD_BY_UP, |
---|
| 865 | + interrupt_info, sizeof(*interrupt_info), |
---|
| 866 | + interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC); |
---|
| 867 | + if (err || !out_size || interrupt_info->status) { |
---|
| 868 | + dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n", |
---|
| 869 | + err, interrupt_info->status, out_size); |
---|
| 870 | + return -EIO; |
---|
| 871 | + } |
---|
| 872 | + |
---|
| 873 | + return 0; |
---|
| 874 | +} |
---|
| 875 | + |
---|
| 876 | +int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev, |
---|
| 877 | + struct hinic_msix_config *interrupt_info) |
---|
| 878 | +{ |
---|
| 879 | + u16 out_size = sizeof(*interrupt_info); |
---|
| 880 | + struct hinic_msix_config temp_info; |
---|
| 881 | + struct hinic_pfhwdev *pfhwdev; |
---|
| 882 | + int err; |
---|
| 883 | + |
---|
| 884 | + if (!hwdev) |
---|
| 885 | + return -EINVAL; |
---|
| 886 | + |
---|
| 887 | + pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
---|
| 888 | + |
---|
| 889 | + interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); |
---|
| 890 | + |
---|
| 891 | + err = hinic_get_interrupt_cfg(hwdev, &temp_info); |
---|
| 892 | + if (err) |
---|
| 893 | + return -EINVAL; |
---|
| 894 | + |
---|
| 895 | + interrupt_info->lli_credit_cnt = temp_info.lli_credit_cnt; |
---|
| 896 | + interrupt_info->lli_timer_cnt = temp_info.lli_timer_cnt; |
---|
| 897 | + |
---|
| 898 | + err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, |
---|
| 899 | + HINIC_COMM_CMD_MSI_CTRL_REG_WR_BY_UP, |
---|
| 900 | + interrupt_info, sizeof(*interrupt_info), |
---|
| 901 | + interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC); |
---|
| 902 | + if (err || !out_size || interrupt_info->status) { |
---|
| 903 | + dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n", |
---|
| 904 | + err, interrupt_info->status, out_size); |
---|
| 905 | + return -EIO; |
---|
| 906 | + } |
---|
| 907 | + |
---|
| 908 | + return 0; |
---|
709 | 909 | } |
---|
710 | 910 | |
---|
711 | 911 | /** |
---|
712 | 912 | * hinic_init_hwdev - Initialize the NIC HW |
---|
713 | 913 | * @pdev: the NIC pci device |
---|
| 914 | + * @devlink: the poniter of hinic devlink |
---|
714 | 915 | * |
---|
715 | 916 | * Return initialized NIC HW device |
---|
716 | 917 | * |
---|
717 | 918 | * Initialize the NIC HW device and return a pointer to it |
---|
718 | 919 | **/ |
---|
719 | | -struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev) |
---|
| 920 | +struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev, struct devlink *devlink) |
---|
720 | 921 | { |
---|
721 | 922 | struct hinic_pfhwdev *pfhwdev; |
---|
722 | 923 | struct hinic_hwdev *hwdev; |
---|
.. | .. |
---|
733 | 934 | return ERR_PTR(err); |
---|
734 | 935 | } |
---|
735 | 936 | |
---|
736 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
---|
737 | | - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); |
---|
738 | | - err = -EFAULT; |
---|
739 | | - goto err_func_type; |
---|
740 | | - } |
---|
741 | | - |
---|
742 | 937 | pfhwdev = devm_kzalloc(&pdev->dev, sizeof(*pfhwdev), GFP_KERNEL); |
---|
743 | 938 | if (!pfhwdev) { |
---|
744 | 939 | err = -ENOMEM; |
---|
.. | .. |
---|
747 | 942 | |
---|
748 | 943 | hwdev = &pfhwdev->hwdev; |
---|
749 | 944 | hwdev->hwif = hwif; |
---|
| 945 | + hwdev->devlink_dev = devlink_priv(devlink); |
---|
| 946 | + hwdev->devlink_dev->hwdev = hwdev; |
---|
750 | 947 | |
---|
751 | 948 | err = init_msix(hwdev); |
---|
752 | 949 | if (err) { |
---|
.. | .. |
---|
776 | 973 | goto err_init_pfhwdev; |
---|
777 | 974 | } |
---|
778 | 975 | |
---|
| 976 | + err = hinic_l2nic_reset(hwdev); |
---|
| 977 | + if (err) |
---|
| 978 | + goto err_l2nic_reset; |
---|
| 979 | + |
---|
779 | 980 | err = get_dev_cap(hwdev); |
---|
780 | 981 | if (err) { |
---|
781 | 982 | dev_err(&pdev->dev, "Failed to get device capabilities\n"); |
---|
782 | 983 | goto err_dev_cap; |
---|
| 984 | + } |
---|
| 985 | + |
---|
| 986 | + mutex_init(&hwdev->func_to_io.nic_cfg.cfg_mutex); |
---|
| 987 | + |
---|
| 988 | + err = hinic_vf_func_init(hwdev); |
---|
| 989 | + if (err) { |
---|
| 990 | + dev_err(&pdev->dev, "Failed to init nic mbox\n"); |
---|
| 991 | + goto err_vf_func_init; |
---|
783 | 992 | } |
---|
784 | 993 | |
---|
785 | 994 | err = init_fw_ctxt(hwdev); |
---|
.. | .. |
---|
798 | 1007 | |
---|
799 | 1008 | err_resources_state: |
---|
800 | 1009 | err_init_fw_ctxt: |
---|
| 1010 | + hinic_vf_func_free(hwdev); |
---|
| 1011 | +err_vf_func_init: |
---|
| 1012 | +err_l2nic_reset: |
---|
801 | 1013 | err_dev_cap: |
---|
802 | 1014 | free_pfhwdev(pfhwdev); |
---|
803 | 1015 | |
---|
.. | .. |
---|
809 | 1021 | |
---|
810 | 1022 | err_init_msix: |
---|
811 | 1023 | err_pfhwdev_alloc: |
---|
812 | | -err_func_type: |
---|
813 | 1024 | hinic_free_hwif(hwif); |
---|
| 1025 | + if (err > 0) |
---|
| 1026 | + err = -EIO; |
---|
814 | 1027 | return ERR_PTR(err); |
---|
815 | 1028 | } |
---|
816 | 1029 | |
---|
.. | .. |
---|
826 | 1039 | |
---|
827 | 1040 | set_resources_state(hwdev, HINIC_RES_CLEAN); |
---|
828 | 1041 | |
---|
| 1042 | + hinic_vf_func_free(hwdev); |
---|
| 1043 | + |
---|
829 | 1044 | free_pfhwdev(pfhwdev); |
---|
830 | 1045 | |
---|
831 | 1046 | hinic_aeqs_free(&hwdev->aeqs); |
---|
.. | .. |
---|
833 | 1048 | disable_msix(hwdev); |
---|
834 | 1049 | |
---|
835 | 1050 | hinic_free_hwif(hwdev->hwif); |
---|
| 1051 | +} |
---|
| 1052 | + |
---|
| 1053 | +int hinic_hwdev_max_num_qps(struct hinic_hwdev *hwdev) |
---|
| 1054 | +{ |
---|
| 1055 | + struct hinic_cap *nic_cap = &hwdev->nic_cap; |
---|
| 1056 | + |
---|
| 1057 | + return nic_cap->max_qps; |
---|
836 | 1058 | } |
---|
837 | 1059 | |
---|
838 | 1060 | /** |
---|
.. | .. |
---|
902 | 1124 | * @msix_index: msix_index |
---|
903 | 1125 | * @pending_limit: the maximum pending interrupt events (unit 8) |
---|
904 | 1126 | * @coalesc_timer: coalesc period for interrupt (unit 8 us) |
---|
905 | | - * @lli_timer: replenishing period for low latency credit (unit 8 us) |
---|
| 1127 | + * @lli_timer_cfg: replenishing period for low latency credit (unit 8 us) |
---|
906 | 1128 | * @lli_credit_limit: maximum credits for low latency msix messages (unit 8) |
---|
907 | 1129 | * @resend_timer: maximum wait for resending msix (unit coalesc period) |
---|
908 | 1130 | * |
---|
.. | .. |
---|
933 | 1155 | { |
---|
934 | 1156 | struct hinic_qp *qp = container_of(sq, struct hinic_qp, sq); |
---|
935 | 1157 | struct hinic_hwif *hwif = hwdev->hwif; |
---|
936 | | - struct pci_dev *pdev = hwif->pdev; |
---|
937 | 1158 | struct hinic_pfhwdev *pfhwdev; |
---|
938 | 1159 | struct hinic_cmd_hw_ci hw_ci; |
---|
939 | | - |
---|
940 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
---|
941 | | - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); |
---|
942 | | - return -EINVAL; |
---|
943 | | - } |
---|
944 | 1160 | |
---|
945 | 1161 | hw_ci.dma_attr_off = 0; |
---|
946 | 1162 | hw_ci.pending_limit = pending_limit; |
---|
.. | .. |
---|
962 | 1178 | &hw_ci, sizeof(hw_ci), NULL, |
---|
963 | 1179 | NULL, HINIC_MGMT_MSG_SYNC); |
---|
964 | 1180 | } |
---|
| 1181 | + |
---|
| 1182 | +/** |
---|
| 1183 | + * hinic_hwdev_set_msix_state- set msix state |
---|
| 1184 | + * @hwdev: the NIC HW device |
---|
| 1185 | + * @msix_index: IRQ corresponding index number |
---|
| 1186 | + * @flag: msix state |
---|
| 1187 | + * |
---|
| 1188 | + **/ |
---|
| 1189 | +void hinic_hwdev_set_msix_state(struct hinic_hwdev *hwdev, u16 msix_index, |
---|
| 1190 | + enum hinic_msix_state flag) |
---|
| 1191 | +{ |
---|
| 1192 | + hinic_set_msix_state(hwdev->hwif, msix_index, flag); |
---|
| 1193 | +} |
---|
| 1194 | + |
---|
| 1195 | +int hinic_get_board_info(struct hinic_hwdev *hwdev, |
---|
| 1196 | + struct hinic_comm_board_info *board_info) |
---|
| 1197 | +{ |
---|
| 1198 | + u16 out_size = sizeof(*board_info); |
---|
| 1199 | + struct hinic_pfhwdev *pfhwdev; |
---|
| 1200 | + int err; |
---|
| 1201 | + |
---|
| 1202 | + if (!hwdev || !board_info) |
---|
| 1203 | + return -EINVAL; |
---|
| 1204 | + |
---|
| 1205 | + pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
---|
| 1206 | + |
---|
| 1207 | + err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, |
---|
| 1208 | + HINIC_COMM_CMD_GET_BOARD_INFO, |
---|
| 1209 | + board_info, sizeof(*board_info), |
---|
| 1210 | + board_info, &out_size, HINIC_MGMT_MSG_SYNC); |
---|
| 1211 | + if (err || board_info->status || !out_size) { |
---|
| 1212 | + dev_err(&hwdev->hwif->pdev->dev, |
---|
| 1213 | + "Failed to get board info, err: %d, status: 0x%x, out size: 0x%x\n", |
---|
| 1214 | + err, board_info->status, out_size); |
---|
| 1215 | + return -EIO; |
---|
| 1216 | + } |
---|
| 1217 | + |
---|
| 1218 | + return 0; |
---|
| 1219 | +} |
---|