WIP FPC-III support
[linux/fpc-iii.git] / drivers / net / ethernet / huawei / hinic / hinic_port.c
blobeb97f2d6b1adae8a51dbd3ccde23ad65f0e08a91
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 */
7 #include <linux/types.h>
8 #include <linux/netdevice.h>
9 #include <linux/etherdevice.h>
10 #include <linux/if_vlan.h>
11 #include <linux/pci.h>
12 #include <linux/device.h>
13 #include <linux/errno.h>
15 #include "hinic_hw_if.h"
16 #include "hinic_hw_dev.h"
17 #include "hinic_port.h"
18 #include "hinic_dev.h"
20 #define HINIC_MIN_MTU_SIZE 256
21 #define HINIC_MAX_JUMBO_FRAME_SIZE 15872
23 enum mac_op {
24 MAC_DEL,
25 MAC_SET,
28 /**
29 * change_mac - change(add or delete) mac address
30 * @nic_dev: nic device
31 * @addr: mac address
32 * @vlan_id: vlan number to set with the mac
33 * @op: add or delete the mac
35 * Return 0 - Success, negative - Failure
36 **/
37 static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
38 u16 vlan_id, enum mac_op op)
40 struct hinic_hwdev *hwdev = nic_dev->hwdev;
41 struct hinic_port_mac_cmd port_mac_cmd;
42 struct hinic_hwif *hwif = hwdev->hwif;
43 u16 out_size = sizeof(port_mac_cmd);
44 struct pci_dev *pdev = hwif->pdev;
45 enum hinic_port_cmd cmd;
46 int err;
48 if (op == MAC_SET)
49 cmd = HINIC_PORT_CMD_SET_MAC;
50 else
51 cmd = HINIC_PORT_CMD_DEL_MAC;
53 port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
54 port_mac_cmd.vlan_id = vlan_id;
55 memcpy(port_mac_cmd.mac, addr, ETH_ALEN);
57 err = hinic_port_msg_cmd(hwdev, cmd, &port_mac_cmd,
58 sizeof(port_mac_cmd),
59 &port_mac_cmd, &out_size);
60 if (err || out_size != sizeof(port_mac_cmd) ||
61 (port_mac_cmd.status &&
62 (port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY || !HINIC_IS_VF(hwif)) &&
63 port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
64 dev_err(&pdev->dev, "Failed to change MAC, err: %d, status: 0x%x, out size: 0x%x\n",
65 err, port_mac_cmd.status, out_size);
66 return -EFAULT;
69 if (port_mac_cmd.status == HINIC_PF_SET_VF_ALREADY) {
70 dev_warn(&pdev->dev, "PF has already set VF mac, ignore %s operation\n",
71 (op == MAC_SET) ? "set" : "del");
72 return HINIC_PF_SET_VF_ALREADY;
75 if (cmd == HINIC_PORT_CMD_SET_MAC && port_mac_cmd.status ==
76 HINIC_MGMT_STATUS_EXIST)
77 dev_warn(&pdev->dev, "MAC is repeated, ignore set operation\n");
79 return 0;
82 /**
83 * hinic_port_add_mac - add mac address
84 * @nic_dev: nic device
85 * @addr: mac address
86 * @vlan_id: vlan number to set with the mac
88 * Return 0 - Success, negative - Failure
89 **/
90 int hinic_port_add_mac(struct hinic_dev *nic_dev,
91 const u8 *addr, u16 vlan_id)
93 return change_mac(nic_dev, addr, vlan_id, MAC_SET);
96 /**
97 * hinic_port_del_mac - remove mac address
98 * @nic_dev: nic device
99 * @addr: mac address
100 * @vlan_id: vlan number that is connected to the mac
102 * Return 0 - Success, negative - Failure
104 int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr,
105 u16 vlan_id)
107 return change_mac(nic_dev, addr, vlan_id, MAC_DEL);
111 * hinic_port_get_mac - get the mac address of the nic device
112 * @nic_dev: nic device
113 * @addr: returned mac address
115 * Return 0 - Success, negative - Failure
117 int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
119 struct hinic_hwdev *hwdev = nic_dev->hwdev;
120 struct hinic_port_mac_cmd port_mac_cmd;
121 struct hinic_hwif *hwif = hwdev->hwif;
122 u16 out_size = sizeof(port_mac_cmd);
123 struct pci_dev *pdev = hwif->pdev;
124 int err;
126 port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
128 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MAC,
129 &port_mac_cmd, sizeof(port_mac_cmd),
130 &port_mac_cmd, &out_size);
131 if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) {
132 dev_err(&pdev->dev, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x\n",
133 err, port_mac_cmd.status, out_size);
134 return -EFAULT;
137 memcpy(addr, port_mac_cmd.mac, ETH_ALEN);
138 return 0;
142 * hinic_port_set_mtu - set mtu
143 * @nic_dev: nic device
144 * @new_mtu: new mtu
146 * Return 0 - Success, negative - Failure
148 int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
150 struct net_device *netdev = nic_dev->netdev;
151 struct hinic_hwdev *hwdev = nic_dev->hwdev;
152 struct hinic_port_mtu_cmd port_mtu_cmd;
153 struct hinic_hwif *hwif = hwdev->hwif;
154 u16 out_size = sizeof(port_mtu_cmd);
155 struct pci_dev *pdev = hwif->pdev;
156 int err, max_frame;
158 if (new_mtu < HINIC_MIN_MTU_SIZE) {
159 netif_err(nic_dev, drv, netdev, "mtu < MIN MTU size");
160 return -EINVAL;
163 max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
164 if (max_frame > HINIC_MAX_JUMBO_FRAME_SIZE) {
165 netif_err(nic_dev, drv, netdev, "mtu > MAX MTU size");
166 return -EINVAL;
169 port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
170 port_mtu_cmd.mtu = new_mtu;
172 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
173 &port_mtu_cmd, sizeof(port_mtu_cmd),
174 &port_mtu_cmd, &out_size);
175 if (err || out_size != sizeof(port_mtu_cmd) || port_mtu_cmd.status) {
176 dev_err(&pdev->dev, "Failed to set mtu, err: %d, status: 0x%x, out size: 0x%x\n",
177 err, port_mtu_cmd.status, out_size);
178 return -EFAULT;
181 return 0;
185 * hinic_port_add_vlan - add vlan to the nic device
186 * @nic_dev: nic device
187 * @vlan_id: the vlan number to add
189 * Return 0 - Success, negative - Failure
191 int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
193 struct hinic_hwdev *hwdev = nic_dev->hwdev;
194 struct hinic_port_vlan_cmd port_vlan_cmd;
196 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
197 port_vlan_cmd.vlan_id = vlan_id;
199 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN,
200 &port_vlan_cmd, sizeof(port_vlan_cmd),
201 NULL, NULL);
205 * hinic_port_del_vlan - delete vlan from the nic device
206 * @nic_dev: nic device
207 * @vlan_id: the vlan number to delete
209 * Return 0 - Success, negative - Failure
211 int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
213 struct hinic_hwdev *hwdev = nic_dev->hwdev;
214 struct hinic_port_vlan_cmd port_vlan_cmd;
216 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
217 port_vlan_cmd.vlan_id = vlan_id;
219 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN,
220 &port_vlan_cmd, sizeof(port_vlan_cmd),
221 NULL, NULL);
225 * hinic_port_set_rx_mode - set rx mode in the nic device
226 * @nic_dev: nic device
227 * @rx_mode: the rx mode to set
229 * Return 0 - Success, negative - Failure
231 int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode)
233 struct hinic_hwdev *hwdev = nic_dev->hwdev;
234 struct hinic_port_rx_mode_cmd rx_mode_cmd;
236 rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
237 rx_mode_cmd.rx_mode = rx_mode;
239 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
240 &rx_mode_cmd, sizeof(rx_mode_cmd),
241 NULL, NULL);
245 * hinic_port_link_state - get the link state
246 * @nic_dev: nic device
247 * @link_state: the returned link state
249 * Return 0 - Success, negative - Failure
251 int hinic_port_link_state(struct hinic_dev *nic_dev,
252 enum hinic_port_link_state *link_state)
254 struct hinic_hwdev *hwdev = nic_dev->hwdev;
255 struct hinic_hwif *hwif = hwdev->hwif;
256 struct hinic_port_link_cmd link_cmd;
257 struct pci_dev *pdev = hwif->pdev;
258 u16 out_size = sizeof(link_cmd);
259 int err;
261 link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
263 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_STATE,
264 &link_cmd, sizeof(link_cmd),
265 &link_cmd, &out_size);
266 if (err || (out_size != sizeof(link_cmd)) || link_cmd.status) {
267 dev_err(&pdev->dev, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x\n",
268 err, link_cmd.status, out_size);
269 return -EINVAL;
272 *link_state = link_cmd.state;
273 return 0;
277 * hinic_port_set_state - set port state
278 * @nic_dev: nic device
279 * @state: the state to set
281 * Return 0 - Success, negative - Failure
283 int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
285 struct hinic_hwdev *hwdev = nic_dev->hwdev;
286 struct hinic_port_state_cmd port_state;
287 struct hinic_hwif *hwif = hwdev->hwif;
288 struct pci_dev *pdev = hwif->pdev;
289 u16 out_size = sizeof(port_state);
290 int err;
292 if (HINIC_IS_VF(hwdev->hwif))
293 return 0;
295 port_state.state = state;
297 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PORT_STATE,
298 &port_state, sizeof(port_state),
299 &port_state, &out_size);
300 if (err || (out_size != sizeof(port_state)) || port_state.status) {
301 dev_err(&pdev->dev, "Failed to set port state, err: %d, status: 0x%x, out size: 0x%x\n",
302 err, port_state.status, out_size);
303 return -EFAULT;
306 return 0;
310 * hinic_port_set_func_state- set func device state
311 * @nic_dev: nic device
312 * @state: the state to set
314 * Return 0 - Success, negative - Failure
316 int hinic_port_set_func_state(struct hinic_dev *nic_dev,
317 enum hinic_func_port_state state)
319 struct hinic_port_func_state_cmd func_state;
320 struct hinic_hwdev *hwdev = nic_dev->hwdev;
321 struct hinic_hwif *hwif = hwdev->hwif;
322 struct pci_dev *pdev = hwif->pdev;
323 u16 out_size = sizeof(func_state);
324 int err;
326 func_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
327 func_state.state = state;
329 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_FUNC_STATE,
330 &func_state, sizeof(func_state),
331 &func_state, &out_size);
332 if (err || (out_size != sizeof(func_state)) || func_state.status) {
333 dev_err(&pdev->dev, "Failed to set port func state, err: %d, status: 0x%x, out size: 0x%x\n",
334 err, func_state.status, out_size);
335 return -EFAULT;
338 return 0;
342 * hinic_port_get_cap - get port capabilities
343 * @nic_dev: nic device
344 * @port_cap: returned port capabilities
346 * Return 0 - Success, negative - Failure
348 int hinic_port_get_cap(struct hinic_dev *nic_dev,
349 struct hinic_port_cap *port_cap)
351 struct hinic_hwdev *hwdev = nic_dev->hwdev;
352 struct hinic_hwif *hwif = hwdev->hwif;
353 struct pci_dev *pdev = hwif->pdev;
354 u16 out_size = sizeof(*port_cap);
355 int err;
357 port_cap->func_idx = HINIC_HWIF_FUNC_IDX(hwif);
359 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_CAP,
360 port_cap, sizeof(*port_cap),
361 port_cap, &out_size);
362 if (err || (out_size != sizeof(*port_cap)) || port_cap->status) {
363 dev_err(&pdev->dev,
364 "Failed to get port capabilities, err: %d, status: 0x%x, out size: 0x%x\n",
365 err, port_cap->status, out_size);
366 return -EIO;
369 return 0;
373 * hinic_port_set_tso - set port tso configuration
374 * @nic_dev: nic device
375 * @state: the tso state to set
377 * Return 0 - Success, negative - Failure
379 int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state)
381 struct hinic_hwdev *hwdev = nic_dev->hwdev;
382 struct hinic_hwif *hwif = hwdev->hwif;
383 struct hinic_tso_config tso_cfg = {0};
384 struct pci_dev *pdev = hwif->pdev;
385 u16 out_size = sizeof(tso_cfg);
386 int err;
388 tso_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
389 tso_cfg.tso_en = state;
391 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_TSO,
392 &tso_cfg, sizeof(tso_cfg),
393 &tso_cfg, &out_size);
394 if (err || out_size != sizeof(tso_cfg) || tso_cfg.status) {
395 dev_err(&pdev->dev,
396 "Failed to set port tso, err: %d, status: 0x%x, out size: 0x%x\n",
397 err, tso_cfg.status, out_size);
398 return -EIO;
401 return 0;
404 int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en)
406 struct hinic_checksum_offload rx_csum_cfg = {0};
407 struct hinic_hwdev *hwdev = nic_dev->hwdev;
408 u16 out_size = sizeof(rx_csum_cfg);
409 struct hinic_hwif *hwif;
410 struct pci_dev *pdev;
411 int err;
413 if (!hwdev)
414 return -EINVAL;
416 hwif = hwdev->hwif;
417 pdev = hwif->pdev;
418 rx_csum_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
419 rx_csum_cfg.rx_csum_offload = en;
421 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_CSUM,
422 &rx_csum_cfg, sizeof(rx_csum_cfg),
423 &rx_csum_cfg, &out_size);
424 if (err || !out_size || rx_csum_cfg.status) {
425 dev_err(&pdev->dev,
426 "Failed to set rx csum offload, err: %d, status: 0x%x, out size: 0x%x\n",
427 err, rx_csum_cfg.status, out_size);
428 return -EIO;
431 return 0;
434 int hinic_set_rx_vlan_offload(struct hinic_dev *nic_dev, u8 en)
436 struct hinic_hwdev *hwdev = nic_dev->hwdev;
437 struct hinic_vlan_cfg vlan_cfg;
438 struct hinic_hwif *hwif;
439 struct pci_dev *pdev;
440 u16 out_size;
441 int err;
443 if (!hwdev)
444 return -EINVAL;
446 out_size = sizeof(vlan_cfg);
447 hwif = hwdev->hwif;
448 pdev = hwif->pdev;
449 vlan_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
450 vlan_cfg.vlan_rx_offload = en;
452 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD,
453 &vlan_cfg, sizeof(vlan_cfg),
454 &vlan_cfg, &out_size);
455 if (err || !out_size || vlan_cfg.status) {
456 dev_err(&pdev->dev,
457 "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n",
458 err, vlan_cfg.status, out_size);
459 return -EINVAL;
462 return 0;
465 int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
467 struct hinic_hwdev *hwdev = nic_dev->hwdev;
468 struct hinic_hwif *hwif = hwdev->hwif;
469 struct hinic_rq_num rq_num = { 0 };
470 struct pci_dev *pdev = hwif->pdev;
471 u16 out_size = sizeof(rq_num);
472 int err;
474 rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif);
475 rq_num.num_rqs = num_rqs;
476 rq_num.rq_depth = ilog2(nic_dev->rq_depth);
478 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP,
479 &rq_num, sizeof(rq_num),
480 &rq_num, &out_size);
481 if (err || !out_size || rq_num.status) {
482 dev_err(&pdev->dev,
483 "Failed to set rxq number, err: %d, status: 0x%x, out size: 0x%x\n",
484 err, rq_num.status, out_size);
485 return -EIO;
488 return 0;
491 static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
492 u8 max_wqe_num)
494 struct hinic_hwdev *hwdev = nic_dev->hwdev;
495 struct hinic_lro_config lro_cfg = { 0 };
496 struct hinic_hwif *hwif = hwdev->hwif;
497 struct pci_dev *pdev = hwif->pdev;
498 u16 out_size = sizeof(lro_cfg);
499 int err;
501 lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
502 lro_cfg.lro_ipv4_en = ipv4_en;
503 lro_cfg.lro_ipv6_en = ipv6_en;
504 lro_cfg.lro_max_wqe_num = max_wqe_num;
506 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO,
507 &lro_cfg, sizeof(lro_cfg),
508 &lro_cfg, &out_size);
509 if (err || !out_size || lro_cfg.status) {
510 dev_err(&pdev->dev,
511 "Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n",
512 err, lro_cfg.status, out_size);
513 return -EIO;
516 return 0;
519 static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
521 struct hinic_hwdev *hwdev = nic_dev->hwdev;
522 struct hinic_lro_timer lro_timer = { 0 };
523 struct hinic_hwif *hwif = hwdev->hwif;
524 struct pci_dev *pdev = hwif->pdev;
525 u16 out_size = sizeof(lro_timer);
526 int err;
528 lro_timer.status = 0;
529 lro_timer.type = 0;
530 lro_timer.enable = 1;
531 lro_timer.timer = timer_value;
533 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER,
534 &lro_timer, sizeof(lro_timer),
535 &lro_timer, &out_size);
536 if (lro_timer.status == 0xFF) {
537 /* For this case, we think status (0xFF) is OK */
538 lro_timer.status = 0;
539 dev_dbg(&pdev->dev,
540 "Set lro timer not supported by the current FW version, it will be 1ms default\n");
543 if (err || !out_size || lro_timer.status) {
544 dev_err(&pdev->dev,
545 "Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n",
546 err, lro_timer.status, out_size);
548 return -EIO;
551 return 0;
554 int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en,
555 u32 lro_timer, u32 wqe_num)
557 struct hinic_hwdev *hwdev = nic_dev->hwdev;
558 u8 ipv4_en;
559 u8 ipv6_en;
560 int err;
562 if (!hwdev)
563 return -EINVAL;
565 ipv4_en = lro_en ? 1 : 0;
566 ipv6_en = lro_en ? 1 : 0;
568 err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num);
569 if (err)
570 return err;
572 if (HINIC_IS_VF(nic_dev->hwdev->hwif))
573 return 0;
575 err = hinic_set_rx_lro_timer(nic_dev, lro_timer);
576 if (err)
577 return err;
579 return 0;
582 int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
583 const u32 *indir_table)
585 struct hinic_rss_indirect_tbl *indir_tbl;
586 struct hinic_func_to_io *func_to_io;
587 struct hinic_cmdq_buf cmd_buf;
588 struct hinic_hwdev *hwdev;
589 struct hinic_hwif *hwif;
590 struct pci_dev *pdev;
591 u32 indir_size;
592 u64 out_param;
593 int err, i;
594 u32 *temp;
596 hwdev = nic_dev->hwdev;
597 func_to_io = &hwdev->func_to_io;
598 hwif = hwdev->hwif;
599 pdev = hwif->pdev;
601 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
602 if (err) {
603 dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
604 return err;
607 cmd_buf.size = sizeof(*indir_tbl);
609 indir_tbl = cmd_buf.buf;
610 indir_tbl->group_index = cpu_to_be32(tmpl_idx);
612 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
613 indir_tbl->entry[i] = indir_table[i];
615 if (0x3 == (i & 0x3)) {
616 temp = (u32 *)&indir_tbl->entry[i - 3];
617 *temp = cpu_to_be32(*temp);
621 /* cfg the rss indirect table by command queue */
622 indir_size = HINIC_RSS_INDIR_SIZE / 2;
623 indir_tbl->offset = 0;
624 indir_tbl->size = cpu_to_be32(indir_size);
626 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
627 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
628 &cmd_buf, &out_param);
629 if (err || out_param != 0) {
630 dev_err(&pdev->dev, "Failed to set rss indir table\n");
631 err = -EFAULT;
632 goto free_buf;
635 indir_tbl->offset = cpu_to_be32(indir_size);
636 indir_tbl->size = cpu_to_be32(indir_size);
637 memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size);
639 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
640 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
641 &cmd_buf, &out_param);
642 if (err || out_param != 0) {
643 dev_err(&pdev->dev, "Failed to set rss indir table\n");
644 err = -EFAULT;
647 free_buf:
648 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
650 return err;
653 int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
654 u32 *indir_table)
656 struct hinic_rss_indir_table rss_cfg = { 0 };
657 struct hinic_hwdev *hwdev = nic_dev->hwdev;
658 struct hinic_hwif *hwif = hwdev->hwif;
659 struct pci_dev *pdev = hwif->pdev;
660 u16 out_size = sizeof(rss_cfg);
661 int err = 0, i;
663 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
664 rss_cfg.template_id = tmpl_idx;
666 err = hinic_port_msg_cmd(hwdev,
667 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
668 &rss_cfg, sizeof(rss_cfg), &rss_cfg,
669 &out_size);
670 if (err || !out_size || rss_cfg.status) {
671 dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n",
672 err, rss_cfg.status, out_size);
673 return -EINVAL;
676 hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE);
677 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)
678 indir_table[i] = rss_cfg.indir[i];
680 return 0;
683 int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
684 struct hinic_rss_type rss_type)
686 struct hinic_rss_context_tbl *ctx_tbl;
687 struct hinic_func_to_io *func_to_io;
688 struct hinic_cmdq_buf cmd_buf;
689 struct hinic_hwdev *hwdev;
690 struct hinic_hwif *hwif;
691 struct pci_dev *pdev;
692 u64 out_param;
693 u32 ctx = 0;
694 int err;
696 hwdev = nic_dev->hwdev;
697 func_to_io = &hwdev->func_to_io;
698 hwif = hwdev->hwif;
699 pdev = hwif->pdev;
701 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
702 if (err) {
703 dev_err(&pdev->dev, "Failed to allocate cmd buf\n");
704 return -ENOMEM;
707 ctx |= HINIC_RSS_TYPE_SET(1, VALID) |
708 HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
709 HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
710 HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
711 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
712 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
713 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
714 HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
715 HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
717 cmd_buf.size = sizeof(struct hinic_rss_context_tbl);
719 ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf;
720 ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
721 ctx_tbl->offset = 0;
722 ctx_tbl->size = sizeof(u32);
723 ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
724 ctx_tbl->rsvd = 0;
725 ctx_tbl->ctx = cpu_to_be32(ctx);
727 /* cfg the rss context table by command queue */
728 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
729 HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
730 &cmd_buf, &out_param);
732 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
734 if (err || out_param != 0) {
735 dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n",
736 err);
737 return -EFAULT;
740 return 0;
743 int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
744 struct hinic_rss_type *rss_type)
746 struct hinic_rss_context_table ctx_tbl = { 0 };
747 struct hinic_hwdev *hwdev = nic_dev->hwdev;
748 u16 out_size = sizeof(ctx_tbl);
749 struct hinic_hwif *hwif;
750 struct pci_dev *pdev;
751 int err;
753 if (!hwdev || !rss_type)
754 return -EINVAL;
756 hwif = hwdev->hwif;
757 pdev = hwif->pdev;
759 ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif);
760 ctx_tbl.template_id = tmpl_idx;
762 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL,
763 &ctx_tbl, sizeof(ctx_tbl),
764 &ctx_tbl, &out_size);
765 if (err || !out_size || ctx_tbl.status) {
766 dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n",
767 err, ctx_tbl.status, out_size);
768 return -EINVAL;
771 rss_type->ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
772 rss_type->ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
773 rss_type->ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
774 rss_type->tcp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
775 rss_type->tcp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
776 rss_type->tcp_ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context,
777 TCP_IPV6_EXT);
778 rss_type->udp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
779 rss_type->udp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
781 return 0;
784 int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id,
785 const u8 *temp)
787 struct hinic_hwdev *hwdev = nic_dev->hwdev;
788 struct hinic_hwif *hwif = hwdev->hwif;
789 struct hinic_rss_key rss_key = { 0 };
790 struct pci_dev *pdev = hwif->pdev;
791 u16 out_size = sizeof(rss_key);
792 int err;
794 rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
795 rss_key.template_id = template_id;
796 memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE);
798 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL,
799 &rss_key, sizeof(rss_key),
800 &rss_key, &out_size);
801 if (err || !out_size || rss_key.status) {
802 dev_err(&pdev->dev,
803 "Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n",
804 err, rss_key.status, out_size);
805 return -EINVAL;
808 return 0;
811 int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
812 u8 *temp)
814 struct hinic_rss_template_key temp_key = { 0 };
815 struct hinic_hwdev *hwdev = nic_dev->hwdev;
816 u16 out_size = sizeof(temp_key);
817 struct hinic_hwif *hwif;
818 struct pci_dev *pdev;
819 int err;
821 if (!hwdev || !temp)
822 return -EINVAL;
824 hwif = hwdev->hwif;
825 pdev = hwif->pdev;
827 temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
828 temp_key.template_id = tmpl_idx;
830 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL,
831 &temp_key, sizeof(temp_key),
832 &temp_key, &out_size);
833 if (err || !out_size || temp_key.status) {
834 dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n",
835 err, temp_key.status, out_size);
836 return -EINVAL;
839 memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
841 return 0;
844 int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id,
845 u8 type)
847 struct hinic_rss_engine_type rss_engine = { 0 };
848 struct hinic_hwdev *hwdev = nic_dev->hwdev;
849 struct hinic_hwif *hwif = hwdev->hwif;
850 struct pci_dev *pdev = hwif->pdev;
851 u16 out_size = sizeof(rss_engine);
852 int err;
854 rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif);
855 rss_engine.hash_engine = type;
856 rss_engine.template_id = template_id;
858 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE,
859 &rss_engine, sizeof(rss_engine),
860 &rss_engine, &out_size);
861 if (err || !out_size || rss_engine.status) {
862 dev_err(&pdev->dev,
863 "Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
864 err, rss_engine.status, out_size);
865 return -EINVAL;
868 return 0;
871 int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type)
873 struct hinic_rss_engine_type hash_type = { 0 };
874 struct hinic_hwdev *hwdev = nic_dev->hwdev;
875 u16 out_size = sizeof(hash_type);
876 struct hinic_hwif *hwif;
877 struct pci_dev *pdev;
878 int err;
880 if (!hwdev || !type)
881 return -EINVAL;
883 hwif = hwdev->hwif;
884 pdev = hwif->pdev;
886 hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif);
887 hash_type.template_id = tmpl_idx;
889 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE,
890 &hash_type, sizeof(hash_type),
891 &hash_type, &out_size);
892 if (err || !out_size || hash_type.status) {
893 dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
894 err, hash_type.status, out_size);
895 return -EINVAL;
898 *type = hash_type.hash_engine;
899 return 0;
902 int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id)
904 struct hinic_hwdev *hwdev = nic_dev->hwdev;
905 struct hinic_rss_config rss_cfg = { 0 };
906 struct hinic_hwif *hwif = hwdev->hwif;
907 struct pci_dev *pdev = hwif->pdev;
908 u16 out_size = sizeof(rss_cfg);
909 int err;
911 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
912 rss_cfg.rss_en = rss_en;
913 rss_cfg.template_id = template_id;
914 rss_cfg.rq_priority_number = 0;
916 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG,
917 &rss_cfg, sizeof(rss_cfg),
918 &rss_cfg, &out_size);
919 if (err || !out_size || rss_cfg.status) {
920 dev_err(&pdev->dev,
921 "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n",
922 err, rss_cfg.status, out_size);
923 return -EINVAL;
926 return 0;
929 int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx)
931 struct hinic_rss_template_mgmt template_mgmt = { 0 };
932 struct hinic_hwdev *hwdev = nic_dev->hwdev;
933 struct hinic_hwif *hwif = hwdev->hwif;
934 u16 out_size = sizeof(template_mgmt);
935 struct pci_dev *pdev = hwif->pdev;
936 int err;
938 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
939 template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
941 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
942 &template_mgmt, sizeof(template_mgmt),
943 &template_mgmt, &out_size);
944 if (err || !out_size || template_mgmt.status) {
945 dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n",
946 err, template_mgmt.status, out_size);
947 return -EINVAL;
950 *tmpl_idx = template_mgmt.template_id;
952 return 0;
955 int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx)
957 struct hinic_rss_template_mgmt template_mgmt = { 0 };
958 struct hinic_hwdev *hwdev = nic_dev->hwdev;
959 struct hinic_hwif *hwif = hwdev->hwif;
960 u16 out_size = sizeof(template_mgmt);
961 struct pci_dev *pdev = hwif->pdev;
962 int err;
964 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
965 template_mgmt.template_id = tmpl_idx;
966 template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
968 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
969 &template_mgmt, sizeof(template_mgmt),
970 &template_mgmt, &out_size);
971 if (err || !out_size || template_mgmt.status) {
972 dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n",
973 err, template_mgmt.status, out_size);
974 return -EINVAL;
977 return 0;
980 int hinic_get_vport_stats(struct hinic_dev *nic_dev,
981 struct hinic_vport_stats *stats)
983 struct hinic_cmd_vport_stats vport_stats = { 0 };
984 struct hinic_port_stats_info stats_info = { 0 };
985 struct hinic_hwdev *hwdev = nic_dev->hwdev;
986 struct hinic_hwif *hwif = hwdev->hwif;
987 u16 out_size = sizeof(vport_stats);
988 struct pci_dev *pdev = hwif->pdev;
989 int err;
991 stats_info.stats_version = HINIC_PORT_STATS_VERSION;
992 stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif);
993 stats_info.stats_size = sizeof(vport_stats);
995 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT,
996 &stats_info, sizeof(stats_info),
997 &vport_stats, &out_size);
998 if (err || !out_size || vport_stats.status) {
999 dev_err(&pdev->dev,
1000 "Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n",
1001 err, vport_stats.status, out_size);
1002 return -EFAULT;
1005 memcpy(stats, &vport_stats.stats, sizeof(*stats));
1006 return 0;
1009 int hinic_get_phy_port_stats(struct hinic_dev *nic_dev,
1010 struct hinic_phy_port_stats *stats)
1012 struct hinic_port_stats_info stats_info = { 0 };
1013 struct hinic_hwdev *hwdev = nic_dev->hwdev;
1014 struct hinic_hwif *hwif = hwdev->hwif;
1015 struct hinic_port_stats *port_stats;
1016 u16 out_size = sizeof(*port_stats);
1017 struct pci_dev *pdev = hwif->pdev;
1018 int err;
1020 port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
1021 if (!port_stats)
1022 return -ENOMEM;
1024 stats_info.stats_version = HINIC_PORT_STATS_VERSION;
1025 stats_info.stats_size = sizeof(*port_stats);
1027 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS,
1028 &stats_info, sizeof(stats_info),
1029 port_stats, &out_size);
1030 if (err || !out_size || port_stats->status) {
1031 dev_err(&pdev->dev,
1032 "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
1033 err, port_stats->status, out_size);
1034 err = -EINVAL;
1035 goto out;
1038 memcpy(stats, &port_stats->stats, sizeof(*stats));
1040 out:
1041 kfree(port_stats);
1043 return err;
1046 int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver)
1048 struct hinic_hwdev *hwdev = nic_dev->hwdev;
1049 struct hinic_version_info up_ver = {0};
1050 u16 out_size = sizeof(up_ver);
1051 struct hinic_hwif *hwif;
1052 struct pci_dev *pdev;
1053 int err;
1055 if (!hwdev)
1056 return -EINVAL;
1058 hwif = hwdev->hwif;
1059 pdev = hwif->pdev;
1061 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
1062 &up_ver, sizeof(up_ver), &up_ver,
1063 &out_size);
1064 if (err || !out_size || up_ver.status) {
1065 dev_err(&pdev->dev,
1066 "Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n",
1067 err, up_ver.status, out_size);
1068 return -EINVAL;
1071 snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver);
1073 return 0;
1076 int hinic_get_link_mode(struct hinic_hwdev *hwdev,
1077 struct hinic_link_mode_cmd *link_mode)
1079 u16 out_size;
1080 int err;
1082 if (!hwdev || !link_mode)
1083 return -EINVAL;
1085 link_mode->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1086 out_size = sizeof(*link_mode);
1088 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_MODE,
1089 link_mode, sizeof(*link_mode),
1090 link_mode, &out_size);
1091 if (err || !out_size || link_mode->status) {
1092 dev_err(&hwdev->hwif->pdev->dev,
1093 "Failed to get link mode, err: %d, status: 0x%x, out size: 0x%x\n",
1094 err, link_mode->status, out_size);
1095 return -EIO;
1098 return 0;
1101 int hinic_set_autoneg(struct hinic_hwdev *hwdev, bool enable)
1103 struct hinic_set_autoneg_cmd autoneg = {0};
1104 u16 out_size = sizeof(autoneg);
1105 int err;
1107 if (!hwdev)
1108 return -EINVAL;
1110 autoneg.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1111 autoneg.enable = enable;
1113 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_AUTONEG,
1114 &autoneg, sizeof(autoneg),
1115 &autoneg, &out_size);
1116 if (err || !out_size || autoneg.status) {
1117 dev_err(&hwdev->hwif->pdev->dev, "Failed to %s autoneg, err: %d, status: 0x%x, out size: 0x%x\n",
1118 enable ? "enable" : "disable", err, autoneg.status,
1119 out_size);
1120 return -EIO;
1123 return 0;
1126 int hinic_set_speed(struct hinic_hwdev *hwdev, enum nic_speed_level speed)
1128 struct hinic_speed_cmd speed_info = {0};
1129 u16 out_size = sizeof(speed_info);
1130 int err;
1132 if (!hwdev)
1133 return -EINVAL;
1135 speed_info.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1136 speed_info.speed = speed;
1138 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_SPEED,
1139 &speed_info, sizeof(speed_info),
1140 &speed_info, &out_size);
1141 if (err || !out_size || speed_info.status) {
1142 dev_err(&hwdev->hwif->pdev->dev,
1143 "Failed to set speed, err: %d, status: 0x%x, out size: 0x%x\n",
1144 err, speed_info.status, out_size);
1145 return -EIO;
1148 return 0;
1151 int hinic_set_link_settings(struct hinic_hwdev *hwdev,
1152 struct hinic_link_ksettings_info *info)
1154 u16 out_size = sizeof(*info);
1155 int err;
1157 err = hinic_hilink_msg_cmd(hwdev, HINIC_HILINK_CMD_SET_LINK_SETTINGS,
1158 info, sizeof(*info), info, &out_size);
1159 if ((info->status != HINIC_MGMT_CMD_UNSUPPORTED &&
1160 info->status) || err || !out_size) {
1161 dev_err(&hwdev->hwif->pdev->dev,
1162 "Failed to set link settings, err: %d, status: 0x%x, out size: 0x%x\n",
1163 err, info->status, out_size);
1164 return -EFAULT;
1167 return info->status;
1170 int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev,
1171 struct hinic_pause_config *pause_info)
1173 u16 out_size = sizeof(*pause_info);
1174 int err;
1176 pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1178 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO,
1179 pause_info, sizeof(*pause_info),
1180 pause_info, &out_size);
1181 if (err || !out_size || pause_info->status) {
1182 dev_err(&hwdev->hwif->pdev->dev, "Failed to get pause info, err: %d, status: 0x%x, out size: 0x%x\n",
1183 err, pause_info->status, out_size);
1184 return -EIO;
1187 return 0;
1190 int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev,
1191 struct hinic_pause_config *pause_info)
1193 u16 out_size = sizeof(*pause_info);
1194 int err;
1196 pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1198 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PAUSE_INFO,
1199 pause_info, sizeof(*pause_info),
1200 pause_info, &out_size);
1201 if (err || !out_size || pause_info->status) {
1202 dev_err(&hwdev->hwif->pdev->dev, "Failed to set pause info, err: %d, status: 0x%x, out size: 0x%x\n",
1203 err, pause_info->status, out_size);
1204 return -EIO;
1207 return 0;
1210 int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap)
1212 struct hinic_nic_cfg *nic_cfg = &hwdev->func_to_io.nic_cfg;
1213 struct hinic_set_pfc pfc = {0};
1214 u16 out_size = sizeof(pfc);
1215 int err;
1217 if (HINIC_IS_VF(hwdev->hwif))
1218 return 0;
1220 mutex_lock(&nic_cfg->cfg_mutex);
1222 pfc.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1223 pfc.pfc_bitmap = pfc_bitmap;
1224 pfc.pfc_en = pfc_en;
1226 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PFC,
1227 &pfc, sizeof(pfc), &pfc, &out_size);
1228 if (err || pfc.status || !out_size) {
1229 dev_err(&hwdev->hwif->pdev->dev, "Failed to %s pfc, err: %d, status: 0x%x, out size: 0x%x\n",
1230 pfc_en ? "enable" : "disable", err, pfc.status,
1231 out_size);
1232 mutex_unlock(&nic_cfg->cfg_mutex);
1233 return -EIO;
1236 /* pause settings is opposite from pfc */
1237 nic_cfg->rx_pause = pfc_en ? 0 : 1;
1238 nic_cfg->tx_pause = pfc_en ? 0 : 1;
1240 mutex_unlock(&nic_cfg->cfg_mutex);
1242 return 0;
1245 int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable)
1247 struct hinic_port_loopback lb = {0};
1248 u16 out_size = sizeof(lb);
1249 int err;
1251 lb.mode = mode;
1252 lb.en = enable;
1254 if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
1255 dev_err(&hwdev->hwif->pdev->dev,
1256 "Invalid loopback mode %d to set\n", mode);
1257 return -EINVAL;
1260 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LOOPBACK_MODE,
1261 &lb, sizeof(lb), &lb, &out_size);
1262 if (err || !out_size || lb.status) {
1263 dev_err(&hwdev->hwif->pdev->dev,
1264 "Failed to set loopback mode %d en %d, err: %d, status: 0x%x, out size: 0x%x\n",
1265 mode, enable, err, lb.status, out_size);
1266 return -EIO;
1269 return 0;
1272 static int _set_led_status(struct hinic_hwdev *hwdev, u8 port,
1273 enum hinic_led_type type,
1274 enum hinic_led_mode mode, u8 reset)
1276 struct hinic_led_info led_info = {0};
1277 u16 out_size = sizeof(led_info);
1278 struct hinic_pfhwdev *pfhwdev;
1279 int err;
1281 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
1283 led_info.port = port;
1284 led_info.reset = reset;
1286 led_info.type = type;
1287 led_info.mode = mode;
1289 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
1290 HINIC_COMM_CMD_SET_LED_STATUS,
1291 &led_info, sizeof(led_info),
1292 &led_info, &out_size, HINIC_MGMT_MSG_SYNC);
1293 if (err || led_info.status || !out_size) {
1294 dev_err(&hwdev->hwif->pdev->dev, "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n",
1295 err, led_info.status, out_size);
1296 return -EIO;
1299 return 0;
1302 int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port,
1303 enum hinic_led_type type, enum hinic_led_mode mode)
1305 if (!hwdev)
1306 return -EINVAL;
1308 return _set_led_status(hwdev, port, type, mode, 0);
1311 int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port)
1313 int err;
1315 if (!hwdev)
1316 return -EINVAL;
1318 err = _set_led_status(hwdev, port, HINIC_LED_TYPE_INVALID,
1319 HINIC_LED_MODE_INVALID, 1);
1320 if (err)
1321 dev_err(&hwdev->hwif->pdev->dev,
1322 "Failed to reset led status\n");
1324 return err;
1327 static bool hinic_if_sfp_absent(struct hinic_hwdev *hwdev)
1329 struct hinic_cmd_get_light_module_abs sfp_abs = {0};
1330 u16 out_size = sizeof(sfp_abs);
1331 u8 port_id = hwdev->port_id;
1332 int err;
1334 sfp_abs.port_id = port_id;
1335 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_SFP_ABS,
1336 &sfp_abs, sizeof(sfp_abs), &sfp_abs,
1337 &out_size);
1338 if (sfp_abs.status || err || !out_size) {
1339 dev_err(&hwdev->hwif->pdev->dev,
1340 "Failed to get port%d sfp absent status, err: %d, status: 0x%x, out size: 0x%x\n",
1341 port_id, err, sfp_abs.status, out_size);
1342 return true;
1345 return ((sfp_abs.abs_status == 0) ? false : true);
1348 int hinic_get_sfp_eeprom(struct hinic_hwdev *hwdev, u8 *data, u16 *len)
1350 struct hinic_cmd_get_std_sfp_info sfp_info = {0};
1351 u16 out_size = sizeof(sfp_info);
1352 u8 port_id;
1353 int err;
1355 if (!hwdev || !data || !len)
1356 return -EINVAL;
1358 port_id = hwdev->port_id;
1360 if (hinic_if_sfp_absent(hwdev))
1361 return -ENXIO;
1363 sfp_info.port_id = port_id;
1364 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_STD_SFP_INFO,
1365 &sfp_info, sizeof(sfp_info), &sfp_info,
1366 &out_size);
1367 if (sfp_info.status || err || !out_size) {
1368 dev_err(&hwdev->hwif->pdev->dev,
1369 "Failed to get port%d sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
1370 port_id, err, sfp_info.status, out_size);
1371 return -EIO;
1374 *len = min_t(u16, sfp_info.eeprom_len, STD_SFP_INFO_MAX_SIZE);
1375 memcpy(data, sfp_info.sfp_info, STD_SFP_INFO_MAX_SIZE);
1377 return 0;
1380 int hinic_get_sfp_type(struct hinic_hwdev *hwdev, u8 *data0, u8 *data1)
1382 u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
1383 u16 len;
1384 int err;
1386 if (hinic_if_sfp_absent(hwdev))
1387 return -ENXIO;
1389 err = hinic_get_sfp_eeprom(hwdev, sfp_data, &len);
1390 if (err)
1391 return err;
1393 *data0 = sfp_data[0];
1394 *data1 = sfp_data[1];
1396 return 0;