1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Huawei HiNIC PCI Express Linux driver
4 * Copyright(c) 2017 Huawei Technologies Co., Ltd
5 */
6
7 #include <linux/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
23 enum mac_op {
24 MAC_DEL,
25 MAC_SET,
26 };
27
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
34 *
35 * Return 0 - Success, negative - Failure
36 **/
change_mac(struct hinic_dev * nic_dev,const u8 * addr,u16 vlan_id,enum mac_op op)37 static 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 * 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
87 *
88 * Return 0 - Success, negative - Failure
89 **/
hinic_port_add_mac(struct hinic_dev * nic_dev,const u8 * addr,u16 vlan_id)90 int 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 * 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
101 *
102 * Return 0 - Success, negative - Failure
103 **/
hinic_port_del_mac(struct hinic_dev * nic_dev,const u8 * addr,u16 vlan_id)104 int 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 * hinic_port_get_mac - get the mac address of the nic device
112 * @nic_dev: nic device
113 * @addr: returned mac address
114 *
115 * Return 0 - Success, negative - Failure
116 **/
hinic_port_get_mac(struct hinic_dev * nic_dev,u8 * addr)117 int 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 * hinic_port_set_mtu - set mtu
143 * @nic_dev: nic device
144 * @new_mtu: new mtu
145 *
146 * Return 0 - Success, negative - Failure
147 **/
hinic_port_set_mtu(struct hinic_dev * nic_dev,int new_mtu)148 int 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 * hinic_port_add_vlan - add vlan to the nic device
186 * @nic_dev: nic device
187 * @vlan_id: the vlan number to add
188 *
189 * Return 0 - Success, negative - Failure
190 **/
hinic_port_add_vlan(struct hinic_dev * nic_dev,u16 vlan_id)191 int 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 * hinic_port_del_vlan - delete vlan from the nic device
206 * @nic_dev: nic device
207 * @vlan_id: the vlan number to delete
208 *
209 * Return 0 - Success, negative - Failure
210 **/
hinic_port_del_vlan(struct hinic_dev * nic_dev,u16 vlan_id)211 int 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 * 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
228 *
229 * Return 0 - Success, negative - Failure
230 **/
hinic_port_set_rx_mode(struct hinic_dev * nic_dev,u32 rx_mode)231 int 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 * hinic_port_link_state - get the link state
246 * @nic_dev: nic device
247 * @link_state: the returned link state
248 *
249 * Return 0 - Success, negative - Failure
250 **/
hinic_port_link_state(struct hinic_dev * nic_dev,enum hinic_port_link_state * link_state)251 int 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 * hinic_port_set_state - set port state
278 * @nic_dev: nic device
279 * @state: the state to set
280 *
281 * Return 0 - Success, negative - Failure
282 **/
hinic_port_set_state(struct hinic_dev * nic_dev,enum hinic_port_state state)283 int 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 * hinic_port_set_func_state- set func device state
311 * @nic_dev: nic device
312 * @state: the state to set
313 *
314 * Return 0 - Success, negative - Failure
315 **/
hinic_port_set_func_state(struct hinic_dev * nic_dev,enum hinic_func_port_state state)316 int 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 * hinic_port_get_cap - get port capabilities
343 * @nic_dev: nic device
344 * @port_cap: returned port capabilities
345 *
346 * Return 0 - Success, negative - Failure
347 **/
hinic_port_get_cap(struct hinic_dev * nic_dev,struct hinic_port_cap * port_cap)348 int 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 * hinic_port_set_tso - set port tso configuration
374 * @nic_dev: nic device
375 * @state: the tso state to set
376 *
377 * Return 0 - Success, negative - Failure
378 **/
hinic_port_set_tso(struct hinic_dev * nic_dev,enum hinic_tso_state state)379 int 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
hinic_set_rx_csum_offload(struct hinic_dev * nic_dev,u32 en)404 int 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
hinic_set_rx_vlan_offload(struct hinic_dev * nic_dev,u8 en)434 int 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
hinic_set_max_qnum(struct hinic_dev * nic_dev,u8 num_rqs)465 int 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
hinic_set_rx_lro(struct hinic_dev * nic_dev,u8 ipv4_en,u8 ipv6_en,u8 max_wqe_num)491 static 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
hinic_set_rx_lro_timer(struct hinic_dev * nic_dev,u32 timer_value)519 static 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 /* 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");
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
hinic_set_rx_lro_state(struct hinic_dev * nic_dev,u8 lro_en,u32 lro_timer,u32 wqe_num)554 int 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
hinic_rss_set_indir_tbl(struct hinic_dev * nic_dev,u32 tmpl_idx,const u32 * indir_table)582 int 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 /* 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);
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
647 free_buf:
648 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
649
650 return err;
651 }
652
hinic_rss_get_indir_tbl(struct hinic_dev * nic_dev,u32 tmpl_idx,u32 * indir_table)653 int 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
hinic_set_rss_type(struct hinic_dev * nic_dev,u32 tmpl_idx,struct hinic_rss_type rss_type)683 int 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 /* 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);
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
hinic_get_rss_type(struct hinic_dev * nic_dev,u32 tmpl_idx,struct hinic_rss_type * rss_type)743 int 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
hinic_rss_set_template_tbl(struct hinic_dev * nic_dev,u32 template_id,const u8 * temp)784 int 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
hinic_rss_get_template_tbl(struct hinic_dev * nic_dev,u32 tmpl_idx,u8 * temp)811 int 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
hinic_rss_set_hash_engine(struct hinic_dev * nic_dev,u8 template_id,u8 type)844 int 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
hinic_rss_get_hash_engine(struct hinic_dev * nic_dev,u8 tmpl_idx,u8 * type)871 int 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
hinic_rss_cfg(struct hinic_dev * nic_dev,u8 rss_en,u8 template_id)902 int 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
hinic_rss_template_alloc(struct hinic_dev * nic_dev,u8 * tmpl_idx)929 int 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
hinic_rss_template_free(struct hinic_dev * nic_dev,u8 tmpl_idx)955 int 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
hinic_get_vport_stats(struct hinic_dev * nic_dev,struct hinic_vport_stats * stats)980 int 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
hinic_get_phy_port_stats(struct hinic_dev * nic_dev,struct hinic_phy_port_stats * stats)1009 int 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
1040 out:
1041 kfree(port_stats);
1042
1043 return err;
1044 }
1045
hinic_get_mgmt_version(struct hinic_dev * nic_dev,u8 * mgmt_ver)1046 int 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
hinic_get_link_mode(struct hinic_hwdev * hwdev,struct hinic_link_mode_cmd * link_mode)1076 int 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
hinic_set_autoneg(struct hinic_hwdev * hwdev,bool enable)1101 int 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
hinic_set_speed(struct hinic_hwdev * hwdev,enum nic_speed_level speed)1126 int 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
hinic_set_link_settings(struct hinic_hwdev * hwdev,struct hinic_link_ksettings_info * info)1151 int 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
hinic_get_hw_pause_info(struct hinic_hwdev * hwdev,struct hinic_pause_config * pause_info)1170 int 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
hinic_set_hw_pause_info(struct hinic_hwdev * hwdev,struct hinic_pause_config * pause_info)1190 int 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
hinic_dcb_set_pfc(struct hinic_hwdev * hwdev,u8 pfc_en,u8 pfc_bitmap)1210 int 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 /* pause settings is opposite from pfc */
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
hinic_set_loopback_mode(struct hinic_hwdev * hwdev,u32 mode,u32 enable)1245 int 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
_set_led_status(struct hinic_hwdev * hwdev,u8 port,enum hinic_led_type type,enum hinic_led_mode mode,u8 reset)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)
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
hinic_set_led_status(struct hinic_hwdev * hwdev,u8 port,enum hinic_led_type type,enum hinic_led_mode mode)1302 int 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
hinic_reset_led_status(struct hinic_hwdev * hwdev,u8 port)1311 int 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
hinic_if_sfp_absent(struct hinic_hwdev * hwdev)1327 static 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
hinic_get_sfp_eeprom(struct hinic_hwdev * hwdev,u8 * data,u16 * len)1348 int 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
hinic_get_sfp_type(struct hinic_hwdev * hwdev,u8 * data0,u8 * data1)1380 int 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