1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/kernel.h>
17#include <linux/types.h>
18#include <linux/pci.h>
19#include <linux/device.h>
20#include <linux/errno.h>
21#include <linux/slab.h>
22#include <linux/bitops.h>
23#include <linux/delay.h>
24#include <linux/jiffies.h>
25#include <linux/log2.h>
26#include <linux/err.h>
27
28#include "hinic_hw_if.h"
29#include "hinic_hw_eqs.h"
30#include "hinic_hw_mgmt.h"
31#include "hinic_hw_qp_ctxt.h"
32#include "hinic_hw_qp.h"
33#include "hinic_hw_io.h"
34#include "hinic_hw_dev.h"
35
36#define IO_STATUS_TIMEOUT 100
37#define OUTBOUND_STATE_TIMEOUT 100
38#define DB_STATE_TIMEOUT 100
39
40#define MAX_IRQS(max_qps, num_aeqs, num_ceqs) \
41 (2 * (max_qps) + (num_aeqs) + (num_ceqs))
42
43#define ADDR_IN_4BYTES(addr) ((addr) >> 2)
44
45enum intr_type {
46 INTR_MSIX_TYPE,
47};
48
49enum io_status {
50 IO_STOPPED = 0,
51 IO_RUNNING = 1,
52};
53
54enum hw_ioctxt_set_cmdq_depth {
55 HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT,
56};
57
58
59struct 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
73
74
75
76
77
78
79static int get_capability(struct hinic_hwdev *hwdev,
80 struct hinic_dev_cap *dev_cap)
81{
82 struct hinic_cap *nic_cap = &hwdev->nic_cap;
83 int num_aeqs, num_ceqs, num_irqs;
84
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)
89 return -EFAULT;
90
91 num_aeqs = HINIC_HWIF_NUM_AEQS(hwdev->hwif);
92 num_ceqs = HINIC_HWIF_NUM_CEQS(hwdev->hwif);
93 num_irqs = HINIC_HWIF_NUM_IRQS(hwdev->hwif);
94
95
96 nic_cap->num_qps = (num_irqs - (num_aeqs + num_ceqs)) / 2;
97
98 if (nic_cap->num_qps > HINIC_Q_CTXT_MAX)
99 nic_cap->num_qps = HINIC_Q_CTXT_MAX;
100
101
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;
107
108 if (nic_cap->num_qps > nic_cap->max_qps)
109 nic_cap->num_qps = nic_cap->max_qps;
110
111 return 0;
112}
113
114
115
116
117
118
119
120static int get_cap_from_fw(struct hinic_pfhwdev *pfhwdev)
121{
122 struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
123 struct hinic_hwif *hwif = hwdev->hwif;
124 struct pci_dev *pdev = hwif->pdev;
125 struct hinic_dev_cap dev_cap;
126 u16 in_len, out_len;
127 int err;
128
129 in_len = 0;
130 out_len = sizeof(dev_cap);
131
132 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);
135 if (err) {
136 dev_err(&pdev->dev, "Failed to get capability from FW\n");
137 return err;
138 }
139
140 return get_capability(hwdev, &dev_cap);
141}
142
143
144
145
146
147
148
149static int get_dev_cap(struct hinic_hwdev *hwdev)
150{
151 struct hinic_hwif *hwif = hwdev->hwif;
152 struct pci_dev *pdev = hwif->pdev;
153 struct hinic_pfhwdev *pfhwdev;
154 int err;
155
156 switch (HINIC_FUNC_TYPE(hwif)) {
157 case HINIC_PPF:
158 case HINIC_PF:
159 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
160
161 err = get_cap_from_fw(pfhwdev);
162 if (err) {
163 dev_err(&pdev->dev, "Failed to get capability from FW\n");
164 return err;
165 }
166 break;
167
168 default:
169 dev_err(&pdev->dev, "Unsupported PCI Function type\n");
170 return -EINVAL;
171 }
172
173 return 0;
174}
175
176
177
178
179
180
181
182static int init_msix(struct hinic_hwdev *hwdev)
183{
184 struct hinic_hwif *hwif = hwdev->hwif;
185 struct pci_dev *pdev = hwif->pdev;
186 int nr_irqs, num_aeqs, num_ceqs;
187 size_t msix_entries_size;
188 int i, err;
189
190 num_aeqs = HINIC_HWIF_NUM_AEQS(hwif);
191 num_ceqs = HINIC_HWIF_NUM_CEQS(hwif);
192 nr_irqs = MAX_IRQS(HINIC_MAX_QPS, num_aeqs, num_ceqs);
193 if (nr_irqs > HINIC_HWIF_NUM_IRQS(hwif))
194 nr_irqs = HINIC_HWIF_NUM_IRQS(hwif);
195
196 msix_entries_size = nr_irqs * sizeof(*hwdev->msix_entries);
197 hwdev->msix_entries = devm_kzalloc(&pdev->dev, msix_entries_size,
198 GFP_KERNEL);
199 if (!hwdev->msix_entries)
200 return -ENOMEM;
201
202 for (i = 0; i < nr_irqs; i++)
203 hwdev->msix_entries[i].entry = i;
204
205 err = pci_enable_msix_exact(pdev, hwdev->msix_entries, nr_irqs);
206 if (err) {
207 dev_err(&pdev->dev, "Failed to enable pci msix\n");
208 return err;
209 }
210
211 return 0;
212}
213
214
215
216
217
218static void disable_msix(struct hinic_hwdev *hwdev)
219{
220 struct hinic_hwif *hwif = hwdev->hwif;
221 struct pci_dev *pdev = hwif->pdev;
222
223 pci_disable_msix(pdev);
224}
225
226
227
228
229
230
231
232
233
234
235
236
237int hinic_port_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_port_cmd cmd,
238 void *buf_in, u16 in_size, void *buf_out, u16 *out_size)
239{
240 struct hinic_hwif *hwif = hwdev->hwif;
241 struct pci_dev *pdev = hwif->pdev;
242 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
249 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
250
251 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC, cmd,
252 buf_in, in_size, buf_out, out_size,
253 HINIC_MGMT_MSG_SYNC);
254}
255
256
257
258
259
260
261
262static int init_fw_ctxt(struct hinic_hwdev *hwdev)
263{
264 struct hinic_hwif *hwif = hwdev->hwif;
265 struct pci_dev *pdev = hwif->pdev;
266 struct hinic_cmd_fw_ctxt fw_ctxt;
267 struct hinic_pfhwdev *pfhwdev;
268 u16 out_size;
269 int err;
270
271 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
272 dev_err(&pdev->dev, "Unsupported PCI Function type\n");
273 return -EINVAL;
274 }
275
276 fw_ctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
277 fw_ctxt.rx_buf_sz = HINIC_RX_BUF_SZ;
278
279 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
280
281 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_FWCTXT_INIT,
282 &fw_ctxt, sizeof(fw_ctxt),
283 &fw_ctxt, &out_size);
284 if (err || (out_size != sizeof(fw_ctxt)) || fw_ctxt.status) {
285 dev_err(&pdev->dev, "Failed to init FW ctxt, ret = %d\n",
286 fw_ctxt.status);
287 return -EFAULT;
288 }
289
290 return 0;
291}
292
293
294
295
296
297
298
299
300
301static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth,
302 unsigned int sq_depth)
303{
304 struct hinic_hwif *hwif = hwdev->hwif;
305 struct hinic_cmd_hw_ioctxt hw_ioctxt;
306 struct pci_dev *pdev = hwif->pdev;
307 struct hinic_pfhwdev *pfhwdev;
308
309 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
310 dev_err(&pdev->dev, "Unsupported PCI Function type\n");
311 return -EINVAL;
312 }
313
314 hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
315
316 hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT;
317 hw_ioctxt.cmdq_depth = 0;
318
319 hw_ioctxt.rq_depth = ilog2(rq_depth);
320
321 hw_ioctxt.rx_buf_sz_idx = HINIC_RX_BUF_SZ_IDX;
322
323 hw_ioctxt.sq_depth = ilog2(sq_depth);
324
325 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
326
327 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
328 HINIC_COMM_CMD_HWCTXT_SET,
329 &hw_ioctxt, sizeof(hw_ioctxt), NULL,
330 NULL, HINIC_MGMT_MSG_SYNC);
331}
332
333static int wait_for_outbound_state(struct hinic_hwdev *hwdev)
334{
335 enum hinic_outbound_state outbound_state;
336 struct hinic_hwif *hwif = hwdev->hwif;
337 struct pci_dev *pdev = hwif->pdev;
338 unsigned long end;
339
340 end = jiffies + msecs_to_jiffies(OUTBOUND_STATE_TIMEOUT);
341 do {
342 outbound_state = hinic_outbound_state_get(hwif);
343
344 if (outbound_state == HINIC_OUTBOUND_ENABLE)
345 return 0;
346
347 msleep(20);
348 } while (time_before(jiffies, end));
349
350 dev_err(&pdev->dev, "Wait for OUTBOUND - Timeout\n");
351 return -EFAULT;
352}
353
354static int wait_for_db_state(struct hinic_hwdev *hwdev)
355{
356 struct hinic_hwif *hwif = hwdev->hwif;
357 struct pci_dev *pdev = hwif->pdev;
358 enum hinic_db_state db_state;
359 unsigned long end;
360
361 end = jiffies + msecs_to_jiffies(DB_STATE_TIMEOUT);
362 do {
363 db_state = hinic_db_state_get(hwif);
364
365 if (db_state == HINIC_DB_ENABLE)
366 return 0;
367
368 msleep(20);
369 } while (time_before(jiffies, end));
370
371 dev_err(&pdev->dev, "Wait for DB - Timeout\n");
372 return -EFAULT;
373}
374
375static int wait_for_io_stopped(struct hinic_hwdev *hwdev)
376{
377 struct hinic_cmd_io_status cmd_io_status;
378 struct hinic_hwif *hwif = hwdev->hwif;
379 struct pci_dev *pdev = hwif->pdev;
380 struct hinic_pfhwdev *pfhwdev;
381 unsigned long end;
382 u16 out_size;
383 int err;
384
385 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
386 dev_err(&pdev->dev, "Unsupported PCI Function type\n");
387 return -EINVAL;
388 }
389
390 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
391
392 cmd_io_status.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
393
394 end = jiffies + msecs_to_jiffies(IO_STATUS_TIMEOUT);
395 do {
396 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
397 HINIC_COMM_CMD_IO_STATUS_GET,
398 &cmd_io_status, sizeof(cmd_io_status),
399 &cmd_io_status, &out_size,
400 HINIC_MGMT_MSG_SYNC);
401 if ((err) || (out_size != sizeof(cmd_io_status))) {
402 dev_err(&pdev->dev, "Failed to get IO status, ret = %d\n",
403 err);
404 return err;
405 }
406
407 if (cmd_io_status.status == IO_STOPPED) {
408 dev_info(&pdev->dev, "IO stopped\n");
409 return 0;
410 }
411
412 msleep(20);
413 } while (time_before(jiffies, end));
414
415 dev_err(&pdev->dev, "Wait for IO stopped - Timeout\n");
416 return -ETIMEDOUT;
417}
418
419
420
421
422
423
424
425static int clear_io_resources(struct hinic_hwdev *hwdev)
426{
427 struct hinic_cmd_clear_io_res cmd_clear_io_res;
428 struct hinic_hwif *hwif = hwdev->hwif;
429 struct pci_dev *pdev = hwif->pdev;
430 struct hinic_pfhwdev *pfhwdev;
431 int err;
432
433 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
434 dev_err(&pdev->dev, "Unsupported PCI Function type\n");
435 return -EINVAL;
436 }
437
438 err = wait_for_io_stopped(hwdev);
439 if (err) {
440 dev_err(&pdev->dev, "IO has not stopped yet\n");
441 return err;
442 }
443
444 cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
445
446 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
447
448 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
449 HINIC_COMM_CMD_IO_RES_CLEAR, &cmd_clear_io_res,
450 sizeof(cmd_clear_io_res), NULL, NULL,
451 HINIC_MGMT_MSG_SYNC);
452 if (err) {
453 dev_err(&pdev->dev, "Failed to clear IO resources\n");
454 return err;
455 }
456
457 return 0;
458}
459
460
461
462
463
464
465
466
467static int set_resources_state(struct hinic_hwdev *hwdev,
468 enum hinic_res_state state)
469{
470 struct hinic_cmd_set_res_state res_state;
471 struct hinic_hwif *hwif = hwdev->hwif;
472 struct pci_dev *pdev = hwif->pdev;
473 struct hinic_pfhwdev *pfhwdev;
474
475 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
476 dev_err(&pdev->dev, "Unsupported PCI Function type\n");
477 return -EINVAL;
478 }
479
480 res_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
481 res_state.state = state;
482
483 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
484
485 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt,
486 HINIC_MOD_COMM,
487 HINIC_COMM_CMD_RES_STATE_SET,
488 &res_state, sizeof(res_state), NULL,
489 NULL, HINIC_MGMT_MSG_SYNC);
490}
491
492
493
494
495
496
497
498
499static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn)
500{
501 struct hinic_cmd_base_qpn cmd_base_qpn;
502 struct hinic_hwif *hwif = hwdev->hwif;
503 struct pci_dev *pdev = hwif->pdev;
504 u16 out_size;
505 int err;
506
507 cmd_base_qpn.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
508
509 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_GLOBAL_QPN,
510 &cmd_base_qpn, sizeof(cmd_base_qpn),
511 &cmd_base_qpn, &out_size);
512 if (err || (out_size != sizeof(cmd_base_qpn)) || cmd_base_qpn.status) {
513 dev_err(&pdev->dev, "Failed to get base qpn, status = %d\n",
514 cmd_base_qpn.status);
515 return -EFAULT;
516 }
517
518 *base_qpn = cmd_base_qpn.qpn;
519 return 0;
520}
521
522
523
524
525
526
527
528int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)
529{
530 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
531 struct hinic_cap *nic_cap = &hwdev->nic_cap;
532 struct hinic_hwif *hwif = hwdev->hwif;
533 int err, num_aeqs, num_ceqs, num_qps;
534 struct msix_entry *ceq_msix_entries;
535 struct msix_entry *sq_msix_entries;
536 struct msix_entry *rq_msix_entries;
537 struct pci_dev *pdev = hwif->pdev;
538 u16 base_qpn;
539
540 err = get_base_qpn(hwdev, &base_qpn);
541 if (err) {
542 dev_err(&pdev->dev, "Failed to get global base qp number\n");
543 return err;
544 }
545
546 num_aeqs = HINIC_HWIF_NUM_AEQS(hwif);
547 num_ceqs = HINIC_HWIF_NUM_CEQS(hwif);
548
549 ceq_msix_entries = &hwdev->msix_entries[num_aeqs];
550
551 err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs,
552 ceq_msix_entries);
553 if (err) {
554 dev_err(&pdev->dev, "Failed to init IO channel\n");
555 return err;
556 }
557
558 num_qps = nic_cap->num_qps;
559 sq_msix_entries = &hwdev->msix_entries[num_aeqs + num_ceqs];
560 rq_msix_entries = &hwdev->msix_entries[num_aeqs + num_ceqs + num_qps];
561
562 err = hinic_io_create_qps(func_to_io, base_qpn, num_qps,
563 sq_msix_entries, rq_msix_entries);
564 if (err) {
565 dev_err(&pdev->dev, "Failed to create QPs\n");
566 goto err_create_qps;
567 }
568
569 err = wait_for_db_state(hwdev);
570 if (err) {
571 dev_warn(&pdev->dev, "db - disabled, try again\n");
572 hinic_db_state_set(hwif, HINIC_DB_ENABLE);
573 }
574
575 err = set_hw_ioctxt(hwdev, HINIC_SQ_DEPTH, HINIC_RQ_DEPTH);
576 if (err) {
577 dev_err(&pdev->dev, "Failed to set HW IO ctxt\n");
578 goto err_hw_ioctxt;
579 }
580
581 return 0;
582
583err_hw_ioctxt:
584 hinic_io_destroy_qps(func_to_io, num_qps);
585
586err_create_qps:
587 hinic_io_free(func_to_io);
588 return err;
589}
590
591
592
593
594
595
596void hinic_hwdev_ifdown(struct hinic_hwdev *hwdev)
597{
598 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
599 struct hinic_cap *nic_cap = &hwdev->nic_cap;
600
601 clear_io_resources(hwdev);
602
603 hinic_io_destroy_qps(func_to_io, nic_cap->num_qps);
604 hinic_io_free(func_to_io);
605}
606
607
608
609
610
611
612
613
614void hinic_hwdev_cb_register(struct hinic_hwdev *hwdev,
615 enum hinic_mgmt_msg_cmd cmd, void *handle,
616 void (*handler)(void *handle, void *buf_in,
617 u16 in_size, void *buf_out,
618 u16 *out_size))
619{
620 struct hinic_hwif *hwif = hwdev->hwif;
621 struct pci_dev *pdev = hwif->pdev;
622 struct hinic_pfhwdev *pfhwdev;
623 struct hinic_nic_cb *nic_cb;
624 u8 cmd_cb;
625
626 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
627 dev_err(&pdev->dev, "unsupported PCI Function type\n");
628 return;
629 }
630
631 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
632
633 cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE;
634 nic_cb = &pfhwdev->nic_cb[cmd_cb];
635
636 nic_cb->handler = handler;
637 nic_cb->handle = handle;
638 nic_cb->cb_state = HINIC_CB_ENABLED;
639}
640
641
642
643
644
645
646void hinic_hwdev_cb_unregister(struct hinic_hwdev *hwdev,
647 enum hinic_mgmt_msg_cmd cmd)
648{
649 struct hinic_hwif *hwif = hwdev->hwif;
650 struct pci_dev *pdev = hwif->pdev;
651 struct hinic_pfhwdev *pfhwdev;
652 struct hinic_nic_cb *nic_cb;
653 u8 cmd_cb;
654
655 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
656 dev_err(&pdev->dev, "unsupported PCI Function type\n");
657 return;
658 }
659
660 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
661
662 cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE;
663 nic_cb = &pfhwdev->nic_cb[cmd_cb];
664
665 nic_cb->cb_state &= ~HINIC_CB_ENABLED;
666
667 while (nic_cb->cb_state & HINIC_CB_RUNNING)
668 schedule();
669
670 nic_cb->handler = NULL;
671}
672
673
674
675
676
677
678
679
680
681static void nic_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in,
682 u16 in_size, void *buf_out, u16 *out_size)
683{
684 struct hinic_pfhwdev *pfhwdev = handle;
685 enum hinic_cb_state cb_state;
686 struct hinic_nic_cb *nic_cb;
687 struct hinic_hwdev *hwdev;
688 struct hinic_hwif *hwif;
689 struct pci_dev *pdev;
690 u8 cmd_cb;
691
692 hwdev = &pfhwdev->hwdev;
693 hwif = hwdev->hwif;
694 pdev = hwif->pdev;
695
696 if ((cmd < HINIC_MGMT_MSG_CMD_BASE) ||
697 (cmd >= HINIC_MGMT_MSG_CMD_MAX)) {
698 dev_err(&pdev->dev, "unknown L2NIC event, cmd = %d\n", cmd);
699 return;
700 }
701
702 cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE;
703
704 nic_cb = &pfhwdev->nic_cb[cmd_cb];
705
706 cb_state = cmpxchg(&nic_cb->cb_state,
707 HINIC_CB_ENABLED,
708 HINIC_CB_ENABLED | HINIC_CB_RUNNING);
709
710 if ((cb_state == HINIC_CB_ENABLED) && (nic_cb->handler))
711 nic_cb->handler(nic_cb->handle, buf_in,
712 in_size, buf_out, out_size);
713 else
714 dev_err(&pdev->dev, "Unhandled NIC Event %d\n", cmd);
715
716 nic_cb->cb_state &= ~HINIC_CB_RUNNING;
717}
718
719
720
721
722
723
724
725static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev)
726{
727 struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
728 struct hinic_hwif *hwif = hwdev->hwif;
729 struct pci_dev *pdev = hwif->pdev;
730 int err;
731
732 err = hinic_pf_to_mgmt_init(&pfhwdev->pf_to_mgmt, hwif);
733 if (err) {
734 dev_err(&pdev->dev, "Failed to initialize PF to MGMT channel\n");
735 return err;
736 }
737
738 hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC,
739 pfhwdev, nic_mgmt_msg_handler);
740
741 hinic_set_pf_action(hwif, HINIC_PF_MGMT_ACTIVE);
742 return 0;
743}
744
745
746
747
748
749static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev)
750{
751 struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
752
753 hinic_set_pf_action(hwdev->hwif, HINIC_PF_MGMT_INIT);
754
755 hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC);
756
757 hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
758}
759
760
761
762
763
764
765
766
767
768struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev)
769{
770 struct hinic_pfhwdev *pfhwdev;
771 struct hinic_hwdev *hwdev;
772 struct hinic_hwif *hwif;
773 int err, num_aeqs;
774
775 hwif = devm_kzalloc(&pdev->dev, sizeof(*hwif), GFP_KERNEL);
776 if (!hwif)
777 return ERR_PTR(-ENOMEM);
778
779 err = hinic_init_hwif(hwif, pdev);
780 if (err) {
781 dev_err(&pdev->dev, "Failed to init HW interface\n");
782 return ERR_PTR(err);
783 }
784
785 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
786 dev_err(&pdev->dev, "Unsupported PCI Function type\n");
787 err = -EFAULT;
788 goto err_func_type;
789 }
790
791 pfhwdev = devm_kzalloc(&pdev->dev, sizeof(*pfhwdev), GFP_KERNEL);
792 if (!pfhwdev) {
793 err = -ENOMEM;
794 goto err_pfhwdev_alloc;
795 }
796
797 hwdev = &pfhwdev->hwdev;
798 hwdev->hwif = hwif;
799
800 err = init_msix(hwdev);
801 if (err) {
802 dev_err(&pdev->dev, "Failed to init msix\n");
803 goto err_init_msix;
804 }
805
806 err = wait_for_outbound_state(hwdev);
807 if (err) {
808 dev_warn(&pdev->dev, "outbound - disabled, try again\n");
809 hinic_outbound_state_set(hwif, HINIC_OUTBOUND_ENABLE);
810 }
811
812 num_aeqs = HINIC_HWIF_NUM_AEQS(hwif);
813
814 err = hinic_aeqs_init(&hwdev->aeqs, hwif, num_aeqs,
815 HINIC_DEFAULT_AEQ_LEN, HINIC_EQ_PAGE_SIZE,
816 hwdev->msix_entries);
817 if (err) {
818 dev_err(&pdev->dev, "Failed to init async event queues\n");
819 goto err_aeqs_init;
820 }
821
822 err = init_pfhwdev(pfhwdev);
823 if (err) {
824 dev_err(&pdev->dev, "Failed to init PF HW device\n");
825 goto err_init_pfhwdev;
826 }
827
828 err = get_dev_cap(hwdev);
829 if (err) {
830 dev_err(&pdev->dev, "Failed to get device capabilities\n");
831 goto err_dev_cap;
832 }
833
834 err = init_fw_ctxt(hwdev);
835 if (err) {
836 dev_err(&pdev->dev, "Failed to init function table\n");
837 goto err_init_fw_ctxt;
838 }
839
840 err = set_resources_state(hwdev, HINIC_RES_ACTIVE);
841 if (err) {
842 dev_err(&pdev->dev, "Failed to set resources state\n");
843 goto err_resources_state;
844 }
845
846 return hwdev;
847
848err_resources_state:
849err_init_fw_ctxt:
850err_dev_cap:
851 free_pfhwdev(pfhwdev);
852
853err_init_pfhwdev:
854 hinic_aeqs_free(&hwdev->aeqs);
855
856err_aeqs_init:
857 disable_msix(hwdev);
858
859err_init_msix:
860err_pfhwdev_alloc:
861err_func_type:
862 hinic_free_hwif(hwif);
863 return ERR_PTR(err);
864}
865
866
867
868
869
870void hinic_free_hwdev(struct hinic_hwdev *hwdev)
871{
872 struct hinic_pfhwdev *pfhwdev = container_of(hwdev,
873 struct hinic_pfhwdev,
874 hwdev);
875
876 set_resources_state(hwdev, HINIC_RES_CLEAN);
877
878 free_pfhwdev(pfhwdev);
879
880 hinic_aeqs_free(&hwdev->aeqs);
881
882 disable_msix(hwdev);
883
884 hinic_free_hwif(hwdev->hwif);
885}
886
887
888
889
890
891
892
893int hinic_hwdev_num_qps(struct hinic_hwdev *hwdev)
894{
895 struct hinic_cap *nic_cap = &hwdev->nic_cap;
896
897 return nic_cap->num_qps;
898}
899
900
901
902
903
904
905
906
907struct hinic_sq *hinic_hwdev_get_sq(struct hinic_hwdev *hwdev, int i)
908{
909 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
910 struct hinic_qp *qp = &func_to_io->qps[i];
911
912 if (i >= hinic_hwdev_num_qps(hwdev))
913 return NULL;
914
915 return &qp->sq;
916}
917
918
919
920
921
922
923
924
925struct hinic_rq *hinic_hwdev_get_rq(struct hinic_hwdev *hwdev, int i)
926{
927 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
928 struct hinic_qp *qp = &func_to_io->qps[i];
929
930 if (i >= hinic_hwdev_num_qps(hwdev))
931 return NULL;
932
933 return &qp->rq;
934}
935
936
937
938
939
940
941
942
943int hinic_hwdev_msix_cnt_set(struct hinic_hwdev *hwdev, u16 msix_index)
944{
945 return hinic_msix_attr_cnt_clear(hwdev->hwif, msix_index);
946}
947
948
949
950
951
952
953
954
955
956
957
958
959
960int hinic_hwdev_msix_set(struct hinic_hwdev *hwdev, u16 msix_index,
961 u8 pending_limit, u8 coalesc_timer,
962 u8 lli_timer_cfg, u8 lli_credit_limit,
963 u8 resend_timer)
964{
965 return hinic_msix_attr_set(hwdev->hwif, msix_index,
966 pending_limit, coalesc_timer,
967 lli_timer_cfg, lli_credit_limit,
968 resend_timer);
969}
970
971
972
973
974
975
976
977
978
979
980int hinic_hwdev_hw_ci_addr_set(struct hinic_hwdev *hwdev, struct hinic_sq *sq,
981 u8 pending_limit, u8 coalesc_timer)
982{
983 struct hinic_qp *qp = container_of(sq, struct hinic_qp, sq);
984 struct hinic_hwif *hwif = hwdev->hwif;
985 struct pci_dev *pdev = hwif->pdev;
986 struct hinic_pfhwdev *pfhwdev;
987 struct hinic_cmd_hw_ci hw_ci;
988
989 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
990 dev_err(&pdev->dev, "Unsupported PCI Function type\n");
991 return -EINVAL;
992 }
993
994 hw_ci.dma_attr_off = 0;
995 hw_ci.pending_limit = pending_limit;
996 hw_ci.coalesc_timer = coalesc_timer;
997
998 hw_ci.msix_en = 1;
999 hw_ci.msix_entry_idx = sq->msix_entry;
1000
1001 hw_ci.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
1002
1003 hw_ci.sq_id = qp->q_id;
1004
1005 hw_ci.ci_addr = ADDR_IN_4BYTES(sq->hw_ci_dma_addr);
1006
1007 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
1008 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt,
1009 HINIC_MOD_COMM,
1010 HINIC_COMM_CMD_SQ_HI_CI_SET,
1011 &hw_ci, sizeof(hw_ci), NULL,
1012 NULL, HINIC_MGMT_MSG_SYNC);
1013}
1014