2 * Huawei HiNIC PCI Express Linux driver
3 * Copyright(c) 2017 Huawei Technologies Co., Ltd
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include <linux/types.h>
17 #include <linux/netdevice.h>
18 #include <linux/etherdevice.h>
19 #include <linux/if_vlan.h>
20 #include <linux/pci.h>
21 #include <linux/device.h>
22 #include <linux/errno.h>
24 #include "hinic_hw_if.h"
25 #include "hinic_hw_dev.h"
26 #include "hinic_port.h"
27 #include "hinic_dev.h"
29 #define HINIC_MIN_MTU_SIZE 256
30 #define HINIC_MAX_JUMBO_FRAME_SIZE 15872
38 * change_mac - change(add or delete) mac address
39 * @nic_dev: nic device
41 * @vlan_id: vlan number to set with the mac
42 * @op: add or delete the mac
44 * Return 0 - Success, negative - Failure
46 static int change_mac(struct hinic_dev
*nic_dev
, const u8
*addr
,
47 u16 vlan_id
, enum mac_op op
)
49 struct net_device
*netdev
= nic_dev
->netdev
;
50 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
51 struct hinic_port_mac_cmd port_mac_cmd
;
52 struct hinic_hwif
*hwif
= hwdev
->hwif
;
53 struct pci_dev
*pdev
= hwif
->pdev
;
54 enum hinic_port_cmd cmd
;
58 if (vlan_id
>= VLAN_N_VID
) {
59 netif_err(nic_dev
, drv
, netdev
, "Invalid VLAN number\n");
64 cmd
= HINIC_PORT_CMD_SET_MAC
;
66 cmd
= HINIC_PORT_CMD_DEL_MAC
;
68 port_mac_cmd
.func_idx
= HINIC_HWIF_FUNC_IDX(hwif
);
69 port_mac_cmd
.vlan_id
= vlan_id
;
70 memcpy(port_mac_cmd
.mac
, addr
, ETH_ALEN
);
72 err
= hinic_port_msg_cmd(hwdev
, cmd
, &port_mac_cmd
,
74 &port_mac_cmd
, &out_size
);
75 if (err
|| (out_size
!= sizeof(port_mac_cmd
)) || port_mac_cmd
.status
) {
76 dev_err(&pdev
->dev
, "Failed to change MAC, ret = %d\n",
85 * hinic_port_add_mac - add mac address
86 * @nic_dev: nic device
88 * @vlan_id: vlan number to set with the mac
90 * Return 0 - Success, negative - Failure
92 int hinic_port_add_mac(struct hinic_dev
*nic_dev
,
93 const u8
*addr
, u16 vlan_id
)
95 return change_mac(nic_dev
, addr
, vlan_id
, MAC_SET
);
99 * hinic_port_del_mac - remove mac address
100 * @nic_dev: nic device
102 * @vlan_id: vlan number that is connected to the mac
104 * Return 0 - Success, negative - Failure
106 int hinic_port_del_mac(struct hinic_dev
*nic_dev
, const u8
*addr
,
109 return change_mac(nic_dev
, addr
, vlan_id
, MAC_DEL
);
113 * hinic_port_get_mac - get the mac address of the nic device
114 * @nic_dev: nic device
115 * @addr: returned mac address
117 * Return 0 - Success, negative - Failure
119 int hinic_port_get_mac(struct hinic_dev
*nic_dev
, u8
*addr
)
121 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
122 struct hinic_port_mac_cmd port_mac_cmd
;
123 struct hinic_hwif
*hwif
= hwdev
->hwif
;
124 struct pci_dev
*pdev
= hwif
->pdev
;
128 port_mac_cmd
.func_idx
= HINIC_HWIF_FUNC_IDX(hwif
);
130 err
= hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_GET_MAC
,
131 &port_mac_cmd
, sizeof(port_mac_cmd
),
132 &port_mac_cmd
, &out_size
);
133 if (err
|| (out_size
!= sizeof(port_mac_cmd
)) || port_mac_cmd
.status
) {
134 dev_err(&pdev
->dev
, "Failed to get mac, ret = %d\n",
135 port_mac_cmd
.status
);
139 memcpy(addr
, port_mac_cmd
.mac
, ETH_ALEN
);
144 * hinic_port_set_mtu - set mtu
145 * @nic_dev: nic device
148 * Return 0 - Success, negative - Failure
150 int hinic_port_set_mtu(struct hinic_dev
*nic_dev
, int new_mtu
)
152 struct net_device
*netdev
= nic_dev
->netdev
;
153 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
154 struct hinic_port_mtu_cmd port_mtu_cmd
;
155 struct hinic_hwif
*hwif
= hwdev
->hwif
;
156 struct pci_dev
*pdev
= hwif
->pdev
;
160 if (new_mtu
< HINIC_MIN_MTU_SIZE
) {
161 netif_err(nic_dev
, drv
, netdev
, "mtu < MIN MTU size");
165 max_frame
= new_mtu
+ ETH_HLEN
+ ETH_FCS_LEN
;
166 if (max_frame
> HINIC_MAX_JUMBO_FRAME_SIZE
) {
167 netif_err(nic_dev
, drv
, netdev
, "mtu > MAX MTU size");
171 port_mtu_cmd
.func_idx
= HINIC_HWIF_FUNC_IDX(hwif
);
172 port_mtu_cmd
.mtu
= new_mtu
;
174 err
= hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_CHANGE_MTU
,
175 &port_mtu_cmd
, sizeof(port_mtu_cmd
),
176 &port_mtu_cmd
, &out_size
);
177 if (err
|| (out_size
!= sizeof(port_mtu_cmd
)) || port_mtu_cmd
.status
) {
178 dev_err(&pdev
->dev
, "Failed to set mtu, ret = %d\n",
179 port_mtu_cmd
.status
);
187 * hinic_port_add_vlan - add vlan to the nic device
188 * @nic_dev: nic device
189 * @vlan_id: the vlan number to add
191 * Return 0 - Success, negative - Failure
193 int hinic_port_add_vlan(struct hinic_dev
*nic_dev
, u16 vlan_id
)
195 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
196 struct hinic_port_vlan_cmd port_vlan_cmd
;
198 port_vlan_cmd
.func_idx
= HINIC_HWIF_FUNC_IDX(hwdev
->hwif
);
199 port_vlan_cmd
.vlan_id
= vlan_id
;
201 return hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_ADD_VLAN
,
202 &port_vlan_cmd
, sizeof(port_vlan_cmd
),
207 * hinic_port_del_vlan - delete vlan from the nic device
208 * @nic_dev: nic device
209 * @vlan_id: the vlan number to delete
211 * Return 0 - Success, negative - Failure
213 int hinic_port_del_vlan(struct hinic_dev
*nic_dev
, u16 vlan_id
)
215 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
216 struct hinic_port_vlan_cmd port_vlan_cmd
;
218 port_vlan_cmd
.func_idx
= HINIC_HWIF_FUNC_IDX(hwdev
->hwif
);
219 port_vlan_cmd
.vlan_id
= vlan_id
;
221 return hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_DEL_VLAN
,
222 &port_vlan_cmd
, sizeof(port_vlan_cmd
),
227 * hinic_port_set_rx_mode - set rx mode in the nic device
228 * @nic_dev: nic device
229 * @rx_mode: the rx mode to set
231 * Return 0 - Success, negative - Failure
233 int hinic_port_set_rx_mode(struct hinic_dev
*nic_dev
, u32 rx_mode
)
235 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
236 struct hinic_port_rx_mode_cmd rx_mode_cmd
;
238 rx_mode_cmd
.func_idx
= HINIC_HWIF_FUNC_IDX(hwdev
->hwif
);
239 rx_mode_cmd
.rx_mode
= rx_mode
;
241 return hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_SET_RX_MODE
,
242 &rx_mode_cmd
, sizeof(rx_mode_cmd
),
247 * hinic_port_link_state - get the link state
248 * @nic_dev: nic device
249 * @link_state: the returned link state
251 * Return 0 - Success, negative - Failure
253 int hinic_port_link_state(struct hinic_dev
*nic_dev
,
254 enum hinic_port_link_state
*link_state
)
256 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
257 struct hinic_hwif
*hwif
= hwdev
->hwif
;
258 struct hinic_port_link_cmd link_cmd
;
259 struct pci_dev
*pdev
= hwif
->pdev
;
263 if (!HINIC_IS_PF(hwif
) && !HINIC_IS_PPF(hwif
)) {
264 dev_err(&pdev
->dev
, "unsupported PCI Function type\n");
268 link_cmd
.func_idx
= HINIC_HWIF_FUNC_IDX(hwif
);
270 err
= hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_GET_LINK_STATE
,
271 &link_cmd
, sizeof(link_cmd
),
272 &link_cmd
, &out_size
);
273 if (err
|| (out_size
!= sizeof(link_cmd
)) || link_cmd
.status
) {
274 dev_err(&pdev
->dev
, "Failed to get link state, ret = %d\n",
279 *link_state
= link_cmd
.state
;
284 * hinic_port_set_state - set port state
285 * @nic_dev: nic device
286 * @state: the state to set
288 * Return 0 - Success, negative - Failure
290 int hinic_port_set_state(struct hinic_dev
*nic_dev
, enum hinic_port_state state
)
292 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
293 struct hinic_port_state_cmd port_state
;
294 struct hinic_hwif
*hwif
= hwdev
->hwif
;
295 struct pci_dev
*pdev
= hwif
->pdev
;
299 if (!HINIC_IS_PF(hwif
) && !HINIC_IS_PPF(hwif
)) {
300 dev_err(&pdev
->dev
, "unsupported PCI Function type\n");
304 port_state
.state
= state
;
306 err
= hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_SET_PORT_STATE
,
307 &port_state
, sizeof(port_state
),
308 &port_state
, &out_size
);
309 if (err
|| (out_size
!= sizeof(port_state
)) || port_state
.status
) {
310 dev_err(&pdev
->dev
, "Failed to set port state, ret = %d\n",
319 * hinic_port_set_func_state- set func device state
320 * @nic_dev: nic device
321 * @state: the state to set
323 * Return 0 - Success, negative - Failure
325 int hinic_port_set_func_state(struct hinic_dev
*nic_dev
,
326 enum hinic_func_port_state state
)
328 struct hinic_port_func_state_cmd func_state
;
329 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
330 struct hinic_hwif
*hwif
= hwdev
->hwif
;
331 struct pci_dev
*pdev
= hwif
->pdev
;
335 func_state
.func_idx
= HINIC_HWIF_FUNC_IDX(hwif
);
336 func_state
.state
= state
;
338 err
= hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_SET_FUNC_STATE
,
339 &func_state
, sizeof(func_state
),
340 &func_state
, &out_size
);
341 if (err
|| (out_size
!= sizeof(func_state
)) || func_state
.status
) {
342 dev_err(&pdev
->dev
, "Failed to set port func state, ret = %d\n",
351 * hinic_port_get_cap - get port capabilities
352 * @nic_dev: nic device
353 * @port_cap: returned port capabilities
355 * Return 0 - Success, negative - Failure
357 int hinic_port_get_cap(struct hinic_dev
*nic_dev
,
358 struct hinic_port_cap
*port_cap
)
360 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
361 struct hinic_hwif
*hwif
= hwdev
->hwif
;
362 struct pci_dev
*pdev
= hwif
->pdev
;
366 port_cap
->func_idx
= HINIC_HWIF_FUNC_IDX(hwif
);
368 err
= hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_GET_CAP
,
369 port_cap
, sizeof(*port_cap
),
370 port_cap
, &out_size
);
371 if (err
|| (out_size
!= sizeof(*port_cap
)) || port_cap
->status
) {
373 "Failed to get port capabilities, ret = %d\n",
382 * hinic_port_set_tso - set port tso configuration
383 * @nic_dev: nic device
384 * @state: the tso state to set
386 * Return 0 - Success, negative - Failure
388 int hinic_port_set_tso(struct hinic_dev
*nic_dev
, enum hinic_tso_state state
)
390 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
391 struct hinic_hwif
*hwif
= hwdev
->hwif
;
392 struct hinic_tso_config tso_cfg
= {0};
393 struct pci_dev
*pdev
= hwif
->pdev
;
397 tso_cfg
.func_id
= HINIC_HWIF_FUNC_IDX(hwif
);
398 tso_cfg
.tso_en
= state
;
400 err
= hinic_port_msg_cmd(hwdev
, HINIC_PORT_CMD_SET_TSO
,
401 &tso_cfg
, sizeof(tso_cfg
),
402 &tso_cfg
, &out_size
);
403 if (err
|| out_size
!= sizeof(tso_cfg
) || tso_cfg
.status
) {
405 "Failed to set port tso, ret = %d\n",