Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018-2021 HiSilicon Limited.
3 : : */
4 : :
5 : : #include <rte_alarm.h>
6 : : #include <ethdev_pci.h>
7 : : #include <rte_io.h>
8 : :
9 : : #include "hns3_ethdev.h"
10 : : #include "hns3_common.h"
11 : : #include "hns3_dump.h"
12 : : #include "hns3_logs.h"
13 : : #include "hns3_rxtx.h"
14 : : #include "hns3_regs.h"
15 : : #include "hns3_intr.h"
16 : : #include "hns3_dcb.h"
17 : : #include "hns3_mp.h"
18 : : #include "hns3_flow.h"
19 : :
20 : : #define HNS3VF_KEEP_ALIVE_INTERVAL 2000000 /* us */
21 : : #define HNS3VF_SERVICE_INTERVAL 1000000 /* us */
22 : :
23 : : #define HNS3VF_RESET_WAIT_MS 20
24 : : #define HNS3VF_RESET_WAIT_CNT 2000
25 : :
26 : : /* Reset related Registers */
27 : : #define HNS3_GLOBAL_RESET_BIT 0
28 : : #define HNS3_CORE_RESET_BIT 1
29 : : #define HNS3_IMP_RESET_BIT 2
30 : : #define HNS3_FUN_RST_ING_B 0
31 : :
32 : : enum hns3vf_evt_cause {
33 : : HNS3VF_VECTOR0_EVENT_RST,
34 : : HNS3VF_VECTOR0_EVENT_MBX,
35 : : HNS3VF_VECTOR0_EVENT_OTHER,
36 : : };
37 : :
38 : : static enum hns3_reset_level hns3vf_get_reset_level(struct hns3_hw *hw,
39 : : RTE_ATOMIC(uint64_t) *levels);
40 : : static int hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
41 : : static int hns3vf_dev_configure_vlan(struct rte_eth_dev *dev);
42 : :
43 : : static int hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
44 : : struct rte_ether_addr *mac_addr);
45 : : static int hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
46 : : struct rte_ether_addr *mac_addr);
47 : : static int hns3vf_dev_link_update(struct rte_eth_dev *eth_dev,
48 : : __rte_unused int wait_to_complete);
49 : :
50 : : static int
51 : 0 : hns3vf_enable_msix(const struct rte_pci_device *device, bool op)
52 : : {
53 : : uint16_t control;
54 : : off_t pos;
55 : : int ret;
56 : :
57 [ # # ]: 0 : if (!rte_pci_has_capability_list(device)) {
58 : 0 : PMD_INIT_LOG(ERR, "Failed to read PCI capability list");
59 : 0 : return 0;
60 : : }
61 : :
62 : 0 : pos = rte_pci_find_capability(device, RTE_PCI_CAP_ID_MSIX);
63 [ # # ]: 0 : if (pos > 0) {
64 : 0 : ret = rte_pci_read_config(device, &control, sizeof(control),
65 : : pos + RTE_PCI_MSIX_FLAGS);
66 [ # # ]: 0 : if (ret < 0) {
67 : 0 : PMD_INIT_LOG(ERR, "Failed to read MSIX flags");
68 : 0 : return -ENXIO;
69 : : }
70 : :
71 [ # # ]: 0 : if (op)
72 : 0 : control |= RTE_PCI_MSIX_FLAGS_ENABLE;
73 : : else
74 : 0 : control &= ~RTE_PCI_MSIX_FLAGS_ENABLE;
75 : 0 : ret = rte_pci_write_config(device, &control, sizeof(control),
76 : : pos + RTE_PCI_MSIX_FLAGS);
77 [ # # ]: 0 : if (ret < 0) {
78 : 0 : PMD_INIT_LOG(ERR, "failed to write MSIX flags");
79 : 0 : return -ENXIO;
80 : : }
81 : :
82 : : return 0;
83 : : }
84 : :
85 : : return -ENXIO;
86 : : }
87 : :
88 : : static int
89 : 0 : hns3vf_add_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
90 : : {
91 : : /* mac address was checked by upper level interface */
92 : : char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
93 : : struct hns3_vf_to_pf_msg req;
94 : : int ret;
95 : :
96 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_UNICAST,
97 : : HNS3_MBX_MAC_VLAN_UC_ADD);
98 : 0 : memcpy(req.data, mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN);
99 : 0 : ret = hns3vf_mbx_send(hw, &req, false, NULL, 0);
100 [ # # ]: 0 : if (ret) {
101 : 0 : hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
102 : : mac_addr);
103 : 0 : hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
104 : : mac_str, ret);
105 : : }
106 : 0 : return ret;
107 : : }
108 : :
109 : : static int
110 : 0 : hns3vf_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
111 : : {
112 : : /* mac address was checked by upper level interface */
113 : : char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
114 : : struct hns3_vf_to_pf_msg req;
115 : : int ret;
116 : :
117 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_UNICAST,
118 : : HNS3_MBX_MAC_VLAN_UC_REMOVE);
119 : 0 : memcpy(req.data, mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN);
120 : 0 : ret = hns3vf_mbx_send(hw, &req, false, NULL, 0);
121 [ # # ]: 0 : if (ret) {
122 : 0 : hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
123 : : mac_addr);
124 : 0 : hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
125 : : mac_str, ret);
126 : : }
127 : 0 : return ret;
128 : : }
129 : :
130 : : static int
131 : 0 : hns3vf_set_default_mac_addr(struct rte_eth_dev *dev,
132 : : struct rte_ether_addr *mac_addr)
133 : : {
134 : : #define HNS3_TWO_ETHER_ADDR_LEN (RTE_ETHER_ADDR_LEN * 2)
135 : 0 : struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
136 : : struct rte_ether_addr *old_addr;
137 : : uint8_t addr_bytes[HNS3_TWO_ETHER_ADDR_LEN]; /* for 2 MAC addresses */
138 : : char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
139 : : struct hns3_vf_to_pf_msg req;
140 : : int ret;
141 : :
142 : : /*
143 : : * It has been guaranteed that input parameter named mac_addr is valid
144 : : * address in the rte layer of DPDK framework.
145 : : */
146 : 0 : old_addr = (struct rte_ether_addr *)hw->mac.mac_addr;
147 : 0 : rte_spinlock_lock(&hw->lock);
148 : 0 : memcpy(addr_bytes, mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN);
149 : 0 : memcpy(&addr_bytes[RTE_ETHER_ADDR_LEN], old_addr->addr_bytes,
150 : : RTE_ETHER_ADDR_LEN);
151 : :
152 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_UNICAST,
153 : : HNS3_MBX_MAC_VLAN_UC_MODIFY);
154 : : memcpy(req.data, addr_bytes, HNS3_TWO_ETHER_ADDR_LEN);
155 : 0 : ret = hns3vf_mbx_send(hw, &req, true, NULL, 0);
156 [ # # ]: 0 : if (ret) {
157 : : /*
158 : : * The hns3 VF PMD depends on the hns3 PF kernel ethdev
159 : : * driver. When user has configured a MAC address for VF device
160 : : * by "ip link set ..." command based on the PF device, the hns3
161 : : * PF kernel ethdev driver does not allow VF driver to request
162 : : * reconfiguring a different default MAC address, and return
163 : : * -EPREM to VF driver through mailbox.
164 : : */
165 [ # # ]: 0 : if (ret == -EPERM) {
166 : 0 : hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
167 : : old_addr);
168 : 0 : hns3_warn(hw, "Has permanent mac addr(%s) for vf",
169 : : mac_str);
170 : : } else {
171 : 0 : hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
172 : : mac_addr);
173 : 0 : hns3_err(hw, "Failed to set mac addr(%s) for vf: %d",
174 : : mac_str, ret);
175 : : }
176 : : rte_spinlock_unlock(&hw->lock);
177 : 0 : return ret;
178 : : }
179 : :
180 : : rte_ether_addr_copy(mac_addr,
181 : : (struct rte_ether_addr *)hw->mac.mac_addr);
182 : : rte_spinlock_unlock(&hw->lock);
183 : :
184 : 0 : return ret;
185 : : }
186 : :
187 : : static int
188 : 0 : hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
189 : : struct rte_ether_addr *mac_addr)
190 : : {
191 : : char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
192 : : struct hns3_vf_to_pf_msg req;
193 : : int ret;
194 : :
195 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_MULTICAST,
196 : : HNS3_MBX_MAC_VLAN_MC_ADD);
197 : 0 : memcpy(req.data, mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN);
198 : 0 : ret = hns3vf_mbx_send(hw, &req, false, NULL, 0);
199 [ # # ]: 0 : if (ret) {
200 : 0 : hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
201 : : mac_addr);
202 : 0 : hns3_err(hw, "Failed to add mc mac addr(%s) for vf: %d",
203 : : mac_str, ret);
204 : : }
205 : :
206 : 0 : return ret;
207 : : }
208 : :
209 : : static int
210 : 0 : hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
211 : : struct rte_ether_addr *mac_addr)
212 : : {
213 : : char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
214 : : struct hns3_vf_to_pf_msg req;
215 : : int ret;
216 : :
217 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_MULTICAST,
218 : : HNS3_MBX_MAC_VLAN_MC_REMOVE);
219 : 0 : memcpy(req.data, mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN);
220 : 0 : ret = hns3vf_mbx_send(hw, &req, false, NULL, 0);
221 [ # # ]: 0 : if (ret) {
222 : 0 : hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
223 : : mac_addr);
224 : 0 : hns3_err(hw, "Failed to remove mc mac addr(%s) for vf: %d",
225 : : mac_str, ret);
226 : : }
227 : :
228 : 0 : return ret;
229 : : }
230 : :
231 : : static int
232 : 0 : hns3vf_set_promisc_mode(struct hns3_hw *hw, bool en_bc_pmc,
233 : : bool en_uc_pmc, bool en_mc_pmc)
234 : : {
235 : : struct hns3_mbx_vf_to_pf_cmd *req;
236 : : struct hns3_cmd_desc desc;
237 : : int ret;
238 : :
239 : : req = (struct hns3_mbx_vf_to_pf_cmd *)desc.data;
240 : :
241 : : /*
242 : : * The hns3 VF PMD depends on the hns3 PF kernel ethdev driver,
243 : : * so there are some features for promiscuous/allmulticast mode in hns3
244 : : * VF PMD as below:
245 : : * 1. The promiscuous/allmulticast mode can be configured successfully
246 : : * only based on the trusted VF device. If based on the non trusted
247 : : * VF device, configuring promiscuous/allmulticast mode will fail.
248 : : * The hns3 VF device can be configured as trusted device by hns3 PF
249 : : * kernel ethdev driver on the host by the following command:
250 : : * "ip link set <eth num> vf <vf id> turst on"
251 : : * 2. After the promiscuous mode is configured successfully, hns3 VF PMD
252 : : * can receive the ingress and outgoing traffic. This includes
253 : : * all the ingress packets, all the packets sent from the PF and
254 : : * other VFs on the same physical port.
255 : : * 3. Note: Because of the hardware constraints, By default vlan filter
256 : : * is enabled and couldn't be turned off based on VF device, so vlan
257 : : * filter is still effective even in promiscuous mode. If upper
258 : : * applications don't call rte_eth_dev_vlan_filter API function to
259 : : * set vlan based on VF device, hns3 VF PMD will can't receive
260 : : * the packets with vlan tag in promiscuous mode.
261 : : */
262 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_MBX_VF_TO_PF, false);
263 : 0 : req->msg.code = HNS3_MBX_SET_PROMISC_MODE;
264 : 0 : req->msg.en_bc = en_bc_pmc ? 1 : 0;
265 : 0 : req->msg.en_uc = en_uc_pmc ? 1 : 0;
266 : 0 : req->msg.en_mc = en_mc_pmc ? 1 : 0;
267 : 0 : req->msg.en_limit_promisc =
268 : 0 : hw->promisc_mode == HNS3_LIMIT_PROMISC_MODE ? 1 : 0;
269 : :
270 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
271 [ # # ]: 0 : if (ret)
272 : 0 : hns3_err(hw, "Set promisc mode fail, ret = %d", ret);
273 : :
274 : 0 : return ret;
275 : : }
276 : :
277 : : static int
278 : 0 : hns3vf_dev_promiscuous_enable(struct rte_eth_dev *dev)
279 : : {
280 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
281 : 0 : struct hns3_hw *hw = &hns->hw;
282 : : int ret;
283 : :
284 : 0 : ret = hns3vf_set_promisc_mode(hw, true, true, true);
285 [ # # ]: 0 : if (ret)
286 : 0 : hns3_err(hw, "Failed to enable promiscuous mode, ret = %d",
287 : : ret);
288 : 0 : return ret;
289 : : }
290 : :
291 : : static int
292 : 0 : hns3vf_dev_promiscuous_disable(struct rte_eth_dev *dev)
293 : : {
294 : 0 : bool allmulti = dev->data->all_multicast ? true : false;
295 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
296 : 0 : struct hns3_hw *hw = &hns->hw;
297 : : int ret;
298 : :
299 : 0 : ret = hns3vf_set_promisc_mode(hw, true, false, allmulti);
300 [ # # ]: 0 : if (ret)
301 : 0 : hns3_err(hw, "Failed to disable promiscuous mode, ret = %d",
302 : : ret);
303 : 0 : return ret;
304 : : }
305 : :
306 : : static int
307 : 0 : hns3vf_dev_allmulticast_enable(struct rte_eth_dev *dev)
308 : : {
309 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
310 : 0 : struct hns3_hw *hw = &hns->hw;
311 : : int ret;
312 : :
313 [ # # ]: 0 : if (dev->data->promiscuous)
314 : : return 0;
315 : :
316 : 0 : ret = hns3vf_set_promisc_mode(hw, true, false, true);
317 [ # # ]: 0 : if (ret)
318 : 0 : hns3_err(hw, "Failed to enable allmulticast mode, ret = %d",
319 : : ret);
320 : : return ret;
321 : : }
322 : :
323 : : static int
324 : 0 : hns3vf_dev_allmulticast_disable(struct rte_eth_dev *dev)
325 : : {
326 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
327 : 0 : struct hns3_hw *hw = &hns->hw;
328 : : int ret;
329 : :
330 [ # # ]: 0 : if (dev->data->promiscuous)
331 : : return 0;
332 : :
333 : 0 : ret = hns3vf_set_promisc_mode(hw, true, false, false);
334 [ # # ]: 0 : if (ret)
335 : 0 : hns3_err(hw, "Failed to disable allmulticast mode, ret = %d",
336 : : ret);
337 : : return ret;
338 : : }
339 : :
340 : : static int
341 : 0 : hns3vf_restore_promisc(struct hns3_adapter *hns)
342 : : {
343 : 0 : struct hns3_hw *hw = &hns->hw;
344 : 0 : bool allmulti = hw->data->all_multicast ? true : false;
345 : :
346 [ # # ]: 0 : if (hw->data->promiscuous)
347 : 0 : return hns3vf_set_promisc_mode(hw, true, true, true);
348 : :
349 : 0 : return hns3vf_set_promisc_mode(hw, true, false, allmulti);
350 : : }
351 : :
352 : : static int
353 : 0 : hns3vf_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id,
354 : : bool mmap, enum hns3_ring_type queue_type,
355 : : uint16_t queue_id)
356 : : {
357 : 0 : struct hns3_vf_to_pf_msg req = {0};
358 : : const char *op_str;
359 : : int ret;
360 : :
361 [ # # ]: 0 : req.code = mmap ? HNS3_MBX_MAP_RING_TO_VECTOR :
362 : : HNS3_MBX_UNMAP_RING_TO_VECTOR;
363 : 0 : req.vector_id = (uint8_t)vector_id;
364 : 0 : req.ring_num = 1;
365 : :
366 [ # # ]: 0 : if (queue_type == HNS3_RING_TYPE_RX)
367 : : req.ring_param[0].int_gl_index = HNS3_RING_GL_RX;
368 : : else
369 : 0 : req.ring_param[0].int_gl_index = HNS3_RING_GL_TX;
370 : 0 : req.ring_param[0].ring_type = queue_type;
371 : 0 : req.ring_param[0].tqp_index = queue_id;
372 [ # # ]: 0 : op_str = mmap ? "Map" : "Unmap";
373 : 0 : ret = hns3vf_mbx_send(hw, &req, false, NULL, 0);
374 [ # # ]: 0 : if (ret)
375 : 0 : hns3_err(hw, "%s TQP %u fail, vector_id is %u, ret = %d.",
376 : : op_str, queue_id, req.vector_id, ret);
377 : :
378 : 0 : return ret;
379 : : }
380 : :
381 : : static int
382 : 0 : hns3vf_set_multi_tc(struct hns3_hw *hw, const struct hns3_mbx_tc_config *config)
383 : : {
384 : : struct hns3_mbx_tc_config *payload;
385 : : struct hns3_vf_to_pf_msg req;
386 : : int ret;
387 : :
388 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_TC, 0);
389 : : payload = (struct hns3_mbx_tc_config *)req.data;
390 : : memcpy(payload, config, sizeof(*payload));
391 : : payload->prio_tc_map = rte_cpu_to_le_32(config->prio_tc_map);
392 : 0 : ret = hns3vf_mbx_send(hw, &req, true, NULL, 0);
393 [ # # ]: 0 : if (ret)
394 : 0 : hns3_err(hw, "failed to set multi-tc, ret = %d.", ret);
395 : :
396 : 0 : return ret;
397 : : }
398 : :
399 : : static int
400 : 0 : hns3vf_unset_multi_tc(struct hns3_hw *hw)
401 : : {
402 : : struct hns3_mbx_tc_config *paylod;
403 : : struct hns3_vf_to_pf_msg req;
404 : : int ret;
405 : :
406 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_TC, 0);
407 : : paylod = (struct hns3_mbx_tc_config *)req.data;
408 : 0 : paylod->tc_dwrr[0] = HNS3_ETS_DWRR_MAX;
409 : 0 : paylod->num_tc = 1;
410 : 0 : ret = hns3vf_mbx_send(hw, &req, true, NULL, 0);
411 [ # # ]: 0 : if (ret)
412 : 0 : hns3_err(hw, "failed to unset multi-tc, ret = %d.", ret);
413 : :
414 : 0 : return ret;
415 : : }
416 : :
417 : : static int
418 : 0 : hns3vf_check_multi_tc_config(struct rte_eth_dev *dev, const struct hns3_mbx_tc_config *info)
419 : : {
420 : 0 : struct rte_eth_dcb_rx_conf *rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf;
421 : 0 : struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
422 : 0 : uint32_t prio_tc_map = info->prio_tc_map;
423 : : uint8_t map;
424 : : int i;
425 : :
426 [ # # ]: 0 : if (rx_conf->nb_tcs != info->num_tc) {
427 : 0 : hns3_err(hw, "num_tcs(%d) is not equal to PF config(%u)!",
428 : : rx_conf->nb_tcs, info->num_tc);
429 : 0 : return -EINVAL;
430 : : }
431 : :
432 [ # # ]: 0 : for (i = 0; i < HNS3_MAX_USER_PRIO; i++) {
433 : 0 : map = prio_tc_map & HNS3_MBX_PRIO_MASK;
434 : 0 : prio_tc_map >>= HNS3_MBX_PRIO_SHIFT;
435 [ # # ]: 0 : if (rx_conf->dcb_tc[i] != map) {
436 : 0 : hns3_err(hw, "dcb_tc[%d] = %u is not equal to PF config(%u)!",
437 : : i, rx_conf->dcb_tc[i], map);
438 : 0 : return -EINVAL;
439 : : }
440 : : }
441 : :
442 : : return 0;
443 : : }
444 : :
445 : : static int
446 : 0 : hns3vf_get_multi_tc_info(struct hns3_hw *hw, struct hns3_mbx_tc_config *info)
447 : : {
448 : : uint8_t resp_msg[HNS3_MBX_MAX_RESP_DATA_SIZE];
449 : : struct hns3_mbx_tc_prio_map *map = (struct hns3_mbx_tc_prio_map *)resp_msg;
450 : : struct hns3_mbx_tc_ets_info *ets = (struct hns3_mbx_tc_ets_info *)resp_msg;
451 : : struct hns3_vf_to_pf_msg req;
452 : : int i, ret;
453 : :
454 : : memset(info, 0, sizeof(*info));
455 : :
456 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_GET_TC, HNS3_MBX_GET_PRIO_MAP);
457 : 0 : ret = hns3vf_mbx_send(hw, &req, true, resp_msg, sizeof(resp_msg));
458 [ # # ]: 0 : if (ret) {
459 : 0 : hns3_err(hw, "failed to get multi-tc prio map, ret = %d.", ret);
460 : 0 : return ret;
461 : : }
462 : 0 : info->prio_tc_map = rte_le_to_cpu_32(map->prio_tc_map);
463 : :
464 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_GET_TC, HNS3_MBX_GET_ETS_INFO);
465 : 0 : ret = hns3vf_mbx_send(hw, &req, true, resp_msg, sizeof(resp_msg));
466 [ # # ]: 0 : if (ret) {
467 : 0 : hns3_err(hw, "failed to get multi-tc ETS info, ret = %d.", ret);
468 : 0 : return ret;
469 : : }
470 [ # # ]: 0 : for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
471 [ # # ]: 0 : if (ets->sch_mode[i] == HNS3_ETS_SCHED_MODE_INVALID)
472 : 0 : continue;
473 : 0 : info->tc_dwrr[i] = ets->sch_mode[i];
474 : 0 : info->num_tc++;
475 [ # # ]: 0 : if (ets->sch_mode[i] > 0)
476 : 0 : info->tc_sch_mode |= 1u << i;
477 : : }
478 : :
479 : : return 0;
480 : : }
481 : :
482 : : static void
483 : 0 : hns3vf_update_dcb_info(struct hns3_hw *hw, const struct hns3_mbx_tc_config *info)
484 : : {
485 : : uint32_t prio_tc_map;
486 : : uint8_t map;
487 : : int i;
488 : :
489 : 0 : hw->dcb_info.local_max_tc = hw->dcb_info.num_tc;
490 : 0 : hw->dcb_info.hw_tc_map = (1u << hw->dcb_info.num_tc) - 1u;
491 [ # # ]: 0 : memset(hw->dcb_info.pg_info[0].tc_dwrr, 0, sizeof(hw->dcb_info.pg_info[0].tc_dwrr));
492 : :
493 [ # # ]: 0 : if (hw->dcb_info.num_tc == 1) {
494 : 0 : memset(hw->dcb_info.prio_tc, 0, sizeof(hw->dcb_info.prio_tc));
495 : 0 : hw->dcb_info.pg_info[0].tc_dwrr[0] = HNS3_ETS_DWRR_MAX;
496 : 0 : return;
497 : : }
498 : :
499 [ # # ]: 0 : if (info == NULL)
500 : : return;
501 : :
502 : 0 : prio_tc_map = info->prio_tc_map;
503 [ # # ]: 0 : for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
504 : 0 : map = prio_tc_map & HNS3_MBX_PRIO_MASK;
505 : 0 : prio_tc_map >>= HNS3_MBX_PRIO_SHIFT;
506 : 0 : hw->dcb_info.prio_tc[i] = map;
507 : : }
508 [ # # ]: 0 : for (i = 0; i < hw->dcb_info.num_tc; i++)
509 : 0 : hw->dcb_info.pg_info[0].tc_dwrr[i] = info->tc_dwrr[i];
510 : : }
511 : :
512 : : static int
513 : 0 : hns3vf_setup_dcb(struct rte_eth_dev *dev)
514 : : {
515 : 0 : struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
516 : : struct hns3_mbx_tc_config info;
517 : : int ret;
518 : :
519 [ # # ]: 0 : if (!hns3_dev_get_support(hw, VF_MULTI_TCS)) {
520 : 0 : hns3_err(hw, "this port does not support dcb configurations.");
521 : 0 : return -ENOTSUP;
522 : : }
523 : :
524 [ # # ]: 0 : if (dev->data->dev_conf.dcb_capability_en & RTE_ETH_DCB_PFC_SUPPORT) {
525 : 0 : hns3_err(hw, "VF don't support PFC!");
526 : 0 : return -ENOTSUP;
527 : : }
528 : :
529 : 0 : ret = hns3vf_get_multi_tc_info(hw, &info);
530 [ # # ]: 0 : if (ret)
531 : : return ret;
532 : :
533 : 0 : ret = hns3vf_check_multi_tc_config(dev, &info);
534 [ # # ]: 0 : if (ret)
535 : : return ret;
536 : :
537 : : /*
538 : : * If multiple-TCs have been configured, cancel the configuration
539 : : * first. Otherwise, the configuration will fail.
540 : : */
541 [ # # ]: 0 : if (hw->dcb_info.num_tc > 1) {
542 : 0 : ret = hns3vf_unset_multi_tc(hw);
543 [ # # ]: 0 : if (ret)
544 : : return ret;
545 : 0 : hw->dcb_info.num_tc = 1;
546 : 0 : hns3vf_update_dcb_info(hw, NULL);
547 : : }
548 : :
549 : 0 : ret = hns3vf_set_multi_tc(hw, &info);
550 [ # # ]: 0 : if (ret)
551 : : return ret;
552 : :
553 : 0 : hw->dcb_info.num_tc = info.num_tc;
554 : 0 : hns3vf_update_dcb_info(hw, &info);
555 : :
556 : 0 : return hns3_queue_to_tc_mapping(hw, hw->data->nb_rx_queues, hw->data->nb_rx_queues);
557 : : }
558 : :
559 : : static int
560 : 0 : hns3vf_unset_dcb(struct rte_eth_dev *dev)
561 : : {
562 : 0 : struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
563 : : int ret;
564 : :
565 [ # # ]: 0 : if (hw->dcb_info.num_tc > 1) {
566 : 0 : ret = hns3vf_unset_multi_tc(hw);
567 [ # # ]: 0 : if (ret)
568 : : return ret;
569 : : }
570 : :
571 : 0 : hw->dcb_info.num_tc = 1;
572 : 0 : hns3vf_update_dcb_info(hw, NULL);
573 : :
574 : 0 : return hns3_queue_to_tc_mapping(hw, hw->data->nb_rx_queues, hw->data->nb_rx_queues);
575 : : }
576 : :
577 : : static int
578 : 0 : hns3vf_config_dcb(struct rte_eth_dev *dev)
579 : : {
580 : 0 : struct rte_eth_conf *conf = &dev->data->dev_conf;
581 : 0 : uint32_t rx_mq_mode = conf->rxmode.mq_mode;
582 : : int ret;
583 : :
584 [ # # ]: 0 : if (rx_mq_mode & RTE_ETH_MQ_RX_DCB_FLAG)
585 : 0 : ret = hns3vf_setup_dcb(dev);
586 : : else
587 : 0 : ret = hns3vf_unset_dcb(dev);
588 : :
589 : 0 : return ret;
590 : : }
591 : :
592 : : static int
593 : 0 : hns3vf_check_dev_conf(struct rte_eth_dev *dev)
594 : : {
595 : 0 : struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
596 : : struct rte_eth_conf *conf = &dev->data->dev_conf;
597 : : int ret;
598 : :
599 : 0 : ret = hns3_check_dev_mq_mode(dev);
600 [ # # ]: 0 : if (ret)
601 : : return ret;
602 : :
603 [ # # ]: 0 : if (conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) {
604 : 0 : hns3_err(hw, "setting link speed/duplex not supported");
605 : : ret = -EINVAL;
606 : : }
607 : :
608 : : return ret;
609 : : }
610 : :
611 : : static int
612 : 0 : hns3vf_dev_configure(struct rte_eth_dev *dev)
613 : : {
614 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
615 : 0 : struct hns3_hw *hw = &hns->hw;
616 : : struct rte_eth_conf *conf = &dev->data->dev_conf;
617 : 0 : enum rte_eth_rx_mq_mode mq_mode = conf->rxmode.mq_mode;
618 : 0 : uint16_t nb_rx_q = dev->data->nb_rx_queues;
619 : 0 : uint16_t nb_tx_q = dev->data->nb_tx_queues;
620 : : struct rte_eth_rss_conf rss_conf;
621 : : bool gro_en;
622 : : int ret;
623 : :
624 : 0 : hw->cfg_max_queues = RTE_MAX(nb_rx_q, nb_tx_q);
625 : :
626 : : /*
627 : : * Some versions of hardware network engine does not support
628 : : * individually enable/disable/reset the Tx or Rx queue. These devices
629 : : * must enable/disable/reset Tx and Rx queues at the same time. When the
630 : : * numbers of Tx queues allocated by upper applications are not equal to
631 : : * the numbers of Rx queues, driver needs to setup fake Tx or Rx queues
632 : : * to adjust numbers of Tx/Rx queues. otherwise, network engine can not
633 : : * work as usual. But these fake queues are imperceptible, and can not
634 : : * be used by upper applications.
635 : : */
636 : 0 : ret = hns3_set_fake_rx_or_tx_queues(dev, nb_rx_q, nb_tx_q);
637 [ # # ]: 0 : if (ret) {
638 : 0 : hns3_err(hw, "fail to set Rx/Tx fake queues, ret = %d.", ret);
639 : 0 : hw->cfg_max_queues = 0;
640 : 0 : return ret;
641 : : }
642 : :
643 : 0 : hw->adapter_state = HNS3_NIC_CONFIGURING;
644 : 0 : ret = hns3vf_check_dev_conf(dev);
645 [ # # ]: 0 : if (ret)
646 : 0 : goto cfg_err;
647 : :
648 : 0 : ret = hns3vf_config_dcb(dev);
649 [ # # ]: 0 : if (ret)
650 : 0 : goto cfg_err;
651 : :
652 : : /* When RSS is not configured, redirect the packet queue 0 */
653 [ # # ]: 0 : if ((uint32_t)mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {
654 : 0 : conf->rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
655 : 0 : rss_conf = conf->rx_adv_conf.rss_conf;
656 : 0 : ret = hns3_dev_rss_hash_update(dev, &rss_conf);
657 [ # # ]: 0 : if (ret)
658 : 0 : goto cfg_err;
659 : : }
660 : :
661 : 0 : ret = hns3vf_dev_mtu_set(dev, conf->rxmode.mtu);
662 [ # # ]: 0 : if (ret != 0)
663 : 0 : goto cfg_err;
664 : :
665 : 0 : ret = hns3vf_dev_configure_vlan(dev);
666 [ # # ]: 0 : if (ret)
667 : 0 : goto cfg_err;
668 : :
669 : : /* config hardware GRO */
670 : 0 : gro_en = conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO ? true : false;
671 : 0 : ret = hns3_config_gro(hw, gro_en);
672 [ # # ]: 0 : if (ret)
673 : 0 : goto cfg_err;
674 : :
675 : 0 : hns3_init_rx_ptype_tble(dev);
676 : :
677 : 0 : hw->adapter_state = HNS3_NIC_CONFIGURED;
678 : 0 : return 0;
679 : :
680 : 0 : cfg_err:
681 : 0 : hw->cfg_max_queues = 0;
682 : 0 : (void)hns3_set_fake_rx_or_tx_queues(dev, 0, 0);
683 : 0 : hw->adapter_state = HNS3_NIC_INITIALIZED;
684 : :
685 : 0 : return ret;
686 : : }
687 : :
688 : : static int
689 : 0 : hns3vf_config_mtu(struct hns3_hw *hw, uint16_t mtu)
690 : : {
691 : : struct hns3_vf_to_pf_msg req;
692 : : int ret;
693 : :
694 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_MTU, 0);
695 : : memcpy(req.data, &mtu, sizeof(mtu));
696 : 0 : ret = hns3vf_mbx_send(hw, &req, true, NULL, 0);
697 [ # # ]: 0 : if (ret)
698 : 0 : hns3_err(hw, "Failed to set mtu (%u) for vf: %d", mtu, ret);
699 : :
700 : 0 : return ret;
701 : : }
702 : :
703 : : static int
704 : 0 : hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
705 : : {
706 : 0 : struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
707 : 0 : uint32_t frame_size = mtu + HNS3_ETH_OVERHEAD;
708 : : int ret;
709 : :
710 : : /*
711 : : * The hns3 PF/VF devices on the same port share the hardware MTU
712 : : * configuration. Currently, we send mailbox to inform hns3 PF kernel
713 : : * ethdev driver to finish hardware MTU configuration in hns3 VF PMD,
714 : : * there is no need to stop the port for hns3 VF device, and the
715 : : * MTU value issued by hns3 VF PMD must be less than or equal to
716 : : * PF's MTU.
717 : : */
718 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.resetting, rte_memory_order_relaxed)) {
719 : 0 : hns3_err(hw, "Failed to set mtu during resetting");
720 : 0 : return -EIO;
721 : : }
722 : :
723 : : /*
724 : : * when Rx of scattered packets is off, we have some possibility of
725 : : * using vector Rx process function or simple Rx functions in hns3 PMD.
726 : : * If the input MTU is increased and the maximum length of
727 : : * received packets is greater than the length of a buffer for Rx
728 : : * packet, the hardware network engine needs to use multiple BDs and
729 : : * buffers to store these packets. This will cause problems when still
730 : : * using vector Rx process function or simple Rx function to receiving
731 : : * packets. So, when Rx of scattered packets is off and device is
732 : : * started, it is not permitted to increase MTU so that the maximum
733 : : * length of Rx packets is greater than Rx buffer length.
734 : : */
735 [ # # ]: 0 : if (dev->data->dev_started && !dev->data->scattered_rx &&
736 [ # # ]: 0 : frame_size > hw->rx_buf_len) {
737 : 0 : hns3_err(hw, "failed to set mtu because current is "
738 : : "not scattered rx mode");
739 : 0 : return -EOPNOTSUPP;
740 : : }
741 : :
742 : 0 : rte_spinlock_lock(&hw->lock);
743 : 0 : ret = hns3vf_config_mtu(hw, mtu);
744 [ # # ]: 0 : if (ret) {
745 : : rte_spinlock_unlock(&hw->lock);
746 : 0 : return ret;
747 : : }
748 : : rte_spinlock_unlock(&hw->lock);
749 : :
750 : 0 : return 0;
751 : : }
752 : :
753 : : static void
754 : : hns3vf_clear_event_cause(struct hns3_hw *hw, uint32_t regclr)
755 : : {
756 : 0 : hns3_write_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG, regclr);
757 : : }
758 : :
759 : : static void
760 : : hns3vf_disable_irq0(struct hns3_hw *hw)
761 : : {
762 : 0 : hns3_write_dev(hw, HNS3_MISC_VECTOR_REG_BASE, 0);
763 : : }
764 : :
765 : : static void
766 : : hns3vf_enable_irq0(struct hns3_hw *hw)
767 : : {
768 : 0 : hns3_write_dev(hw, HNS3_MISC_VECTOR_REG_BASE, 1);
769 : 0 : }
770 : :
771 : : void
772 : 0 : hns3vf_clear_reset_event(struct hns3_hw *hw)
773 : : {
774 : : uint32_t clearval;
775 : : uint32_t cmdq_stat_reg;
776 : :
777 : 0 : cmdq_stat_reg = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_STAT_REG);
778 : 0 : clearval = cmdq_stat_reg & ~BIT(HNS3_VECTOR0_RST_INT_B);
779 : 0 : hns3_write_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG, clearval);
780 : :
781 : : hns3vf_enable_irq0(hw);
782 : 0 : }
783 : :
784 : : static enum hns3vf_evt_cause
785 : 0 : hns3vf_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)
786 : : {
787 : : struct hns3_hw *hw = &hns->hw;
788 : : enum hns3vf_evt_cause ret;
789 : : uint32_t cmdq_stat_reg;
790 : : uint32_t rst_ing_reg;
791 : : uint32_t val;
792 : :
793 : : /* Fetch the events from their corresponding regs */
794 : 0 : cmdq_stat_reg = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_STAT_REG);
795 [ # # ]: 0 : if (BIT(HNS3_VECTOR0_RST_INT_B) & cmdq_stat_reg) {
796 : 0 : rst_ing_reg = hns3_read_dev(hw, HNS3_FUN_RST_ING);
797 : 0 : hns3_warn(hw, "resetting reg: 0x%x", rst_ing_reg);
798 : 0 : hns3_atomic_set_bit(HNS3_VF_RESET, &hw->reset.pending);
799 : 0 : rte_atomic_store_explicit(&hw->reset.disable_cmd, 1, rte_memory_order_relaxed);
800 : 0 : val = hns3_read_dev(hw, HNS3_VF_RST_ING);
801 : 0 : hns3_write_dev(hw, HNS3_VF_RST_ING, val | HNS3_VF_RST_ING_BIT);
802 : 0 : val = cmdq_stat_reg & ~BIT(HNS3_VECTOR0_RST_INT_B);
803 : 0 : hw->reset.stats.global_cnt++;
804 : 0 : hns3_warn(hw, "Global reset detected, clear reset status");
805 : :
806 : : ret = HNS3VF_VECTOR0_EVENT_RST;
807 : 0 : goto out;
808 : : }
809 : :
810 : : /* Check for vector0 mailbox(=CMDQ RX) event source */
811 [ # # ]: 0 : if (BIT(HNS3_VECTOR0_RX_CMDQ_INT_B) & cmdq_stat_reg) {
812 : 0 : val = cmdq_stat_reg & ~BIT(HNS3_VECTOR0_RX_CMDQ_INT_B);
813 : : ret = HNS3VF_VECTOR0_EVENT_MBX;
814 : 0 : goto out;
815 : : }
816 : :
817 : : val = 0;
818 : : ret = HNS3VF_VECTOR0_EVENT_OTHER;
819 : :
820 : 0 : out:
821 : 0 : *clearval = val;
822 : 0 : return ret;
823 : : }
824 : :
825 : : static void
826 : 0 : hns3vf_interrupt_handler(void *param)
827 : : {
828 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
829 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
830 : 0 : struct hns3_hw *hw = &hns->hw;
831 : : enum hns3vf_evt_cause event_cause;
832 : : uint32_t clearval;
833 : :
834 : : /* Disable interrupt */
835 : : hns3vf_disable_irq0(hw);
836 : :
837 : : /* Read out interrupt causes */
838 : 0 : event_cause = hns3vf_check_event_cause(hns, &clearval);
839 : : /* Clear interrupt causes */
840 : 0 : hns3vf_clear_event_cause(hw, clearval);
841 : :
842 [ # # # ]: 0 : switch (event_cause) {
843 : 0 : case HNS3VF_VECTOR0_EVENT_RST:
844 : 0 : hns3_schedule_reset(hns);
845 : 0 : break;
846 : 0 : case HNS3VF_VECTOR0_EVENT_MBX:
847 : 0 : hns3vf_handle_mbx_msg(hw);
848 : 0 : break;
849 : : default:
850 : : break;
851 : : }
852 : :
853 : : /* Enable interrupt if it is not caused by reset */
854 [ # # ]: 0 : if (event_cause == HNS3VF_VECTOR0_EVENT_MBX ||
855 : : event_cause == HNS3VF_VECTOR0_EVENT_OTHER)
856 : : hns3vf_enable_irq0(hw);
857 : 0 : }
858 : :
859 : : void
860 : 0 : hns3vf_update_push_lsc_cap(struct hns3_hw *hw, bool supported)
861 : : {
862 : : uint16_t val = supported ? HNS3_PF_PUSH_LSC_CAP_SUPPORTED :
863 : : HNS3_PF_PUSH_LSC_CAP_NOT_SUPPORTED;
864 : : uint16_t exp = HNS3_PF_PUSH_LSC_CAP_UNKNOWN;
865 : : struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw);
866 : :
867 [ # # ]: 0 : if (vf->pf_push_lsc_cap == HNS3_PF_PUSH_LSC_CAP_UNKNOWN)
868 : 0 : rte_atomic_compare_exchange_strong_explicit(&vf->pf_push_lsc_cap, &exp, val,
869 : : rte_memory_order_acquire, rte_memory_order_acquire);
870 : 0 : }
871 : :
872 : : static void
873 : 0 : hns3vf_get_push_lsc_cap(struct hns3_hw *hw)
874 : : {
875 : : #define HNS3_CHECK_PUSH_LSC_CAP_TIMEOUT_MS 500
876 : :
877 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
878 : : int32_t remain_ms = HNS3_CHECK_PUSH_LSC_CAP_TIMEOUT_MS;
879 : : uint16_t val = HNS3_PF_PUSH_LSC_CAP_NOT_SUPPORTED;
880 : : uint16_t exp = HNS3_PF_PUSH_LSC_CAP_UNKNOWN;
881 : : struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw);
882 : : struct hns3_vf_to_pf_msg req;
883 : :
884 : 0 : rte_atomic_store_explicit(&vf->pf_push_lsc_cap, HNS3_PF_PUSH_LSC_CAP_UNKNOWN,
885 : : rte_memory_order_release);
886 : :
887 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_GET_LINK_STATUS, 0);
888 : 0 : (void)hns3vf_mbx_send(hw, &req, false, NULL, 0);
889 : :
890 [ # # ]: 0 : while (remain_ms > 0) {
891 : : rte_delay_ms(HNS3_POLL_RESPONE_MS);
892 : : /*
893 : : * The probe process may perform in interrupt thread context.
894 : : * For example, users attach a device in the secondary process.
895 : : * At the moment, the handling mailbox task will be blocked. So
896 : : * driver has to actively handle the HNS3_MBX_LINK_STAT_CHANGE
897 : : * mailbox from PF driver to get this capability.
898 : : */
899 : 0 : hns3vf_handle_mbx_msg(hw);
900 [ # # ]: 0 : if (rte_atomic_load_explicit(&vf->pf_push_lsc_cap, rte_memory_order_acquire) !=
901 : : HNS3_PF_PUSH_LSC_CAP_UNKNOWN)
902 : : break;
903 : 0 : remain_ms--;
904 : : }
905 : :
906 : : /*
907 : : * When exit above loop, the pf_push_lsc_cap could be one of the three
908 : : * state: unknown (means pf not ack), not_supported, supported.
909 : : * Here config it as 'not_supported' when it's 'unknown' state.
910 : : */
911 : 0 : rte_atomic_compare_exchange_strong_explicit(&vf->pf_push_lsc_cap, &exp, val,
912 : : rte_memory_order_acquire, rte_memory_order_acquire);
913 : :
914 [ # # ]: 0 : if (rte_atomic_load_explicit(&vf->pf_push_lsc_cap, rte_memory_order_acquire) ==
915 : : HNS3_PF_PUSH_LSC_CAP_SUPPORTED) {
916 : 0 : hns3_info(hw, "detect PF support push link status change!");
917 : : } else {
918 : : /*
919 : : * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver
920 : : * declared RTE_PCI_DRV_INTR_LSC in drv_flags. So here cleared
921 : : * the RTE_ETH_DEV_INTR_LSC capability.
922 : : */
923 : 0 : dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
924 : : }
925 : 0 : }
926 : :
927 : : static int
928 : 0 : hns3vf_get_capability(struct hns3_hw *hw)
929 : : {
930 : : int ret;
931 : :
932 [ # # ]: 0 : if (hw->revision < PCI_REVISION_ID_HIP09_A) {
933 : 0 : hns3_set_default_dev_specifications(hw);
934 : 0 : hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_RSV_ONE;
935 : 0 : hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US;
936 : 0 : hw->tso_mode = HNS3_TSO_SW_CAL_PSEUDO_H_CSUM;
937 : 0 : hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE1;
938 : 0 : hw->min_tx_pkt_len = HNS3_HIP08_MIN_TX_PKT_LEN;
939 : 0 : hw->rss_info.ipv6_sctp_offload_supported = false;
940 : 0 : hw->promisc_mode = HNS3_UNLIMIT_PROMISC_MODE;
941 : 0 : hw->rx_dma_addr_align = HNS3_RX_DMA_ADDR_ALIGN_64;
942 : 0 : return 0;
943 : : }
944 : :
945 : 0 : ret = hns3_query_dev_specifications(hw);
946 [ # # ]: 0 : if (ret) {
947 : 0 : PMD_INIT_LOG(ERR,
948 : : "failed to query dev specifications, ret = %d",
949 : : ret);
950 : 0 : return ret;
951 : : }
952 : :
953 : 0 : hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_ALL;
954 : 0 : hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_1US;
955 : 0 : hw->tso_mode = HNS3_TSO_HW_CAL_PSEUDO_H_CSUM;
956 : 0 : hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE2;
957 : 0 : hw->rss_info.ipv6_sctp_offload_supported = true;
958 : 0 : hw->promisc_mode = HNS3_LIMIT_PROMISC_MODE;
959 : 0 : hw->rx_dma_addr_align = HNS3_RX_DMA_ADDR_ALIGN_128;
960 : :
961 : 0 : return 0;
962 : : }
963 : :
964 : : static int
965 : 0 : hns3vf_check_tqp_info(struct hns3_hw *hw)
966 : : {
967 [ # # ]: 0 : if (hw->tqps_num == 0) {
968 : 0 : PMD_INIT_LOG(ERR, "Get invalid tqps_num(0) from PF.");
969 : 0 : return -EINVAL;
970 : : }
971 : :
972 [ # # ]: 0 : if (hw->rss_size_max == 0) {
973 : 0 : PMD_INIT_LOG(ERR, "Get invalid rss_size_max(0) from PF.");
974 : 0 : return -EINVAL;
975 : : }
976 : :
977 : 0 : hw->tqps_num = RTE_MIN(hw->rss_size_max, hw->tqps_num);
978 : :
979 : 0 : return 0;
980 : : }
981 : :
982 : : static int
983 : 0 : hns3vf_get_port_base_vlan_filter_state(struct hns3_hw *hw)
984 : : {
985 : : struct hns3_vf_to_pf_msg req;
986 : : uint8_t resp_msg;
987 : : int ret;
988 : :
989 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_VLAN,
990 : : HNS3_MBX_GET_PORT_BASE_VLAN_STATE);
991 : 0 : ret = hns3vf_mbx_send(hw, &req, true, &resp_msg, sizeof(resp_msg));
992 [ # # ]: 0 : if (ret) {
993 [ # # ]: 0 : if (ret == -ETIME) {
994 : : /*
995 : : * Getting current port based VLAN state from PF driver
996 : : * will not affect VF driver's basic function. Because
997 : : * the VF driver relies on hns3 PF kernel ether driver,
998 : : * to avoid introducing compatibility issues with older
999 : : * version of PF driver, no failure will be returned
1000 : : * when the return value is ETIME. This return value has
1001 : : * the following scenarios:
1002 : : * 1) Firmware didn't return the results in time
1003 : : * 2) the result return by firmware is timeout
1004 : : * 3) the older version of kernel side PF driver does
1005 : : * not support this mailbox message.
1006 : : * For scenarios 1 and 2, it is most likely that a
1007 : : * hardware error has occurred, or a hardware reset has
1008 : : * occurred. In this case, these errors will be caught
1009 : : * by other functions.
1010 : : */
1011 : 0 : PMD_INIT_LOG(WARNING,
1012 : : "failed to get PVID state for timeout, maybe "
1013 : : "kernel side PF driver doesn't support this "
1014 : : "mailbox message, or firmware didn't respond.");
1015 : 0 : resp_msg = HNS3_PORT_BASE_VLAN_DISABLE;
1016 : : } else {
1017 : 0 : PMD_INIT_LOG(ERR, "failed to get port based VLAN state,"
1018 : : " ret = %d", ret);
1019 : 0 : return ret;
1020 : : }
1021 : : }
1022 : 0 : hw->port_base_vlan_cfg.state = resp_msg ?
1023 : 0 : HNS3_PORT_BASE_VLAN_ENABLE : HNS3_PORT_BASE_VLAN_DISABLE;
1024 : 0 : return 0;
1025 : : }
1026 : :
1027 : : static int
1028 : 0 : hns3vf_get_queue_info(struct hns3_hw *hw)
1029 : : {
1030 : : #define HNS3VF_TQPS_RSS_INFO_LEN 6
1031 : : uint8_t resp_msg[HNS3VF_TQPS_RSS_INFO_LEN];
1032 : : struct hns3_vf_to_pf_msg req;
1033 : : int ret;
1034 : :
1035 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_GET_QINFO, 0);
1036 : 0 : ret = hns3vf_mbx_send(hw, &req, true,
1037 : : resp_msg, HNS3VF_TQPS_RSS_INFO_LEN);
1038 [ # # ]: 0 : if (ret) {
1039 : 0 : PMD_INIT_LOG(ERR, "Failed to get tqp info from PF: %d", ret);
1040 : 0 : return ret;
1041 : : }
1042 : :
1043 : 0 : memcpy(&hw->tqps_num, &resp_msg[0], sizeof(uint16_t));
1044 : 0 : memcpy(&hw->rss_size_max, &resp_msg[2], sizeof(uint16_t));
1045 : :
1046 : 0 : return hns3vf_check_tqp_info(hw);
1047 : : }
1048 : :
1049 : : static void
1050 : 0 : hns3vf_update_multi_tcs_cap(struct hns3_hw *hw, uint32_t pf_multi_tcs_bit)
1051 : : {
1052 : : uint8_t resp_msg[HNS3_MBX_MAX_RESP_DATA_SIZE];
1053 : : struct hns3_vf_to_pf_msg req;
1054 : : int ret;
1055 : :
1056 [ # # ]: 0 : if (!hns3_dev_get_support(hw, VF_MULTI_TCS))
1057 : 0 : return;
1058 : :
1059 [ # # ]: 0 : if (pf_multi_tcs_bit == 0) {
1060 : : /*
1061 : : * Early PF driver versions may don't report
1062 : : * HNS3VF_CAPS_MULTI_TCS_B when VF query basic info, so clear
1063 : : * the corresponding capability bit.
1064 : : */
1065 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_VF_MULTI_TCS_B, 0);
1066 : 0 : return;
1067 : : }
1068 : :
1069 : : /*
1070 : : * Early PF driver versions may also report HNS3VF_CAPS_MULTI_TCS_B
1071 : : * when VF query basic info, but they don't support query TC info
1072 : : * mailbox message, so clear the corresponding capability bit.
1073 : : */
1074 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_GET_TC, HNS3_MBX_GET_PRIO_MAP);
1075 : 0 : ret = hns3vf_mbx_send(hw, &req, true, resp_msg, sizeof(resp_msg));
1076 [ # # ]: 0 : if (ret)
1077 : 0 : hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_VF_MULTI_TCS_B, 0);
1078 : : }
1079 : :
1080 : : static void
1081 : 0 : hns3vf_update_caps(struct hns3_hw *hw, uint32_t caps)
1082 : : {
1083 [ # # ]: 0 : if (hns3_get_bit(caps, HNS3VF_CAPS_VLAN_FLT_MOD_B))
1084 : 0 : hns3_set_bit(hw->capability,
1085 : : HNS3_DEV_SUPPORT_VF_VLAN_FLT_MOD_B, 1);
1086 : :
1087 : 0 : hns3vf_update_multi_tcs_cap(hw, hns3_get_bit(caps, HNS3VF_CAPS_MULTI_TCS_B));
1088 : 0 : }
1089 : :
1090 : : static int
1091 : : hns3vf_get_num_tc(struct hns3_hw *hw)
1092 : : {
1093 : : uint8_t num_tc = 0;
1094 : : uint32_t i;
1095 : :
1096 [ # # ]: 0 : for (i = 0; i < HNS3_MAX_TC_NUM; i++) {
1097 [ # # ]: 0 : if (hw->dcb_info.hw_tc_map & BIT(i))
1098 : 0 : num_tc++;
1099 : : }
1100 : : return num_tc;
1101 : : }
1102 : :
1103 : : static int
1104 : 0 : hns3vf_get_basic_info(struct hns3_hw *hw)
1105 : : {
1106 : : uint8_t resp_msg[HNS3_MBX_MAX_RESP_DATA_SIZE];
1107 : : struct hns3_basic_info *basic_info;
1108 : : struct hns3_vf_to_pf_msg req;
1109 : : int ret;
1110 : :
1111 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_GET_BASIC_INFO, 0);
1112 : 0 : ret = hns3vf_mbx_send(hw, &req, true, resp_msg, sizeof(resp_msg));
1113 [ # # ]: 0 : if (ret) {
1114 : 0 : hns3_err(hw, "failed to get basic info from PF, ret = %d.",
1115 : : ret);
1116 : 0 : return ret;
1117 : : }
1118 : :
1119 : : basic_info = (struct hns3_basic_info *)resp_msg;
1120 : 0 : hw->dcb_info.tc_max = basic_info->tc_max;
1121 : 0 : hw->dcb_info.hw_tc_map = basic_info->hw_tc_map;
1122 : 0 : hw->dcb_info.num_tc = hns3vf_get_num_tc(hw);
1123 : 0 : hw->pf_vf_if_version = basic_info->pf_vf_if_version;
1124 : 0 : hns3vf_update_caps(hw, basic_info->caps);
1125 : :
1126 : 0 : return 0;
1127 : : }
1128 : :
1129 : : static int
1130 : 0 : hns3vf_get_host_mac_addr(struct hns3_hw *hw)
1131 : : {
1132 : : uint8_t host_mac[RTE_ETHER_ADDR_LEN];
1133 : : struct hns3_vf_to_pf_msg req;
1134 : : int ret;
1135 : :
1136 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_GET_MAC_ADDR, 0);
1137 : 0 : ret = hns3vf_mbx_send(hw, &req, true, host_mac, RTE_ETHER_ADDR_LEN);
1138 [ # # ]: 0 : if (ret) {
1139 : 0 : hns3_err(hw, "Failed to get mac addr from PF: %d", ret);
1140 : 0 : return ret;
1141 : : }
1142 : :
1143 : 0 : memcpy(hw->mac.mac_addr, host_mac, RTE_ETHER_ADDR_LEN);
1144 : :
1145 : 0 : return 0;
1146 : : }
1147 : :
1148 : : static int
1149 : 0 : hns3vf_get_configuration(struct hns3_hw *hw)
1150 : : {
1151 : : int ret;
1152 : :
1153 : 0 : hw->mac.media_type = HNS3_MEDIA_TYPE_NONE;
1154 : :
1155 : : /* Get device capability */
1156 : 0 : ret = hns3vf_get_capability(hw);
1157 [ # # ]: 0 : if (ret) {
1158 : 0 : PMD_INIT_LOG(ERR, "failed to get device capability: %d.", ret);
1159 : 0 : return ret;
1160 : : }
1161 : :
1162 : 0 : hns3vf_get_push_lsc_cap(hw);
1163 : :
1164 : : /* Get basic info from PF */
1165 : 0 : ret = hns3vf_get_basic_info(hw);
1166 [ # # ]: 0 : if (ret)
1167 : : return ret;
1168 : :
1169 : : /* Get queue configuration from PF */
1170 : 0 : ret = hns3vf_get_queue_info(hw);
1171 [ # # ]: 0 : if (ret)
1172 : : return ret;
1173 : :
1174 : : /* Get user defined VF MAC addr from PF */
1175 : 0 : ret = hns3vf_get_host_mac_addr(hw);
1176 [ # # ]: 0 : if (ret)
1177 : : return ret;
1178 : :
1179 : 0 : return hns3vf_get_port_base_vlan_filter_state(hw);
1180 : : }
1181 : :
1182 : : static void
1183 : 0 : hns3vf_request_link_info(struct hns3_hw *hw)
1184 : : {
1185 : : struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw);
1186 : : struct hns3_vf_to_pf_msg req;
1187 : : bool send_req;
1188 : : int ret;
1189 : :
1190 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.resetting, rte_memory_order_relaxed))
1191 : 0 : return;
1192 : :
1193 [ # # ]: 0 : send_req = vf->pf_push_lsc_cap == HNS3_PF_PUSH_LSC_CAP_NOT_SUPPORTED ||
1194 [ # # ]: 0 : vf->req_link_info_cnt > 0;
1195 [ # # ]: 0 : if (!send_req)
1196 : : return;
1197 : :
1198 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_GET_LINK_STATUS, 0);
1199 : 0 : ret = hns3vf_mbx_send(hw, &req, false, NULL, 0);
1200 [ # # ]: 0 : if (ret) {
1201 : 0 : hns3_err(hw, "failed to fetch link status, ret = %d", ret);
1202 : 0 : return;
1203 : : }
1204 : :
1205 [ # # ]: 0 : if (vf->req_link_info_cnt > 0)
1206 : 0 : vf->req_link_info_cnt--;
1207 : : }
1208 : :
1209 : : void
1210 : 0 : hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status,
1211 : : uint32_t link_speed, uint8_t link_duplex)
1212 : : {
1213 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
1214 : : struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw);
1215 : : struct hns3_mac *mac = &hw->mac;
1216 : : int ret;
1217 : :
1218 : : /*
1219 : : * PF kernel driver may push link status when VF driver is in resetting,
1220 : : * driver will stop polling job in this case, after resetting done
1221 : : * driver will start polling job again.
1222 : : * When polling job started, driver will get initial link status by
1223 : : * sending request to PF kernel driver, then could update link status by
1224 : : * process PF kernel driver's link status mailbox message.
1225 : : */
1226 [ # # ]: 0 : if (!rte_atomic_load_explicit(&vf->poll_job_started, rte_memory_order_relaxed))
1227 : : return;
1228 : :
1229 [ # # ]: 0 : if (hw->adapter_state != HNS3_NIC_STARTED)
1230 : : return;
1231 : :
1232 : 0 : mac->link_status = link_status;
1233 : 0 : mac->link_speed = link_speed;
1234 : 0 : mac->link_duplex = link_duplex;
1235 : 0 : ret = hns3vf_dev_link_update(dev, 0);
1236 [ # # # # ]: 0 : if (ret == 0 && dev->data->dev_conf.intr_conf.lsc != 0)
1237 : 0 : hns3_start_report_lse(dev);
1238 : : }
1239 : :
1240 : : static int
1241 : 0 : hns3vf_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on)
1242 : : {
1243 : : struct hns3_mbx_vlan_filter *vlan_filter;
1244 : 0 : struct hns3_vf_to_pf_msg req = {0};
1245 : 0 : struct hns3_hw *hw = &hns->hw;
1246 : :
1247 : 0 : req.code = HNS3_MBX_SET_VLAN;
1248 : : req.subcode = HNS3_MBX_VLAN_FILTER;
1249 : : vlan_filter = (struct hns3_mbx_vlan_filter *)req.data;
1250 : 0 : vlan_filter->is_kill = on ? 0 : 1;
1251 : 0 : vlan_filter->proto = rte_cpu_to_le_16(RTE_ETHER_TYPE_VLAN);
1252 : 0 : vlan_filter->vlan_id = rte_cpu_to_le_16(vlan_id);
1253 : :
1254 : 0 : return hns3vf_mbx_send(hw, &req, true, NULL, 0);
1255 : : }
1256 : :
1257 : : static int
1258 : 0 : hns3vf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
1259 : : {
1260 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
1261 : : struct hns3_hw *hw = &hns->hw;
1262 : : int ret;
1263 : :
1264 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.resetting, rte_memory_order_relaxed)) {
1265 : 0 : hns3_err(hw,
1266 : : "vf set vlan id failed during resetting, vlan_id =%u",
1267 : : vlan_id);
1268 : 0 : return -EIO;
1269 : : }
1270 : 0 : rte_spinlock_lock(&hw->lock);
1271 : 0 : ret = hns3vf_vlan_filter_configure(hns, vlan_id, on);
1272 : : rte_spinlock_unlock(&hw->lock);
1273 [ # # ]: 0 : if (ret)
1274 : 0 : hns3_err(hw, "vf set vlan id failed, vlan_id =%u, ret =%d",
1275 : : vlan_id, ret);
1276 : :
1277 : : return ret;
1278 : : }
1279 : :
1280 : : static int
1281 : 0 : hns3vf_en_vlan_filter(struct hns3_hw *hw, bool enable)
1282 : : {
1283 : : struct hns3_vf_to_pf_msg req;
1284 : : uint8_t msg_data;
1285 : : int ret;
1286 : :
1287 [ # # ]: 0 : if (!hns3_dev_get_support(hw, VF_VLAN_FLT_MOD))
1288 : : return 0;
1289 : :
1290 : 0 : msg_data = enable ? 1 : 0;
1291 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_VLAN,
1292 : : HNS3_MBX_ENABLE_VLAN_FILTER);
1293 : : memcpy(req.data, &msg_data, sizeof(msg_data));
1294 : 0 : ret = hns3vf_mbx_send(hw, &req, true, NULL, 0);
1295 [ # # ]: 0 : if (ret)
1296 [ # # ]: 0 : hns3_err(hw, "%s vlan filter failed, ret = %d.",
1297 : : enable ? "enable" : "disable", ret);
1298 : :
1299 : : return ret;
1300 : : }
1301 : :
1302 : : static int
1303 : 0 : hns3vf_en_hw_strip_rxvtag(struct hns3_hw *hw, bool enable)
1304 : : {
1305 : : struct hns3_vf_to_pf_msg req;
1306 : : uint8_t msg_data;
1307 : : int ret;
1308 : :
1309 : 0 : msg_data = enable ? 1 : 0;
1310 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_VLAN,
1311 : : HNS3_MBX_VLAN_RX_OFF_CFG);
1312 : : memcpy(req.data, &msg_data, sizeof(msg_data));
1313 : 0 : ret = hns3vf_mbx_send(hw, &req, false, NULL, 0);
1314 [ # # ]: 0 : if (ret)
1315 [ # # ]: 0 : hns3_err(hw, "vf %s strip failed, ret = %d.",
1316 : : enable ? "enable" : "disable", ret);
1317 : :
1318 : 0 : return ret;
1319 : : }
1320 : :
1321 : : static int
1322 : 0 : hns3vf_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1323 : : {
1324 : 0 : struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1325 : : struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
1326 : : unsigned int tmp_mask;
1327 : : int ret = 0;
1328 : :
1329 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.resetting, rte_memory_order_relaxed)) {
1330 : 0 : hns3_err(hw, "vf set vlan offload failed during resetting, mask = 0x%x",
1331 : : mask);
1332 : 0 : return -EIO;
1333 : : }
1334 : :
1335 : 0 : tmp_mask = (unsigned int)mask;
1336 : :
1337 [ # # ]: 0 : if (tmp_mask & RTE_ETH_VLAN_FILTER_MASK) {
1338 : 0 : rte_spinlock_lock(&hw->lock);
1339 : : /* Enable or disable VLAN filter */
1340 [ # # ]: 0 : if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)
1341 : 0 : ret = hns3vf_en_vlan_filter(hw, true);
1342 : : else
1343 : 0 : ret = hns3vf_en_vlan_filter(hw, false);
1344 : : rte_spinlock_unlock(&hw->lock);
1345 [ # # ]: 0 : if (ret)
1346 : : return ret;
1347 : : }
1348 : :
1349 : : /* Vlan stripping setting */
1350 [ # # ]: 0 : if (tmp_mask & RTE_ETH_VLAN_STRIP_MASK) {
1351 : 0 : rte_spinlock_lock(&hw->lock);
1352 : : /* Enable or disable VLAN stripping */
1353 [ # # ]: 0 : if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
1354 : 0 : ret = hns3vf_en_hw_strip_rxvtag(hw, true);
1355 : : else
1356 : 0 : ret = hns3vf_en_hw_strip_rxvtag(hw, false);
1357 : : rte_spinlock_unlock(&hw->lock);
1358 : : }
1359 : :
1360 : : return ret;
1361 : : }
1362 : :
1363 : : static int
1364 : 0 : hns3vf_handle_all_vlan_table(struct hns3_adapter *hns, int on)
1365 : : {
1366 : : struct rte_vlan_filter_conf *vfc;
1367 : : struct hns3_hw *hw = &hns->hw;
1368 : : uint16_t vlan_id;
1369 : : uint64_t vbit;
1370 : : uint64_t ids;
1371 : : int ret = 0;
1372 : : uint32_t i;
1373 : :
1374 : 0 : vfc = &hw->data->vlan_filter_conf;
1375 [ # # ]: 0 : for (i = 0; i < RTE_DIM(vfc->ids); i++) {
1376 [ # # ]: 0 : if (vfc->ids[i] == 0)
1377 : 0 : continue;
1378 : : ids = vfc->ids[i];
1379 [ # # ]: 0 : while (ids) {
1380 : : /*
1381 : : * 64 means the num bits of ids, one bit corresponds to
1382 : : * one vlan id
1383 : : */
1384 : 0 : vlan_id = 64 * i;
1385 : : /* count trailing zeroes */
1386 : 0 : vbit = ~ids & (ids - 1);
1387 : : /* clear least significant bit set */
1388 : 0 : ids ^= (ids ^ (ids - 1)) ^ vbit;
1389 [ # # ]: 0 : for (; vbit;) {
1390 : 0 : vbit >>= 1;
1391 : 0 : vlan_id++;
1392 : : }
1393 : 0 : ret = hns3vf_vlan_filter_configure(hns, vlan_id, on);
1394 [ # # ]: 0 : if (ret) {
1395 : 0 : hns3_err(hw,
1396 : : "VF handle vlan table failed, ret =%d, on = %d",
1397 : : ret, on);
1398 : 0 : return ret;
1399 : : }
1400 : : }
1401 : : }
1402 : :
1403 : : return ret;
1404 : : }
1405 : :
1406 : : static int
1407 : : hns3vf_remove_all_vlan_table(struct hns3_adapter *hns)
1408 : : {
1409 : 0 : return hns3vf_handle_all_vlan_table(hns, 0);
1410 : : }
1411 : :
1412 : : static int
1413 : 0 : hns3vf_restore_vlan_conf(struct hns3_adapter *hns)
1414 : : {
1415 : 0 : struct hns3_hw *hw = &hns->hw;
1416 : : struct rte_eth_conf *dev_conf;
1417 : : bool en;
1418 : : int ret;
1419 : :
1420 : 0 : dev_conf = &hw->data->dev_conf;
1421 : 0 : en = dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP ? true
1422 : : : false;
1423 : 0 : ret = hns3vf_en_hw_strip_rxvtag(hw, en);
1424 [ # # ]: 0 : if (ret)
1425 : 0 : hns3_err(hw, "VF restore vlan conf fail, en =%d, ret =%d", en,
1426 : : ret);
1427 : 0 : return ret;
1428 : : }
1429 : :
1430 : : static int
1431 : 0 : hns3vf_dev_configure_vlan(struct rte_eth_dev *dev)
1432 : : {
1433 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
1434 : : struct rte_eth_dev_data *data = dev->data;
1435 : : struct hns3_hw *hw = &hns->hw;
1436 : : int ret;
1437 : :
1438 : 0 : if (data->dev_conf.txmode.hw_vlan_reject_tagged ||
1439 [ # # ]: 0 : data->dev_conf.txmode.hw_vlan_reject_untagged ||
1440 : : data->dev_conf.txmode.hw_vlan_insert_pvid) {
1441 : 0 : hns3_warn(hw, "hw_vlan_reject_tagged, hw_vlan_reject_untagged "
1442 : : "or hw_vlan_insert_pvid is not support!");
1443 : : }
1444 : :
1445 : : /* Apply vlan offload setting */
1446 : 0 : ret = hns3vf_vlan_offload_set(dev, RTE_ETH_VLAN_STRIP_MASK |
1447 : : RTE_ETH_VLAN_FILTER_MASK);
1448 [ # # ]: 0 : if (ret)
1449 : 0 : hns3_err(hw, "dev config vlan offload failed, ret = %d.", ret);
1450 : :
1451 : 0 : return ret;
1452 : : }
1453 : :
1454 : : static int
1455 : 0 : hns3vf_set_alive(struct hns3_hw *hw, bool alive)
1456 : : {
1457 : : struct hns3_vf_to_pf_msg req;
1458 : : uint8_t msg_data;
1459 : :
1460 : 0 : msg_data = alive ? 1 : 0;
1461 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_SET_ALIVE, 0);
1462 : : memcpy(req.data, &msg_data, sizeof(msg_data));
1463 : 0 : return hns3vf_mbx_send(hw, &req, false, NULL, 0);
1464 : : }
1465 : :
1466 : : static void
1467 : 0 : hns3vf_keep_alive_handler(void *param)
1468 : : {
1469 : : struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
1470 : 0 : struct hns3_adapter *hns = eth_dev->data->dev_private;
1471 : : struct hns3_vf_to_pf_msg req;
1472 : 0 : struct hns3_hw *hw = &hns->hw;
1473 : : int ret;
1474 : :
1475 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_KEEP_ALIVE, 0);
1476 : 0 : ret = hns3vf_mbx_send(hw, &req, false, NULL, 0);
1477 [ # # ]: 0 : if (ret)
1478 : 0 : hns3_err(hw, "VF sends keeping alive cmd failed(=%d)",
1479 : : ret);
1480 : :
1481 : 0 : rte_eal_alarm_set(HNS3VF_KEEP_ALIVE_INTERVAL, hns3vf_keep_alive_handler,
1482 : : eth_dev);
1483 : 0 : }
1484 : :
1485 : : static void
1486 : 0 : hns3vf_service_handler(void *param)
1487 : : {
1488 : : struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
1489 : 0 : struct hns3_adapter *hns = eth_dev->data->dev_private;
1490 : 0 : struct hns3_hw *hw = &hns->hw;
1491 : :
1492 : : /*
1493 : : * The query link status and reset processing are executed in the
1494 : : * interrupt thread. When the IMP reset occurs, IMP will not respond,
1495 : : * and the query operation will timeout after 30ms. In the case of
1496 : : * multiple PF/VFs, each query failure timeout causes the IMP reset
1497 : : * interrupt to fail to respond within 100ms.
1498 : : * Before querying the link status, check whether there is a reset
1499 : : * pending, and if so, abandon the query.
1500 : : */
1501 [ # # ]: 0 : if (!hns3vf_is_reset_pending(hns)) {
1502 : 0 : hns3vf_request_link_info(hw);
1503 : 0 : hns3_update_hw_stats(hw);
1504 : : } else {
1505 : 0 : hns3_warn(hw, "Cancel the query when reset is pending");
1506 : : }
1507 : :
1508 : 0 : rte_eal_alarm_set(HNS3VF_SERVICE_INTERVAL, hns3vf_service_handler,
1509 : : eth_dev);
1510 : 0 : }
1511 : :
1512 : : static void
1513 : 0 : hns3vf_start_poll_job(struct rte_eth_dev *dev)
1514 : : {
1515 : : #define HNS3_REQUEST_LINK_INFO_REMAINS_CNT 3
1516 : :
1517 : 0 : struct hns3_vf *vf = HNS3_DEV_PRIVATE_TO_VF(dev->data->dev_private);
1518 : :
1519 [ # # ]: 0 : if (vf->pf_push_lsc_cap == HNS3_PF_PUSH_LSC_CAP_SUPPORTED)
1520 : 0 : vf->req_link_info_cnt = HNS3_REQUEST_LINK_INFO_REMAINS_CNT;
1521 : :
1522 : 0 : rte_atomic_store_explicit(&vf->poll_job_started, 1, rte_memory_order_relaxed);
1523 : :
1524 : 0 : hns3vf_service_handler(dev);
1525 : 0 : }
1526 : :
1527 : : static void
1528 : 0 : hns3vf_stop_poll_job(struct rte_eth_dev *dev)
1529 : : {
1530 : 0 : struct hns3_vf *vf = HNS3_DEV_PRIVATE_TO_VF(dev->data->dev_private);
1531 : :
1532 : 0 : rte_eal_alarm_cancel(hns3vf_service_handler, dev);
1533 : :
1534 : 0 : rte_atomic_store_explicit(&vf->poll_job_started, 0, rte_memory_order_relaxed);
1535 : 0 : }
1536 : :
1537 : : static int
1538 : 0 : hns3_query_vf_resource(struct hns3_hw *hw)
1539 : : {
1540 : : struct hns3_vf_res_cmd *req;
1541 : : struct hns3_cmd_desc desc;
1542 : : uint16_t num_msi;
1543 : : int ret;
1544 : :
1545 : 0 : hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_VF_RSRC, true);
1546 : 0 : ret = hns3_cmd_send(hw, &desc, 1);
1547 [ # # ]: 0 : if (ret) {
1548 : 0 : hns3_err(hw, "query vf resource failed, ret = %d", ret);
1549 : 0 : return ret;
1550 : : }
1551 : :
1552 : : req = (struct hns3_vf_res_cmd *)desc.data;
1553 : 0 : num_msi = hns3_get_field(rte_le_to_cpu_16(req->vf_intr_vector_number),
1554 : : HNS3_VF_VEC_NUM_M, HNS3_VF_VEC_NUM_S);
1555 [ # # ]: 0 : if (num_msi < HNS3_MIN_VECTOR_NUM) {
1556 : 0 : hns3_err(hw, "Just %u msi resources, not enough for vf(min:%d)",
1557 : : num_msi, HNS3_MIN_VECTOR_NUM);
1558 : 0 : return -EINVAL;
1559 : : }
1560 : :
1561 : 0 : hw->num_msi = num_msi;
1562 : :
1563 : 0 : return 0;
1564 : : }
1565 : :
1566 : : static int
1567 : 0 : hns3vf_init_hardware(struct hns3_adapter *hns)
1568 : : {
1569 : 0 : struct hns3_hw *hw = &hns->hw;
1570 : 0 : uint16_t mtu = hw->data->mtu;
1571 : : int ret;
1572 : :
1573 : 0 : ret = hns3vf_set_promisc_mode(hw, true, false, false);
1574 [ # # ]: 0 : if (ret)
1575 : : return ret;
1576 : :
1577 : 0 : ret = hns3vf_config_mtu(hw, mtu);
1578 [ # # ]: 0 : if (ret)
1579 : 0 : goto err_init_hardware;
1580 : :
1581 : : ret = hns3vf_vlan_filter_configure(hns, 0, 1);
1582 [ # # ]: 0 : if (ret) {
1583 : 0 : PMD_INIT_LOG(ERR, "Failed to initialize VLAN config: %d", ret);
1584 : 0 : goto err_init_hardware;
1585 : : }
1586 : :
1587 : 0 : ret = hns3_config_gro(hw, false);
1588 [ # # ]: 0 : if (ret) {
1589 : 0 : PMD_INIT_LOG(ERR, "Failed to config gro: %d", ret);
1590 : 0 : goto err_init_hardware;
1591 : : }
1592 : :
1593 : : /*
1594 : : * In the initialization clearing the all hardware mapping relationship
1595 : : * configurations between queues and interrupt vectors is needed, so
1596 : : * some error caused by the residual configurations, such as the
1597 : : * unexpected interrupt, can be avoid.
1598 : : */
1599 : 0 : ret = hns3_init_ring_with_vector(hw);
1600 [ # # ]: 0 : if (ret) {
1601 : 0 : PMD_INIT_LOG(ERR, "Failed to init ring intr vector: %d", ret);
1602 : 0 : goto err_init_hardware;
1603 : : }
1604 : :
1605 : : return 0;
1606 : :
1607 : 0 : err_init_hardware:
1608 : 0 : (void)hns3vf_set_promisc_mode(hw, false, false, false);
1609 : 0 : return ret;
1610 : : }
1611 : :
1612 : : static int
1613 : 0 : hns3vf_clear_vport_list(struct hns3_hw *hw)
1614 : : {
1615 : : struct hns3_vf_to_pf_msg req;
1616 : :
1617 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_HANDLE_VF_TBL,
1618 : : HNS3_MBX_VPORT_LIST_CLEAR);
1619 : 0 : return hns3vf_mbx_send(hw, &req, false, NULL, 0);
1620 : : }
1621 : :
1622 : : static int
1623 : 0 : hns3vf_init_vf(struct rte_eth_dev *eth_dev)
1624 : : {
1625 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
1626 : 0 : struct hns3_adapter *hns = eth_dev->data->dev_private;
1627 : 0 : struct hns3_hw *hw = &hns->hw;
1628 : : int ret;
1629 : :
1630 : 0 : PMD_INIT_FUNC_TRACE();
1631 : :
1632 : : /* Get hardware io base address from pcie BAR2 IO space */
1633 : 0 : hw->io_base = pci_dev->mem_resource[2].addr;
1634 : :
1635 : 0 : ret = hns3_get_pci_revision_id(hw, &hw->revision);
1636 [ # # ]: 0 : if (ret)
1637 : : return ret;
1638 : :
1639 : : /* Firmware command queue initialize */
1640 : 0 : ret = hns3_cmd_init_queue(hw);
1641 [ # # ]: 0 : if (ret) {
1642 : 0 : PMD_INIT_LOG(ERR, "Failed to init cmd queue: %d", ret);
1643 : 0 : goto err_cmd_init_queue;
1644 : : }
1645 : :
1646 : : /* Firmware command initialize */
1647 : 0 : ret = hns3_cmd_init(hw);
1648 [ # # ]: 0 : if (ret) {
1649 : 0 : PMD_INIT_LOG(ERR, "Failed to init cmd: %d", ret);
1650 : 0 : goto err_cmd_init;
1651 : : }
1652 : :
1653 : 0 : hns3_tx_push_init(eth_dev);
1654 : :
1655 : : /* Get VF resource */
1656 : 0 : ret = hns3_query_vf_resource(hw);
1657 [ # # ]: 0 : if (ret)
1658 : 0 : goto err_cmd_init;
1659 : :
1660 : : rte_spinlock_init(&hw->mbx_resp.lock);
1661 : :
1662 : : hns3vf_clear_event_cause(hw, 0);
1663 : :
1664 : 0 : ret = rte_intr_callback_register(pci_dev->intr_handle,
1665 : : hns3vf_interrupt_handler, eth_dev);
1666 [ # # ]: 0 : if (ret) {
1667 : 0 : PMD_INIT_LOG(ERR, "Failed to register intr: %d", ret);
1668 : 0 : goto err_intr_callback_register;
1669 : : }
1670 : :
1671 : : /* Enable interrupt */
1672 : 0 : rte_intr_enable(pci_dev->intr_handle);
1673 : : hns3vf_enable_irq0(hw);
1674 : :
1675 : : /* Get configuration from PF */
1676 : 0 : ret = hns3vf_get_configuration(hw);
1677 [ # # ]: 0 : if (ret) {
1678 : 0 : PMD_INIT_LOG(ERR, "Failed to fetch configuration: %d", ret);
1679 : 0 : goto err_get_config;
1680 : : }
1681 : :
1682 : 0 : ret = hns3_stats_init(hw);
1683 [ # # ]: 0 : if (ret)
1684 : 0 : goto err_get_config;
1685 : :
1686 : 0 : ret = hns3_queue_to_tc_mapping(hw, hw->tqps_num, hw->tqps_num);
1687 [ # # ]: 0 : if (ret) {
1688 : 0 : PMD_INIT_LOG(ERR, "failed to set tc info, ret = %d.", ret);
1689 : 0 : goto err_set_tc_queue;
1690 : : }
1691 : :
1692 : 0 : ret = hns3vf_clear_vport_list(hw);
1693 [ # # ]: 0 : if (ret) {
1694 : 0 : PMD_INIT_LOG(ERR, "Failed to clear tbl list: %d", ret);
1695 : 0 : goto err_set_tc_queue;
1696 : : }
1697 : :
1698 : 0 : ret = hns3vf_init_hardware(hns);
1699 [ # # ]: 0 : if (ret)
1700 : 0 : goto err_set_tc_queue;
1701 : :
1702 : 0 : hns3_rss_set_default_args(hw);
1703 : :
1704 : 0 : ret = hns3vf_set_alive(hw, true);
1705 [ # # ]: 0 : if (ret) {
1706 : 0 : PMD_INIT_LOG(ERR, "Failed to VF send alive to PF: %d", ret);
1707 : 0 : goto err_set_tc_queue;
1708 : : }
1709 : :
1710 : : return 0;
1711 : :
1712 : 0 : err_set_tc_queue:
1713 : 0 : hns3_stats_uninit(hw);
1714 : :
1715 : 0 : err_get_config:
1716 : : hns3vf_disable_irq0(hw);
1717 : 0 : rte_intr_disable(pci_dev->intr_handle);
1718 : 0 : hns3_intr_unregister(pci_dev->intr_handle, hns3vf_interrupt_handler,
1719 : : eth_dev);
1720 : 0 : err_intr_callback_register:
1721 : 0 : err_cmd_init:
1722 : 0 : hns3_cmd_uninit(hw);
1723 : 0 : hns3_cmd_destroy_queue(hw);
1724 : 0 : err_cmd_init_queue:
1725 : 0 : hw->io_base = NULL;
1726 : :
1727 : 0 : return ret;
1728 : : }
1729 : :
1730 : : static void
1731 : 0 : hns3vf_notify_uninit(struct hns3_hw *hw)
1732 : : {
1733 : : struct hns3_vf_to_pf_msg req;
1734 : :
1735 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_VF_UNINIT, 0);
1736 : 0 : (void)hns3vf_mbx_send(hw, &req, false, NULL, 0);
1737 : 0 : }
1738 : :
1739 : : static void
1740 : 0 : hns3vf_uninit_vf(struct rte_eth_dev *eth_dev)
1741 : : {
1742 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
1743 : 0 : struct hns3_adapter *hns = eth_dev->data->dev_private;
1744 : 0 : struct hns3_hw *hw = &hns->hw;
1745 : :
1746 : 0 : PMD_INIT_FUNC_TRACE();
1747 : :
1748 : 0 : hns3_rss_uninit(hns);
1749 : 0 : (void)hns3_config_gro(hw, false);
1750 : 0 : (void)hns3vf_set_alive(hw, false);
1751 : 0 : (void)hns3vf_set_promisc_mode(hw, false, false, false);
1752 : 0 : hns3_flow_uninit(eth_dev);
1753 : 0 : hns3_stats_uninit(hw);
1754 : : hns3vf_disable_irq0(hw);
1755 : 0 : rte_intr_disable(pci_dev->intr_handle);
1756 : 0 : hns3_intr_unregister(pci_dev->intr_handle, hns3vf_interrupt_handler,
1757 : : eth_dev);
1758 : 0 : (void)hns3vf_notify_uninit(hw);
1759 : 0 : hns3_cmd_uninit(hw);
1760 : 0 : hns3_cmd_destroy_queue(hw);
1761 : 0 : hw->io_base = NULL;
1762 : 0 : }
1763 : :
1764 : : static int
1765 : 0 : hns3vf_do_stop(struct hns3_adapter *hns)
1766 : : {
1767 : : struct hns3_hw *hw = &hns->hw;
1768 : : int ret;
1769 : :
1770 : 0 : hw->mac.link_status = RTE_ETH_LINK_DOWN;
1771 : :
1772 : : /*
1773 : : * The "hns3vf_do_stop" function will also be called by .stop_service to
1774 : : * prepare reset. At the time of global or IMP reset, the command cannot
1775 : : * be sent to stop the tx/rx queues. The mbuf in Tx/Rx queues may be
1776 : : * accessed during the reset process. So the mbuf can not be released
1777 : : * during reset and is required to be released after the reset is
1778 : : * completed.
1779 : : */
1780 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.resetting, rte_memory_order_relaxed) == 0)
1781 : 0 : hns3_dev_release_mbufs(hns);
1782 : :
1783 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.disable_cmd, rte_memory_order_relaxed) == 0) {
1784 : 0 : hns3_configure_all_mac_addr(hns, true);
1785 : 0 : ret = hns3_reset_all_tqps(hns);
1786 [ # # ]: 0 : if (ret) {
1787 : 0 : hns3_err(hw, "failed to reset all queues ret = %d",
1788 : : ret);
1789 : 0 : return ret;
1790 : : }
1791 : : }
1792 : : return 0;
1793 : : }
1794 : :
1795 : : static int
1796 : 0 : hns3vf_dev_stop(struct rte_eth_dev *dev)
1797 : : {
1798 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
1799 : 0 : struct hns3_hw *hw = &hns->hw;
1800 : :
1801 : 0 : PMD_INIT_FUNC_TRACE();
1802 : 0 : dev->data->dev_started = 0;
1803 : :
1804 : 0 : hw->adapter_state = HNS3_NIC_STOPPING;
1805 : 0 : hns3_stop_rxtx_datapath(dev);
1806 : :
1807 : 0 : rte_spinlock_lock(&hw->lock);
1808 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.resetting, rte_memory_order_relaxed) == 0) {
1809 : 0 : hns3_stop_tqps(hw);
1810 : 0 : hns3vf_do_stop(hns);
1811 : 0 : hns3_unmap_rx_interrupt(dev);
1812 : 0 : hw->adapter_state = HNS3_NIC_CONFIGURED;
1813 : : }
1814 : 0 : hns3_rx_scattered_reset(dev);
1815 : 0 : hns3vf_stop_poll_job(dev);
1816 : 0 : hns3_stop_report_lse(dev);
1817 : : rte_spinlock_unlock(&hw->lock);
1818 : :
1819 : 0 : return 0;
1820 : : }
1821 : :
1822 : : static int
1823 : 0 : hns3vf_dev_close(struct rte_eth_dev *eth_dev)
1824 : : {
1825 : 0 : struct hns3_adapter *hns = eth_dev->data->dev_private;
1826 : : struct hns3_hw *hw = &hns->hw;
1827 : : int ret = 0;
1828 : :
1829 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1830 : 0 : hns3_mp_uninit(eth_dev);
1831 : 0 : return 0;
1832 : : }
1833 : :
1834 [ # # ]: 0 : if (hw->adapter_state == HNS3_NIC_STARTED)
1835 : 0 : ret = hns3vf_dev_stop(eth_dev);
1836 : :
1837 : 0 : hw->adapter_state = HNS3_NIC_CLOSING;
1838 : 0 : hns3_reset_abort(hns);
1839 : 0 : hw->adapter_state = HNS3_NIC_CLOSED;
1840 : 0 : rte_eal_alarm_cancel(hns3vf_keep_alive_handler, eth_dev);
1841 : 0 : hns3_configure_all_mc_mac_addr(hns, true);
1842 : : hns3vf_remove_all_vlan_table(hns);
1843 : 0 : hns3vf_uninit_vf(eth_dev);
1844 : 0 : hns3_free_all_queues(eth_dev);
1845 : 0 : rte_free(hw->reset.wait_data);
1846 : 0 : hns3_mp_uninit(eth_dev);
1847 : 0 : hns3_warn(hw, "Close port %u finished", hw->data->port_id);
1848 : :
1849 : 0 : return ret;
1850 : : }
1851 : :
1852 : : static int
1853 : 0 : hns3vf_dev_link_update(struct rte_eth_dev *eth_dev,
1854 : : __rte_unused int wait_to_complete)
1855 : : {
1856 [ # # ]: 0 : struct hns3_adapter *hns = eth_dev->data->dev_private;
1857 : : struct hns3_hw *hw = &hns->hw;
1858 : : struct hns3_mac *mac = &hw->mac;
1859 : : struct rte_eth_link new_link;
1860 : :
1861 : : memset(&new_link, 0, sizeof(new_link));
1862 [ # # ]: 0 : switch (mac->link_speed) {
1863 : 0 : case RTE_ETH_SPEED_NUM_10M:
1864 : : case RTE_ETH_SPEED_NUM_100M:
1865 : : case RTE_ETH_SPEED_NUM_1G:
1866 : : case RTE_ETH_SPEED_NUM_10G:
1867 : : case RTE_ETH_SPEED_NUM_25G:
1868 : : case RTE_ETH_SPEED_NUM_40G:
1869 : : case RTE_ETH_SPEED_NUM_50G:
1870 : : case RTE_ETH_SPEED_NUM_100G:
1871 : : case RTE_ETH_SPEED_NUM_200G:
1872 [ # # ]: 0 : if (mac->link_status)
1873 : 0 : new_link.link_speed = mac->link_speed;
1874 : : break;
1875 : 0 : default:
1876 [ # # ]: 0 : if (mac->link_status)
1877 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
1878 : : break;
1879 : : }
1880 : :
1881 [ # # ]: 0 : if (!mac->link_status)
1882 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
1883 : :
1884 : 0 : new_link.link_duplex = mac->link_duplex;
1885 : 0 : new_link.link_status = mac->link_status ? RTE_ETH_LINK_UP : RTE_ETH_LINK_DOWN;
1886 : 0 : new_link.link_autoneg =
1887 [ # # ]: 0 : !(eth_dev->data->dev_conf.link_speeds & RTE_ETH_LINK_SPEED_FIXED);
1888 : :
1889 : 0 : return rte_eth_linkstatus_set(eth_dev, &new_link);
1890 : : }
1891 : :
1892 : : static int
1893 : 0 : hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue)
1894 : : {
1895 : 0 : struct hns3_hw *hw = &hns->hw;
1896 : : int ret;
1897 : :
1898 : 0 : hns3_enable_rxd_adv_layout(hw);
1899 : :
1900 : 0 : ret = hns3_init_queues(hns, reset_queue);
1901 [ # # ]: 0 : if (ret) {
1902 : 0 : hns3_err(hw, "failed to init queues, ret = %d.", ret);
1903 : 0 : return ret;
1904 : : }
1905 : :
1906 : 0 : return hns3_restore_filter(hns);
1907 : : }
1908 : :
1909 : : static int
1910 : 0 : hns3vf_dev_start(struct rte_eth_dev *dev)
1911 : : {
1912 : 0 : struct hns3_adapter *hns = dev->data->dev_private;
1913 : 0 : struct hns3_hw *hw = &hns->hw;
1914 : : int ret;
1915 : :
1916 : 0 : PMD_INIT_FUNC_TRACE();
1917 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.resetting, rte_memory_order_relaxed))
1918 : : return -EBUSY;
1919 : :
1920 : 0 : rte_spinlock_lock(&hw->lock);
1921 : 0 : hw->adapter_state = HNS3_NIC_STARTING;
1922 : 0 : ret = hns3vf_do_start(hns, true);
1923 [ # # ]: 0 : if (ret) {
1924 : 0 : hw->adapter_state = HNS3_NIC_CONFIGURED;
1925 : : rte_spinlock_unlock(&hw->lock);
1926 : 0 : return ret;
1927 : : }
1928 : 0 : ret = hns3_map_rx_interrupt(dev);
1929 [ # # ]: 0 : if (ret)
1930 : 0 : goto map_rx_inter_err;
1931 : :
1932 : : /*
1933 : : * There are three register used to control the status of a TQP
1934 : : * (contains a pair of Tx queue and Rx queue) in the new version network
1935 : : * engine. One is used to control the enabling of Tx queue, the other is
1936 : : * used to control the enabling of Rx queue, and the last is the master
1937 : : * switch used to control the enabling of the tqp. The Tx register and
1938 : : * TQP register must be enabled at the same time to enable a Tx queue.
1939 : : * The same applies to the Rx queue. For the older network enginem, this
1940 : : * function only refresh the enabled flag, and it is used to update the
1941 : : * status of queue in the dpdk framework.
1942 : : */
1943 : 0 : ret = hns3_start_all_txqs(dev);
1944 [ # # ]: 0 : if (ret)
1945 : 0 : goto map_rx_inter_err;
1946 : :
1947 : 0 : ret = hns3_start_all_rxqs(dev);
1948 [ # # ]: 0 : if (ret)
1949 : 0 : goto start_all_rxqs_fail;
1950 : :
1951 : 0 : hw->adapter_state = HNS3_NIC_STARTED;
1952 : : rte_spinlock_unlock(&hw->lock);
1953 : :
1954 : 0 : hns3_rx_scattered_calc(dev);
1955 : 0 : hns3_start_rxtx_datapath(dev);
1956 : :
1957 : : /* Enable interrupt of all rx queues before enabling queues */
1958 : 0 : hns3_dev_all_rx_queue_intr_enable(hw, true);
1959 : 0 : hns3_start_tqps(hw);
1960 : :
1961 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.lsc != 0)
1962 : 0 : hns3vf_dev_link_update(dev, 0);
1963 : 0 : hns3vf_start_poll_job(dev);
1964 : :
1965 : 0 : return ret;
1966 : :
1967 : : start_all_rxqs_fail:
1968 : 0 : hns3_stop_all_txqs(dev);
1969 : 0 : map_rx_inter_err:
1970 : 0 : (void)hns3vf_do_stop(hns);
1971 : 0 : hw->adapter_state = HNS3_NIC_CONFIGURED;
1972 : : rte_spinlock_unlock(&hw->lock);
1973 : :
1974 : 0 : return ret;
1975 : : }
1976 : :
1977 : : static bool
1978 : 0 : is_vf_reset_done(struct hns3_hw *hw)
1979 : : {
1980 : : #define HNS3_FUN_RST_ING_BITS \
1981 : : (BIT(HNS3_VECTOR0_GLOBALRESET_INT_B) | \
1982 : : BIT(HNS3_VECTOR0_CORERESET_INT_B) | \
1983 : : BIT(HNS3_VECTOR0_IMPRESET_INT_B) | \
1984 : : BIT(HNS3_VECTOR0_FUNCRESET_INT_B))
1985 : :
1986 : : uint32_t val;
1987 : :
1988 [ # # ]: 0 : if (hw->reset.level == HNS3_VF_RESET) {
1989 : 0 : val = hns3_read_dev(hw, HNS3_VF_RST_ING);
1990 [ # # ]: 0 : if (val & HNS3_VF_RST_ING_BIT)
1991 : 0 : return false;
1992 : : } else {
1993 : 0 : val = hns3_read_dev(hw, HNS3_FUN_RST_ING);
1994 [ # # ]: 0 : if (val & HNS3_FUN_RST_ING_BITS)
1995 : 0 : return false;
1996 : : }
1997 : : return true;
1998 : : }
1999 : :
2000 : : static enum hns3_reset_level
2001 : : hns3vf_detect_reset_event(struct hns3_hw *hw)
2002 : : {
2003 : : enum hns3_reset_level reset = HNS3_NONE_RESET;
2004 : : uint32_t cmdq_stat_reg;
2005 : :
2006 : 0 : cmdq_stat_reg = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_STAT_REG);
2007 [ # # ]: 0 : if (BIT(HNS3_VECTOR0_RST_INT_B) & cmdq_stat_reg)
2008 : : reset = HNS3_VF_RESET;
2009 : :
2010 : : return reset;
2011 : : }
2012 : :
2013 : : bool
2014 : 0 : hns3vf_is_reset_pending(struct hns3_adapter *hns)
2015 : : {
2016 : : enum hns3_reset_level last_req;
2017 : 0 : struct hns3_hw *hw = &hns->hw;
2018 : : enum hns3_reset_level new_req;
2019 : :
2020 : : /*
2021 : : * According to the protocol of PCIe, FLR to a PF device resets the PF
2022 : : * state as well as the SR-IOV extended capability including VF Enable
2023 : : * which means that VFs no longer exist.
2024 : : *
2025 : : * HNS3_VF_FULL_RESET means PF device is in FLR reset. when PF device
2026 : : * is in FLR stage, the register state of VF device is not reliable,
2027 : : * so register states detection can not be carried out. In this case,
2028 : : * we just ignore the register states and return false to indicate that
2029 : : * there are no other reset states that need to be processed by driver.
2030 : : */
2031 [ # # ]: 0 : if (hw->reset.level == HNS3_VF_FULL_RESET)
2032 : : return false;
2033 : :
2034 : : /*
2035 : : * Only primary can process can process the reset event,
2036 : : * so don't check reset event in secondary.
2037 : : */
2038 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2039 : : return false;
2040 : :
2041 : : new_req = hns3vf_detect_reset_event(hw);
2042 : : if (new_req == HNS3_NONE_RESET)
2043 : : return false;
2044 : :
2045 : 0 : last_req = hns3vf_get_reset_level(hw, &hw->reset.pending);
2046 [ # # ]: 0 : if (last_req == HNS3_NONE_RESET || last_req < new_req) {
2047 : 0 : rte_atomic_store_explicit(&hw->reset.disable_cmd, 1, rte_memory_order_relaxed);
2048 : 0 : hns3_schedule_delayed_reset(hns);
2049 : 0 : hns3_warn(hw, "High level reset detected, delay do reset");
2050 : 0 : return true;
2051 : : }
2052 : :
2053 : : return false;
2054 : : }
2055 : :
2056 : : static int
2057 : 0 : hns3vf_wait_hardware_ready(struct hns3_adapter *hns)
2058 : : {
2059 : : #define HNS3_WAIT_PF_RESET_READY_TIME 5
2060 : : struct hns3_hw *hw = &hns->hw;
2061 : 0 : struct hns3_wait_data *wait_data = hw->reset.wait_data;
2062 : : struct timeval tv;
2063 : :
2064 [ # # ]: 0 : if (wait_data->result == HNS3_WAIT_SUCCESS) {
2065 : : /*
2066 : : * After vf reset is ready, the PF may not have completed
2067 : : * the reset processing. The vf sending mbox to PF may fail
2068 : : * during the pf reset, so it is better to add extra delay.
2069 : : */
2070 [ # # ]: 0 : if (hw->reset.level == HNS3_VF_FUNC_RESET ||
2071 : : hw->reset.level == HNS3_FLR_RESET)
2072 : : return 0;
2073 : : /* Reset retry process, no need to add extra delay. */
2074 [ # # ]: 0 : if (hw->reset.attempts)
2075 : : return 0;
2076 [ # # ]: 0 : if (wait_data->check_completion == NULL)
2077 : : return 0;
2078 : :
2079 : 0 : wait_data->check_completion = NULL;
2080 : 0 : wait_data->interval = HNS3_WAIT_PF_RESET_READY_TIME *
2081 : : MSEC_PER_SEC * USEC_PER_MSEC;
2082 : 0 : wait_data->count = 1;
2083 : 0 : wait_data->result = HNS3_WAIT_REQUEST;
2084 : 0 : rte_eal_alarm_set(wait_data->interval, hns3_wait_callback,
2085 : : wait_data);
2086 : 0 : hns3_warn(hw, "hardware is ready, delay %d sec for PF reset complete",
2087 : : HNS3_WAIT_PF_RESET_READY_TIME);
2088 : 0 : return -EAGAIN;
2089 [ # # ]: 0 : } else if (wait_data->result == HNS3_WAIT_TIMEOUT) {
2090 : 0 : hns3_clock_gettime(&tv);
2091 : 0 : hns3_warn(hw, "Reset step4 hardware not ready after reset time=%ld.%.6ld",
2092 : : tv.tv_sec, tv.tv_usec);
2093 : 0 : return -ETIME;
2094 [ # # ]: 0 : } else if (wait_data->result == HNS3_WAIT_REQUEST)
2095 : : return -EAGAIN;
2096 : :
2097 : 0 : wait_data->hns = hns;
2098 : 0 : wait_data->check_completion = is_vf_reset_done;
2099 : 0 : wait_data->end_ms = (uint64_t)HNS3VF_RESET_WAIT_CNT *
2100 : 0 : HNS3VF_RESET_WAIT_MS + hns3_clock_gettime_ms();
2101 : 0 : wait_data->interval = HNS3VF_RESET_WAIT_MS * USEC_PER_MSEC;
2102 : 0 : wait_data->count = HNS3VF_RESET_WAIT_CNT;
2103 : 0 : wait_data->result = HNS3_WAIT_REQUEST;
2104 : 0 : rte_eal_alarm_set(wait_data->interval, hns3_wait_callback, wait_data);
2105 : 0 : return -EAGAIN;
2106 : : }
2107 : :
2108 : : static int
2109 : 0 : hns3vf_prepare_reset(struct hns3_adapter *hns)
2110 : : {
2111 : : struct hns3_vf_to_pf_msg req;
2112 : 0 : struct hns3_hw *hw = &hns->hw;
2113 : : int ret;
2114 : :
2115 [ # # ]: 0 : if (hw->reset.level == HNS3_VF_FUNC_RESET) {
2116 : 0 : hns3vf_mbx_setup(&req, HNS3_MBX_RESET, 0);
2117 : 0 : ret = hns3vf_mbx_send(hw, &req, true, NULL, 0);
2118 [ # # ]: 0 : if (ret)
2119 : : return ret;
2120 : : }
2121 : 0 : rte_atomic_store_explicit(&hw->reset.disable_cmd, 1, rte_memory_order_relaxed);
2122 : :
2123 : 0 : return 0;
2124 : : }
2125 : :
2126 : : static int
2127 : 0 : hns3vf_stop_service(struct hns3_adapter *hns)
2128 : : {
2129 : 0 : struct hns3_hw *hw = &hns->hw;
2130 : : struct rte_eth_dev *eth_dev;
2131 : :
2132 : 0 : eth_dev = &rte_eth_devices[hw->data->port_id];
2133 [ # # ]: 0 : if (hw->adapter_state == HNS3_NIC_STARTED) {
2134 : : /*
2135 : : * Make sure call update link status before hns3vf_stop_poll_job
2136 : : * because update link status depend on polling job exist.
2137 : : */
2138 : 0 : hns3vf_update_link_status(hw, RTE_ETH_LINK_DOWN, hw->mac.link_speed,
2139 : 0 : hw->mac.link_duplex);
2140 : 0 : hns3vf_stop_poll_job(eth_dev);
2141 : : }
2142 : 0 : hw->mac.link_status = RTE_ETH_LINK_DOWN;
2143 : :
2144 : 0 : hns3_stop_rxtx_datapath(eth_dev);
2145 : :
2146 : 0 : rte_spinlock_lock(&hw->lock);
2147 [ # # ]: 0 : if (hw->adapter_state == HNS3_NIC_STARTED ||
2148 : : hw->adapter_state == HNS3_NIC_STOPPING) {
2149 : 0 : hns3_enable_all_queues(hw, false);
2150 : 0 : hns3vf_do_stop(hns);
2151 : 0 : hw->reset.mbuf_deferred_free = true;
2152 : : } else
2153 : 0 : hw->reset.mbuf_deferred_free = false;
2154 : :
2155 : 0 : rte_eal_alarm_cancel(hns3vf_keep_alive_handler, eth_dev);
2156 : :
2157 : : /*
2158 : : * It is cumbersome for hardware to pick-and-choose entries for deletion
2159 : : * from table space. Hence, for function reset software intervention is
2160 : : * required to delete the entries.
2161 : : */
2162 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.disable_cmd, rte_memory_order_relaxed) == 0)
2163 : 0 : hns3_configure_all_mc_mac_addr(hns, true);
2164 : : rte_spinlock_unlock(&hw->lock);
2165 : :
2166 : 0 : return 0;
2167 : : }
2168 : :
2169 : : static int
2170 : 0 : hns3vf_start_service(struct hns3_adapter *hns)
2171 : : {
2172 : 0 : struct hns3_hw *hw = &hns->hw;
2173 : : struct rte_eth_dev *eth_dev;
2174 : :
2175 : 0 : eth_dev = &rte_eth_devices[hw->data->port_id];
2176 : 0 : hns3_start_rxtx_datapath(eth_dev);
2177 : :
2178 : 0 : rte_eal_alarm_set(HNS3VF_KEEP_ALIVE_INTERVAL, hns3vf_keep_alive_handler,
2179 : : eth_dev);
2180 : :
2181 [ # # ]: 0 : if (hw->adapter_state == HNS3_NIC_STARTED) {
2182 : 0 : hns3vf_start_poll_job(eth_dev);
2183 : :
2184 : : /* Enable interrupt of all rx queues before enabling queues */
2185 : 0 : hns3_dev_all_rx_queue_intr_enable(hw, true);
2186 : : /*
2187 : : * Enable state of each rxq and txq will be recovered after
2188 : : * reset, so we need to restore them before enable all tqps;
2189 : : */
2190 : 0 : hns3_restore_tqp_enable_state(hw);
2191 : : /*
2192 : : * When finished the initialization, enable queues to receive
2193 : : * and transmit packets.
2194 : : */
2195 : 0 : hns3_enable_all_queues(hw, true);
2196 : : }
2197 : :
2198 : 0 : return 0;
2199 : : }
2200 : :
2201 : : static int
2202 : 0 : hns3vf_check_default_mac_change(struct hns3_hw *hw)
2203 : : {
2204 : : char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
2205 : : struct rte_ether_addr *hw_mac;
2206 : : int ret;
2207 : :
2208 : : /*
2209 : : * The hns3 PF ethdev driver in kernel support setting VF MAC address
2210 : : * on the host by "ip link set ..." command. If the hns3 PF kernel
2211 : : * ethdev driver sets the MAC address for VF device after the
2212 : : * initialization of the related VF device, the PF driver will notify
2213 : : * VF driver to reset VF device to make the new MAC address effective
2214 : : * immediately. The hns3 VF PMD should check whether the MAC
2215 : : * address has been changed by the PF kernel ethdev driver, if changed
2216 : : * VF driver should configure hardware using the new MAC address in the
2217 : : * recovering hardware configuration stage of the reset process.
2218 : : */
2219 : 0 : ret = hns3vf_get_host_mac_addr(hw);
2220 [ # # ]: 0 : if (ret)
2221 : : return ret;
2222 : :
2223 : : hw_mac = (struct rte_ether_addr *)hw->mac.mac_addr;
2224 : : ret = rte_is_zero_ether_addr(hw_mac);
2225 [ # # ]: 0 : if (ret) {
2226 : 0 : rte_ether_addr_copy(&hw->data->mac_addrs[0], hw_mac);
2227 : : } else {
2228 [ # # ]: 0 : ret = rte_is_same_ether_addr(&hw->data->mac_addrs[0], hw_mac);
2229 [ # # ]: 0 : if (!ret) {
2230 : : rte_ether_addr_copy(hw_mac, &hw->data->mac_addrs[0]);
2231 : 0 : hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
2232 : : &hw->data->mac_addrs[0]);
2233 : 0 : hns3_warn(hw, "Default MAC address has been changed to:"
2234 : : " %s by the host PF kernel ethdev driver",
2235 : : mac_str);
2236 : : }
2237 : : }
2238 : :
2239 : : return 0;
2240 : : }
2241 : :
2242 : : static int
2243 : 0 : hns3vf_restore_conf(struct hns3_adapter *hns)
2244 : : {
2245 : 0 : struct hns3_hw *hw = &hns->hw;
2246 : : int ret;
2247 : :
2248 : 0 : ret = hns3vf_check_default_mac_change(hw);
2249 [ # # ]: 0 : if (ret)
2250 : : return ret;
2251 : :
2252 : 0 : ret = hns3_configure_all_mac_addr(hns, false);
2253 [ # # ]: 0 : if (ret)
2254 : : return ret;
2255 : :
2256 : 0 : ret = hns3_configure_all_mc_mac_addr(hns, false);
2257 [ # # ]: 0 : if (ret)
2258 : 0 : goto err_mc_mac;
2259 : :
2260 : 0 : ret = hns3vf_restore_promisc(hns);
2261 [ # # ]: 0 : if (ret)
2262 : 0 : goto err_vlan_table;
2263 : :
2264 : 0 : ret = hns3vf_restore_vlan_conf(hns);
2265 [ # # ]: 0 : if (ret)
2266 : 0 : goto err_vlan_table;
2267 : :
2268 : 0 : ret = hns3vf_get_port_base_vlan_filter_state(hw);
2269 [ # # ]: 0 : if (ret)
2270 : 0 : goto err_vlan_table;
2271 : :
2272 : 0 : ret = hns3_restore_rx_interrupt(hw);
2273 [ # # ]: 0 : if (ret)
2274 : 0 : goto err_vlan_table;
2275 : :
2276 : 0 : ret = hns3_restore_gro_conf(hw);
2277 [ # # ]: 0 : if (ret)
2278 : 0 : goto err_vlan_table;
2279 : :
2280 [ # # ]: 0 : if (hw->adapter_state == HNS3_NIC_STARTED) {
2281 : 0 : ret = hns3vf_do_start(hns, false);
2282 [ # # ]: 0 : if (ret)
2283 : 0 : goto err_vlan_table;
2284 : 0 : hns3_info(hw, "hns3vf dev restart successful!");
2285 [ # # ]: 0 : } else if (hw->adapter_state == HNS3_NIC_STOPPING)
2286 : 0 : hw->adapter_state = HNS3_NIC_CONFIGURED;
2287 : :
2288 : 0 : ret = hns3vf_set_alive(hw, true);
2289 [ # # ]: 0 : if (ret) {
2290 : 0 : hns3_err(hw, "failed to VF send alive to PF: %d", ret);
2291 : 0 : goto err_vlan_table;
2292 : : }
2293 : :
2294 : : return 0;
2295 : :
2296 : 0 : err_vlan_table:
2297 : 0 : hns3_configure_all_mc_mac_addr(hns, true);
2298 : 0 : err_mc_mac:
2299 : 0 : hns3_configure_all_mac_addr(hns, true);
2300 : 0 : return ret;
2301 : : }
2302 : :
2303 : : static enum hns3_reset_level
2304 [ # # ]: 0 : hns3vf_get_reset_level(struct hns3_hw *hw, RTE_ATOMIC(uint64_t) *levels)
2305 : : {
2306 : : enum hns3_reset_level reset_level;
2307 : :
2308 : : /* return the highest priority reset level amongst all */
2309 [ # # ]: 0 : if (hns3_atomic_test_bit(HNS3_VF_RESET, levels))
2310 : : reset_level = HNS3_VF_RESET;
2311 [ # # ]: 0 : else if (hns3_atomic_test_bit(HNS3_VF_FULL_RESET, levels))
2312 : : reset_level = HNS3_VF_FULL_RESET;
2313 [ # # ]: 0 : else if (hns3_atomic_test_bit(HNS3_VF_PF_FUNC_RESET, levels))
2314 : : reset_level = HNS3_VF_PF_FUNC_RESET;
2315 [ # # ]: 0 : else if (hns3_atomic_test_bit(HNS3_VF_FUNC_RESET, levels))
2316 : : reset_level = HNS3_VF_FUNC_RESET;
2317 [ # # ]: 0 : else if (hns3_atomic_test_bit(HNS3_FLR_RESET, levels))
2318 : : reset_level = HNS3_FLR_RESET;
2319 : : else
2320 : : reset_level = HNS3_NONE_RESET;
2321 : :
2322 [ # # # # ]: 0 : if (hw->reset.level != HNS3_NONE_RESET && reset_level < hw->reset.level)
2323 : 0 : return HNS3_NONE_RESET;
2324 : :
2325 : : return reset_level;
2326 : : }
2327 : :
2328 : : static void
2329 : 0 : hns3vf_reset_service(void *param)
2330 : : {
2331 : : struct hns3_adapter *hns = (struct hns3_adapter *)param;
2332 : 0 : struct hns3_hw *hw = &hns->hw;
2333 : : enum hns3_reset_level reset_level;
2334 : : struct timeval tv_delta;
2335 : : struct timeval tv_start;
2336 : : struct timeval tv;
2337 : : uint64_t msec;
2338 : :
2339 : : /*
2340 : : * The interrupt is not triggered within the delay time.
2341 : : * The interrupt may have been lost. It is necessary to handle
2342 : : * the interrupt to recover from the error.
2343 : : */
2344 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.schedule, rte_memory_order_relaxed) ==
2345 : : SCHEDULE_DEFERRED) {
2346 : 0 : rte_atomic_store_explicit(&hw->reset.schedule, SCHEDULE_REQUESTED,
2347 : : rte_memory_order_relaxed);
2348 : 0 : hns3_err(hw, "Handling interrupts in delayed tasks");
2349 : 0 : hns3vf_interrupt_handler(&rte_eth_devices[hw->data->port_id]);
2350 : 0 : reset_level = hns3vf_get_reset_level(hw, &hw->reset.pending);
2351 [ # # ]: 0 : if (reset_level == HNS3_NONE_RESET) {
2352 : 0 : hns3_err(hw, "No reset level is set, try global reset");
2353 : : hns3_atomic_set_bit(HNS3_VF_RESET, &hw->reset.pending);
2354 : : }
2355 : : }
2356 : 0 : rte_atomic_store_explicit(&hw->reset.schedule, SCHEDULE_NONE, rte_memory_order_relaxed);
2357 : :
2358 : : /*
2359 : : * Hardware reset has been notified, we now have to poll & check if
2360 : : * hardware has actually completed the reset sequence.
2361 : : */
2362 : 0 : reset_level = hns3vf_get_reset_level(hw, &hw->reset.pending);
2363 [ # # ]: 0 : if (reset_level != HNS3_NONE_RESET) {
2364 : 0 : hns3_clock_gettime(&tv_start);
2365 : 0 : hns3_reset_process(hns, reset_level);
2366 : 0 : hns3_clock_gettime(&tv);
2367 [ # # ]: 0 : timersub(&tv, &tv_start, &tv_delta);
2368 : 0 : msec = hns3_clock_calctime_ms(&tv_delta);
2369 [ # # ]: 0 : if (msec > HNS3_RESET_PROCESS_MS)
2370 : 0 : hns3_err(hw, "%d handle long time delta %" PRIu64
2371 : : " ms time=%ld.%.6ld",
2372 : : hw->reset.level, msec, tv.tv_sec, tv.tv_usec);
2373 : : }
2374 : 0 : }
2375 : :
2376 : : static int
2377 : 0 : hns3vf_reinit_dev(struct hns3_adapter *hns)
2378 : : {
2379 : 0 : struct rte_eth_dev *eth_dev = &rte_eth_devices[hns->hw.data->port_id];
2380 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
2381 : 0 : struct hns3_hw *hw = &hns->hw;
2382 : : int ret;
2383 : :
2384 [ # # ]: 0 : if (hw->reset.level == HNS3_VF_FULL_RESET) {
2385 : 0 : rte_intr_disable(pci_dev->intr_handle);
2386 : 0 : ret = rte_pci_set_bus_master(pci_dev, true);
2387 [ # # ]: 0 : if (ret < 0) {
2388 : 0 : hns3_err(hw, "failed to set pci bus, ret = %d", ret);
2389 : 0 : return ret;
2390 : : }
2391 : : }
2392 : :
2393 : : /* Firmware command initialize */
2394 : 0 : ret = hns3_cmd_init(hw);
2395 [ # # ]: 0 : if (ret) {
2396 : 0 : hns3_err(hw, "Failed to init cmd: %d", ret);
2397 : 0 : return ret;
2398 : : }
2399 : :
2400 [ # # ]: 0 : if (hw->reset.level == HNS3_VF_FULL_RESET) {
2401 : : /*
2402 : : * UIO enables msix by writing the pcie configuration space
2403 : : * vfio_pci enables msix in rte_intr_enable.
2404 : : */
2405 [ # # ]: 0 : if (pci_dev->kdrv == RTE_PCI_KDRV_IGB_UIO ||
2406 : : pci_dev->kdrv == RTE_PCI_KDRV_UIO_GENERIC) {
2407 : 0 : ret = hns3vf_enable_msix(pci_dev, true);
2408 [ # # ]: 0 : if (ret != 0) {
2409 : 0 : hns3_err(hw, "Failed to enable msix");
2410 : 0 : return ret;
2411 : : }
2412 : : }
2413 : :
2414 : 0 : rte_intr_enable(pci_dev->intr_handle);
2415 : : }
2416 : :
2417 : 0 : ret = hns3_reset_all_tqps(hns);
2418 [ # # ]: 0 : if (ret) {
2419 : 0 : hns3_err(hw, "Failed to reset all queues: %d", ret);
2420 : 0 : return ret;
2421 : : }
2422 : :
2423 : 0 : ret = hns3vf_init_hardware(hns);
2424 [ # # ]: 0 : if (ret) {
2425 : 0 : hns3_err(hw, "Failed to init hardware: %d", ret);
2426 : 0 : return ret;
2427 : : }
2428 : :
2429 : : return 0;
2430 : : }
2431 : :
2432 : : static const struct eth_dev_ops hns3vf_eth_dev_ops = {
2433 : : .dev_configure = hns3vf_dev_configure,
2434 : : .dev_start = hns3vf_dev_start,
2435 : : .dev_stop = hns3vf_dev_stop,
2436 : : .dev_close = hns3vf_dev_close,
2437 : : .mtu_set = hns3vf_dev_mtu_set,
2438 : : .promiscuous_enable = hns3vf_dev_promiscuous_enable,
2439 : : .promiscuous_disable = hns3vf_dev_promiscuous_disable,
2440 : : .allmulticast_enable = hns3vf_dev_allmulticast_enable,
2441 : : .allmulticast_disable = hns3vf_dev_allmulticast_disable,
2442 : : .stats_get = hns3_stats_get,
2443 : : .stats_reset = hns3_stats_reset,
2444 : : .xstats_get = hns3_dev_xstats_get,
2445 : : .xstats_get_names = hns3_dev_xstats_get_names,
2446 : : .xstats_reset = hns3_dev_xstats_reset,
2447 : : .xstats_get_by_id = hns3_dev_xstats_get_by_id,
2448 : : .xstats_get_names_by_id = hns3_dev_xstats_get_names_by_id,
2449 : : .dev_infos_get = hns3_dev_infos_get,
2450 : : .fw_version_get = hns3_fw_version_get,
2451 : : .rx_queue_setup = hns3_rx_queue_setup,
2452 : : .tx_queue_setup = hns3_tx_queue_setup,
2453 : : .rx_queue_release = hns3_dev_rx_queue_release,
2454 : : .tx_queue_release = hns3_dev_tx_queue_release,
2455 : : .rx_queue_start = hns3_dev_rx_queue_start,
2456 : : .rx_queue_stop = hns3_dev_rx_queue_stop,
2457 : : .tx_queue_start = hns3_dev_tx_queue_start,
2458 : : .tx_queue_stop = hns3_dev_tx_queue_stop,
2459 : : .rx_queue_intr_enable = hns3_dev_rx_queue_intr_enable,
2460 : : .rx_queue_intr_disable = hns3_dev_rx_queue_intr_disable,
2461 : : .rxq_info_get = hns3_rxq_info_get,
2462 : : .txq_info_get = hns3_txq_info_get,
2463 : : .rx_burst_mode_get = hns3_rx_burst_mode_get,
2464 : : .tx_burst_mode_get = hns3_tx_burst_mode_get,
2465 : : .mac_addr_add = hns3_add_mac_addr,
2466 : : .mac_addr_remove = hns3_remove_mac_addr,
2467 : : .mac_addr_set = hns3vf_set_default_mac_addr,
2468 : : .set_mc_addr_list = hns3_set_mc_mac_addr_list,
2469 : : .link_update = hns3vf_dev_link_update,
2470 : : .rss_hash_update = hns3_dev_rss_hash_update,
2471 : : .rss_hash_conf_get = hns3_dev_rss_hash_conf_get,
2472 : : .reta_update = hns3_dev_rss_reta_update,
2473 : : .reta_query = hns3_dev_rss_reta_query,
2474 : : .flow_ops_get = hns3_dev_flow_ops_get,
2475 : : .vlan_filter_set = hns3vf_vlan_filter_set,
2476 : : .vlan_offload_set = hns3vf_vlan_offload_set,
2477 : : .get_reg = hns3_get_regs,
2478 : : .get_dcb_info = hns3_get_dcb_info,
2479 : : .dev_supported_ptypes_get = hns3_dev_supported_ptypes_get,
2480 : : .tx_done_cleanup = hns3_tx_done_cleanup,
2481 : : .eth_dev_priv_dump = hns3_eth_dev_priv_dump,
2482 : : .eth_rx_descriptor_dump = hns3_rx_descriptor_dump,
2483 : : .eth_tx_descriptor_dump = hns3_tx_descriptor_dump,
2484 : : .get_monitor_addr = hns3_get_monitor_addr,
2485 : : };
2486 : :
2487 : : static const struct hns3_reset_ops hns3vf_reset_ops = {
2488 : : .reset_service = hns3vf_reset_service,
2489 : : .stop_service = hns3vf_stop_service,
2490 : : .prepare_reset = hns3vf_prepare_reset,
2491 : : .wait_hardware_ready = hns3vf_wait_hardware_ready,
2492 : : .reinit_dev = hns3vf_reinit_dev,
2493 : : .restore_conf = hns3vf_restore_conf,
2494 : : .start_service = hns3vf_start_service,
2495 : : };
2496 : :
2497 : : static void
2498 : : hns3vf_init_hw_ops(struct hns3_hw *hw)
2499 : : {
2500 : 0 : hw->ops.add_mc_mac_addr = hns3vf_add_mc_mac_addr;
2501 : 0 : hw->ops.del_mc_mac_addr = hns3vf_remove_mc_mac_addr;
2502 : 0 : hw->ops.add_uc_mac_addr = hns3vf_add_uc_mac_addr;
2503 : 0 : hw->ops.del_uc_mac_addr = hns3vf_remove_uc_mac_addr;
2504 : 0 : hw->ops.bind_ring_with_vector = hns3vf_bind_ring_with_vector;
2505 : : }
2506 : :
2507 : : static int
2508 : 0 : hns3vf_dev_init(struct rte_eth_dev *eth_dev)
2509 : : {
2510 : 0 : struct hns3_adapter *hns = eth_dev->data->dev_private;
2511 : 0 : struct hns3_hw *hw = &hns->hw;
2512 : : int ret;
2513 : :
2514 : 0 : PMD_INIT_FUNC_TRACE();
2515 : :
2516 : 0 : hns3_flow_init(eth_dev);
2517 : :
2518 : 0 : hns3_set_rxtx_function(eth_dev);
2519 : 0 : eth_dev->dev_ops = &hns3vf_eth_dev_ops;
2520 : 0 : eth_dev->rx_queue_count = hns3_rx_queue_count;
2521 : 0 : ret = hns3_mp_init(eth_dev);
2522 [ # # ]: 0 : if (ret)
2523 : 0 : goto err_mp_init;
2524 : :
2525 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
2526 : 0 : hns3_tx_push_init(eth_dev);
2527 : 0 : return 0;
2528 : : }
2529 : :
2530 : 0 : hw->adapter_state = HNS3_NIC_UNINITIALIZED;
2531 : 0 : hns->is_vf = true;
2532 : 0 : hw->data = eth_dev->data;
2533 : 0 : hns3_parse_devargs(eth_dev);
2534 : :
2535 : 0 : ret = hns3_reset_init(hw);
2536 [ # # ]: 0 : if (ret)
2537 : 0 : goto err_init_reset;
2538 : 0 : hw->reset.ops = &hns3vf_reset_ops;
2539 : :
2540 : : hns3vf_init_hw_ops(hw);
2541 : 0 : ret = hns3vf_init_vf(eth_dev);
2542 [ # # ]: 0 : if (ret) {
2543 : 0 : PMD_INIT_LOG(ERR, "Failed to init vf: %d", ret);
2544 : 0 : goto err_init_vf;
2545 : : }
2546 : :
2547 : 0 : ret = hns3_init_mac_addrs(eth_dev);
2548 [ # # ]: 0 : if (ret != 0)
2549 : 0 : goto err_init_mac_addrs;
2550 : :
2551 : 0 : hw->adapter_state = HNS3_NIC_INITIALIZED;
2552 : :
2553 [ # # ]: 0 : if (rte_atomic_load_explicit(&hw->reset.schedule, rte_memory_order_relaxed) ==
2554 : : SCHEDULE_PENDING) {
2555 : 0 : hns3_err(hw, "Reschedule reset service after dev_init");
2556 : 0 : hns3_schedule_reset(hns);
2557 : : } else {
2558 : : /* IMP will wait ready flag before reset */
2559 : 0 : hns3_notify_reset_ready(hw, false);
2560 : : }
2561 : 0 : rte_eal_alarm_set(HNS3VF_KEEP_ALIVE_INTERVAL, hns3vf_keep_alive_handler,
2562 : : eth_dev);
2563 : 0 : return 0;
2564 : :
2565 : : err_init_mac_addrs:
2566 : 0 : hns3vf_uninit_vf(eth_dev);
2567 : :
2568 : 0 : err_init_vf:
2569 : 0 : rte_free(hw->reset.wait_data);
2570 : :
2571 : 0 : err_init_reset:
2572 : 0 : hns3_mp_uninit(eth_dev);
2573 : :
2574 : 0 : err_mp_init:
2575 : 0 : eth_dev->dev_ops = NULL;
2576 : 0 : eth_dev->rx_pkt_burst = NULL;
2577 : 0 : eth_dev->rx_descriptor_status = NULL;
2578 : 0 : eth_dev->tx_pkt_burst = NULL;
2579 : 0 : eth_dev->tx_pkt_prepare = NULL;
2580 : 0 : eth_dev->tx_descriptor_status = NULL;
2581 : :
2582 : 0 : return ret;
2583 : : }
2584 : :
2585 : : static int
2586 : 0 : hns3vf_dev_uninit(struct rte_eth_dev *eth_dev)
2587 : : {
2588 : 0 : struct hns3_adapter *hns = eth_dev->data->dev_private;
2589 : : struct hns3_hw *hw = &hns->hw;
2590 : :
2591 : 0 : PMD_INIT_FUNC_TRACE();
2592 : :
2593 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
2594 : 0 : hns3_mp_uninit(eth_dev);
2595 : 0 : return 0;
2596 : : }
2597 : :
2598 [ # # ]: 0 : if (hw->adapter_state < HNS3_NIC_CLOSING)
2599 : 0 : hns3vf_dev_close(eth_dev);
2600 : :
2601 : 0 : hw->adapter_state = HNS3_NIC_REMOVED;
2602 : 0 : return 0;
2603 : : }
2604 : :
2605 : : static int
2606 : 0 : eth_hns3vf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
2607 : : struct rte_pci_device *pci_dev)
2608 : : {
2609 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev,
2610 : : sizeof(struct hns3_adapter),
2611 : : hns3vf_dev_init);
2612 : : }
2613 : :
2614 : : static int
2615 : 0 : eth_hns3vf_pci_remove(struct rte_pci_device *pci_dev)
2616 : : {
2617 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, hns3vf_dev_uninit);
2618 : : }
2619 : :
2620 : : static const struct rte_pci_id pci_id_hns3vf_map[] = {
2621 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_100G_VF) },
2622 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_100G_RDMA_PFC_VF) },
2623 : : { .vendor_id = 0, }, /* sentinel */
2624 : : };
2625 : :
2626 : : static struct rte_pci_driver rte_hns3vf_pmd = {
2627 : : .id_table = pci_id_hns3vf_map,
2628 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
2629 : : .probe = eth_hns3vf_pci_probe,
2630 : : .remove = eth_hns3vf_pci_remove,
2631 : : };
2632 : :
2633 : 253 : RTE_PMD_REGISTER_PCI(net_hns3_vf, rte_hns3vf_pmd);
2634 : : RTE_PMD_REGISTER_PCI_TABLE(net_hns3_vf, pci_id_hns3vf_map);
2635 : : RTE_PMD_REGISTER_KMOD_DEP(net_hns3_vf, "* igb_uio | vfio-pci");
2636 : : RTE_PMD_REGISTER_PARAM_STRING(net_hns3_vf,
2637 : : HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common "
2638 : : HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common "
2639 : : HNS3_DEVARG_DEV_CAPS_MASK "=<1-65535> "
2640 : : HNS3_DEVARG_MBX_TIME_LIMIT_MS "=<uint16_t> ");
|