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