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