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