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 net_device *netdev = nic_dev->netdev;
41 struct hinic_hwdev *hwdev = nic_dev->hwdev;
42 struct hinic_port_mac_cmd port_mac_cmd;
43 struct hinic_hwif *hwif = hwdev->hwif;
44 struct pci_dev *pdev = hwif->pdev;
45 enum hinic_port_cmd cmd;
46 u16 out_size;
47 int err;
48
49 if (vlan_id >= VLAN_N_VID) {
50 netif_err(nic_dev, drv, netdev, "Invalid VLAN number\n");
51 return -EINVAL;
52 }
53
54 if (op == MAC_SET)
55 cmd = HINIC_PORT_CMD_SET_MAC;
56 else
57 cmd = HINIC_PORT_CMD_DEL_MAC;
58
59 port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
60 port_mac_cmd.vlan_id = vlan_id;
61 memcpy(port_mac_cmd.mac, addr, ETH_ALEN);
62
63 err = hinic_port_msg_cmd(hwdev, cmd, &port_mac_cmd,
64 sizeof(port_mac_cmd),
65 &port_mac_cmd, &out_size);
66 if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) {
67 dev_err(&pdev->dev, "Failed to change MAC, ret = %d\n",
68 port_mac_cmd.status);
69 return -EFAULT;
70 }
71
72 return 0;
73}
74
75
76
77
78
79
80
81
82
83int hinic_port_add_mac(struct hinic_dev *nic_dev,
84 const u8 *addr, u16 vlan_id)
85{
86 return change_mac(nic_dev, addr, vlan_id, MAC_SET);
87}
88
89
90
91
92
93
94
95
96
97int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr,
98 u16 vlan_id)
99{
100 return change_mac(nic_dev, addr, vlan_id, MAC_DEL);
101}
102
103
104
105
106
107
108
109
110int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
111{
112 struct hinic_hwdev *hwdev = nic_dev->hwdev;
113 struct hinic_port_mac_cmd port_mac_cmd;
114 struct hinic_hwif *hwif = hwdev->hwif;
115 struct pci_dev *pdev = hwif->pdev;
116 u16 out_size;
117 int err;
118
119 port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
120
121 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MAC,
122 &port_mac_cmd, sizeof(port_mac_cmd),
123 &port_mac_cmd, &out_size);
124 if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) {
125 dev_err(&pdev->dev, "Failed to get mac, ret = %d\n",
126 port_mac_cmd.status);
127 return -EFAULT;
128 }
129
130 memcpy(addr, port_mac_cmd.mac, ETH_ALEN);
131 return 0;
132}
133
134
135
136
137
138
139
140
141int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
142{
143 struct net_device *netdev = nic_dev->netdev;
144 struct hinic_hwdev *hwdev = nic_dev->hwdev;
145 struct hinic_port_mtu_cmd port_mtu_cmd;
146 struct hinic_hwif *hwif = hwdev->hwif;
147 struct pci_dev *pdev = hwif->pdev;
148 int err, max_frame;
149 u16 out_size;
150
151 if (new_mtu < HINIC_MIN_MTU_SIZE) {
152 netif_err(nic_dev, drv, netdev, "mtu < MIN MTU size");
153 return -EINVAL;
154 }
155
156 max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
157 if (max_frame > HINIC_MAX_JUMBO_FRAME_SIZE) {
158 netif_err(nic_dev, drv, netdev, "mtu > MAX MTU size");
159 return -EINVAL;
160 }
161
162 port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
163 port_mtu_cmd.mtu = new_mtu;
164
165 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
166 &port_mtu_cmd, sizeof(port_mtu_cmd),
167 &port_mtu_cmd, &out_size);
168 if (err || (out_size != sizeof(port_mtu_cmd)) || port_mtu_cmd.status) {
169 dev_err(&pdev->dev, "Failed to set mtu, ret = %d\n",
170 port_mtu_cmd.status);
171 return -EFAULT;
172 }
173
174 return 0;
175}
176
177
178
179
180
181
182
183
184int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
185{
186 struct hinic_hwdev *hwdev = nic_dev->hwdev;
187 struct hinic_port_vlan_cmd port_vlan_cmd;
188
189 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
190 port_vlan_cmd.vlan_id = vlan_id;
191
192 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN,
193 &port_vlan_cmd, sizeof(port_vlan_cmd),
194 NULL, NULL);
195}
196
197
198
199
200
201
202
203
204int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
205{
206 struct hinic_hwdev *hwdev = nic_dev->hwdev;
207 struct hinic_port_vlan_cmd port_vlan_cmd;
208
209 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
210 port_vlan_cmd.vlan_id = vlan_id;
211
212 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN,
213 &port_vlan_cmd, sizeof(port_vlan_cmd),
214 NULL, NULL);
215}
216
217
218
219
220
221
222
223
224int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode)
225{
226 struct hinic_hwdev *hwdev = nic_dev->hwdev;
227 struct hinic_port_rx_mode_cmd rx_mode_cmd;
228
229 rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
230 rx_mode_cmd.rx_mode = rx_mode;
231
232 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
233 &rx_mode_cmd, sizeof(rx_mode_cmd),
234 NULL, NULL);
235}
236
237
238
239
240
241
242
243
244int hinic_port_link_state(struct hinic_dev *nic_dev,
245 enum hinic_port_link_state *link_state)
246{
247 struct hinic_hwdev *hwdev = nic_dev->hwdev;
248 struct hinic_hwif *hwif = hwdev->hwif;
249 struct hinic_port_link_cmd link_cmd;
250 struct pci_dev *pdev = hwif->pdev;
251 u16 out_size;
252 int err;
253
254 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
255 dev_err(&pdev->dev, "unsupported PCI Function type\n");
256 return -EINVAL;
257 }
258
259 link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
260
261 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_STATE,
262 &link_cmd, sizeof(link_cmd),
263 &link_cmd, &out_size);
264 if (err || (out_size != sizeof(link_cmd)) || link_cmd.status) {
265 dev_err(&pdev->dev, "Failed to get link state, ret = %d\n",
266 link_cmd.status);
267 return -EINVAL;
268 }
269
270 *link_state = link_cmd.state;
271 return 0;
272}
273
274
275
276
277
278
279
280
281int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
282{
283 struct hinic_hwdev *hwdev = nic_dev->hwdev;
284 struct hinic_port_state_cmd port_state;
285 struct hinic_hwif *hwif = hwdev->hwif;
286 struct pci_dev *pdev = hwif->pdev;
287 u16 out_size;
288 int err;
289
290 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
291 dev_err(&pdev->dev, "unsupported PCI Function type\n");
292 return -EINVAL;
293 }
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, ret = %d\n",
302 port_state.status);
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;
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, ret = %d\n",
334 func_state.status);
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;
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, ret = %d\n",
365 port_cap->status);
366 return -EINVAL;
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;
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, ret = %d\n",
397 tso_cfg.status);
398 return -EINVAL;
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 struct hinic_hwif *hwif;
409 struct pci_dev *pdev;
410 u16 out_size;
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, ret = %d\n",
427 rx_csum_cfg.status);
428 return -EINVAL;
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 hwif = hwdev->hwif;
447 pdev = hwif->pdev;
448 vlan_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
449 vlan_cfg.vlan_rx_offload = en;
450
451 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD,
452 &vlan_cfg, sizeof(vlan_cfg),
453 &vlan_cfg, &out_size);
454 if (err || !out_size || vlan_cfg.status) {
455 dev_err(&pdev->dev,
456 "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n",
457 err, vlan_cfg.status, out_size);
458 return -EINVAL;
459 }
460
461 return 0;
462}
463
464int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
465{
466 struct hinic_hwdev *hwdev = nic_dev->hwdev;
467 struct hinic_hwif *hwif = hwdev->hwif;
468 struct pci_dev *pdev = hwif->pdev;
469 struct hinic_rq_num rq_num = { 0 };
470 u16 out_size = sizeof(rq_num);
471 int err;
472
473 rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif);
474 rq_num.num_rqs = num_rqs;
475 rq_num.rq_depth = ilog2(HINIC_SQ_DEPTH);
476
477 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP,
478 &rq_num, sizeof(rq_num),
479 &rq_num, &out_size);
480 if (err || !out_size || rq_num.status) {
481 dev_err(&pdev->dev,
482 "Failed to rxq number, ret = %d\n",
483 rq_num.status);
484 return -EINVAL;
485 }
486
487 return 0;
488}
489
490static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
491 u8 max_wqe_num)
492{
493 struct hinic_hwdev *hwdev = nic_dev->hwdev;
494 struct hinic_hwif *hwif = hwdev->hwif;
495 struct hinic_lro_config lro_cfg = { 0 };
496 struct pci_dev *pdev = hwif->pdev;
497 u16 out_size = sizeof(lro_cfg);
498 int err;
499
500 lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
501 lro_cfg.lro_ipv4_en = ipv4_en;
502 lro_cfg.lro_ipv6_en = ipv6_en;
503 lro_cfg.lro_max_wqe_num = max_wqe_num;
504
505 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO,
506 &lro_cfg, sizeof(lro_cfg),
507 &lro_cfg, &out_size);
508 if (err || !out_size || lro_cfg.status) {
509 dev_err(&pdev->dev,
510 "Failed to set lro offload, ret = %d\n",
511 lro_cfg.status);
512 return -EINVAL;
513 }
514
515 return 0;
516}
517
518static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
519{
520 struct hinic_hwdev *hwdev = nic_dev->hwdev;
521 struct hinic_lro_timer lro_timer = { 0 };
522 struct hinic_hwif *hwif = hwdev->hwif;
523 struct pci_dev *pdev = hwif->pdev;
524 u16 out_size = sizeof(lro_timer);
525 int err;
526
527 lro_timer.status = 0;
528 lro_timer.type = 0;
529 lro_timer.enable = 1;
530 lro_timer.timer = timer_value;
531
532 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER,
533 &lro_timer, sizeof(lro_timer),
534 &lro_timer, &out_size);
535 if (lro_timer.status == 0xFF) {
536
537 lro_timer.status = 0;
538 dev_dbg(&pdev->dev,
539 "Set lro timer not supported by the current FW version, it will be 1ms default\n");
540 }
541
542 if (err || !out_size || lro_timer.status) {
543 dev_err(&pdev->dev,
544 "Failed to set lro timer, ret = %d\n",
545 lro_timer.status);
546
547 return -EINVAL;
548 }
549
550 return 0;
551}
552
553int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en,
554 u32 lro_timer, u32 wqe_num)
555{
556 struct hinic_hwdev *hwdev = nic_dev->hwdev;
557 u8 ipv4_en;
558 u8 ipv6_en;
559 int err;
560
561 if (!hwdev)
562 return -EINVAL;
563
564 ipv4_en = lro_en ? 1 : 0;
565 ipv6_en = lro_en ? 1 : 0;
566
567 err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num);
568 if (err)
569 return err;
570
571 err = hinic_set_rx_lro_timer(nic_dev, lro_timer);
572 if (err)
573 return err;
574
575 return 0;
576}
577
578int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
579 const u32 *indir_table)
580{
581 struct hinic_rss_indirect_tbl *indir_tbl;
582 struct hinic_func_to_io *func_to_io;
583 struct hinic_cmdq_buf cmd_buf;
584 struct hinic_hwdev *hwdev;
585 struct hinic_hwif *hwif;
586 struct pci_dev *pdev;
587 u32 indir_size;
588 u64 out_param;
589 int err, i;
590 u32 *temp;
591
592 hwdev = nic_dev->hwdev;
593 func_to_io = &hwdev->func_to_io;
594 hwif = hwdev->hwif;
595 pdev = hwif->pdev;
596
597 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
598 if (err) {
599 dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
600 return err;
601 }
602
603 cmd_buf.size = sizeof(*indir_tbl);
604
605 indir_tbl = cmd_buf.buf;
606 indir_tbl->group_index = cpu_to_be32(tmpl_idx);
607
608 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
609 indir_tbl->entry[i] = indir_table[i];
610
611 if (0x3 == (i & 0x3)) {
612 temp = (u32 *)&indir_tbl->entry[i - 3];
613 *temp = cpu_to_be32(*temp);
614 }
615 }
616
617
618 indir_size = HINIC_RSS_INDIR_SIZE / 2;
619 indir_tbl->offset = 0;
620 indir_tbl->size = cpu_to_be32(indir_size);
621
622 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
623 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
624 &cmd_buf, &out_param);
625 if (err || out_param != 0) {
626 dev_err(&pdev->dev, "Failed to set rss indir table\n");
627 err = -EFAULT;
628 goto free_buf;
629 }
630
631 indir_tbl->offset = cpu_to_be32(indir_size);
632 indir_tbl->size = cpu_to_be32(indir_size);
633 memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size);
634
635 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
636 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
637 &cmd_buf, &out_param);
638 if (err || out_param != 0) {
639 dev_err(&pdev->dev, "Failed to set rss indir table\n");
640 err = -EFAULT;
641 }
642
643free_buf:
644 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
645
646 return err;
647}
648
649int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
650 u32 *indir_table)
651{
652 struct hinic_rss_indir_table rss_cfg = { 0 };
653 struct hinic_hwdev *hwdev = nic_dev->hwdev;
654 struct hinic_hwif *hwif = hwdev->hwif;
655 struct pci_dev *pdev = hwif->pdev;
656 u16 out_size = sizeof(rss_cfg);
657 int err = 0, i;
658
659 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
660 rss_cfg.template_id = tmpl_idx;
661
662 err = hinic_port_msg_cmd(hwdev,
663 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
664 &rss_cfg, sizeof(rss_cfg), &rss_cfg,
665 &out_size);
666 if (err || !out_size || rss_cfg.status) {
667 dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n",
668 err, rss_cfg.status, out_size);
669 return -EINVAL;
670 }
671
672 hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE);
673 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)
674 indir_table[i] = rss_cfg.indir[i];
675
676 return 0;
677}
678
679int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
680 struct hinic_rss_type rss_type)
681{
682 struct hinic_rss_context_tbl *ctx_tbl;
683 struct hinic_func_to_io *func_to_io;
684 struct hinic_cmdq_buf cmd_buf;
685 struct hinic_hwdev *hwdev;
686 struct hinic_hwif *hwif;
687 struct pci_dev *pdev;
688 u64 out_param;
689 u32 ctx = 0;
690 int err;
691
692 hwdev = nic_dev->hwdev;
693 func_to_io = &hwdev->func_to_io;
694 hwif = hwdev->hwif;
695 pdev = hwif->pdev;
696
697 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
698 if (err) {
699 dev_err(&pdev->dev, "Failed to allocate cmd buf\n");
700 return -ENOMEM;
701 }
702
703 ctx |= HINIC_RSS_TYPE_SET(1, VALID) |
704 HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
705 HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
706 HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
707 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
708 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
709 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
710 HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
711 HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
712
713 cmd_buf.size = sizeof(struct hinic_rss_context_tbl);
714
715 ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf;
716 ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
717 ctx_tbl->offset = 0;
718 ctx_tbl->size = sizeof(u32);
719 ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
720 ctx_tbl->rsvd = 0;
721 ctx_tbl->ctx = cpu_to_be32(ctx);
722
723
724 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
725 HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
726 &cmd_buf, &out_param);
727
728 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
729
730 if (err || out_param != 0) {
731 dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n",
732 err);
733 return -EFAULT;
734 }
735
736 return 0;
737}
738
739int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
740 struct hinic_rss_type *rss_type)
741{
742 struct hinic_rss_context_table ctx_tbl = { 0 };
743 struct hinic_hwdev *hwdev = nic_dev->hwdev;
744 struct hinic_hwif *hwif;
745 struct pci_dev *pdev;
746 u16 out_size = sizeof(ctx_tbl);
747 int err;
748
749 if (!hwdev || !rss_type)
750 return -EINVAL;
751
752 hwif = hwdev->hwif;
753 pdev = hwif->pdev;
754
755 ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif);
756 ctx_tbl.template_id = tmpl_idx;
757
758 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL,
759 &ctx_tbl, sizeof(ctx_tbl),
760 &ctx_tbl, &out_size);
761 if (err || !out_size || ctx_tbl.status) {
762 dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n",
763 err, ctx_tbl.status, out_size);
764 return -EINVAL;
765 }
766
767 rss_type->ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
768 rss_type->ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
769 rss_type->ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
770 rss_type->tcp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
771 rss_type->tcp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
772 rss_type->tcp_ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context,
773 TCP_IPV6_EXT);
774 rss_type->udp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
775 rss_type->udp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
776
777 return 0;
778}
779
780int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id,
781 const u8 *temp)
782{
783 struct hinic_hwdev *hwdev = nic_dev->hwdev;
784 struct hinic_hwif *hwif = hwdev->hwif;
785 struct hinic_rss_key rss_key = { 0 };
786 struct pci_dev *pdev = hwif->pdev;
787 u16 out_size;
788 int err;
789
790 rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
791 rss_key.template_id = template_id;
792 memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE);
793
794 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL,
795 &rss_key, sizeof(rss_key),
796 &rss_key, &out_size);
797 if (err || !out_size || rss_key.status) {
798 dev_err(&pdev->dev,
799 "Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n",
800 err, rss_key.status, out_size);
801 return -EINVAL;
802 }
803
804 return 0;
805}
806
807int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
808 u8 *temp)
809{
810 struct hinic_rss_template_key temp_key = { 0 };
811 struct hinic_hwdev *hwdev = nic_dev->hwdev;
812 struct hinic_hwif *hwif;
813 struct pci_dev *pdev;
814 u16 out_size = sizeof(temp_key);
815 int err;
816
817 if (!hwdev || !temp)
818 return -EINVAL;
819
820 hwif = hwdev->hwif;
821 pdev = hwif->pdev;
822
823 temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
824 temp_key.template_id = tmpl_idx;
825
826 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL,
827 &temp_key, sizeof(temp_key),
828 &temp_key, &out_size);
829 if (err || !out_size || temp_key.status) {
830 dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n",
831 err, temp_key.status, out_size);
832 return -EINVAL;
833 }
834
835 memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
836
837 return 0;
838}
839
840int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id,
841 u8 type)
842{
843 struct hinic_rss_engine_type rss_engine = { 0 };
844 struct hinic_hwdev *hwdev = nic_dev->hwdev;
845 struct hinic_hwif *hwif = hwdev->hwif;
846 struct pci_dev *pdev = hwif->pdev;
847 u16 out_size;
848 int err;
849
850 rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif);
851 rss_engine.hash_engine = type;
852 rss_engine.template_id = template_id;
853
854 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE,
855 &rss_engine, sizeof(rss_engine),
856 &rss_engine, &out_size);
857 if (err || !out_size || rss_engine.status) {
858 dev_err(&pdev->dev,
859 "Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
860 err, rss_engine.status, out_size);
861 return -EINVAL;
862 }
863
864 return 0;
865}
866
867int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type)
868{
869 struct hinic_rss_engine_type hash_type = { 0 };
870 struct hinic_hwdev *hwdev = nic_dev->hwdev;
871 struct hinic_hwif *hwif;
872 struct pci_dev *pdev;
873 u16 out_size = sizeof(hash_type);
874 int err;
875
876 if (!hwdev || !type)
877 return -EINVAL;
878
879 hwif = hwdev->hwif;
880 pdev = hwif->pdev;
881
882 hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif);
883 hash_type.template_id = tmpl_idx;
884
885 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE,
886 &hash_type, sizeof(hash_type),
887 &hash_type, &out_size);
888 if (err || !out_size || hash_type.status) {
889 dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
890 err, hash_type.status, out_size);
891 return -EINVAL;
892 }
893
894 *type = hash_type.hash_engine;
895 return 0;
896}
897
898int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id)
899{
900 struct hinic_hwdev *hwdev = nic_dev->hwdev;
901 struct hinic_rss_config rss_cfg = { 0 };
902 struct hinic_hwif *hwif = hwdev->hwif;
903 struct pci_dev *pdev = hwif->pdev;
904 u16 out_size;
905 int err;
906
907 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
908 rss_cfg.rss_en = rss_en;
909 rss_cfg.template_id = template_id;
910 rss_cfg.rq_priority_number = 0;
911
912 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG,
913 &rss_cfg, sizeof(rss_cfg),
914 &rss_cfg, &out_size);
915 if (err || !out_size || rss_cfg.status) {
916 dev_err(&pdev->dev,
917 "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n",
918 err, rss_cfg.status, out_size);
919 return -EINVAL;
920 }
921
922 return 0;
923}
924
925int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx)
926{
927 struct hinic_rss_template_mgmt template_mgmt = { 0 };
928 struct hinic_hwdev *hwdev = nic_dev->hwdev;
929 struct hinic_hwif *hwif = hwdev->hwif;
930 struct pci_dev *pdev = hwif->pdev;
931 u16 out_size;
932 int err;
933
934 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
935 template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
936
937 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
938 &template_mgmt, sizeof(template_mgmt),
939 &template_mgmt, &out_size);
940 if (err || !out_size || template_mgmt.status) {
941 dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n",
942 err, template_mgmt.status, out_size);
943 return -EINVAL;
944 }
945
946 *tmpl_idx = template_mgmt.template_id;
947
948 return 0;
949}
950
951int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx)
952{
953 struct hinic_rss_template_mgmt template_mgmt = { 0 };
954 struct hinic_hwdev *hwdev = nic_dev->hwdev;
955 struct hinic_hwif *hwif = hwdev->hwif;
956 struct pci_dev *pdev = hwif->pdev;
957 u16 out_size;
958 int err;
959
960 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
961 template_mgmt.template_id = tmpl_idx;
962 template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
963
964 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
965 &template_mgmt, sizeof(template_mgmt),
966 &template_mgmt, &out_size);
967 if (err || !out_size || template_mgmt.status) {
968 dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n",
969 err, template_mgmt.status, out_size);
970 return -EINVAL;
971 }
972
973 return 0;
974}
975
976int hinic_get_vport_stats(struct hinic_dev *nic_dev,
977 struct hinic_vport_stats *stats)
978{
979 struct hinic_cmd_vport_stats vport_stats = { 0 };
980 struct hinic_port_stats_info stats_info = { 0 };
981 struct hinic_hwdev *hwdev = nic_dev->hwdev;
982 struct hinic_hwif *hwif = hwdev->hwif;
983 u16 out_size = sizeof(vport_stats);
984 struct pci_dev *pdev = hwif->pdev;
985 int err;
986
987 stats_info.stats_version = HINIC_PORT_STATS_VERSION;
988 stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif);
989 stats_info.stats_size = sizeof(vport_stats);
990
991 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT,
992 &stats_info, sizeof(stats_info),
993 &vport_stats, &out_size);
994 if (err || !out_size || vport_stats.status) {
995 dev_err(&pdev->dev,
996 "Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n",
997 err, vport_stats.status, out_size);
998 return -EFAULT;
999 }
1000
1001 memcpy(stats, &vport_stats.stats, sizeof(*stats));
1002 return 0;
1003}
1004
1005int hinic_get_phy_port_stats(struct hinic_dev *nic_dev,
1006 struct hinic_phy_port_stats *stats)
1007{
1008 struct hinic_port_stats_info stats_info = { 0 };
1009 struct hinic_hwdev *hwdev = nic_dev->hwdev;
1010 struct hinic_hwif *hwif = hwdev->hwif;
1011 struct hinic_port_stats *port_stats;
1012 u16 out_size = sizeof(*port_stats);
1013 struct pci_dev *pdev = hwif->pdev;
1014 int err;
1015
1016 port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
1017 if (!port_stats)
1018 return -ENOMEM;
1019
1020 stats_info.stats_version = HINIC_PORT_STATS_VERSION;
1021 stats_info.stats_size = sizeof(*port_stats);
1022
1023 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS,
1024 &stats_info, sizeof(stats_info),
1025 port_stats, &out_size);
1026 if (err || !out_size || port_stats->status) {
1027 dev_err(&pdev->dev,
1028 "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
1029 err, port_stats->status, out_size);
1030 err = -EINVAL;
1031 goto out;
1032 }
1033
1034 memcpy(stats, &port_stats->stats, sizeof(*stats));
1035
1036out:
1037 kfree(port_stats);
1038
1039 return err;
1040}
1041
1042int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver)
1043{
1044 struct hinic_hwdev *hwdev = nic_dev->hwdev;
1045 struct hinic_version_info up_ver = {0};
1046 struct hinic_hwif *hwif;
1047 struct pci_dev *pdev;
1048 u16 out_size;
1049 int err;
1050
1051 if (!hwdev)
1052 return -EINVAL;
1053
1054 hwif = hwdev->hwif;
1055 pdev = hwif->pdev;
1056
1057 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
1058 &up_ver, sizeof(up_ver), &up_ver,
1059 &out_size);
1060 if (err || !out_size || up_ver.status) {
1061 dev_err(&pdev->dev,
1062 "Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n",
1063 err, up_ver.status, out_size);
1064 return -EINVAL;
1065 }
1066
1067 snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver);
1068
1069 return 0;
1070}
1071