1
2
3
4
5
6
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>
14
15#include "hinic_hw_if.h"
16#include "hinic_hw_dev.h"
17#include "hinic_port.h"
18#include "hinic_dev.h"
19
20#define HINIC_MIN_MTU_SIZE 256
21#define HINIC_MAX_JUMBO_FRAME_SIZE 15872
22
23enum mac_op {
24 MAC_DEL,
25 MAC_SET,
26};
27
28
29
30
31
32
33
34
35
36
37static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
38 u16 vlan_id, enum mac_op op)
39{
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;
47
48 if (op == MAC_SET)
49 cmd = HINIC_PORT_CMD_SET_MAC;
50 else
51 cmd = HINIC_PORT_CMD_DEL_MAC;
52
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);
56
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;
67 }
68
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;
73 }
74
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");
78
79 return 0;
80}
81
82
83
84
85
86
87
88
89
90int hinic_port_add_mac(struct hinic_dev *nic_dev,
91 const u8 *addr, u16 vlan_id)
92{
93 return change_mac(nic_dev, addr, vlan_id, MAC_SET);
94}
95
96
97
98
99
100
101
102
103
104int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr,
105 u16 vlan_id)
106{
107 return change_mac(nic_dev, addr, vlan_id, MAC_DEL);
108}
109
110
111
112
113
114
115
116
117int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
118{
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;
125
126 port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
127
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;
135 }
136
137 memcpy(addr, port_mac_cmd.mac, ETH_ALEN);
138 return 0;
139}
140
141
142
143
144
145
146
147
148int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
149{
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;
157
158 if (new_mtu < HINIC_MIN_MTU_SIZE) {
159 netif_err(nic_dev, drv, netdev, "mtu < MIN MTU size");
160 return -EINVAL;
161 }
162
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;
167 }
168
169 port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
170 port_mtu_cmd.mtu = new_mtu;
171
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;
179 }
180
181 return 0;
182}
183
184
185
186
187
188
189
190
191int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
192{
193 struct hinic_hwdev *hwdev = nic_dev->hwdev;
194 struct hinic_port_vlan_cmd port_vlan_cmd;
195
196 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
197 port_vlan_cmd.vlan_id = vlan_id;
198
199 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN,
200 &port_vlan_cmd, sizeof(port_vlan_cmd),
201 NULL, NULL);
202}
203
204
205
206
207
208
209
210
211int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
212{
213 struct hinic_hwdev *hwdev = nic_dev->hwdev;
214 struct hinic_port_vlan_cmd port_vlan_cmd;
215
216 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
217 port_vlan_cmd.vlan_id = vlan_id;
218
219 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN,
220 &port_vlan_cmd, sizeof(port_vlan_cmd),
221 NULL, NULL);
222}
223
224
225
226
227
228
229
230
231int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode)
232{
233 struct hinic_hwdev *hwdev = nic_dev->hwdev;
234 struct hinic_port_rx_mode_cmd rx_mode_cmd;
235
236 rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
237 rx_mode_cmd.rx_mode = rx_mode;
238
239 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
240 &rx_mode_cmd, sizeof(rx_mode_cmd),
241 NULL, NULL);
242}
243
244
245
246
247
248
249
250
251int hinic_port_link_state(struct hinic_dev *nic_dev,
252 enum hinic_port_link_state *link_state)
253{
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;
260
261 link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
262
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;
270 }
271
272 *link_state = link_cmd.state;
273 return 0;
274}
275
276
277
278
279
280
281
282
283int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
284{
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;
291
292 if (HINIC_IS_VF(hwdev->hwif))
293 return 0;
294
295 port_state.state = state;
296
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;
304 }
305
306 return 0;
307}
308
309
310
311
312
313
314
315
316int hinic_port_set_func_state(struct hinic_dev *nic_dev,
317 enum hinic_func_port_state state)
318{
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;
325
326 func_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
327 func_state.state = state;
328
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;
336 }
337
338 return 0;
339}
340
341
342
343
344
345
346
347
348int hinic_port_get_cap(struct hinic_dev *nic_dev,
349 struct hinic_port_cap *port_cap)
350{
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;
356
357 port_cap->func_idx = HINIC_HWIF_FUNC_IDX(hwif);
358
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;
367 }
368
369 return 0;
370}
371
372
373
374
375
376
377
378
379int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state)
380{
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;
387
388 tso_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
389 tso_cfg.tso_en = state;
390
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;
399 }
400
401 return 0;
402}
403
404int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en)
405{
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;
412
413 if (!hwdev)
414 return -EINVAL;
415
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;
420
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;
429 }
430
431 return 0;
432}
433
434int hinic_set_rx_vlan_offload(struct hinic_dev *nic_dev, u8 en)
435{
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;
442
443 if (!hwdev)
444 return -EINVAL;
445
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;
451
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;
460 }
461
462 return 0;
463}
464
465int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
466{
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;
473
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);
477
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;
486 }
487
488 return 0;
489}
490
491static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
492 u8 max_wqe_num)
493{
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;
500
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;
505
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;
514 }
515
516 return 0;
517}
518
519static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
520{
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;
527
528 lro_timer.status = 0;
529 lro_timer.type = 0;
530 lro_timer.enable = 1;
531 lro_timer.timer = timer_value;
532
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
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");
541 }
542
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);
547
548 return -EIO;
549 }
550
551 return 0;
552}
553
554int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en,
555 u32 lro_timer, u32 wqe_num)
556{
557 struct hinic_hwdev *hwdev = nic_dev->hwdev;
558 u8 ipv4_en;
559 u8 ipv6_en;
560 int err;
561
562 if (!hwdev)
563 return -EINVAL;
564
565 ipv4_en = lro_en ? 1 : 0;
566 ipv6_en = lro_en ? 1 : 0;
567
568 err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num);
569 if (err)
570 return err;
571
572 if (HINIC_IS_VF(nic_dev->hwdev->hwif))
573 return 0;
574
575 err = hinic_set_rx_lro_timer(nic_dev, lro_timer);
576 if (err)
577 return err;
578
579 return 0;
580}
581
582int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
583 const u32 *indir_table)
584{
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;
595
596 hwdev = nic_dev->hwdev;
597 func_to_io = &hwdev->func_to_io;
598 hwif = hwdev->hwif;
599 pdev = hwif->pdev;
600
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;
605 }
606
607 cmd_buf.size = sizeof(*indir_tbl);
608
609 indir_tbl = cmd_buf.buf;
610 indir_tbl->group_index = cpu_to_be32(tmpl_idx);
611
612 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
613 indir_tbl->entry[i] = indir_table[i];
614
615 if (0x3 == (i & 0x3)) {
616 temp = (u32 *)&indir_tbl->entry[i - 3];
617 *temp = cpu_to_be32(*temp);
618 }
619 }
620
621
622 indir_size = HINIC_RSS_INDIR_SIZE / 2;
623 indir_tbl->offset = 0;
624 indir_tbl->size = cpu_to_be32(indir_size);
625
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;
633 }
634
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);
638
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;
645 }
646
647free_buf:
648 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
649
650 return err;
651}
652
653int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
654 u32 *indir_table)
655{
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;
662
663 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
664 rss_cfg.template_id = tmpl_idx;
665
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;
674 }
675
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];
679
680 return 0;
681}
682
683int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
684 struct hinic_rss_type rss_type)
685{
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;
695
696 hwdev = nic_dev->hwdev;
697 func_to_io = &hwdev->func_to_io;
698 hwif = hwdev->hwif;
699 pdev = hwif->pdev;
700
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;
705 }
706
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);
716
717 cmd_buf.size = sizeof(struct hinic_rss_context_tbl);
718
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);
726
727
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);
731
732 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
733
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;
738 }
739
740 return 0;
741}
742
743int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
744 struct hinic_rss_type *rss_type)
745{
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;
752
753 if (!hwdev || !rss_type)
754 return -EINVAL;
755
756 hwif = hwdev->hwif;
757 pdev = hwif->pdev;
758
759 ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif);
760 ctx_tbl.template_id = tmpl_idx;
761
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;
769 }
770
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);
780
781 return 0;
782}
783
784int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id,
785 const u8 *temp)
786{
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;
793
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);
797
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;
806 }
807
808 return 0;
809}
810
811int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
812 u8 *temp)
813{
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;
820
821 if (!hwdev || !temp)
822 return -EINVAL;
823
824 hwif = hwdev->hwif;
825 pdev = hwif->pdev;
826
827 temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
828 temp_key.template_id = tmpl_idx;
829
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;
837 }
838
839 memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
840
841 return 0;
842}
843
844int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id,
845 u8 type)
846{
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;
853
854 rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif);
855 rss_engine.hash_engine = type;
856 rss_engine.template_id = template_id;
857
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;
866 }
867
868 return 0;
869}
870
871int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type)
872{
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;
879
880 if (!hwdev || !type)
881 return -EINVAL;
882
883 hwif = hwdev->hwif;
884 pdev = hwif->pdev;
885
886 hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif);
887 hash_type.template_id = tmpl_idx;
888
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;
896 }
897
898 *type = hash_type.hash_engine;
899 return 0;
900}
901
902int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id)
903{
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;
910
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;
915
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;
924 }
925
926 return 0;
927}
928
929int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx)
930{
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;
937
938 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
939 template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
940
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;
948 }
949
950 *tmpl_idx = template_mgmt.template_id;
951
952 return 0;
953}
954
955int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx)
956{
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;
963
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;
967
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;
975 }
976
977 return 0;
978}
979
980int hinic_get_vport_stats(struct hinic_dev *nic_dev,
981 struct hinic_vport_stats *stats)
982{
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;
990
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);
994
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;
1003 }
1004
1005 memcpy(stats, &vport_stats.stats, sizeof(*stats));
1006 return 0;
1007}
1008
1009int hinic_get_phy_port_stats(struct hinic_dev *nic_dev,
1010 struct hinic_phy_port_stats *stats)
1011{
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;
1019
1020 port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
1021 if (!port_stats)
1022 return -ENOMEM;
1023
1024 stats_info.stats_version = HINIC_PORT_STATS_VERSION;
1025 stats_info.stats_size = sizeof(*port_stats);
1026
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;
1036 }
1037
1038 memcpy(stats, &port_stats->stats, sizeof(*stats));
1039
1040out:
1041 kfree(port_stats);
1042
1043 return err;
1044}
1045
1046int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver)
1047{
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;
1054
1055 if (!hwdev)
1056 return -EINVAL;
1057
1058 hwif = hwdev->hwif;
1059 pdev = hwif->pdev;
1060
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;
1069 }
1070
1071 snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver);
1072
1073 return 0;
1074}
1075
1076int hinic_get_link_mode(struct hinic_hwdev *hwdev,
1077 struct hinic_link_mode_cmd *link_mode)
1078{
1079 u16 out_size;
1080 int err;
1081
1082 if (!hwdev || !link_mode)
1083 return -EINVAL;
1084
1085 link_mode->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1086 out_size = sizeof(*link_mode);
1087
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;
1096 }
1097
1098 return 0;
1099}
1100
1101int hinic_set_autoneg(struct hinic_hwdev *hwdev, bool enable)
1102{
1103 struct hinic_set_autoneg_cmd autoneg = {0};
1104 u16 out_size = sizeof(autoneg);
1105 int err;
1106
1107 if (!hwdev)
1108 return -EINVAL;
1109
1110 autoneg.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1111 autoneg.enable = enable;
1112
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;
1121 }
1122
1123 return 0;
1124}
1125
1126int hinic_set_speed(struct hinic_hwdev *hwdev, enum nic_speed_level speed)
1127{
1128 struct hinic_speed_cmd speed_info = {0};
1129 u16 out_size = sizeof(speed_info);
1130 int err;
1131
1132 if (!hwdev)
1133 return -EINVAL;
1134
1135 speed_info.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1136 speed_info.speed = speed;
1137
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;
1146 }
1147
1148 return 0;
1149}
1150
1151int hinic_set_link_settings(struct hinic_hwdev *hwdev,
1152 struct hinic_link_ksettings_info *info)
1153{
1154 u16 out_size = sizeof(*info);
1155 int err;
1156
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;
1165 }
1166
1167 return info->status;
1168}
1169
1170int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev,
1171 struct hinic_pause_config *pause_info)
1172{
1173 u16 out_size = sizeof(*pause_info);
1174 int err;
1175
1176 pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1177
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;
1185 }
1186
1187 return 0;
1188}
1189
1190int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev,
1191 struct hinic_pause_config *pause_info)
1192{
1193 u16 out_size = sizeof(*pause_info);
1194 int err;
1195
1196 pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1197
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;
1205 }
1206
1207 return 0;
1208}
1209
1210int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap)
1211{
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;
1216
1217 if (HINIC_IS_VF(hwdev->hwif))
1218 return 0;
1219
1220 mutex_lock(&nic_cfg->cfg_mutex);
1221
1222 pfc.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1223 pfc.pfc_bitmap = pfc_bitmap;
1224 pfc.pfc_en = pfc_en;
1225
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;
1234 }
1235
1236
1237 nic_cfg->rx_pause = pfc_en ? 0 : 1;
1238 nic_cfg->tx_pause = pfc_en ? 0 : 1;
1239
1240 mutex_unlock(&nic_cfg->cfg_mutex);
1241
1242 return 0;
1243}
1244
1245int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable)
1246{
1247 struct hinic_port_loopback lb = {0};
1248 u16 out_size = sizeof(lb);
1249 int err;
1250
1251 lb.mode = mode;
1252 lb.en = enable;
1253
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;
1258 }
1259
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;
1267 }
1268
1269 return 0;
1270}
1271
1272static int _set_led_status(struct hinic_hwdev *hwdev, u8 port,
1273 enum hinic_led_type type,
1274 enum hinic_led_mode mode, u8 reset)
1275{
1276 struct hinic_led_info led_info = {0};
1277 u16 out_size = sizeof(led_info);
1278 struct hinic_pfhwdev *pfhwdev;
1279 int err;
1280
1281 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
1282
1283 led_info.port = port;
1284 led_info.reset = reset;
1285
1286 led_info.type = type;
1287 led_info.mode = mode;
1288
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;
1297 }
1298
1299 return 0;
1300}
1301
1302int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port,
1303 enum hinic_led_type type, enum hinic_led_mode mode)
1304{
1305 if (!hwdev)
1306 return -EINVAL;
1307
1308 return _set_led_status(hwdev, port, type, mode, 0);
1309}
1310
1311int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port)
1312{
1313 int err;
1314
1315 if (!hwdev)
1316 return -EINVAL;
1317
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");
1323
1324 return err;
1325}
1326
1327static bool hinic_if_sfp_absent(struct hinic_hwdev *hwdev)
1328{
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;
1333
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;
1343 }
1344
1345 return ((sfp_abs.abs_status == 0) ? false : true);
1346}
1347
1348int hinic_get_sfp_eeprom(struct hinic_hwdev *hwdev, u8 *data, u16 *len)
1349{
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;
1354
1355 if (!hwdev || !data || !len)
1356 return -EINVAL;
1357
1358 port_id = hwdev->port_id;
1359
1360 if (hinic_if_sfp_absent(hwdev))
1361 return -ENXIO;
1362
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;
1372 }
1373
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);
1376
1377 return 0;
1378}
1379
1380int hinic_get_sfp_type(struct hinic_hwdev *hwdev, u8 *data0, u8 *data1)
1381{
1382 u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
1383 u16 len;
1384 int err;
1385
1386 if (hinic_if_sfp_absent(hwdev))
1387 return -ENXIO;
1388
1389 err = hinic_get_sfp_eeprom(hwdev, sfp_data, &len);
1390 if (err)
1391 return err;
1392
1393 *data0 = sfp_data[0];
1394 *data1 = sfp_data[1];
1395
1396 return 0;
1397}
1398