Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 ZTE Corporation
3 : : */
4 : :
5 : : #include <rte_malloc.h>
6 : : #include <rte_ether.h>
7 : :
8 : : #include "zxdh_ethdev.h"
9 : : #include "zxdh_pci.h"
10 : : #include "zxdh_msg.h"
11 : : #include "zxdh_ethdev_ops.h"
12 : : #include "zxdh_tables.h"
13 : : #include "zxdh_logs.h"
14 : : #include "zxdh_rxtx.h"
15 : : #include "zxdh_np.h"
16 : : #include "zxdh_queue.h"
17 : :
18 : : #define ZXDH_VLAN_FILTER_GROUPS 64
19 : : #define ZXDH_INVALID_LOGIC_QID 0xFFFFU
20 : :
21 : : /* Supported RSS */
22 : : #define ZXDH_RSS_HF_MASK (~(ZXDH_RSS_HF))
23 : : #define ZXDH_HF_F5 1
24 : : #define ZXDH_HF_F3 2
25 : : #define ZXDH_HF_MAC_VLAN 4
26 : : #define ZXDH_HF_ALL 0
27 : :
28 : : struct zxdh_hw_mac_stats {
29 : : uint64_t rx_total;
30 : : uint64_t rx_pause;
31 : : uint64_t rx_unicast;
32 : : uint64_t rx_multicast;
33 : : uint64_t rx_broadcast;
34 : : uint64_t rx_vlan;
35 : : uint64_t rx_size_64;
36 : : uint64_t rx_size_65_127;
37 : : uint64_t rx_size_128_255;
38 : : uint64_t rx_size_256_511;
39 : : uint64_t rx_size_512_1023;
40 : : uint64_t rx_size_1024_1518;
41 : : uint64_t rx_size_1519_mru;
42 : : uint64_t rx_undersize;
43 : : uint64_t rx_oversize;
44 : : uint64_t rx_fragment;
45 : : uint64_t rx_jabber;
46 : : uint64_t rx_control;
47 : : uint64_t rx_eee;
48 : :
49 : : uint64_t tx_total;
50 : : uint64_t tx_pause;
51 : : uint64_t tx_unicast;
52 : : uint64_t tx_multicast;
53 : : uint64_t tx_broadcast;
54 : : uint64_t tx_vlan;
55 : : uint64_t tx_size_64;
56 : : uint64_t tx_size_65_127;
57 : : uint64_t tx_size_128_255;
58 : : uint64_t tx_size_256_511;
59 : : uint64_t tx_size_512_1023;
60 : : uint64_t tx_size_1024_1518;
61 : : uint64_t tx_size_1519_mtu;
62 : : uint64_t tx_undersize;
63 : : uint64_t tx_oversize;
64 : : uint64_t tx_fragment;
65 : : uint64_t tx_jabber;
66 : : uint64_t tx_control;
67 : : uint64_t tx_eee;
68 : :
69 : : uint64_t rx_error;
70 : : uint64_t rx_fcs_error;
71 : : uint64_t rx_drop;
72 : :
73 : : uint64_t tx_error;
74 : : uint64_t tx_fcs_error;
75 : : uint64_t tx_drop;
76 : :
77 : : };
78 : :
79 : : struct zxdh_hw_mac_bytes {
80 : : uint64_t rx_total_bytes;
81 : : uint64_t rx_good_bytes;
82 : : uint64_t tx_total_bytes;
83 : : uint64_t tx_good_bytes;
84 : : };
85 : :
86 : : struct zxdh_np_stats_data {
87 : : uint64_t n_pkts_dropped;
88 : : uint64_t n_bytes_dropped;
89 : : };
90 : :
91 : : struct zxdh_xstats_name_off {
92 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
93 : : unsigned int offset;
94 : : };
95 : :
96 : : static const struct zxdh_xstats_name_off zxdh_rxq_stat_strings[] = {
97 : : {"good_packets", offsetof(struct zxdh_virtnet_rx, stats.packets)},
98 : : {"good_bytes", offsetof(struct zxdh_virtnet_rx, stats.bytes)},
99 : : {"errors", offsetof(struct zxdh_virtnet_rx, stats.errors)},
100 : : {"multicast_packets", offsetof(struct zxdh_virtnet_rx, stats.multicast)},
101 : : {"broadcast_packets", offsetof(struct zxdh_virtnet_rx, stats.broadcast)},
102 : : {"truncated_err", offsetof(struct zxdh_virtnet_rx, stats.truncated_err)},
103 : : {"undersize_packets", offsetof(struct zxdh_virtnet_rx, stats.size_bins[0])},
104 : : {"size_64_packets", offsetof(struct zxdh_virtnet_rx, stats.size_bins[1])},
105 : : {"size_65_127_packets", offsetof(struct zxdh_virtnet_rx, stats.size_bins[2])},
106 : : {"size_128_255_packets", offsetof(struct zxdh_virtnet_rx, stats.size_bins[3])},
107 : : {"size_256_511_packets", offsetof(struct zxdh_virtnet_rx, stats.size_bins[4])},
108 : : {"size_512_1023_packets", offsetof(struct zxdh_virtnet_rx, stats.size_bins[5])},
109 : : {"size_1024_1518_packets", offsetof(struct zxdh_virtnet_rx, stats.size_bins[6])},
110 : : {"size_1519_max_packets", offsetof(struct zxdh_virtnet_rx, stats.size_bins[7])},
111 : : };
112 : :
113 : : static const struct zxdh_xstats_name_off zxdh_txq_stat_strings[] = {
114 : : {"good_packets", offsetof(struct zxdh_virtnet_tx, stats.packets)},
115 : : {"good_bytes", offsetof(struct zxdh_virtnet_tx, stats.bytes)},
116 : : {"errors", offsetof(struct zxdh_virtnet_tx, stats.errors)},
117 : : {"multicast_packets", offsetof(struct zxdh_virtnet_tx, stats.multicast)},
118 : : {"broadcast_packets", offsetof(struct zxdh_virtnet_tx, stats.broadcast)},
119 : : {"truncated_err", offsetof(struct zxdh_virtnet_tx, stats.truncated_err)},
120 : : {"undersize_packets", offsetof(struct zxdh_virtnet_tx, stats.size_bins[0])},
121 : : {"size_64_packets", offsetof(struct zxdh_virtnet_tx, stats.size_bins[1])},
122 : : {"size_65_127_packets", offsetof(struct zxdh_virtnet_tx, stats.size_bins[2])},
123 : : {"size_128_255_packets", offsetof(struct zxdh_virtnet_tx, stats.size_bins[3])},
124 : : {"size_256_511_packets", offsetof(struct zxdh_virtnet_tx, stats.size_bins[4])},
125 : : {"size_512_1023_packets", offsetof(struct zxdh_virtnet_tx, stats.size_bins[5])},
126 : : {"size_1024_1518_packets", offsetof(struct zxdh_virtnet_tx, stats.size_bins[6])},
127 : : {"size_1519_max_packets", offsetof(struct zxdh_virtnet_tx, stats.size_bins[7])},
128 : : };
129 : :
130 : 0 : static int32_t zxdh_config_port_status(struct rte_eth_dev *dev, uint16_t link_status)
131 : : {
132 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
133 : 0 : struct zxdh_port_attr_table port_attr = {0};
134 : 0 : struct zxdh_msg_info msg_info = {0};
135 : : int32_t ret = 0;
136 : :
137 [ # # ]: 0 : if (hw->is_pf) {
138 : 0 : ret = zxdh_get_port_attr(hw->vfid, &port_attr);
139 [ # # ]: 0 : if (ret) {
140 : 0 : PMD_DRV_LOG(ERR, "get port_attr failed");
141 : 0 : return -1;
142 : : }
143 : 0 : port_attr.is_up = link_status;
144 : :
145 : 0 : ret = zxdh_set_port_attr(hw->vfid, &port_attr);
146 [ # # ]: 0 : if (ret) {
147 : 0 : PMD_DRV_LOG(ERR, "write port_attr failed");
148 : 0 : return -1;
149 : : }
150 : : } else {
151 : : struct zxdh_port_attr_set_msg *port_attr_msg = &msg_info.data.port_attr_msg;
152 : :
153 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
154 : 0 : port_attr_msg->mode = ZXDH_PORT_ATTR_IS_UP_FLAG;
155 : 0 : port_attr_msg->value = link_status;
156 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
157 [ # # ]: 0 : if (ret) {
158 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
159 : : hw->vport.vport, ZXDH_PORT_ATTR_IS_UP_FLAG);
160 : 0 : return ret;
161 : : }
162 : : }
163 : : return ret;
164 : : }
165 : :
166 : : static int32_t
167 : 0 : zxdh_link_info_get(struct rte_eth_dev *dev, struct rte_eth_link *link)
168 : : {
169 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
170 : 0 : struct zxdh_msg_info msg_info = {0};
171 : 0 : struct zxdh_msg_reply_info reply_info = {0};
172 [ # # ]: 0 : uint16_t status = 0;
173 : : int32_t ret = 0;
174 : :
175 [ # # ]: 0 : if (zxdh_pci_with_feature(hw, ZXDH_NET_F_STATUS))
176 : 0 : zxdh_pci_read_dev_config(hw, offsetof(struct zxdh_net_config, status),
177 : : &status, sizeof(status));
178 : :
179 : 0 : link->link_status = status;
180 : :
181 [ # # ]: 0 : if (status == RTE_ETH_LINK_DOWN) {
182 : 0 : link->link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
183 : 0 : link->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
184 : : } else {
185 : 0 : zxdh_agent_msg_build(hw, ZXDH_MAC_LINK_GET, &msg_info);
186 : :
187 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
188 : : &reply_info, sizeof(struct zxdh_msg_reply_info),
189 : : ZXDH_BAR_MODULE_MAC);
190 [ # # ]: 0 : if (ret) {
191 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
192 : : hw->vport.vport, ZXDH_MAC_LINK_GET);
193 : 0 : return -1;
194 : : }
195 : 0 : link->link_speed = reply_info.reply_body.link_msg.speed;
196 : 0 : hw->speed_mode = reply_info.reply_body.link_msg.speed_modes;
197 [ # # ]: 0 : if ((reply_info.reply_body.link_msg.duplex & RTE_ETH_LINK_FULL_DUPLEX) ==
198 : : RTE_ETH_LINK_FULL_DUPLEX)
199 : 0 : link->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
200 : : else
201 : 0 : link->link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
202 : : }
203 : 0 : hw->speed = link->link_speed;
204 : :
205 : 0 : return 0;
206 : : }
207 : :
208 : 0 : static int zxdh_set_link_status(struct rte_eth_dev *dev, uint8_t link_status)
209 : : {
210 : 0 : uint16_t curr_link_status = dev->data->dev_link.link_status;
211 : :
212 : : struct rte_eth_link link;
213 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
214 : : int32_t ret = 0;
215 : :
216 [ # # ]: 0 : if (link_status == curr_link_status) {
217 : 0 : PMD_DRV_LOG(DEBUG, "curr_link_status %u", curr_link_status);
218 : 0 : return 0;
219 : : }
220 : :
221 : 0 : hw->admin_status = link_status;
222 : 0 : ret = zxdh_link_info_get(dev, &link);
223 [ # # ]: 0 : if (ret != 0) {
224 : 0 : PMD_DRV_LOG(ERR, "Failed to get link status from hw");
225 : 0 : return ret;
226 : : }
227 : 0 : dev->data->dev_link.link_status = hw->admin_status & link.link_status;
228 : :
229 [ # # ]: 0 : if (dev->data->dev_link.link_status == RTE_ETH_LINK_UP) {
230 : 0 : dev->data->dev_link.link_speed = link.link_speed;
231 : 0 : dev->data->dev_link.link_duplex = link.link_duplex;
232 : : } else {
233 : 0 : dev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
234 : 0 : dev->data->dev_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
235 : : }
236 : 0 : return zxdh_config_port_status(dev, dev->data->dev_link.link_status);
237 : : }
238 : :
239 : 0 : int zxdh_dev_set_link_up(struct rte_eth_dev *dev)
240 : : {
241 : 0 : int ret = zxdh_set_link_status(dev, RTE_ETH_LINK_UP);
242 : :
243 [ # # ]: 0 : if (ret)
244 : 0 : PMD_DRV_LOG(ERR, "Set link up failed, code:%d", ret);
245 : :
246 : 0 : return ret;
247 : : }
248 : :
249 : 0 : int32_t zxdh_dev_link_update(struct rte_eth_dev *dev, int32_t wait_to_complete __rte_unused)
250 : : {
251 : : struct rte_eth_link link;
252 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
253 : : int32_t ret = 0;
254 : :
255 : : memset(&link, 0, sizeof(link));
256 : 0 : link.link_duplex = hw->duplex;
257 : 0 : link.link_speed = hw->speed;
258 : 0 : link.link_autoneg = RTE_ETH_LINK_AUTONEG;
259 : :
260 : 0 : ret = zxdh_link_info_get(dev, &link);
261 [ # # ]: 0 : if (ret != 0) {
262 : 0 : PMD_DRV_LOG(ERR, "Failed to get link status from hw");
263 : 0 : return ret;
264 : : }
265 : 0 : link.link_status &= hw->admin_status;
266 [ # # ]: 0 : if (link.link_status == RTE_ETH_LINK_DOWN)
267 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
268 : :
269 : 0 : ret = zxdh_config_port_status(dev, link.link_status);
270 [ # # ]: 0 : if (ret != 0) {
271 : 0 : PMD_DRV_LOG(ERR, "set port attr %d failed", link.link_status);
272 : 0 : return ret;
273 : : }
274 : : return rte_eth_linkstatus_set(dev, &link);
275 : : }
276 : :
277 : 0 : int zxdh_dev_set_link_down(struct rte_eth_dev *dev)
278 : : {
279 : 0 : int ret = zxdh_set_link_status(dev, RTE_ETH_LINK_DOWN);
280 : :
281 [ # # ]: 0 : if (ret)
282 : 0 : PMD_DRV_LOG(ERR, "Set link down failed");
283 : 0 : return ret;
284 : : }
285 : :
286 : 0 : int zxdh_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
287 : : {
288 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
289 : 0 : struct rte_ether_addr *old_addr = &dev->data->mac_addrs[0];
290 [ # # ]: 0 : struct zxdh_msg_info msg_info = {0};
291 : : uint16_t ret = 0;
292 : :
293 : : if (!rte_is_valid_assigned_ether_addr(addr)) {
294 : 0 : PMD_DRV_LOG(ERR, "mac address is invalid!");
295 : 0 : return -EINVAL;
296 : : }
297 : :
298 [ # # ]: 0 : if (hw->is_pf) {
299 : 0 : ret = zxdh_del_mac_table(hw->vport.vport, old_addr, hw->hash_search_index);
300 [ # # ]: 0 : if (ret) {
301 : 0 : PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);
302 : 0 : return ret;
303 : : }
304 : 0 : hw->uc_num--;
305 : :
306 : 0 : ret = zxdh_set_mac_table(hw->vport.vport, addr, hw->hash_search_index);
307 [ # # ]: 0 : if (ret) {
308 : 0 : PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);
309 : 0 : return ret;
310 : : }
311 : 0 : hw->uc_num++;
312 : : } else {
313 : : struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;
314 : :
315 : 0 : mac_filter->filter_flag = ZXDH_MAC_UNFILTER;
316 [ # # ]: 0 : mac_filter->mac_flag = true;
317 : : rte_memcpy(&mac_filter->mac, old_addr, sizeof(struct rte_ether_addr));
318 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info);
319 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
320 [ # # ]: 0 : if (ret) {
321 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
322 : : hw->vport.vport, ZXDH_MAC_DEL);
323 : 0 : return ret;
324 : : }
325 : 0 : hw->uc_num--;
326 : 0 : PMD_DRV_LOG(INFO, "Success to send msg: port 0x%x msg type %d",
327 : : hw->vport.vport, ZXDH_MAC_DEL);
328 : :
329 [ # # ]: 0 : mac_filter->filter_flag = ZXDH_MAC_UNFILTER;
330 : : rte_memcpy(&mac_filter->mac, addr, sizeof(struct rte_ether_addr));
331 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);
332 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
333 [ # # ]: 0 : if (ret) {
334 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
335 : : hw->vport.vport, ZXDH_MAC_ADD);
336 : 0 : return ret;
337 : : }
338 : 0 : hw->uc_num++;
339 : : }
340 : : rte_ether_addr_copy(addr, (struct rte_ether_addr *)hw->mac_addr);
341 : 0 : return ret;
342 : : }
343 : :
344 : 0 : int zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
345 : : uint32_t index, uint32_t vmdq __rte_unused)
346 : : {
347 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
348 : 0 : struct zxdh_msg_info msg_info = {0};
349 : : uint16_t i, ret;
350 : :
351 [ # # ]: 0 : if (index >= ZXDH_MAX_MAC_ADDRS) {
352 : 0 : PMD_DRV_LOG(ERR, "Add mac index (%u) is out of range", index);
353 : 0 : return -EINVAL;
354 : : }
355 : :
356 [ # # ]: 0 : for (i = 0; (i != ZXDH_MAX_MAC_ADDRS); ++i) {
357 [ # # ]: 0 : if (memcmp(&dev->data->mac_addrs[i], mac_addr, sizeof(*mac_addr)))
358 : : continue;
359 : :
360 : 0 : PMD_DRV_LOG(INFO, "MAC address already configured");
361 : 0 : return -EADDRINUSE;
362 : : }
363 : :
364 [ # # ]: 0 : if (hw->is_pf) {
365 [ # # ]: 0 : if (rte_is_unicast_ether_addr(mac_addr)) {
366 [ # # ]: 0 : if (hw->uc_num < ZXDH_MAX_UC_MAC_ADDRS) {
367 : 0 : ret = zxdh_set_mac_table(hw->vport.vport,
368 : 0 : mac_addr, hw->hash_search_index);
369 [ # # ]: 0 : if (ret) {
370 : 0 : PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);
371 : 0 : return ret;
372 : : }
373 : 0 : hw->uc_num++;
374 : : } else {
375 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
376 : : ZXDH_MAX_MC_MAC_ADDRS);
377 : 0 : return -EINVAL;
378 : : }
379 : : } else {
380 [ # # ]: 0 : if (hw->mc_num < ZXDH_MAX_MC_MAC_ADDRS) {
381 : 0 : ret = zxdh_set_mac_table(hw->vport.vport,
382 : 0 : mac_addr, hw->hash_search_index);
383 [ # # ]: 0 : if (ret) {
384 : 0 : PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);
385 : 0 : return ret;
386 : : }
387 : 0 : hw->mc_num++;
388 : : } else {
389 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
390 : : ZXDH_MAX_MC_MAC_ADDRS);
391 : 0 : return -EINVAL;
392 : : }
393 : : }
394 : : } else {
395 : : struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;
396 : :
397 [ # # ]: 0 : mac_filter->filter_flag = ZXDH_MAC_FILTER;
398 : : rte_memcpy(&mac_filter->mac, mac_addr, sizeof(struct rte_ether_addr));
399 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);
400 [ # # ]: 0 : if (rte_is_unicast_ether_addr(mac_addr)) {
401 [ # # ]: 0 : if (hw->uc_num < ZXDH_MAX_UC_MAC_ADDRS) {
402 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
403 : : sizeof(msg_info), NULL, 0);
404 [ # # ]: 0 : if (ret) {
405 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
406 : : hw->vport.vport, ZXDH_MAC_ADD);
407 : 0 : return ret;
408 : : }
409 : 0 : hw->uc_num++;
410 : : } else {
411 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
412 : : ZXDH_MAX_MC_MAC_ADDRS);
413 : 0 : return -EINVAL;
414 : : }
415 : : } else {
416 [ # # ]: 0 : if (hw->mc_num < ZXDH_MAX_MC_MAC_ADDRS) {
417 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
418 : : sizeof(msg_info), NULL, 0);
419 [ # # ]: 0 : if (ret) {
420 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
421 : : hw->vport.vport, ZXDH_MAC_ADD);
422 : 0 : return ret;
423 : : }
424 : 0 : hw->mc_num++;
425 : : } else {
426 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
427 : : ZXDH_MAX_MC_MAC_ADDRS);
428 : 0 : return -EINVAL;
429 : : }
430 : : }
431 : : }
432 : 0 : dev->data->mac_addrs[index] = *mac_addr;
433 : 0 : return 0;
434 : : }
435 : :
436 : 0 : void zxdh_dev_mac_addr_remove(struct rte_eth_dev *dev __rte_unused, uint32_t index __rte_unused)
437 : : {
438 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
439 : 0 : struct zxdh_msg_info msg_info = {0};
440 : 0 : struct rte_ether_addr *mac_addr = &dev->data->mac_addrs[index];
441 : : uint16_t ret = 0;
442 : :
443 [ # # ]: 0 : if (index >= ZXDH_MAX_MAC_ADDRS)
444 : 0 : return;
445 : :
446 [ # # ]: 0 : if (hw->is_pf) {
447 [ # # ]: 0 : if (rte_is_unicast_ether_addr(mac_addr)) {
448 [ # # ]: 0 : if (hw->uc_num <= ZXDH_MAX_UC_MAC_ADDRS) {
449 : 0 : ret = zxdh_del_mac_table(hw->vport.vport,
450 : 0 : mac_addr, hw->hash_search_index);
451 [ # # ]: 0 : if (ret) {
452 : 0 : PMD_DRV_LOG(ERR, "mac_addr_del failed, code:%d", ret);
453 : 0 : return;
454 : : }
455 : 0 : hw->uc_num--;
456 : : } else {
457 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
458 : : ZXDH_MAX_MC_MAC_ADDRS);
459 : 0 : return;
460 : : }
461 : : } else {
462 [ # # ]: 0 : if (hw->mc_num <= ZXDH_MAX_MC_MAC_ADDRS) {
463 : 0 : ret = zxdh_del_mac_table(hw->vport.vport,
464 : 0 : mac_addr, hw->hash_search_index);
465 [ # # ]: 0 : if (ret) {
466 : 0 : PMD_DRV_LOG(ERR, "mac_addr_del failed, code:%d", ret);
467 : 0 : return;
468 : : }
469 : 0 : hw->mc_num--;
470 : : } else {
471 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
472 : : ZXDH_MAX_MC_MAC_ADDRS);
473 : 0 : return;
474 : : }
475 : : }
476 : : } else {
477 : : struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;
478 : :
479 [ # # ]: 0 : mac_filter->filter_flag = ZXDH_MAC_FILTER;
480 : : rte_memcpy(&mac_filter->mac, mac_addr, sizeof(struct rte_ether_addr));
481 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info);
482 [ # # ]: 0 : if (rte_is_unicast_ether_addr(mac_addr)) {
483 [ # # ]: 0 : if (hw->uc_num <= ZXDH_MAX_UC_MAC_ADDRS) {
484 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
485 : : sizeof(msg_info), NULL, 0);
486 [ # # ]: 0 : if (ret) {
487 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
488 : : hw->vport.vport, ZXDH_MAC_DEL);
489 : 0 : return;
490 : : }
491 : 0 : hw->uc_num--;
492 : : } else {
493 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
494 : : ZXDH_MAX_MC_MAC_ADDRS);
495 : 0 : return;
496 : : }
497 : : } else {
498 [ # # ]: 0 : if (hw->mc_num <= ZXDH_MAX_MC_MAC_ADDRS) {
499 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
500 : : sizeof(msg_info), NULL, 0);
501 [ # # ]: 0 : if (ret) {
502 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
503 : : hw->vport.vport, ZXDH_MAC_DEL);
504 : 0 : return;
505 : : }
506 : 0 : hw->mc_num--;
507 : : } else {
508 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
509 : : ZXDH_MAX_MC_MAC_ADDRS);
510 : 0 : return;
511 : : }
512 : : }
513 : : }
514 : 0 : memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr));
515 : : }
516 : :
517 : 0 : int zxdh_dev_promiscuous_enable(struct rte_eth_dev *dev)
518 : : {
519 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
520 : 0 : struct zxdh_msg_info msg_info = {0};
521 : : int16_t ret = 0;
522 : :
523 [ # # ]: 0 : if (hw->promisc_status == 0) {
524 [ # # ]: 0 : if (hw->is_pf) {
525 : 0 : ret = zxdh_dev_unicast_table_set(hw, hw->vport.vport, true);
526 [ # # ]: 0 : if (hw->allmulti_status == 0)
527 : 0 : ret = zxdh_dev_multicast_table_set(hw, hw->vport.vport, true);
528 : :
529 : : } else {
530 : : struct zxdh_port_promisc_msg *promisc_msg = &msg_info.data.port_promisc_msg;
531 : :
532 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_PROMISC_SET, &msg_info);
533 : 0 : promisc_msg->mode = ZXDH_PROMISC_MODE;
534 : 0 : promisc_msg->value = true;
535 [ # # ]: 0 : if (hw->allmulti_status == 0)
536 : 0 : promisc_msg->mc_follow = true;
537 : :
538 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
539 [ # # ]: 0 : if (ret) {
540 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
541 : : hw->vport.vport, ZXDH_PROMISC_MODE);
542 : 0 : return ret;
543 : : }
544 : : }
545 : 0 : hw->promisc_status = 1;
546 : : }
547 : 0 : return ret;
548 : : }
549 : :
550 : 0 : int zxdh_dev_promiscuous_disable(struct rte_eth_dev *dev)
551 : : {
552 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
553 : : int16_t ret = 0;
554 : 0 : struct zxdh_msg_info msg_info = {0};
555 : :
556 [ # # ]: 0 : if (hw->promisc_status == 1) {
557 [ # # ]: 0 : if (hw->is_pf) {
558 : 0 : ret = zxdh_dev_unicast_table_set(hw, hw->vport.vport, false);
559 [ # # ]: 0 : if (hw->allmulti_status == 0)
560 : 0 : ret = zxdh_dev_multicast_table_set(hw, hw->vport.vport, false);
561 : :
562 : : } else {
563 : : struct zxdh_port_promisc_msg *promisc_msg = &msg_info.data.port_promisc_msg;
564 : :
565 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_PROMISC_SET, &msg_info);
566 : 0 : promisc_msg->mode = ZXDH_PROMISC_MODE;
567 : 0 : promisc_msg->value = false;
568 [ # # ]: 0 : if (hw->allmulti_status == 0)
569 : 0 : promisc_msg->mc_follow = true;
570 : :
571 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
572 [ # # ]: 0 : if (ret) {
573 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
574 : : hw->vport.vport, ZXDH_PROMISC_MODE);
575 : 0 : return ret;
576 : : }
577 : : }
578 : 0 : hw->promisc_status = 0;
579 : : }
580 : 0 : return ret;
581 : : }
582 : :
583 : 0 : int zxdh_dev_allmulticast_enable(struct rte_eth_dev *dev)
584 : : {
585 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
586 : : int16_t ret = 0;
587 : 0 : struct zxdh_msg_info msg_info = {0};
588 : :
589 [ # # ]: 0 : if (hw->allmulti_status == 0) {
590 [ # # ]: 0 : if (hw->is_pf) {
591 : 0 : ret = zxdh_dev_multicast_table_set(hw, hw->vport.vport, true);
592 : : } else {
593 : : struct zxdh_port_promisc_msg *promisc_msg = &msg_info.data.port_promisc_msg;
594 : :
595 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_PROMISC_SET, &msg_info);
596 : :
597 : 0 : promisc_msg->mode = ZXDH_ALLMULTI_MODE;
598 : 0 : promisc_msg->value = true;
599 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
600 [ # # ]: 0 : if (ret) {
601 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
602 : : hw->vport.vport, ZXDH_ALLMULTI_MODE);
603 : 0 : return ret;
604 : : }
605 : : }
606 : 0 : hw->allmulti_status = 1;
607 : : }
608 : 0 : return ret;
609 : : }
610 : :
611 : 0 : int zxdh_dev_allmulticast_disable(struct rte_eth_dev *dev)
612 : : {
613 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
614 : : int16_t ret = 0;
615 : 0 : struct zxdh_msg_info msg_info = {0};
616 : :
617 [ # # ]: 0 : if (hw->allmulti_status == 1) {
618 [ # # ]: 0 : if (hw->is_pf) {
619 [ # # ]: 0 : if (hw->promisc_status == 1)
620 : 0 : goto end;
621 : 0 : ret = zxdh_dev_multicast_table_set(hw, hw->vport.vport, false);
622 : : } else {
623 : : struct zxdh_port_promisc_msg *promisc_msg = &msg_info.data.port_promisc_msg;
624 : :
625 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_PROMISC_SET, &msg_info);
626 [ # # ]: 0 : if (hw->promisc_status == 1)
627 : 0 : goto end;
628 : 0 : promisc_msg->mode = ZXDH_ALLMULTI_MODE;
629 : 0 : promisc_msg->value = false;
630 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
631 [ # # ]: 0 : if (ret) {
632 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
633 : : hw->vport.vport, ZXDH_ALLMULTI_MODE);
634 : 0 : return ret;
635 : : }
636 : : }
637 : 0 : hw->allmulti_status = 0;
638 : : }
639 : 0 : return ret;
640 : 0 : end:
641 : 0 : hw->allmulti_status = 0;
642 : 0 : return ret;
643 : : }
644 : :
645 : : int
646 : 0 : zxdh_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
647 : : {
648 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
649 : : uint16_t idx = 0;
650 : : uint16_t bit_idx = 0;
651 : : uint8_t msg_type = 0;
652 : : int ret = 0;
653 : :
654 : 0 : vlan_id &= RTE_VLAN_ID_MASK;
655 [ # # ]: 0 : if (vlan_id == 0 || vlan_id == RTE_ETHER_MAX_VLAN_ID) {
656 : 0 : PMD_DRV_LOG(ERR, "vlan id (%d) is reserved", vlan_id);
657 : 0 : return -EINVAL;
658 : : }
659 : :
660 [ # # ]: 0 : if (dev->data->dev_started == 0) {
661 : 0 : PMD_DRV_LOG(ERR, "vlan_filter dev not start");
662 : 0 : return -1;
663 : : }
664 : :
665 : 0 : idx = vlan_id / ZXDH_VLAN_FILTER_GROUPS;
666 : 0 : bit_idx = vlan_id % ZXDH_VLAN_FILTER_GROUPS;
667 : :
668 [ # # ]: 0 : if (on) {
669 [ # # ]: 0 : if (dev->data->vlan_filter_conf.ids[idx] & (1ULL << bit_idx)) {
670 : 0 : PMD_DRV_LOG(ERR, "vlan:%d has already added", vlan_id);
671 : 0 : return 0;
672 : : }
673 : : msg_type = ZXDH_VLAN_FILTER_ADD;
674 : : } else {
675 [ # # ]: 0 : if (!(dev->data->vlan_filter_conf.ids[idx] & (1ULL << bit_idx))) {
676 : 0 : PMD_DRV_LOG(ERR, "vlan:%d has already deleted", vlan_id);
677 : 0 : return 0;
678 : : }
679 : : msg_type = ZXDH_VLAN_FILTER_DEL;
680 : : }
681 : :
682 [ # # ]: 0 : if (hw->is_pf) {
683 : 0 : ret = zxdh_vlan_filter_table_set(hw->vport.vport, vlan_id, on);
684 [ # # ]: 0 : if (ret) {
685 : 0 : PMD_DRV_LOG(ERR, "vlan_id:%d table set failed", vlan_id);
686 : 0 : return -1;
687 : : }
688 : : } else {
689 : 0 : struct zxdh_msg_info msg = {0};
690 : 0 : zxdh_msg_head_build(hw, msg_type, &msg);
691 : 0 : msg.data.vlan_filter_msg.vlan_id = vlan_id;
692 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info), NULL, 0);
693 [ # # ]: 0 : if (ret) {
694 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
695 : : hw->vport.vport, msg_type);
696 : 0 : return ret;
697 : : }
698 : : }
699 : :
700 [ # # ]: 0 : if (on)
701 : 0 : dev->data->vlan_filter_conf.ids[idx] |= (1ULL << bit_idx);
702 : : else
703 : 0 : dev->data->vlan_filter_conf.ids[idx] &= ~(1ULL << bit_idx);
704 : :
705 : : return 0;
706 : : }
707 : :
708 : : int
709 : 0 : zxdh_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
710 : : {
711 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
712 : : struct rte_eth_rxmode *rxmode;
713 : 0 : struct zxdh_msg_info msg = {0};
714 : 0 : struct zxdh_port_attr_table port_attr = {0};
715 : : int ret = 0;
716 : :
717 : : rxmode = &dev->data->dev_conf.rxmode;
718 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
719 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) {
720 [ # # ]: 0 : if (hw->is_pf) {
721 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
722 : 0 : port_attr.vlan_filter_enable = true;
723 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
724 [ # # ]: 0 : if (ret) {
725 : 0 : PMD_DRV_LOG(ERR, "port %d vlan filter set failed",
726 : : hw->vport.vfid);
727 : 0 : return -EAGAIN;
728 : : }
729 : : } else {
730 : 0 : msg.data.vlan_filter_set_msg.enable = true;
731 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_FILTER_SET, &msg);
732 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
733 : : sizeof(struct zxdh_msg_info), NULL, 0);
734 [ # # ]: 0 : if (ret) {
735 : 0 : PMD_DRV_LOG(ERR, "port %d vlan filter set failed",
736 : : hw->vport.vfid);
737 : 0 : return -EAGAIN;
738 : : }
739 : : }
740 : : } else {
741 [ # # ]: 0 : if (hw->is_pf) {
742 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
743 : 0 : port_attr.vlan_filter_enable = false;
744 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
745 [ # # ]: 0 : if (ret) {
746 : 0 : PMD_DRV_LOG(ERR, "port %d vlan filter set failed",
747 : : hw->vport.vfid);
748 : 0 : return -EAGAIN;
749 : : }
750 : : } else {
751 : 0 : msg.data.vlan_filter_set_msg.enable = true;
752 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_FILTER_SET, &msg);
753 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
754 : : sizeof(struct zxdh_msg_info), NULL, 0);
755 [ # # ]: 0 : if (ret) {
756 : 0 : PMD_DRV_LOG(ERR, "port %d vlan filter set failed",
757 : : hw->vport.vfid);
758 : 0 : return -EAGAIN;
759 : : }
760 : : }
761 : : }
762 : : }
763 : :
764 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
765 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
766 [ # # ]: 0 : if (hw->is_pf) {
767 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
768 : 0 : port_attr.vlan_strip_offload = true;
769 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
770 [ # # ]: 0 : if (ret) {
771 : 0 : PMD_DRV_LOG(ERR, "port %d vlan strip set failed",
772 : : hw->vport.vfid);
773 : 0 : return -EAGAIN;
774 : : }
775 : : } else {
776 : 0 : msg.data.vlan_offload_msg.enable = true;
777 : 0 : msg.data.vlan_offload_msg.type = ZXDH_VLAN_STRIP_MSG_TYPE;
778 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_OFFLOAD, &msg);
779 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
780 : : sizeof(struct zxdh_msg_info), NULL, 0);
781 [ # # ]: 0 : if (ret) {
782 : 0 : PMD_DRV_LOG(ERR, "port %d vlan strip set failed",
783 : : hw->vport.vfid);
784 : 0 : return -EAGAIN;
785 : : }
786 : : }
787 : : } else {
788 [ # # ]: 0 : if (hw->is_pf) {
789 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
790 : 0 : port_attr.vlan_strip_offload = false;
791 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
792 [ # # ]: 0 : if (ret) {
793 : 0 : PMD_DRV_LOG(ERR, "port %d vlan strip set failed",
794 : : hw->vport.vfid);
795 : 0 : return -EAGAIN;
796 : : }
797 : : } else {
798 : 0 : msg.data.vlan_offload_msg.enable = false;
799 : 0 : msg.data.vlan_offload_msg.type = ZXDH_VLAN_STRIP_MSG_TYPE;
800 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_OFFLOAD, &msg);
801 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
802 : : sizeof(struct zxdh_msg_info), NULL, 0);
803 [ # # ]: 0 : if (ret) {
804 : 0 : PMD_DRV_LOG(ERR, "port %d vlan strip set failed",
805 : : hw->vport.vfid);
806 : 0 : return -EAGAIN;
807 : : }
808 : : }
809 : : }
810 : : }
811 : :
812 [ # # ]: 0 : if (mask & RTE_ETH_QINQ_STRIP_MASK) {
813 : : memset(&msg, 0, sizeof(struct zxdh_msg_info));
814 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) {
815 [ # # ]: 0 : if (hw->is_pf) {
816 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
817 : 0 : port_attr.qinq_strip_offload = true;
818 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
819 [ # # ]: 0 : if (ret) {
820 : 0 : PMD_DRV_LOG(ERR, "port %d qinq offload set failed",
821 : : hw->vport.vfid);
822 : 0 : return -EAGAIN;
823 : : }
824 : : } else {
825 : 0 : msg.data.vlan_offload_msg.enable = true;
826 : 0 : msg.data.vlan_offload_msg.type = ZXDH_QINQ_STRIP_MSG_TYPE;
827 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_OFFLOAD, &msg);
828 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
829 : : sizeof(struct zxdh_msg_info), NULL, 0);
830 [ # # ]: 0 : if (ret) {
831 : 0 : PMD_DRV_LOG(ERR, "port %d qinq offload set failed",
832 : : hw->vport.vfid);
833 : 0 : return -EAGAIN;
834 : : }
835 : : }
836 : : } else {
837 [ # # ]: 0 : if (hw->is_pf) {
838 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
839 : 0 : port_attr.qinq_strip_offload = true;
840 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
841 [ # # ]: 0 : if (ret) {
842 : 0 : PMD_DRV_LOG(ERR, "port %d qinq offload set failed",
843 : : hw->vport.vfid);
844 : 0 : return -EAGAIN;
845 : : }
846 : : } else {
847 : : msg.data.vlan_offload_msg.enable = false;
848 : 0 : msg.data.vlan_offload_msg.type = ZXDH_QINQ_STRIP_MSG_TYPE;
849 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_OFFLOAD, &msg);
850 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
851 : : sizeof(struct zxdh_msg_info), NULL, 0);
852 [ # # ]: 0 : if (ret) {
853 : 0 : PMD_DRV_LOG(ERR, "port %d qinq offload set failed",
854 : : hw->vport.vfid);
855 : 0 : return -EAGAIN;
856 : : }
857 : : }
858 : : }
859 : : }
860 : :
861 : : return ret;
862 : : }
863 : :
864 : : int
865 : 0 : zxdh_dev_rss_reta_update(struct rte_eth_dev *dev,
866 : : struct rte_eth_rss_reta_entry64 *reta_conf,
867 : : uint16_t reta_size)
868 : : {
869 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
870 : 0 : struct zxdh_msg_info msg = {0};
871 : : uint16_t old_reta[RTE_ETH_RSS_RETA_SIZE_256];
872 : : uint16_t idx;
873 : : uint16_t i;
874 : : uint16_t pos;
875 : : int ret;
876 : :
877 [ # # ]: 0 : if (reta_size != RTE_ETH_RSS_RETA_SIZE_256) {
878 : 0 : PMD_DRV_LOG(ERR, "reta_size is illegal(%u).reta_size should be 256", reta_size);
879 : 0 : return -EINVAL;
880 : : }
881 [ # # ]: 0 : if (!hw->rss_reta) {
882 : 0 : hw->rss_reta = rte_calloc(NULL, RTE_ETH_RSS_RETA_SIZE_256, sizeof(uint16_t), 0);
883 [ # # ]: 0 : if (hw->rss_reta == NULL) {
884 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate RSS reta");
885 : 0 : return -ENOMEM;
886 : : }
887 : : }
888 [ # # ]: 0 : for (idx = 0, i = 0; (i < reta_size); ++i) {
889 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
890 : 0 : pos = i % RTE_ETH_RETA_GROUP_SIZE;
891 [ # # ]: 0 : if (((reta_conf[idx].mask >> pos) & 0x1) == 0)
892 : 0 : continue;
893 [ # # ]: 0 : if (reta_conf[idx].reta[pos] > dev->data->nb_rx_queues) {
894 : 0 : PMD_DRV_LOG(ERR, "reta table value err(%u >= %u)",
895 : : reta_conf[idx].reta[pos], dev->data->nb_rx_queues);
896 : 0 : return -EINVAL;
897 : : }
898 [ # # ]: 0 : if (hw->rss_reta[i] != reta_conf[idx].reta[pos])
899 : : break;
900 : : }
901 [ # # ]: 0 : if (i == reta_size) {
902 : 0 : PMD_DRV_LOG(INFO, "reta table same with buffered table");
903 : 0 : return 0;
904 : : }
905 : 0 : memcpy(old_reta, hw->rss_reta, sizeof(old_reta));
906 : :
907 [ # # ]: 0 : for (idx = 0, i = 0; i < reta_size; ++i) {
908 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
909 : 0 : pos = i % RTE_ETH_RETA_GROUP_SIZE;
910 [ # # ]: 0 : if (((reta_conf[idx].mask >> pos) & 0x1) == 0)
911 : 0 : continue;
912 : 0 : hw->rss_reta[i] = reta_conf[idx].reta[pos];
913 : : }
914 : :
915 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_RETA_SET, &msg);
916 [ # # ]: 0 : for (i = 0; i < reta_size; i++)
917 : 0 : msg.data.rss_reta.reta[i] =
918 : 0 : (hw->channel_context[hw->rss_reta[i] * 2].ph_chno);
919 : :
920 [ # # ]: 0 : if (hw->is_pf) {
921 : 0 : ret = zxdh_rss_table_set(hw->vport.vport, &msg.data.rss_reta);
922 [ # # ]: 0 : if (ret) {
923 : 0 : PMD_DRV_LOG(ERR, "rss reta table set failed");
924 : 0 : return -EINVAL;
925 : : }
926 : : } else {
927 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info), NULL, 0);
928 [ # # ]: 0 : if (ret) {
929 : 0 : PMD_DRV_LOG(ERR, "vf rss reta table set failed");
930 : 0 : return -EINVAL;
931 : : }
932 : : }
933 : : return ret;
934 : : }
935 : :
936 : : static uint16_t
937 : : zxdh_hw_qid_to_logic_qid(struct rte_eth_dev *dev, uint16_t qid)
938 : : {
939 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
940 : 0 : uint16_t rx_queues = dev->data->nb_rx_queues;
941 : : uint16_t i;
942 : :
943 [ # # ]: 0 : for (i = 0; i < rx_queues; i++) {
944 [ # # ]: 0 : if (qid == hw->channel_context[i * 2].ph_chno)
945 : : return i;
946 : : }
947 : : return ZXDH_INVALID_LOGIC_QID;
948 : : }
949 : :
950 : : int
951 : 0 : zxdh_dev_rss_reta_query(struct rte_eth_dev *dev,
952 : : struct rte_eth_rss_reta_entry64 *reta_conf,
953 : : uint16_t reta_size)
954 : : {
955 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
956 : 0 : struct zxdh_msg_info msg = {0};
957 : 0 : struct zxdh_msg_reply_info reply_msg = {0};
958 : : uint16_t idx;
959 : : uint16_t i;
960 : : int ret = 0;
961 : : uint16_t qid_logic;
962 : :
963 : 0 : ret = (!reta_size || reta_size > RTE_ETH_RSS_RETA_SIZE_256);
964 [ # # ]: 0 : if (ret) {
965 : 0 : PMD_DRV_LOG(ERR, "request reta size(%u) not same with buffered(%u)",
966 : : reta_size, RTE_ETH_RSS_RETA_SIZE_256);
967 : 0 : return -EINVAL;
968 : : }
969 : :
970 : : /* Fill each entry of the table even if its bit is not set. */
971 [ # # ]: 0 : for (idx = 0, i = 0; (i != reta_size); ++i) {
972 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
973 : 0 : reta_conf[idx].reta[i % RTE_ETH_RETA_GROUP_SIZE] = hw->rss_reta[i];
974 : : }
975 : :
976 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_RETA_GET, &msg);
977 : :
978 [ # # ]: 0 : if (hw->is_pf) {
979 : 0 : ret = zxdh_rss_table_get(hw->vport.vport, &reply_msg.reply_body.rss_reta);
980 [ # # ]: 0 : if (ret) {
981 : 0 : PMD_DRV_LOG(ERR, "rss reta table set failed");
982 : 0 : return -EINVAL;
983 : : }
984 : : } else {
985 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info),
986 : : &reply_msg, sizeof(struct zxdh_msg_reply_info));
987 [ # # ]: 0 : if (ret) {
988 : 0 : PMD_DRV_LOG(ERR, "vf rss reta table get failed");
989 : 0 : return -EINVAL;
990 : : }
991 : : }
992 : :
993 : : struct zxdh_rss_reta *reta_table = &reply_msg.reply_body.rss_reta;
994 : :
995 [ # # ]: 0 : for (idx = 0, i = 0; i < reta_size; ++i) {
996 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
997 : :
998 : 0 : qid_logic = zxdh_hw_qid_to_logic_qid(dev, reta_table->reta[i]);
999 [ # # ]: 0 : if (qid_logic == ZXDH_INVALID_LOGIC_QID) {
1000 : 0 : PMD_DRV_LOG(ERR, "rsp phy reta qid (%u) is illegal(%u)",
1001 : : reta_table->reta[i], qid_logic);
1002 : 0 : return -EINVAL;
1003 : : }
1004 : 0 : reta_conf[idx].reta[i % RTE_ETH_RETA_GROUP_SIZE] = qid_logic;
1005 : : }
1006 : : return 0;
1007 : : }
1008 : :
1009 : : static uint32_t
1010 : : zxdh_rss_hf_to_hw(uint64_t hf)
1011 : : {
1012 : : uint32_t hw_hf = 0;
1013 : :
1014 [ # # ]: 0 : if (hf & ZXDH_HF_MAC_VLAN_ETH)
1015 : : hw_hf |= ZXDH_HF_MAC_VLAN;
1016 [ # # # # : 0 : if (hf & ZXDH_HF_F3_ETH)
# # ]
1017 : 0 : hw_hf |= ZXDH_HF_F3;
1018 [ # # # # : 0 : if (hf & ZXDH_HF_F5_ETH)
# # ]
1019 : 0 : hw_hf |= ZXDH_HF_F5;
1020 : :
1021 [ # # # # : 0 : if (hw_hf == (ZXDH_HF_MAC_VLAN | ZXDH_HF_F3 | ZXDH_HF_F5))
# # ]
1022 : : hw_hf = ZXDH_HF_ALL;
1023 : : return hw_hf;
1024 : : }
1025 : :
1026 : : static uint64_t
1027 : : zxdh_rss_hf_to_eth(uint32_t hw_hf)
1028 : : {
1029 : : uint64_t hf = 0;
1030 : :
1031 [ # # ]: 0 : if (hw_hf == ZXDH_HF_ALL)
1032 : : return (ZXDH_HF_MAC_VLAN_ETH | ZXDH_HF_F3_ETH | ZXDH_HF_F5_ETH);
1033 : :
1034 [ # # # # ]: 0 : if (hw_hf & ZXDH_HF_MAC_VLAN)
1035 : : hf |= ZXDH_HF_MAC_VLAN_ETH;
1036 [ # # # # ]: 0 : if (hw_hf & ZXDH_HF_F3)
1037 : 0 : hf |= ZXDH_HF_F3_ETH;
1038 [ # # # # ]: 0 : if (hw_hf & ZXDH_HF_F5)
1039 : 0 : hf |= ZXDH_HF_F5_ETH;
1040 : :
1041 : : return hf;
1042 : : }
1043 : :
1044 : : int
1045 : 0 : zxdh_rss_hash_update(struct rte_eth_dev *dev,
1046 : : struct rte_eth_rss_conf *rss_conf)
1047 : : {
1048 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1049 : : struct rte_eth_rss_conf *old_rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
1050 : 0 : struct zxdh_msg_info msg = {0};
1051 : 0 : struct zxdh_port_attr_table port_attr = {0};
1052 : : uint32_t hw_hf_new, hw_hf_old;
1053 : : int need_update_hf = 0;
1054 : : int ret = 0;
1055 : :
1056 : 0 : ret = rss_conf->rss_hf & ZXDH_RSS_HF_MASK;
1057 [ # # ]: 0 : if (ret) {
1058 : 0 : PMD_DRV_LOG(ERR, "Not support some hash function (%08lx)", rss_conf->rss_hf);
1059 : 0 : return -EINVAL;
1060 : : }
1061 : :
1062 : : hw_hf_new = zxdh_rss_hf_to_hw(rss_conf->rss_hf);
1063 [ # # ]: 0 : hw_hf_old = zxdh_rss_hf_to_hw(old_rss_conf->rss_hf);
1064 : :
1065 [ # # # # ]: 0 : if ((hw_hf_new != hw_hf_old || !!rss_conf->rss_hf))
1066 : : need_update_hf = 1;
1067 : :
1068 : : if (need_update_hf) {
1069 [ # # ]: 0 : if (hw->is_pf) {
1070 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
1071 : 0 : port_attr.rss_enable = !!rss_conf->rss_hf;
1072 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
1073 [ # # ]: 0 : if (ret) {
1074 : 0 : PMD_DRV_LOG(ERR, "rss enable set failed");
1075 : 0 : return -EINVAL;
1076 : : }
1077 : : } else {
1078 : 0 : msg.data.rss_enable.enable = !!rss_conf->rss_hf;
1079 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_ENABLE, &msg);
1080 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg,
1081 : : sizeof(struct zxdh_msg_info), NULL, 0);
1082 [ # # ]: 0 : if (ret) {
1083 : 0 : PMD_DRV_LOG(ERR, "rss enable set failed");
1084 : 0 : return -EINVAL;
1085 : : }
1086 : : }
1087 [ # # ]: 0 : if (hw->is_pf) {
1088 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
1089 : 0 : port_attr.rss_hash_factor = hw_hf_new;
1090 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
1091 [ # # ]: 0 : if (ret) {
1092 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1093 : 0 : return -EINVAL;
1094 : : }
1095 : : } else {
1096 : 0 : msg.data.rss_hf.rss_hf = hw_hf_new;
1097 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_HF_SET, &msg);
1098 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg,
1099 : : sizeof(struct zxdh_msg_info), NULL, 0);
1100 [ # # ]: 0 : if (ret) {
1101 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1102 : 0 : return -EINVAL;
1103 : : }
1104 : : }
1105 : 0 : old_rss_conf->rss_hf = rss_conf->rss_hf;
1106 : : }
1107 : :
1108 : : return 0;
1109 : : }
1110 : :
1111 : : int
1112 : 0 : zxdh_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf)
1113 : : {
1114 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
1115 : : struct rte_eth_rss_conf *old_rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
1116 : 0 : struct zxdh_msg_info msg = {0};
1117 : 0 : struct zxdh_msg_reply_info reply_msg = {0};
1118 : 0 : struct zxdh_port_attr_table port_attr = {0};
1119 : : int ret;
1120 : : uint32_t hw_hf;
1121 : :
1122 [ # # ]: 0 : if (rss_conf == NULL) {
1123 : 0 : PMD_DRV_LOG(ERR, "rss conf is NULL");
1124 : 0 : return -ENOMEM;
1125 : : }
1126 : :
1127 [ # # ]: 0 : hw_hf = zxdh_rss_hf_to_hw(old_rss_conf->rss_hf);
1128 : 0 : rss_conf->rss_hf = zxdh_rss_hf_to_eth(hw_hf);
1129 : :
1130 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_HF_GET, &msg);
1131 [ # # ]: 0 : if (hw->is_pf) {
1132 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
1133 [ # # ]: 0 : if (ret) {
1134 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1135 : 0 : return -EINVAL;
1136 : : }
1137 : 0 : reply_msg.reply_body.rss_hf.rss_hf = port_attr.rss_hash_factor;
1138 : : } else {
1139 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_HF_SET, &msg);
1140 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info),
1141 : : &reply_msg, sizeof(struct zxdh_msg_reply_info));
1142 [ # # ]: 0 : if (ret) {
1143 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1144 : 0 : return -EINVAL;
1145 : : }
1146 : : }
1147 [ # # ]: 0 : rss_conf->rss_hf = zxdh_rss_hf_to_eth(reply_msg.reply_body.rss_hf.rss_hf);
1148 : :
1149 : 0 : return 0;
1150 : : }
1151 : :
1152 : : static int
1153 : : zxdh_get_rss_enable_conf(struct rte_eth_dev *dev)
1154 : : {
1155 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode == RTE_ETH_MQ_RX_RSS)
1156 : 0 : return dev->data->nb_rx_queues == 1 ? 0 : 1;
1157 : : else if (dev->data->dev_conf.rxmode.mq_mode == RTE_ETH_MQ_RX_NONE)
1158 : : return 0;
1159 : :
1160 : : return 0;
1161 : : }
1162 : :
1163 : : int
1164 : 0 : zxdh_rss_configure(struct rte_eth_dev *dev)
1165 : : {
1166 : 0 : struct rte_eth_dev_data *dev_data = dev->data;
1167 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
1168 : 0 : struct zxdh_port_attr_table port_attr = {0};
1169 : 0 : struct zxdh_msg_info msg = {0};
1170 : : int ret = 0;
1171 : : uint32_t hw_hf;
1172 : : uint32_t i;
1173 : :
1174 [ # # ]: 0 : if (dev->data->nb_rx_queues == 0) {
1175 : 0 : PMD_DRV_LOG(ERR, "port %u nb_rx_queues is 0", dev->data->port_id);
1176 : 0 : return -1;
1177 : : }
1178 : :
1179 : : /* config rss enable */
1180 : 0 : uint8_t curr_rss_enable = zxdh_get_rss_enable_conf(dev);
1181 : :
1182 [ # # ]: 0 : if (hw->rss_enable != curr_rss_enable) {
1183 [ # # ]: 0 : if (hw->is_pf) {
1184 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
1185 : 0 : port_attr.rss_enable = curr_rss_enable;
1186 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
1187 [ # # ]: 0 : if (ret) {
1188 : 0 : PMD_DRV_LOG(ERR, "rss enable set failed");
1189 : 0 : return -EINVAL;
1190 : : }
1191 : : } else {
1192 : 0 : msg.data.rss_enable.enable = curr_rss_enable;
1193 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_ENABLE, &msg);
1194 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg,
1195 : : sizeof(struct zxdh_msg_info), NULL, 0);
1196 [ # # ]: 0 : if (ret) {
1197 : 0 : PMD_DRV_LOG(ERR, "rss enable set failed");
1198 : 0 : return -EINVAL;
1199 : : }
1200 : : }
1201 : 0 : hw->rss_enable = curr_rss_enable;
1202 : : }
1203 : :
1204 [ # # # # ]: 0 : if (curr_rss_enable && hw->rss_init == 0) {
1205 : : /* config hash factor */
1206 [ # # ]: 0 : dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = ZXDH_HF_F5_ETH;
1207 : : hw_hf = zxdh_rss_hf_to_hw(dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf);
1208 : : memset(&msg, 0, sizeof(msg));
1209 [ # # ]: 0 : if (hw->is_pf) {
1210 : 0 : ret = zxdh_get_port_attr(hw->vport.vfid, &port_attr);
1211 : 0 : port_attr.rss_hash_factor = hw_hf;
1212 : 0 : ret = zxdh_set_port_attr(hw->vport.vfid, &port_attr);
1213 [ # # ]: 0 : if (ret) {
1214 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1215 : 0 : return -EINVAL;
1216 : : }
1217 : : } else {
1218 : 0 : msg.data.rss_hf.rss_hf = hw_hf;
1219 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_HF_SET, &msg);
1220 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg,
1221 : : sizeof(struct zxdh_msg_info), NULL, 0);
1222 [ # # ]: 0 : if (ret) {
1223 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1224 : 0 : return -EINVAL;
1225 : : }
1226 : : }
1227 : 0 : hw->rss_init = 1;
1228 : : }
1229 : :
1230 [ # # ]: 0 : if (!hw->rss_reta) {
1231 : 0 : hw->rss_reta = rte_calloc(NULL, RTE_ETH_RSS_RETA_SIZE_256, sizeof(uint16_t), 0);
1232 [ # # ]: 0 : if (hw->rss_reta == NULL) {
1233 : 0 : PMD_DRV_LOG(ERR, "alloc memory fail");
1234 : 0 : return -1;
1235 : : }
1236 : : }
1237 [ # # ]: 0 : for (i = 0; i < RTE_ETH_RSS_RETA_SIZE_256; i++)
1238 : 0 : hw->rss_reta[i] = i % dev_data->nb_rx_queues;
1239 : :
1240 : : /* hw config reta */
1241 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_RETA_SET, &msg);
1242 [ # # ]: 0 : for (i = 0; i < RTE_ETH_RSS_RETA_SIZE_256; i++)
1243 : 0 : msg.data.rss_reta.reta[i] =
1244 : 0 : hw->channel_context[hw->rss_reta[i] * 2].ph_chno;
1245 : :
1246 [ # # ]: 0 : if (hw->is_pf) {
1247 : 0 : ret = zxdh_rss_table_set(hw->vport.vport, &msg.data.rss_reta);
1248 [ # # ]: 0 : if (ret) {
1249 : 0 : PMD_DRV_LOG(ERR, "rss reta table set failed");
1250 : 0 : return -EINVAL;
1251 : : }
1252 : : } else {
1253 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info), NULL, 0);
1254 [ # # ]: 0 : if (ret) {
1255 : 0 : PMD_DRV_LOG(ERR, "vf rss reta table set failed");
1256 : 0 : return -EINVAL;
1257 : : }
1258 : : }
1259 : : return 0;
1260 : : }
1261 : :
1262 : : static int32_t
1263 : 0 : zxdh_hw_vqm_stats_get(struct rte_eth_dev *dev, enum zxdh_agent_msg_type opcode,
1264 : : struct zxdh_hw_vqm_stats *hw_stats)
1265 : : {
1266 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1267 : 0 : struct zxdh_msg_info msg_info = {0};
1268 : 0 : struct zxdh_msg_reply_info reply_info = {0};
1269 : : enum ZXDH_BAR_MODULE_ID module_id;
1270 : : int ret = 0;
1271 : :
1272 [ # # # ]: 0 : switch (opcode) {
1273 : : case ZXDH_VQM_DEV_STATS_GET:
1274 : : case ZXDH_VQM_QUEUE_STATS_GET:
1275 : : case ZXDH_VQM_QUEUE_STATS_RESET:
1276 : : module_id = ZXDH_BAR_MODULE_VQM;
1277 : : break;
1278 : 0 : case ZXDH_MAC_STATS_GET:
1279 : : case ZXDH_MAC_STATS_RESET:
1280 : : module_id = ZXDH_BAR_MODULE_MAC;
1281 : 0 : break;
1282 : 0 : default:
1283 : 0 : PMD_DRV_LOG(ERR, "invalid opcode %u", opcode);
1284 : 0 : return -1;
1285 : : }
1286 : :
1287 : 0 : zxdh_agent_msg_build(hw, opcode, &msg_info);
1288 : :
1289 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
1290 : : &reply_info, sizeof(struct zxdh_msg_reply_info), module_id);
1291 [ # # ]: 0 : if (ret) {
1292 : 0 : PMD_DRV_LOG(ERR, "Failed to get hw stats");
1293 : 0 : return -1;
1294 : : }
1295 : : struct zxdh_msg_reply_body *reply_body = &reply_info.reply_body;
1296 : :
1297 : : rte_memcpy(hw_stats, &reply_body->vqm_stats, sizeof(struct zxdh_hw_vqm_stats));
1298 : : return 0;
1299 : : }
1300 : :
1301 : 0 : static int zxdh_hw_mac_stats_get(struct rte_eth_dev *dev,
1302 : : struct zxdh_hw_mac_stats *mac_stats,
1303 : : struct zxdh_hw_mac_bytes *mac_bytes)
1304 : : {
1305 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1306 : 0 : uint64_t virt_addr = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] + ZXDH_MAC_OFFSET);
1307 : : uint64_t stats_addr = 0;
1308 : : uint64_t bytes_addr = 0;
1309 : :
1310 [ # # ]: 0 : if (hw->speed <= RTE_ETH_SPEED_NUM_25G) {
1311 : 0 : stats_addr = virt_addr + ZXDH_MAC_STATS_OFFSET + 352 * (hw->phyport % 4);
1312 : 0 : bytes_addr = virt_addr + ZXDH_MAC_BYTES_OFFSET + 32 * (hw->phyport % 4);
1313 : : } else {
1314 : 0 : stats_addr = virt_addr + ZXDH_MAC_STATS_OFFSET + 352 * 4;
1315 : 0 : bytes_addr = virt_addr + ZXDH_MAC_BYTES_OFFSET + 32 * 4;
1316 : : }
1317 : :
1318 [ # # ]: 0 : rte_memcpy(mac_stats, (void *)stats_addr, sizeof(struct zxdh_hw_mac_stats));
1319 [ # # ]: 0 : rte_memcpy(mac_bytes, (void *)bytes_addr, sizeof(struct zxdh_hw_mac_bytes));
1320 : 0 : return 0;
1321 : : }
1322 : :
1323 : : static void zxdh_data_hi_to_lo(uint64_t *data)
1324 : : {
1325 : : uint32_t n_data_hi;
1326 : : uint32_t n_data_lo;
1327 : :
1328 : 0 : n_data_lo = *data >> 32;
1329 : : n_data_hi = *data;
1330 : 0 : *data = (uint64_t)(rte_le_to_cpu_32(n_data_hi)) << 32 |
1331 : : rte_le_to_cpu_32(n_data_lo);
1332 : : }
1333 : :
1334 : 0 : static int zxdh_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *np_stats)
1335 : : {
1336 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1337 : : struct zxdh_np_stats_data stats_data;
1338 : 0 : uint32_t stats_id = zxdh_vport_to_vfid(hw->vport);
1339 : : uint32_t idx = 0;
1340 : : int ret = 0;
1341 : :
1342 : 0 : idx = stats_id + ZXDH_BROAD_STATS_EGRESS_BASE;
1343 : 0 : ret = zxdh_np_dtb_stats_get(ZXDH_DEVICE_NO, g_dtb_data.queueid,
1344 : 0 : 0, idx, (uint32_t *)&np_stats->np_tx_broadcast);
1345 [ # # ]: 0 : if (ret)
1346 : : return ret;
1347 : : zxdh_data_hi_to_lo(&np_stats->np_tx_broadcast);
1348 : :
1349 : 0 : idx = stats_id + ZXDH_BROAD_STATS_INGRESS_BASE;
1350 : : memset(&stats_data, 0, sizeof(stats_data));
1351 : 0 : ret = zxdh_np_dtb_stats_get(ZXDH_DEVICE_NO, g_dtb_data.queueid,
1352 : 0 : 0, idx, (uint32_t *)&np_stats->np_rx_broadcast);
1353 [ # # ]: 0 : if (ret)
1354 : : return ret;
1355 : : zxdh_data_hi_to_lo(&np_stats->np_rx_broadcast);
1356 : :
1357 : 0 : idx = stats_id + ZXDH_MTU_STATS_EGRESS_BASE;
1358 : : memset(&stats_data, 0, sizeof(stats_data));
1359 : 0 : ret = zxdh_np_dtb_stats_get(ZXDH_DEVICE_NO, g_dtb_data.queueid,
1360 : : 1, idx, (uint32_t *)&stats_data);
1361 [ # # ]: 0 : if (ret)
1362 : : return ret;
1363 : :
1364 : 0 : np_stats->np_tx_mtu_drop_pkts = stats_data.n_pkts_dropped;
1365 : 0 : np_stats->np_tx_mtu_drop_bytes = stats_data.n_bytes_dropped;
1366 : : zxdh_data_hi_to_lo(&np_stats->np_tx_mtu_drop_pkts);
1367 : : zxdh_data_hi_to_lo(&np_stats->np_tx_mtu_drop_bytes);
1368 : :
1369 : 0 : idx = stats_id + ZXDH_MTU_STATS_INGRESS_BASE;
1370 : : memset(&stats_data, 0, sizeof(stats_data));
1371 : 0 : ret = zxdh_np_dtb_stats_get(ZXDH_DEVICE_NO, g_dtb_data.queueid,
1372 : : 1, idx, (uint32_t *)&stats_data);
1373 [ # # ]: 0 : if (ret)
1374 : : return ret;
1375 : 0 : np_stats->np_rx_mtu_drop_pkts = stats_data.n_pkts_dropped;
1376 : 0 : np_stats->np_rx_mtu_drop_bytes = stats_data.n_bytes_dropped;
1377 : : zxdh_data_hi_to_lo(&np_stats->np_rx_mtu_drop_pkts);
1378 : : zxdh_data_hi_to_lo(&np_stats->np_rx_mtu_drop_bytes);
1379 : :
1380 : 0 : return 0;
1381 : : }
1382 : :
1383 : : static int
1384 : 0 : zxdh_hw_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *np_stats)
1385 : : {
1386 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1387 : 0 : struct zxdh_msg_info msg_info = {0};
1388 : 0 : struct zxdh_msg_reply_info reply_info = {0};
1389 : : int ret = 0;
1390 : :
1391 [ # # ]: 0 : if (hw->is_pf) {
1392 : 0 : ret = zxdh_np_stats_get(dev, np_stats);
1393 [ # # ]: 0 : if (ret) {
1394 : 0 : PMD_DRV_LOG(ERR, "get np stats failed");
1395 : 0 : return -1;
1396 : : }
1397 : : } else {
1398 : 0 : zxdh_msg_head_build(hw, ZXDH_GET_NP_STATS, &msg_info);
1399 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(struct zxdh_msg_info),
1400 : : &reply_info, sizeof(struct zxdh_msg_reply_info));
1401 [ # # ]: 0 : if (ret) {
1402 : 0 : PMD_DRV_LOG(ERR,
1403 : : "%s Failed to send msg: port 0x%x msg type",
1404 : : __func__, hw->vport.vport);
1405 : 0 : return -1;
1406 : : }
1407 : : memcpy(np_stats, &reply_info.reply_body.np_stats, sizeof(struct zxdh_hw_np_stats));
1408 : : }
1409 : : return ret;
1410 : : }
1411 : :
1412 : : int
1413 : 0 : zxdh_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
1414 : : {
1415 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1416 : 0 : struct zxdh_hw_vqm_stats vqm_stats = {0};
1417 : 0 : struct zxdh_hw_np_stats np_stats = {0};
1418 : 0 : struct zxdh_hw_mac_stats mac_stats = {0};
1419 : 0 : struct zxdh_hw_mac_bytes mac_bytes = {0};
1420 : : uint32_t i = 0;
1421 : :
1422 : 0 : zxdh_hw_vqm_stats_get(dev, ZXDH_VQM_DEV_STATS_GET, &vqm_stats);
1423 [ # # ]: 0 : if (hw->is_pf)
1424 : 0 : zxdh_hw_mac_stats_get(dev, &mac_stats, &mac_bytes);
1425 : :
1426 : 0 : zxdh_hw_np_stats_get(dev, &np_stats);
1427 : :
1428 : 0 : stats->ipackets = vqm_stats.rx_total;
1429 : 0 : stats->opackets = vqm_stats.tx_total;
1430 : 0 : stats->ibytes = vqm_stats.rx_bytes;
1431 : 0 : stats->obytes = vqm_stats.tx_bytes;
1432 : 0 : stats->imissed = vqm_stats.rx_drop + mac_stats.rx_drop;
1433 : 0 : stats->ierrors = vqm_stats.rx_error + mac_stats.rx_error + np_stats.np_rx_mtu_drop_pkts;
1434 : 0 : stats->oerrors = vqm_stats.tx_error + mac_stats.tx_error + np_stats.np_tx_mtu_drop_pkts;
1435 : :
1436 : 0 : stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
1437 [ # # # # ]: 0 : for (i = 0; (i < dev->data->nb_rx_queues) && (i < RTE_ETHDEV_QUEUE_STAT_CNTRS); i++) {
1438 : 0 : struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[i];
1439 : :
1440 [ # # ]: 0 : if (rxvq == NULL)
1441 : 0 : continue;
1442 : 0 : stats->q_ipackets[i] = *(uint64_t *)(((char *)rxvq) +
1443 : : zxdh_rxq_stat_strings[0].offset);
1444 : 0 : stats->q_ibytes[i] = *(uint64_t *)(((char *)rxvq) +
1445 : : zxdh_rxq_stat_strings[1].offset);
1446 : 0 : stats->q_errors[i] = *(uint64_t *)(((char *)rxvq) +
1447 : : zxdh_rxq_stat_strings[2].offset);
1448 : 0 : stats->q_errors[i] += *(uint64_t *)(((char *)rxvq) +
1449 : : zxdh_rxq_stat_strings[5].offset);
1450 : : }
1451 : :
1452 [ # # # # ]: 0 : for (i = 0; (i < dev->data->nb_tx_queues) && (i < RTE_ETHDEV_QUEUE_STAT_CNTRS); i++) {
1453 : 0 : struct zxdh_virtnet_tx *txvq = dev->data->tx_queues[i];
1454 : :
1455 [ # # ]: 0 : if (txvq == NULL)
1456 : 0 : continue;
1457 : 0 : stats->q_opackets[i] = *(uint64_t *)(((char *)txvq) +
1458 : : zxdh_txq_stat_strings[0].offset);
1459 : 0 : stats->q_obytes[i] = *(uint64_t *)(((char *)txvq) +
1460 : : zxdh_txq_stat_strings[1].offset);
1461 : 0 : stats->q_errors[i] += *(uint64_t *)(((char *)txvq) +
1462 : : zxdh_txq_stat_strings[2].offset);
1463 : 0 : stats->q_errors[i] += *(uint64_t *)(((char *)txvq) +
1464 : : zxdh_txq_stat_strings[5].offset);
1465 : : }
1466 : 0 : return 0;
1467 : : }
1468 : :
1469 : 0 : static int zxdh_hw_stats_reset(struct rte_eth_dev *dev, enum zxdh_agent_msg_type opcode)
1470 : : {
1471 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1472 : 0 : struct zxdh_msg_info msg_info = {0};
1473 : 0 : struct zxdh_msg_reply_info reply_info = {0};
1474 : : enum ZXDH_BAR_MODULE_ID module_id;
1475 : : int ret = 0;
1476 : :
1477 [ # # # ]: 0 : switch (opcode) {
1478 : : case ZXDH_VQM_DEV_STATS_RESET:
1479 : : module_id = ZXDH_BAR_MODULE_VQM;
1480 : : break;
1481 : 0 : case ZXDH_MAC_STATS_RESET:
1482 : : module_id = ZXDH_BAR_MODULE_MAC;
1483 : 0 : break;
1484 : 0 : default:
1485 : 0 : PMD_DRV_LOG(ERR, "invalid opcode %u", opcode);
1486 : 0 : return -1;
1487 : : }
1488 : :
1489 : 0 : zxdh_agent_msg_build(hw, opcode, &msg_info);
1490 : :
1491 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
1492 : : &reply_info, sizeof(struct zxdh_msg_reply_info), module_id);
1493 [ # # ]: 0 : if (ret) {
1494 : 0 : PMD_DRV_LOG(ERR, "Failed to reset hw stats");
1495 : 0 : return -1;
1496 : : }
1497 : : return 0;
1498 : : }
1499 : :
1500 : 0 : int zxdh_dev_stats_reset(struct rte_eth_dev *dev)
1501 : : {
1502 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1503 : :
1504 : 0 : zxdh_hw_stats_reset(dev, ZXDH_VQM_DEV_STATS_RESET);
1505 [ # # ]: 0 : if (hw->is_pf)
1506 : 0 : zxdh_hw_stats_reset(dev, ZXDH_MAC_STATS_RESET);
1507 : :
1508 : 0 : return 0;
1509 : : }
1510 : :
1511 : 0 : int zxdh_dev_mtu_set(struct rte_eth_dev *dev, uint16_t new_mtu)
1512 : : {
1513 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1514 : 0 : struct zxdh_panel_table panel = {0};
1515 : 0 : struct zxdh_port_attr_table vport_att = {0};
1516 : 0 : uint16_t vfid = zxdh_vport_to_vfid(hw->vport);
1517 : : int ret;
1518 : :
1519 [ # # ]: 0 : if (hw->is_pf) {
1520 : 0 : ret = zxdh_get_panel_attr(dev, &panel);
1521 [ # # ]: 0 : if (ret != 0) {
1522 : 0 : PMD_DRV_LOG(ERR, "get_panel_attr failed ret:%d", ret);
1523 : 0 : return ret;
1524 : : }
1525 : :
1526 : 0 : ret = zxdh_get_port_attr(vfid, &vport_att);
1527 [ # # ]: 0 : if (ret != 0) {
1528 : 0 : PMD_DRV_LOG(ERR,
1529 : : "[vfid:%d] zxdh_dev_mtu, get vport failed ret:%d", vfid, ret);
1530 : 0 : return ret;
1531 : : }
1532 : :
1533 : 0 : panel.mtu = new_mtu;
1534 : 0 : panel.mtu_enable = 1;
1535 : 0 : ret = zxdh_set_panel_attr(dev, &panel);
1536 [ # # ]: 0 : if (ret != 0) {
1537 : 0 : PMD_DRV_LOG(ERR, "set zxdh_dev_mtu failed, ret:%u", ret);
1538 : 0 : return ret;
1539 : : }
1540 : :
1541 : 0 : vport_att.mtu_enable = 1;
1542 : 0 : vport_att.mtu = new_mtu;
1543 : 0 : ret = zxdh_set_port_attr(vfid, &vport_att);
1544 [ # # ]: 0 : if (ret != 0) {
1545 : 0 : PMD_DRV_LOG(ERR,
1546 : : "[vfid:%d] zxdh_dev_mtu, set vport failed ret:%d", vfid, ret);
1547 : 0 : return ret;
1548 : : }
1549 : : } else {
1550 : 0 : struct zxdh_msg_info msg_info = {0};
1551 : : struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
1552 : :
1553 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
1554 : 0 : attr_msg->mode = ZXDH_PORT_MTU_EN_FLAG;
1555 : 0 : attr_msg->value = 1;
1556 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
1557 [ # # ]: 0 : if (ret) {
1558 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
1559 : : hw->vport.vport, ZXDH_PORT_MTU_EN_FLAG);
1560 : 0 : return ret;
1561 : : }
1562 : 0 : attr_msg->mode = ZXDH_PORT_MTU_FLAG;
1563 : 0 : attr_msg->value = new_mtu;
1564 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
1565 [ # # ]: 0 : if (ret) {
1566 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
1567 : : hw->vport.vport, ZXDH_PORT_MTU_FLAG);
1568 : 0 : return ret;
1569 : : }
1570 : : }
1571 : 0 : dev->data->mtu = new_mtu;
1572 : 0 : return 0;
1573 : : }
|