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 : : #include "zxdh_mtr.h"
18 : : #include "zxdh_common.h"
19 : :
20 : : #define ZXDH_VLAN_FILTER_GROUPS 64
21 : : #define ZXDH_INVALID_LOGIC_QID 0xFFFFU
22 : :
23 : : /* Supported RSS */
24 : : #define ZXDH_RSS_HF_MASK (~(ZXDH_RSS_HF))
25 : : #define ZXDH_HF_F5 1
26 : : #define ZXDH_HF_F3 2
27 : : #define ZXDH_HF_MAC_VLAN 4
28 : : #define ZXDH_HF_ALL 0
29 : :
30 : : struct zxdh_hw_mac_stats {
31 : : uint64_t rx_total;
32 : : uint64_t rx_pause;
33 : : uint64_t rx_unicast;
34 : : uint64_t rx_multicast;
35 : : uint64_t rx_broadcast;
36 : : uint64_t rx_vlan;
37 : : uint64_t rx_size_64;
38 : : uint64_t rx_size_65_127;
39 : : uint64_t rx_size_128_255;
40 : : uint64_t rx_size_256_511;
41 : : uint64_t rx_size_512_1023;
42 : : uint64_t rx_size_1024_1518;
43 : : uint64_t rx_size_1519_mru;
44 : : uint64_t rx_undersize;
45 : : uint64_t rx_oversize;
46 : : uint64_t rx_fragment;
47 : : uint64_t rx_jabber;
48 : : uint64_t rx_control;
49 : : uint64_t rx_eee;
50 : :
51 : : uint64_t tx_total;
52 : : uint64_t tx_pause;
53 : : uint64_t tx_unicast;
54 : : uint64_t tx_multicast;
55 : : uint64_t tx_broadcast;
56 : : uint64_t tx_vlan;
57 : : uint64_t tx_size_64;
58 : : uint64_t tx_size_65_127;
59 : : uint64_t tx_size_128_255;
60 : : uint64_t tx_size_256_511;
61 : : uint64_t tx_size_512_1023;
62 : : uint64_t tx_size_1024_1518;
63 : : uint64_t tx_size_1519_mtu;
64 : : uint64_t tx_undersize;
65 : : uint64_t tx_oversize;
66 : : uint64_t tx_fragment;
67 : : uint64_t tx_jabber;
68 : : uint64_t tx_control;
69 : : uint64_t tx_eee;
70 : :
71 : : uint64_t rx_error;
72 : : uint64_t rx_fcs_error;
73 : : uint64_t rx_drop;
74 : :
75 : : uint64_t tx_error;
76 : : uint64_t tx_fcs_error;
77 : : uint64_t tx_drop;
78 : :
79 : : };
80 : :
81 : : struct zxdh_hw_mac_bytes {
82 : : uint64_t rx_total_bytes;
83 : : uint64_t rx_good_bytes;
84 : : uint64_t tx_total_bytes;
85 : : uint64_t tx_good_bytes;
86 : : };
87 : :
88 : : struct rte_zxdh_xstats_name_off {
89 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
90 : : unsigned int offset;
91 : : };
92 : :
93 : : static const struct rte_zxdh_xstats_name_off zxdh_rxq_stat_strings[] = {
94 : : {"good_packets", offsetof(struct zxdh_virtnet_rx, stats.packets)},
95 : : {"good_bytes", offsetof(struct zxdh_virtnet_rx, stats.bytes)},
96 : : {"errors", offsetof(struct zxdh_virtnet_rx, stats.errors)},
97 : : {"idle", offsetof(struct zxdh_virtnet_rx, stats.idle)},
98 : : {"truncated_err", offsetof(struct zxdh_virtnet_rx, stats.truncated_err)},
99 : : {"offload_cfg_err", offsetof(struct zxdh_virtnet_rx, stats.offload_cfg_err)},
100 : : {"invalid_hdr_len_err", offsetof(struct zxdh_virtnet_rx, stats.invalid_hdr_len_err)},
101 : : {"no_segs_err", offsetof(struct zxdh_virtnet_rx, stats.no_segs_err)},
102 : : };
103 : :
104 : : static const struct rte_zxdh_xstats_name_off zxdh_txq_stat_strings[] = {
105 : : {"good_packets", offsetof(struct zxdh_virtnet_tx, stats.packets)},
106 : : {"good_bytes", offsetof(struct zxdh_virtnet_tx, stats.bytes)},
107 : : {"errors", offsetof(struct zxdh_virtnet_tx, stats.errors)},
108 : : {"idle", offsetof(struct zxdh_virtnet_tx, stats.idle)},
109 : : {"truncated_err", offsetof(struct zxdh_virtnet_tx, stats.truncated_err)},
110 : : {"offload_cfg_err", offsetof(struct zxdh_virtnet_tx, stats.offload_cfg_err)},
111 : : {"invalid_hdr_len_err", offsetof(struct zxdh_virtnet_tx, stats.invalid_hdr_len_err)},
112 : : {"no_segs_err", offsetof(struct zxdh_virtnet_tx, stats.no_segs_err)},
113 : : };
114 : :
115 : : static const struct rte_zxdh_xstats_name_off zxdh_np_stat_strings[] = {
116 : : {"np_rx_unicast_pkts", offsetof(struct zxdh_hw_np_stats, rx_unicast_pkts)},
117 : : {"np_tx_unicast_pkts", offsetof(struct zxdh_hw_np_stats, tx_unicast_pkts)},
118 : : {"np_rx_unicast_bytes", offsetof(struct zxdh_hw_np_stats, rx_unicast_bytes)},
119 : : {"np_tx_unicast_bytes", offsetof(struct zxdh_hw_np_stats, tx_unicast_bytes)},
120 : : {"np_rx_multicast_pkts", offsetof(struct zxdh_hw_np_stats, rx_multicast_pkts)},
121 : : {"np_tx_multicast_pkts", offsetof(struct zxdh_hw_np_stats, tx_multicast_pkts)},
122 : : {"np_rx_multicast_bytes", offsetof(struct zxdh_hw_np_stats, rx_multicast_bytes)},
123 : : {"np_tx_multicast_bytes", offsetof(struct zxdh_hw_np_stats, tx_multicast_bytes)},
124 : : {"np_rx_broadcast_pkts", offsetof(struct zxdh_hw_np_stats, rx_broadcast_pkts)},
125 : : {"np_tx_broadcast_pkts", offsetof(struct zxdh_hw_np_stats, tx_broadcast_pkts)},
126 : : {"np_rx_broadcast_bytes", offsetof(struct zxdh_hw_np_stats, rx_broadcast_bytes)},
127 : : {"np_tx_broadcast_bytes", offsetof(struct zxdh_hw_np_stats, tx_broadcast_bytes)},
128 : : {"np_rx_mtu_drop_pkts", offsetof(struct zxdh_hw_np_stats, rx_mtu_drop_pkts)},
129 : : {"np_tx_mtu_drop_pkts", offsetof(struct zxdh_hw_np_stats, tx_mtu_drop_pkts)},
130 : : {"np_tx_mtu_drop_bytes", offsetof(struct zxdh_hw_np_stats, tx_mtu_drop_bytes)},
131 : : {"np_rx_mtu_drop_bytes", offsetof(struct zxdh_hw_np_stats, rx_mtu_drop_bytes)},
132 : : {"np_rx_plcr_drop_pkts", offsetof(struct zxdh_hw_np_stats, rx_mtr_drop_pkts)},
133 : : {"np_rx_plcr_drop_bytes", offsetof(struct zxdh_hw_np_stats, rx_mtr_drop_bytes)},
134 : : {"np_tx_plcr_drop_pkts", offsetof(struct zxdh_hw_np_stats, tx_mtr_drop_pkts)},
135 : : {"np_tx_plcr_drop_bytes", offsetof(struct zxdh_hw_np_stats, tx_mtr_drop_bytes)},
136 : : };
137 : :
138 : : static const struct rte_zxdh_xstats_name_off zxdh_mac_stat_strings[] = {
139 : : {"mac_rx_total", offsetof(struct zxdh_hw_mac_stats, rx_total)},
140 : : {"mac_rx_pause", offsetof(struct zxdh_hw_mac_stats, rx_pause)},
141 : : {"mac_rx_unicast", offsetof(struct zxdh_hw_mac_stats, rx_unicast)},
142 : : {"mac_rx_multicast", offsetof(struct zxdh_hw_mac_stats, rx_multicast)},
143 : : {"mac_rx_broadcast", offsetof(struct zxdh_hw_mac_stats, rx_broadcast)},
144 : : {"mac_rx_vlan", offsetof(struct zxdh_hw_mac_stats, rx_vlan)},
145 : : {"mac_rx_size_64", offsetof(struct zxdh_hw_mac_stats, rx_size_64)},
146 : : {"mac_rx_size_65_127", offsetof(struct zxdh_hw_mac_stats, rx_size_65_127)},
147 : : {"mac_rx_size_128_255", offsetof(struct zxdh_hw_mac_stats, rx_size_128_255)},
148 : : {"mac_rx_size_256_511", offsetof(struct zxdh_hw_mac_stats, rx_size_256_511)},
149 : : {"mac_rx_size_512_1023", offsetof(struct zxdh_hw_mac_stats, rx_size_512_1023)},
150 : : {"mac_rx_size_1024_1518", offsetof(struct zxdh_hw_mac_stats, rx_size_1024_1518)},
151 : : {"mac_rx_size_1519_mru", offsetof(struct zxdh_hw_mac_stats, rx_size_1519_mru)},
152 : : {"mac_rx_undersize", offsetof(struct zxdh_hw_mac_stats, rx_undersize)},
153 : : {"mac_rx_oversize", offsetof(struct zxdh_hw_mac_stats, rx_oversize)},
154 : : {"mac_rx_fragment", offsetof(struct zxdh_hw_mac_stats, rx_fragment)},
155 : : {"mac_rx_jabber", offsetof(struct zxdh_hw_mac_stats, rx_jabber)},
156 : : {"mac_rx_control", offsetof(struct zxdh_hw_mac_stats, rx_control)},
157 : : {"mac_rx_eee", offsetof(struct zxdh_hw_mac_stats, rx_eee)},
158 : : {"mac_rx_error", offsetof(struct zxdh_hw_mac_stats, rx_error)},
159 : : {"mac_rx_fcs_error", offsetof(struct zxdh_hw_mac_stats, rx_fcs_error)},
160 : : {"mac_rx_drop", offsetof(struct zxdh_hw_mac_stats, rx_drop)},
161 : :
162 : : {"mac_tx_total", offsetof(struct zxdh_hw_mac_stats, tx_total)},
163 : : {"mac_tx_pause", offsetof(struct zxdh_hw_mac_stats, tx_pause)},
164 : : {"mac_tx_unicast", offsetof(struct zxdh_hw_mac_stats, tx_unicast)},
165 : : {"mac_tx_multicast", offsetof(struct zxdh_hw_mac_stats, tx_multicast)},
166 : : {"mac_tx_broadcast", offsetof(struct zxdh_hw_mac_stats, tx_broadcast)},
167 : : {"mac_tx_vlan", offsetof(struct zxdh_hw_mac_stats, tx_vlan)},
168 : : {"mac_tx_size_64", offsetof(struct zxdh_hw_mac_stats, tx_size_64)},
169 : : {"mac_tx_size_65_127", offsetof(struct zxdh_hw_mac_stats, tx_size_65_127)},
170 : : {"mac_tx_size_128_255", offsetof(struct zxdh_hw_mac_stats, tx_size_128_255)},
171 : : {"mac_tx_size_256_511", offsetof(struct zxdh_hw_mac_stats, tx_size_256_511)},
172 : : {"mac_tx_size_512_1023", offsetof(struct zxdh_hw_mac_stats, tx_size_512_1023)},
173 : : {"mac_tx_size_1024_1518", offsetof(struct zxdh_hw_mac_stats, tx_size_1024_1518)},
174 : : {"mac_tx_size_1519_mtu", offsetof(struct zxdh_hw_mac_stats, tx_size_1519_mtu)},
175 : : {"mac_tx_undersize", offsetof(struct zxdh_hw_mac_stats, tx_undersize)},
176 : : {"mac_tx_oversize", offsetof(struct zxdh_hw_mac_stats, tx_oversize)},
177 : : {"mac_tx_fragment", offsetof(struct zxdh_hw_mac_stats, tx_fragment)},
178 : : {"mac_tx_jabber", offsetof(struct zxdh_hw_mac_stats, tx_jabber)},
179 : : {"mac_tx_control", offsetof(struct zxdh_hw_mac_stats, tx_control)},
180 : : {"mac_tx_eee", offsetof(struct zxdh_hw_mac_stats, tx_eee)},
181 : : {"mac_tx_error", offsetof(struct zxdh_hw_mac_stats, tx_error)},
182 : : {"mac_tx_fcs_error", offsetof(struct zxdh_hw_mac_stats, tx_fcs_error)},
183 : : {"mac_tx_drop", offsetof(struct zxdh_hw_mac_stats, tx_drop)},
184 : : };
185 : :
186 : : static const struct rte_zxdh_xstats_name_off zxdh_mac_bytes_strings[] = {
187 : : {"mac_rx_total_bytes", offsetof(struct zxdh_hw_mac_bytes, rx_total_bytes)},
188 : : {"mac_rx_good_bytes", offsetof(struct zxdh_hw_mac_bytes, rx_good_bytes)},
189 : : {"mac_tx_total_bytes", offsetof(struct zxdh_hw_mac_bytes, tx_total_bytes)},
190 : : {"mac_tx_good_bytes", offsetof(struct zxdh_hw_mac_bytes, tx_good_bytes)},
191 : : };
192 : :
193 : : static const struct rte_zxdh_xstats_name_off zxdh_vqm_stat_strings[] = {
194 : : {"vqm_rx_vport_packets", offsetof(struct zxdh_hw_vqm_stats, rx_total)},
195 : : {"vqm_tx_vport_packets", offsetof(struct zxdh_hw_vqm_stats, tx_total)},
196 : : {"vqm_rx_vport_bytes", offsetof(struct zxdh_hw_vqm_stats, rx_bytes)},
197 : : {"vqm_tx_vport_bytes", offsetof(struct zxdh_hw_vqm_stats, tx_bytes)},
198 : : {"vqm_rx_vport_dropped", offsetof(struct zxdh_hw_vqm_stats, rx_drop)},
199 : : };
200 : :
201 : : #define ZXDH_NB_RXQ_XSTATS (sizeof(zxdh_rxq_stat_strings) / \
202 : : sizeof(zxdh_rxq_stat_strings[0]))
203 : : #define ZXDH_NB_TXQ_XSTATS (sizeof(zxdh_txq_stat_strings) / \
204 : : sizeof(zxdh_txq_stat_strings[0]))
205 : :
206 : : #define ZXDH_NP_XSTATS (sizeof(zxdh_np_stat_strings) / \
207 : : sizeof(zxdh_np_stat_strings[0]))
208 : :
209 : : #define ZXDH_MAC_XSTATS (sizeof(zxdh_mac_stat_strings) / \
210 : : sizeof(zxdh_mac_stat_strings[0]))
211 : :
212 : : #define ZXDH_MAC_BYTES (sizeof(zxdh_mac_bytes_strings) / \
213 : : sizeof(zxdh_mac_bytes_strings[0]))
214 : :
215 : : #define ZXDH_VQM_XSTATS (sizeof(zxdh_vqm_stat_strings) / \
216 : : sizeof(zxdh_vqm_stat_strings[0]))
217 : :
218 : 0 : static int32_t zxdh_config_port_status(struct rte_eth_dev *dev, uint16_t link_status)
219 : : {
220 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
221 : 0 : struct zxdh_port_attr_table port_attr = {0};
222 : 0 : struct zxdh_msg_info msg_info = {0};
223 : : int32_t ret = 0;
224 : :
225 [ # # ]: 0 : if (hw->is_pf) {
226 : 0 : ret = zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
227 [ # # ]: 0 : if (ret) {
228 : 0 : PMD_DRV_LOG(ERR, "get port_attr failed");
229 : 0 : return -1;
230 : : }
231 : 0 : port_attr.is_up = link_status;
232 : :
233 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &port_attr);
234 [ # # ]: 0 : if (ret) {
235 : 0 : PMD_DRV_LOG(ERR, "write port_attr failed");
236 : 0 : return -1;
237 : : }
238 : : } else {
239 : : struct zxdh_port_attr_set_msg *port_attr_msg = &msg_info.data.port_attr_msg;
240 : :
241 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
242 : 0 : port_attr_msg->mode = ZXDH_PORT_VPORT_IS_UP_FLAG;
243 : 0 : port_attr_msg->value = link_status;
244 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
245 [ # # ]: 0 : if (ret) {
246 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
247 : : hw->vport.vport, ZXDH_PORT_VPORT_IS_UP_FLAG);
248 : 0 : return ret;
249 : : }
250 : : }
251 : : return ret;
252 : : }
253 : :
254 : : static int32_t
255 : 0 : zxdh_link_info_get(struct rte_eth_dev *dev, struct rte_eth_link *link)
256 : : {
257 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
258 : 0 : struct zxdh_msg_info msg_info = {0};
259 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
260 [ # # ]: 0 : uint16_t status = 0;
261 : : int32_t ret = 0;
262 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
263 : : void *link_msg_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, link_msg);
264 : :
265 [ # # ]: 0 : if (zxdh_pci_with_feature(hw, ZXDH_NET_F_STATUS))
266 : 0 : zxdh_pci_read_dev_config(hw, offsetof(struct zxdh_net_config, status),
267 : : &status, sizeof(status));
268 : :
269 : 0 : link->link_status = status;
270 : :
271 [ # # ]: 0 : if (status == RTE_ETH_LINK_DOWN) {
272 : 0 : link->link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
273 : 0 : link->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
274 : : } else {
275 : 0 : zxdh_agent_msg_build(hw, ZXDH_MAC_LINK_GET, &msg_info);
276 : :
277 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
278 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),
279 : : ZXDH_BAR_MODULE_MAC);
280 [ # # ]: 0 : if (ret) {
281 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
282 : : hw->vport.vport, ZXDH_MAC_LINK_GET);
283 : 0 : return -1;
284 : : }
285 : :
286 : 0 : link->link_speed = ZXDH_GET(link_info_msg, link_msg_addr, speed);
287 : 0 : hw->speed_mode = ZXDH_GET(link_info_msg, link_msg_addr, speed_modes);
288 [ # # ]: 0 : if ((ZXDH_GET(link_info_msg, link_msg_addr, duplex) & RTE_ETH_LINK_FULL_DUPLEX) ==
289 : : RTE_ETH_LINK_FULL_DUPLEX)
290 : 0 : link->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
291 : : else
292 : 0 : link->link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
293 : : }
294 : :
295 [ # # ]: 0 : if (hw->switchoffload) {
296 : 0 : link->link_speed = RTE_ETH_SPEED_NUM_25G;
297 : 0 : link->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
298 : : link->link_autoneg = RTE_ETH_LINK_AUTONEG;
299 : 0 : link->link_status = RTE_ETH_LINK_UP;
300 : : }
301 : 0 : link->link_autoneg = hw->autoneg;
302 : 0 : hw->speed = link->link_speed;
303 : :
304 : 0 : return 0;
305 : : }
306 : :
307 : 0 : static int zxdh_set_link_status(struct rte_eth_dev *dev, uint8_t link_status)
308 : : {
309 : 0 : uint16_t curr_link_status = dev->data->dev_link.link_status;
310 : :
311 : : struct rte_eth_link link;
312 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
313 : : int32_t ret = 0;
314 : :
315 [ # # ]: 0 : if (link_status == curr_link_status) {
316 : 0 : PMD_DRV_LOG(DEBUG, "curr_link_status %u", curr_link_status);
317 : 0 : return 0;
318 : : }
319 : :
320 : 0 : hw->admin_status = link_status;
321 : 0 : ret = zxdh_link_info_get(dev, &link);
322 [ # # ]: 0 : if (ret != 0) {
323 : 0 : PMD_DRV_LOG(ERR, "Failed to get link status from hw");
324 : 0 : return ret;
325 : : }
326 : 0 : dev->data->dev_link.link_status = hw->admin_status & link.link_status;
327 : :
328 [ # # ]: 0 : if (dev->data->dev_link.link_status == RTE_ETH_LINK_UP) {
329 : 0 : dev->data->dev_link.link_speed = link.link_speed;
330 : 0 : dev->data->dev_link.link_duplex = link.link_duplex;
331 : : } else {
332 : 0 : dev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
333 : 0 : dev->data->dev_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
334 : : }
335 : 0 : return zxdh_config_port_status(dev, dev->data->dev_link.link_status);
336 : : }
337 : :
338 : 0 : int zxdh_dev_set_link_up(struct rte_eth_dev *dev)
339 : : {
340 : 0 : int ret = zxdh_set_link_status(dev, RTE_ETH_LINK_UP);
341 : :
342 [ # # ]: 0 : if (ret)
343 : 0 : PMD_DRV_LOG(ERR, "Set link up failed, code:%d", ret);
344 : :
345 : 0 : return ret;
346 : : }
347 : :
348 : 0 : static int32_t zxdh_speed_mode_to_spm(uint32_t link_speed_modes)
349 : : {
350 [ # # # # : 0 : switch (link_speed_modes) {
# # # ]
351 : : case RTE_ETH_LINK_SPEED_1G: return ZXDH_SPM_SPEED_1X_1G;
352 : 0 : case RTE_ETH_LINK_SPEED_10G: return ZXDH_SPM_SPEED_1X_10G;
353 : 0 : case RTE_ETH_LINK_SPEED_25G: return ZXDH_SPM_SPEED_1X_25G;
354 : 0 : case RTE_ETH_LINK_SPEED_50G: return ZXDH_SPM_SPEED_1X_50G;
355 : 0 : case RTE_ETH_LINK_SPEED_100G: return ZXDH_SPM_SPEED_4X_100G;
356 : 0 : case RTE_ETH_LINK_SPEED_200G: return ZXDH_SPM_SPEED_4X_200G;
357 : 0 : default:
358 : 0 : PMD_DRV_LOG(ERR, "unsupported speed!");
359 : 0 : return -1;
360 : : }
361 : : }
362 : :
363 : 0 : int32_t zxdh_link_speed_set(struct rte_eth_dev *dev)
364 : : {
365 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
366 : : struct zxdh_msg_info msg;
367 : : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)];
368 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
369 : : int32_t spm_speed_modes;
370 : : int32_t ret;
371 : :
372 : : spm_speed_modes =
373 : 0 : zxdh_speed_mode_to_spm(dev->data->dev_conf.link_speeds & ~RTE_ETH_LINK_SPEED_FIXED);
374 [ # # # # ]: 0 : if (spm_speed_modes == -1 || spm_speed_modes == hw->speed_mode) {
375 : 0 : PMD_DRV_LOG(DEBUG, "not need update speed");
376 : 0 : return 0;
377 : : }
378 [ # # ]: 0 : if ((spm_speed_modes & hw->support_speed_modes) == 0) {
379 : 0 : PMD_DRV_LOG(ERR, "not support configure this speed");
380 : 0 : return 0;
381 : : }
382 : :
383 : 0 : zxdh_agent_msg_build(hw, ZXDH_MAC_SPEED_SET, &msg);
384 : 0 : msg.data.link_msg.autoneg = 0;
385 : 0 : msg.data.link_msg.speed_modes = spm_speed_modes & hw->support_speed_modes;
386 : :
387 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg, sizeof(struct zxdh_msg_info),
388 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),
389 : : ZXDH_BAR_MODULE_MAC);
390 : 0 : uint8_t flag = ZXDH_GET(msg_reply_body, reply_body_addr, flag);
391 [ # # ]: 0 : if (flag != ZXDH_REPS_SUCC || ret) {
392 : 0 : PMD_DRV_LOG(ERR, "failed to set link speed!");
393 : 0 : return -1;
394 : : }
395 : :
396 : : return 0;
397 : : }
398 : :
399 : : void
400 : 0 : zxdh_speed_modes_get(struct rte_eth_dev *dev)
401 : : {
402 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
403 : : struct zxdh_msg_info msg;
404 : : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)];
405 : : int32_t ret;
406 : :
407 [ # # ]: 0 : if (!hw->is_pf)
408 : 0 : return;
409 : :
410 : 0 : msg.agent_msg_head.msg_type = ZXDH_MAC_PHYPORT_INIT;
411 : 0 : msg.agent_msg_head.init = 1;
412 : :
413 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg, sizeof(struct zxdh_msg_info),
414 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),
415 : : ZXDH_BAR_MODULE_MAC);
416 [ # # ]: 0 : if (ret)
417 : 0 : PMD_DRV_LOG(ERR, "Failed to get speed mode info");
418 : :
419 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
420 : : void *link_msg_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, link_msg);
421 : 0 : uint32_t speed_modes = ZXDH_GET(link_info_msg, link_msg_addr, speed_modes);
422 : :
423 : 0 : hw->support_speed_modes = speed_modes;
424 : : }
425 : :
426 : 0 : int32_t zxdh_autoneg_stats_get(struct rte_eth_dev *dev)
427 : : {
428 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
429 : : struct zxdh_msg_info msg;
430 : : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)];
431 : : int32_t ret;
432 : :
433 : 0 : zxdh_agent_msg_build(hw, ZXDH_MAC_AUTONEG_GET, &msg);
434 : :
435 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg, sizeof(struct zxdh_msg_info),
436 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),
437 : : ZXDH_BAR_MODULE_MAC);
438 [ # # ]: 0 : if (ret) {
439 : 0 : PMD_DRV_LOG(ERR, "Failed to get link autoneg stats!");
440 : 0 : return -1;
441 : : }
442 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
443 : : void *link_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, link_msg);
444 : : void *link_autoeng_addr = ZXDH_ADDR_OF(link_info_msg, link_addr, autoneg);
445 : :
446 : 0 : hw->autoneg = *(uint8_t *)link_autoeng_addr;
447 : 0 : PMD_DRV_LOG(DEBUG, "autoneg stats is: %d", hw->autoneg);
448 : :
449 : 0 : return 0;
450 : : }
451 : :
452 : 0 : int32_t zxdh_dev_link_update(struct rte_eth_dev *dev, int32_t wait_to_complete __rte_unused)
453 : : {
454 : : struct rte_eth_link link;
455 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
456 : : int32_t ret = 0;
457 : :
458 : : memset(&link, 0, sizeof(link));
459 : 0 : link.link_duplex = hw->duplex;
460 : 0 : link.link_speed = hw->speed;
461 : 0 : link.link_autoneg = RTE_ETH_LINK_AUTONEG;
462 : :
463 : 0 : ret = zxdh_link_info_get(dev, &link);
464 [ # # ]: 0 : if (ret != 0) {
465 : 0 : PMD_DRV_LOG(ERR, "Failed to get link status from hw");
466 : 0 : return ret;
467 : : }
468 : :
469 [ # # ]: 0 : if (link.link_status != dev->data->dev_link.link_status) {
470 : 0 : ret = zxdh_config_port_status(dev, link.link_status);
471 [ # # ]: 0 : if (ret != 0) {
472 : 0 : PMD_DRV_LOG(ERR, "set port attr %d failed", link.link_status);
473 : 0 : return ret;
474 : : }
475 : : }
476 : : return rte_eth_linkstatus_set(dev, &link);
477 : : }
478 : :
479 : 0 : int zxdh_dev_set_link_down(struct rte_eth_dev *dev)
480 : : {
481 : 0 : int ret = zxdh_set_link_status(dev, RTE_ETH_LINK_DOWN);
482 : :
483 [ # # ]: 0 : if (ret)
484 : 0 : PMD_DRV_LOG(ERR, "Set link down failed");
485 : 0 : return ret;
486 : : }
487 : :
488 : : int
489 : 0 : zxdh_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
490 : : {
491 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
492 : 0 : struct rte_ether_addr *old_addr = &dev->data->mac_addrs[0];
493 : 0 : struct zxdh_msg_info msg_info = {0};
494 [ # # ]: 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
495 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
496 : : void *mac_reply_msg_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, mac_reply_msg);
497 : : int ret = 0;
498 : :
499 : : if (!rte_is_valid_assigned_ether_addr(addr)) {
500 : 0 : PMD_DRV_LOG(ERR, "mac address is invalid!");
501 : 0 : return -EINVAL;
502 : : }
503 [ # # ]: 0 : if (rte_is_same_ether_addr(old_addr, addr))
504 : : return 0;
505 : :
506 [ # # ]: 0 : if (hw->is_pf) {
507 : 0 : ret = zxdh_add_mac_table(hw, hw->vport.vport, addr, hw->hash_search_index, 0, 0);
508 [ # # ]: 0 : if (ret) {
509 [ # # ]: 0 : if (ret == -EADDRINUSE) {
510 : 0 : PMD_DRV_LOG(ERR, "pf mac add failed! mac is in used, code:%d", ret);
511 : 0 : return -EADDRINUSE;
512 : : }
513 : 0 : PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);
514 : 0 : return ret;
515 : : }
516 : 0 : hw->uc_num++;
517 : :
518 : 0 : ret = zxdh_del_mac_table(hw, hw->vport.vport, old_addr,
519 : 0 : hw->hash_search_index, 0, 0);
520 [ # # ]: 0 : if (ret) {
521 : 0 : PMD_DRV_LOG(ERR, "mac_addr_del failed, code:%d", ret);
522 : 0 : return ret;
523 : : }
524 : 0 : hw->uc_num--;
525 : : } else {
526 : : struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;
527 : 0 : mac_filter->filter_flag = ZXDH_MAC_UNFILTER;
528 : 0 : mac_filter->mac = *addr;
529 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);
530 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info),
531 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info));
532 [ # # ]: 0 : if (ret) {
533 : 0 : uint8_t flag = ZXDH_GET(mac_reply_msg, mac_reply_msg_addr, mac_flag);
534 [ # # ]: 0 : if (flag == ZXDH_EEXIST_MAC_FLAG) {
535 : 0 : PMD_DRV_LOG(ERR, "pf mac add failed! mac is in used, code:%d", ret);
536 : 0 : return -EADDRINUSE;
537 : : }
538 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
539 : : hw->vport.vport, ZXDH_MAC_ADD);
540 : 0 : return ret;
541 : : }
542 : 0 : hw->uc_num++;
543 : :
544 : 0 : mac_filter->filter_flag = ZXDH_MAC_UNFILTER;
545 : 0 : mac_filter->mac_flag = true;
546 : 0 : mac_filter->mac = *old_addr;
547 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info);
548 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
549 [ # # ]: 0 : if (ret) {
550 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
551 : : hw->vport.vport, ZXDH_MAC_DEL);
552 : 0 : return ret;
553 : : }
554 : 0 : hw->uc_num--;
555 : : }
556 : : rte_ether_addr_copy(addr, (struct rte_ether_addr *)hw->mac_addr);
557 : 0 : zxdh_pci_write_dev_config(hw, offsetof(struct zxdh_net_config, mac),
558 : 0 : &hw->mac_addr, RTE_ETHER_ADDR_LEN);
559 : 0 : return ret;
560 : : }
561 : :
562 : : int
563 : 0 : zxdh_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
564 : : uint32_t index, uint32_t vmdq __rte_unused)
565 : : {
566 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
567 : 0 : struct zxdh_msg_info msg_info = {0};
568 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
569 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
570 : : void *mac_reply_msg_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, mac_reply_msg);
571 : : uint16_t i;
572 : : int ret;
573 : :
574 [ # # ]: 0 : if (index >= ZXDH_MAX_MAC_ADDRS) {
575 : 0 : PMD_DRV_LOG(ERR, "Add mac index (%u) is out of range", index);
576 : 0 : return -EINVAL;
577 : : }
578 : :
579 [ # # ]: 0 : for (i = 0; (i != ZXDH_MAX_MAC_ADDRS); ++i) {
580 [ # # ]: 0 : if (memcmp(&dev->data->mac_addrs[i], mac_addr, sizeof(*mac_addr)))
581 : : continue;
582 : :
583 : 0 : PMD_DRV_LOG(INFO, "MAC address already configured");
584 : 0 : return -EADDRINUSE;
585 : : }
586 : :
587 [ # # ]: 0 : if (hw->is_pf) {
588 [ # # ]: 0 : if (rte_is_unicast_ether_addr(mac_addr)) {
589 [ # # ]: 0 : if (hw->uc_num < ZXDH_MAX_UC_MAC_ADDRS) {
590 : 0 : ret = zxdh_add_mac_table(hw, hw->vport.vport,
591 : 0 : mac_addr, hw->hash_search_index, 0, 0);
592 [ # # ]: 0 : if (ret) {
593 [ # # ]: 0 : if (ret == -EADDRINUSE) {
594 : 0 : PMD_DRV_LOG(ERR, "pf mac add failed mac is in used");
595 : 0 : return -EADDRINUSE;
596 : : }
597 : 0 : PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);
598 : 0 : return ret;
599 : : }
600 : 0 : memcpy(&hw->mac_addr, mac_addr, 6);
601 : 0 : hw->uc_num++;
602 : : } else {
603 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
604 : : ZXDH_MAX_MC_MAC_ADDRS);
605 : 0 : return -EINVAL;
606 : : }
607 : : } else {
608 [ # # ]: 0 : if (hw->mc_num < ZXDH_MAX_MC_MAC_ADDRS) {
609 : 0 : ret = zxdh_add_mac_table(hw, hw->vport.vport,
610 : 0 : mac_addr, hw->hash_search_index, 0, 0);
611 [ # # ]: 0 : if (ret) {
612 : 0 : PMD_DRV_LOG(ERR, "mac_addr_add failed, code:%d", ret);
613 : 0 : return ret;
614 : : }
615 : 0 : hw->mc_num++;
616 : : } else {
617 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
618 : : ZXDH_MAX_MC_MAC_ADDRS);
619 : 0 : return -EINVAL;
620 : : }
621 : : }
622 : : } else {
623 : : struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;
624 : :
625 : 0 : mac_filter->filter_flag = ZXDH_MAC_FILTER;
626 : 0 : mac_filter->mac = *mac_addr;
627 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);
628 [ # # ]: 0 : if (rte_is_unicast_ether_addr(mac_addr)) {
629 [ # # ]: 0 : if (hw->uc_num < ZXDH_MAX_UC_MAC_ADDRS) {
630 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info),
631 : : zxdh_msg_reply_info,
632 : : ZXDH_ST_SZ_BYTES(msg_reply_info));
633 [ # # ]: 0 : if (ret) {
634 : 0 : uint8_t flag = ZXDH_GET(mac_reply_msg,
635 : : mac_reply_msg_addr, mac_flag);
636 [ # # ]: 0 : if (flag == ZXDH_EEXIST_MAC_FLAG) {
637 : 0 : PMD_DRV_LOG(ERR, "pf mac add failed mac is in used");
638 : 0 : return -EADDRINUSE;
639 : : }
640 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
641 : : hw->vport.vport, ZXDH_MAC_ADD);
642 : 0 : return ret;
643 : : }
644 : 0 : hw->uc_num++;
645 : : } else {
646 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
647 : : ZXDH_MAX_MC_MAC_ADDRS);
648 : 0 : return -EINVAL;
649 : : }
650 : : } else {
651 [ # # ]: 0 : if (hw->mc_num < ZXDH_MAX_MC_MAC_ADDRS) {
652 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
653 : : sizeof(msg_info), NULL, 0);
654 [ # # ]: 0 : if (ret) {
655 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
656 : : hw->vport.vport, ZXDH_MAC_ADD);
657 : 0 : return ret;
658 : : }
659 : 0 : hw->mc_num++;
660 : : } else {
661 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
662 : : ZXDH_MAX_MC_MAC_ADDRS);
663 : 0 : return -EINVAL;
664 : : }
665 : : }
666 : : }
667 : 0 : dev->data->mac_addrs[index] = *mac_addr;
668 : 0 : return 0;
669 : : }
670 : :
671 : 0 : void zxdh_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
672 : : {
673 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
674 : 0 : struct zxdh_msg_info msg_info = {0};
675 : 0 : struct rte_ether_addr *mac_addr = &dev->data->mac_addrs[index];
676 : : uint16_t ret = 0;
677 : :
678 [ # # ]: 0 : if (index >= ZXDH_MAX_MAC_ADDRS)
679 : 0 : return;
680 : :
681 [ # # ]: 0 : if (hw->is_pf) {
682 [ # # ]: 0 : if (rte_is_unicast_ether_addr(mac_addr)) {
683 [ # # ]: 0 : if (hw->uc_num <= ZXDH_MAX_UC_MAC_ADDRS) {
684 : 0 : ret = zxdh_del_mac_table(hw, hw->vport.vport,
685 : 0 : mac_addr, hw->hash_search_index, 0, 0);
686 [ # # ]: 0 : if (ret) {
687 : 0 : PMD_DRV_LOG(ERR, "mac_addr_del failed, code:%d", ret);
688 : 0 : return;
689 : : }
690 : 0 : hw->uc_num--;
691 : : } else {
692 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
693 : : ZXDH_MAX_MC_MAC_ADDRS);
694 : 0 : return;
695 : : }
696 : : } else {
697 [ # # ]: 0 : if (hw->mc_num <= ZXDH_MAX_MC_MAC_ADDRS) {
698 : 0 : ret = zxdh_del_mac_table(hw, hw->vport.vport,
699 : 0 : mac_addr, hw->hash_search_index, 0, 0);
700 [ # # ]: 0 : if (ret) {
701 : 0 : PMD_DRV_LOG(ERR, "mac_addr_del failed, code:%d", ret);
702 : 0 : return;
703 : : }
704 : 0 : hw->mc_num--;
705 : : } else {
706 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
707 : : ZXDH_MAX_MC_MAC_ADDRS);
708 : 0 : return;
709 : : }
710 : : }
711 : : } else {
712 : : struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;
713 : :
714 : 0 : mac_filter->filter_flag = ZXDH_MAC_FILTER;
715 : 0 : mac_filter->mac = *mac_addr;
716 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_DEL, &msg_info);
717 [ # # ]: 0 : if (rte_is_unicast_ether_addr(mac_addr)) {
718 [ # # ]: 0 : if (hw->uc_num <= ZXDH_MAX_UC_MAC_ADDRS) {
719 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
720 : : sizeof(msg_info), NULL, 0);
721 [ # # ]: 0 : if (ret) {
722 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
723 : : hw->vport.vport, ZXDH_MAC_DEL);
724 : 0 : return;
725 : : }
726 : 0 : hw->uc_num--;
727 : : } else {
728 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
729 : : ZXDH_MAX_MC_MAC_ADDRS);
730 : 0 : return;
731 : : }
732 : : } else {
733 [ # # ]: 0 : if (hw->mc_num <= ZXDH_MAX_MC_MAC_ADDRS) {
734 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
735 : : sizeof(msg_info), NULL, 0);
736 [ # # ]: 0 : if (ret) {
737 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
738 : : hw->vport.vport, ZXDH_MAC_DEL);
739 : 0 : return;
740 : : }
741 : 0 : hw->mc_num--;
742 : : } else {
743 : 0 : PMD_DRV_LOG(ERR, "MC_MAC is out of range, MAX_MC_MAC:%d",
744 : : ZXDH_MAX_MC_MAC_ADDRS);
745 : 0 : return;
746 : : }
747 : : }
748 : : }
749 : 0 : memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr));
750 : : }
751 : :
752 : 0 : int zxdh_dev_promiscuous_enable(struct rte_eth_dev *dev)
753 : : {
754 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
755 : 0 : struct zxdh_msg_info msg_info = {0};
756 : : int16_t ret = 0;
757 : :
758 [ # # ]: 0 : if (hw->promisc_status == 0) {
759 [ # # ]: 0 : if (hw->is_pf) {
760 : 0 : ret = zxdh_dev_unicast_table_set(hw, hw->vport.vport, true);
761 [ # # ]: 0 : if (hw->allmulti_status == 0)
762 : 0 : ret = zxdh_dev_multicast_table_set(hw, hw->vport.vport, true);
763 : :
764 : : } else {
765 : : struct zxdh_port_promisc_msg *promisc_msg = &msg_info.data.port_promisc_msg;
766 : :
767 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_PROMISC_SET, &msg_info);
768 : 0 : promisc_msg->mode = ZXDH_PROMISC_MODE;
769 : 0 : promisc_msg->value = true;
770 [ # # ]: 0 : if (hw->allmulti_status == 0)
771 : 0 : promisc_msg->mc_follow = true;
772 : :
773 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
774 [ # # ]: 0 : if (ret) {
775 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
776 : : hw->vport.vport, ZXDH_PROMISC_MODE);
777 : 0 : return ret;
778 : : }
779 : : }
780 : 0 : hw->promisc_status = 1;
781 : : }
782 : 0 : return ret;
783 : : }
784 : :
785 : 0 : int zxdh_dev_promiscuous_disable(struct rte_eth_dev *dev)
786 : : {
787 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
788 : : int16_t ret = 0;
789 : 0 : struct zxdh_msg_info msg_info = {0};
790 : :
791 [ # # ]: 0 : if (hw->promisc_status == 1) {
792 [ # # ]: 0 : if (hw->is_pf) {
793 : 0 : ret = zxdh_dev_unicast_table_set(hw, hw->vport.vport, false);
794 [ # # ]: 0 : if (hw->allmulti_status == 0)
795 : 0 : ret = zxdh_dev_multicast_table_set(hw, hw->vport.vport, false);
796 : :
797 : : } else {
798 : : struct zxdh_port_promisc_msg *promisc_msg = &msg_info.data.port_promisc_msg;
799 : :
800 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_PROMISC_SET, &msg_info);
801 : 0 : promisc_msg->mode = ZXDH_PROMISC_MODE;
802 : 0 : promisc_msg->value = false;
803 [ # # ]: 0 : if (hw->allmulti_status == 0)
804 : 0 : promisc_msg->mc_follow = true;
805 : :
806 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
807 [ # # ]: 0 : if (ret) {
808 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
809 : : hw->vport.vport, ZXDH_PROMISC_MODE);
810 : 0 : return ret;
811 : : }
812 : : }
813 : 0 : hw->promisc_status = 0;
814 : : }
815 : 0 : return ret;
816 : : }
817 : :
818 : 0 : int zxdh_dev_allmulticast_enable(struct rte_eth_dev *dev)
819 : : {
820 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
821 : : int16_t ret = 0;
822 : 0 : struct zxdh_msg_info msg_info = {0};
823 : :
824 [ # # ]: 0 : if (hw->allmulti_status == 0) {
825 [ # # ]: 0 : if (hw->is_pf) {
826 : 0 : ret = zxdh_dev_multicast_table_set(hw, hw->vport.vport, true);
827 : : } else {
828 : : struct zxdh_port_promisc_msg *promisc_msg = &msg_info.data.port_promisc_msg;
829 : :
830 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_PROMISC_SET, &msg_info);
831 : :
832 : 0 : promisc_msg->mode = ZXDH_ALLMULTI_MODE;
833 : 0 : promisc_msg->value = true;
834 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
835 [ # # ]: 0 : if (ret) {
836 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
837 : : hw->vport.vport, ZXDH_ALLMULTI_MODE);
838 : 0 : return ret;
839 : : }
840 : : }
841 : 0 : hw->allmulti_status = 1;
842 : : }
843 : 0 : return ret;
844 : : }
845 : :
846 : 0 : int zxdh_dev_allmulticast_disable(struct rte_eth_dev *dev)
847 : : {
848 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
849 : : int16_t ret = 0;
850 : 0 : struct zxdh_msg_info msg_info = {0};
851 : :
852 [ # # ]: 0 : if (hw->allmulti_status == 1) {
853 [ # # ]: 0 : if (hw->is_pf) {
854 [ # # ]: 0 : if (hw->promisc_status == 1)
855 : 0 : goto end;
856 : 0 : ret = zxdh_dev_multicast_table_set(hw, hw->vport.vport, false);
857 : : } else {
858 : : struct zxdh_port_promisc_msg *promisc_msg = &msg_info.data.port_promisc_msg;
859 : :
860 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_PROMISC_SET, &msg_info);
861 [ # # ]: 0 : if (hw->promisc_status == 1)
862 : 0 : goto end;
863 : 0 : promisc_msg->mode = ZXDH_ALLMULTI_MODE;
864 : 0 : promisc_msg->value = false;
865 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
866 [ # # ]: 0 : if (ret) {
867 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
868 : : hw->vport.vport, ZXDH_ALLMULTI_MODE);
869 : 0 : return ret;
870 : : }
871 : : }
872 : 0 : hw->allmulti_status = 0;
873 : : }
874 : 0 : return ret;
875 : 0 : end:
876 : 0 : hw->allmulti_status = 0;
877 : 0 : return ret;
878 : : }
879 : :
880 : : int
881 : 0 : zxdh_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
882 : : {
883 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
884 : : uint16_t idx = 0;
885 : : uint16_t bit_idx = 0;
886 : : uint8_t msg_type = 0;
887 : : int ret = 0;
888 : :
889 : 0 : vlan_id &= RTE_VLAN_ID_MASK;
890 [ # # ]: 0 : if (vlan_id == 0 || vlan_id == RTE_ETHER_MAX_VLAN_ID) {
891 : 0 : PMD_DRV_LOG(ERR, "vlan id (%d) is reserved", vlan_id);
892 : 0 : return -EINVAL;
893 : : }
894 : :
895 : 0 : idx = vlan_id / ZXDH_VLAN_FILTER_GROUPS;
896 : 0 : bit_idx = vlan_id % ZXDH_VLAN_FILTER_GROUPS;
897 : :
898 [ # # ]: 0 : if (on) {
899 [ # # ]: 0 : if (dev->data->vlan_filter_conf.ids[idx] & (1ULL << bit_idx)) {
900 : 0 : PMD_DRV_LOG(ERR, "vlan:%d has already added", vlan_id);
901 : 0 : return 0;
902 : : }
903 : : msg_type = ZXDH_VLAN_FILTER_ADD;
904 : : } else {
905 [ # # ]: 0 : if (!(dev->data->vlan_filter_conf.ids[idx] & (1ULL << bit_idx))) {
906 : 0 : PMD_DRV_LOG(ERR, "vlan:%d has already deleted", vlan_id);
907 : 0 : return 0;
908 : : }
909 : : msg_type = ZXDH_VLAN_FILTER_DEL;
910 : : }
911 : :
912 [ # # ]: 0 : if (hw->is_pf) {
913 : 0 : ret = zxdh_vlan_filter_table_set(hw, hw->vport.vport, vlan_id, on);
914 [ # # ]: 0 : if (ret) {
915 : 0 : PMD_DRV_LOG(ERR, "vlan_id:%d table set failed", vlan_id);
916 : 0 : return -1;
917 : : }
918 : : } else {
919 : 0 : struct zxdh_msg_info msg = {0};
920 : 0 : zxdh_msg_head_build(hw, msg_type, &msg);
921 : 0 : msg.data.vlan_filter_msg.vlan_id = vlan_id;
922 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info), NULL, 0);
923 [ # # ]: 0 : if (ret) {
924 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
925 : : hw->vport.vport, msg_type);
926 : 0 : return ret;
927 : : }
928 : : }
929 : :
930 [ # # ]: 0 : if (on)
931 : 0 : dev->data->vlan_filter_conf.ids[idx] |= (1ULL << bit_idx);
932 : : else
933 : 0 : dev->data->vlan_filter_conf.ids[idx] &= ~(1ULL << bit_idx);
934 : :
935 : : return 0;
936 : : }
937 : :
938 : : int
939 : 0 : zxdh_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
940 : : {
941 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
942 : : struct rte_eth_rxmode *rxmode;
943 : 0 : struct zxdh_msg_info msg = {0};
944 : : int ret = 0;
945 : :
946 : : rxmode = &dev->data->dev_conf.rxmode;
947 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
948 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) {
949 [ # # ]: 0 : if (hw->is_pf) {
950 : 0 : ret = zxdh_set_vlan_filter(hw, hw->vport.vport, true);
951 [ # # ]: 0 : if (ret) {
952 : 0 : PMD_DRV_LOG(ERR, "port %d vlan filter set failed",
953 : : hw->vport.vfid);
954 : 0 : return -EAGAIN;
955 : : }
956 : : } else {
957 : 0 : msg.data.vlan_filter_set_msg.enable = true;
958 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_FILTER_SET, &msg);
959 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
960 : : sizeof(struct zxdh_msg_info), NULL, 0);
961 [ # # ]: 0 : if (ret) {
962 : 0 : PMD_DRV_LOG(ERR, "port %d vlan filter set failed",
963 : : hw->vport.vfid);
964 : 0 : return -EAGAIN;
965 : : }
966 : : }
967 : : } else {
968 [ # # ]: 0 : if (hw->is_pf) {
969 : 0 : ret = zxdh_set_vlan_filter(hw, hw->vport.vport, false);
970 [ # # ]: 0 : if (ret) {
971 : 0 : PMD_DRV_LOG(ERR, "port %d vlan filter set failed",
972 : : hw->vport.vfid);
973 : 0 : return -EAGAIN;
974 : : }
975 : : } else {
976 : : msg.data.vlan_filter_set_msg.enable = false;
977 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_FILTER_SET, &msg);
978 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
979 : : sizeof(struct zxdh_msg_info), NULL, 0);
980 [ # # ]: 0 : if (ret) {
981 : 0 : PMD_DRV_LOG(ERR, "port %d vlan filter set failed",
982 : : hw->vport.vfid);
983 : 0 : return -EAGAIN;
984 : : }
985 : : }
986 : : }
987 : : }
988 : :
989 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
990 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
991 [ # # ]: 0 : if (hw->is_pf) {
992 : 0 : ret = zxdh_set_vlan_offload(hw, hw->vport.vport,
993 : : ZXDH_VLAN_STRIP_TYPE, true);
994 [ # # ]: 0 : if (ret) {
995 : 0 : PMD_DRV_LOG(ERR, "port %d vlan strip set failed",
996 : : hw->vport.vfid);
997 : 0 : return -EAGAIN;
998 : : }
999 : : } else {
1000 : 0 : msg.data.vlan_offload_msg.enable = true;
1001 : 0 : msg.data.vlan_offload_msg.type = ZXDH_VLAN_STRIP_TYPE;
1002 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_OFFLOAD, &msg);
1003 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
1004 : : sizeof(struct zxdh_msg_info), NULL, 0);
1005 [ # # ]: 0 : if (ret) {
1006 : 0 : PMD_DRV_LOG(ERR, "port %d vlan strip set failed",
1007 : : hw->vport.vfid);
1008 : 0 : return -EAGAIN;
1009 : : }
1010 : : }
1011 : : } else {
1012 [ # # ]: 0 : if (hw->is_pf) {
1013 : 0 : ret = zxdh_set_vlan_offload(hw, hw->vport.vport,
1014 : : ZXDH_VLAN_STRIP_TYPE, false);
1015 [ # # ]: 0 : if (ret) {
1016 : 0 : PMD_DRV_LOG(ERR, "port %d vlan strip set failed",
1017 : : hw->vport.vfid);
1018 : 0 : return -EAGAIN;
1019 : : }
1020 : : } else {
1021 : 0 : msg.data.vlan_offload_msg.enable = false;
1022 : 0 : msg.data.vlan_offload_msg.type = ZXDH_VLAN_STRIP_TYPE;
1023 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_OFFLOAD, &msg);
1024 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
1025 : : sizeof(struct zxdh_msg_info), NULL, 0);
1026 [ # # ]: 0 : if (ret) {
1027 : 0 : PMD_DRV_LOG(ERR, "port %d vlan strip set failed",
1028 : : hw->vport.vfid);
1029 : 0 : return -EAGAIN;
1030 : : }
1031 : : }
1032 : : }
1033 : : }
1034 : :
1035 [ # # ]: 0 : if (mask & RTE_ETH_QINQ_STRIP_MASK) {
1036 : : memset(&msg, 0, sizeof(struct zxdh_msg_info));
1037 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) {
1038 [ # # ]: 0 : if (hw->is_pf) {
1039 : 0 : ret = zxdh_set_vlan_offload(hw, hw->vport.vport,
1040 : : ZXDH_QINQ_STRIP_TYPE, true);
1041 [ # # ]: 0 : if (ret) {
1042 : 0 : PMD_DRV_LOG(ERR, "port %d qinq offload set failed",
1043 : : hw->vport.vfid);
1044 : 0 : return -EAGAIN;
1045 : : }
1046 : : } else {
1047 : 0 : msg.data.vlan_offload_msg.enable = true;
1048 : 0 : msg.data.vlan_offload_msg.type = ZXDH_QINQ_STRIP_TYPE;
1049 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_OFFLOAD, &msg);
1050 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
1051 : : sizeof(struct zxdh_msg_info), NULL, 0);
1052 [ # # ]: 0 : if (ret) {
1053 : 0 : PMD_DRV_LOG(ERR, "port %d qinq offload set failed",
1054 : : hw->vport.vfid);
1055 : 0 : return -EAGAIN;
1056 : : }
1057 : : }
1058 : : } else {
1059 [ # # ]: 0 : if (hw->is_pf) {
1060 : 0 : ret = zxdh_set_vlan_offload(hw, hw->vport.vport,
1061 : : ZXDH_QINQ_STRIP_TYPE, false);
1062 [ # # ]: 0 : if (ret) {
1063 : 0 : PMD_DRV_LOG(ERR, "port %d qinq offload set failed",
1064 : : hw->vport.vfid);
1065 : 0 : return -EAGAIN;
1066 : : }
1067 : : } else {
1068 : : msg.data.vlan_offload_msg.enable = false;
1069 : 0 : msg.data.vlan_offload_msg.type = ZXDH_QINQ_STRIP_TYPE;
1070 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_OFFLOAD, &msg);
1071 : 0 : ret = zxdh_vf_send_msg_to_pf(hw->eth_dev, &msg,
1072 : : sizeof(struct zxdh_msg_info), NULL, 0);
1073 [ # # ]: 0 : if (ret) {
1074 : 0 : PMD_DRV_LOG(ERR, "port %d qinq offload set failed",
1075 : : hw->vport.vfid);
1076 : 0 : return -EAGAIN;
1077 : : }
1078 : : }
1079 : : }
1080 : : }
1081 : :
1082 : : return ret;
1083 : : }
1084 : :
1085 : : int
1086 : 0 : zxdh_vlan_tpid_set(struct rte_eth_dev *dev, enum rte_vlan_type vlan_type, uint16_t tpid)
1087 : : {
1088 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1089 : 0 : struct zxdh_port_vlan_table port_vlan_table = {0};
1090 : 0 : struct zxdh_msg_info msg = {0};
1091 : : int ret = 0;
1092 : :
1093 [ # # ]: 0 : if (vlan_type != RTE_ETH_VLAN_TYPE_OUTER) {
1094 : 0 : PMD_DRV_LOG(ERR, "unsupported rte vlan type!");
1095 : 0 : return -1;
1096 : : }
1097 : :
1098 [ # # ]: 0 : if (hw->is_pf) {
1099 : 0 : ret = zxdh_get_port_vlan_attr(hw, hw->vport.vport, &port_vlan_table);
1100 [ # # ]: 0 : if (ret != 0)
1101 : 0 : PMD_DRV_LOG(ERR, "get port vlan attr table failed");
1102 : 0 : port_vlan_table.hit_flag = 1;
1103 : 0 : port_vlan_table.business_vlan_tpid = tpid;
1104 : 0 : ret = zxdh_set_port_vlan_attr(hw, hw->vport.vport, &port_vlan_table);
1105 [ # # ]: 0 : if (ret != 0)
1106 : 0 : PMD_DRV_LOG(ERR, "set port vlan tpid %d attr table failed", tpid);
1107 : : } else {
1108 : 0 : zxdh_msg_head_build(hw, ZXDH_VLAN_SET_TPID, &msg);
1109 : 0 : msg.data.zxdh_vlan_tpid.tpid = tpid;
1110 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg,
1111 : : sizeof(struct zxdh_msg_info), NULL, 0);
1112 [ # # ]: 0 : if (ret) {
1113 : 0 : PMD_DRV_LOG(ERR, "port %d vlan tpid %d set failed",
1114 : : hw->vfid, tpid);
1115 : 0 : return -1;
1116 : : }
1117 : : }
1118 : :
1119 : : return 0;
1120 : : }
1121 : :
1122 : : int
1123 : 0 : zxdh_dev_rss_reta_update(struct rte_eth_dev *dev,
1124 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1125 : : uint16_t reta_size)
1126 : : {
1127 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1128 : 0 : struct zxdh_msg_info msg = {0};
1129 : : uint16_t old_reta[RTE_ETH_RSS_RETA_SIZE_256];
1130 : : uint16_t idx;
1131 : : uint16_t i;
1132 : : uint16_t pos;
1133 : : int ret;
1134 : :
1135 [ # # ]: 0 : if (reta_size != RTE_ETH_RSS_RETA_SIZE_256) {
1136 : 0 : PMD_DRV_LOG(ERR, "reta_size is illegal(%u).reta_size should be 256", reta_size);
1137 : 0 : return -EINVAL;
1138 : : }
1139 [ # # ]: 0 : if (!hw->rss_reta) {
1140 : 0 : hw->rss_reta = rte_calloc(NULL, RTE_ETH_RSS_RETA_SIZE_256, sizeof(uint16_t), 0);
1141 [ # # ]: 0 : if (hw->rss_reta == NULL) {
1142 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate RSS reta");
1143 : 0 : return -ENOMEM;
1144 : : }
1145 : : }
1146 [ # # ]: 0 : for (idx = 0, i = 0; (i < reta_size); ++i) {
1147 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1148 : 0 : pos = i % RTE_ETH_RETA_GROUP_SIZE;
1149 [ # # ]: 0 : if (((reta_conf[idx].mask >> pos) & 0x1) == 0)
1150 : 0 : continue;
1151 [ # # ]: 0 : if (reta_conf[idx].reta[pos] > dev->data->nb_rx_queues) {
1152 : 0 : PMD_DRV_LOG(ERR, "reta table value err(%u >= %u)",
1153 : : reta_conf[idx].reta[pos], dev->data->nb_rx_queues);
1154 : 0 : return -EINVAL;
1155 : : }
1156 [ # # ]: 0 : if (hw->rss_reta[i] != reta_conf[idx].reta[pos])
1157 : : break;
1158 : : }
1159 [ # # ]: 0 : if (i == reta_size) {
1160 : 0 : PMD_DRV_LOG(INFO, "reta table same with buffered table");
1161 : 0 : return 0;
1162 : : }
1163 : 0 : memcpy(old_reta, hw->rss_reta, sizeof(old_reta));
1164 : :
1165 [ # # ]: 0 : for (idx = 0, i = 0; i < reta_size; ++i) {
1166 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1167 : 0 : pos = i % RTE_ETH_RETA_GROUP_SIZE;
1168 [ # # ]: 0 : if (((reta_conf[idx].mask >> pos) & 0x1) == 0)
1169 : 0 : continue;
1170 : 0 : hw->rss_reta[i] = reta_conf[idx].reta[pos];
1171 : : }
1172 : :
1173 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_RETA_SET, &msg);
1174 [ # # ]: 0 : for (i = 0; i < reta_size; i++)
1175 : 0 : msg.data.rss_reta.reta[i] =
1176 : 0 : (hw->channel_context[hw->rss_reta[i] * 2].ph_chno);
1177 : :
1178 [ # # ]: 0 : if (hw->is_pf) {
1179 : 0 : ret = zxdh_rss_table_set(hw, hw->vport.vport, &msg.data.rss_reta);
1180 [ # # ]: 0 : if (ret) {
1181 : 0 : PMD_DRV_LOG(ERR, "rss reta table set failed");
1182 : 0 : return -EINVAL;
1183 : : }
1184 : : } else {
1185 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info), NULL, 0);
1186 [ # # ]: 0 : if (ret) {
1187 : 0 : PMD_DRV_LOG(ERR, "vf rss reta table set failed");
1188 : 0 : return -EINVAL;
1189 : : }
1190 : : }
1191 : : return ret;
1192 : : }
1193 : :
1194 : : uint16_t
1195 : 0 : zxdh_hw_qid_to_logic_qid(struct rte_eth_dev *dev, uint16_t qid)
1196 : : {
1197 : 0 : struct zxdh_hw *priv = (struct zxdh_hw *)dev->data->dev_private;
1198 : : uint16_t i;
1199 : :
1200 [ # # ]: 0 : for (i = 0; i < priv->max_queue_pairs * 2 ; i++) {
1201 [ # # ]: 0 : if (priv->channel_context[i].valid)
1202 [ # # ]: 0 : if (qid == priv->channel_context[i].ph_chno)
1203 : 0 : return i;
1204 : : }
1205 : :
1206 : : return ZXDH_INVALID_LOGIC_QID;
1207 : : }
1208 : :
1209 : : int
1210 : 0 : zxdh_dev_rss_reta_query(struct rte_eth_dev *dev,
1211 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1212 : : uint16_t reta_size)
1213 : : {
1214 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
1215 : 0 : struct zxdh_msg_info msg = {0};
1216 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
1217 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
1218 : : void *rss_reta_msg_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, rss_reta_msg);
1219 : : uint16_t idx;
1220 : : uint16_t i;
1221 : : int ret = 0;
1222 : : uint16_t qid_logic;
1223 : :
1224 : 0 : ret = (!reta_size || reta_size > RTE_ETH_RSS_RETA_SIZE_256);
1225 [ # # ]: 0 : if (ret) {
1226 : 0 : PMD_DRV_LOG(ERR, "request reta size(%u) not same with buffered(%u)",
1227 : : reta_size, RTE_ETH_RSS_RETA_SIZE_256);
1228 : 0 : return -EINVAL;
1229 : : }
1230 : :
1231 : : /* Fill each entry of the table even if its bit is not set. */
1232 [ # # ]: 0 : for (idx = 0, i = 0; (i != reta_size); ++i) {
1233 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1234 : 0 : reta_conf[idx].reta[i % RTE_ETH_RETA_GROUP_SIZE] = hw->rss_reta[i];
1235 : : }
1236 : :
1237 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_RETA_GET, &msg);
1238 : :
1239 [ # # ]: 0 : if (hw->is_pf) {
1240 : 0 : ret = zxdh_rss_table_get(hw, hw->vport.vport, rss_reta_msg_addr);
1241 [ # # ]: 0 : if (ret) {
1242 : 0 : PMD_DRV_LOG(ERR, "rss reta table set failed");
1243 : 0 : return -EINVAL;
1244 : : }
1245 : : } else {
1246 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info),
1247 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info));
1248 [ # # ]: 0 : if (ret) {
1249 : 0 : PMD_DRV_LOG(ERR, "vf rss reta table get failed");
1250 : 0 : return -EINVAL;
1251 : : }
1252 : : }
1253 : :
1254 : : struct zxdh_rss_reta *reta_table = rss_reta_msg_addr;
1255 : :
1256 [ # # ]: 0 : for (idx = 0, i = 0; i < reta_size; ++i) {
1257 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1258 : :
1259 : 0 : qid_logic = zxdh_hw_qid_to_logic_qid(dev, reta_table->reta[i]);
1260 [ # # ]: 0 : if (qid_logic == ZXDH_INVALID_LOGIC_QID) {
1261 : 0 : PMD_DRV_LOG(ERR, "rsp phy reta qid (%u) is illegal(%u)",
1262 : : reta_table->reta[i], qid_logic);
1263 : 0 : return -EINVAL;
1264 : : }
1265 : 0 : reta_conf[idx].reta[i % RTE_ETH_RETA_GROUP_SIZE] = qid_logic >> 1;
1266 : : }
1267 : : return 0;
1268 : : }
1269 : :
1270 : : static uint32_t
1271 : : zxdh_rss_hf_to_hw(uint64_t hf)
1272 : : {
1273 : : uint32_t hw_hf = 0;
1274 : :
1275 [ # # # # ]: 0 : if (hf & ZXDH_HF_MAC_VLAN_ETH)
1276 : : hw_hf |= ZXDH_HF_MAC_VLAN;
1277 [ # # # # : 0 : if (hf & ZXDH_HF_F3_ETH)
# # # # ]
1278 : 0 : hw_hf |= ZXDH_HF_F3;
1279 [ # # # # : 0 : if (hf & ZXDH_HF_F5_ETH)
# # # # ]
1280 : 0 : hw_hf |= ZXDH_HF_F5;
1281 : :
1282 [ # # # # : 0 : if (hw_hf == (ZXDH_HF_MAC_VLAN | ZXDH_HF_F3 | ZXDH_HF_F5))
# # # # ]
1283 : : hw_hf = ZXDH_HF_ALL;
1284 : : return hw_hf;
1285 : : }
1286 : :
1287 : : static uint64_t
1288 : : zxdh_rss_hf_to_eth(uint64_t hw_hf)
1289 : : {
1290 : : uint64_t hf = 0;
1291 : :
1292 [ # # ]: 0 : if (hw_hf == ZXDH_HF_ALL)
1293 : : return (ZXDH_HF_MAC_VLAN_ETH | ZXDH_HF_F3_ETH | ZXDH_HF_F5_ETH);
1294 : :
1295 [ # # # # : 0 : if (hw_hf & ZXDH_HF_MAC_VLAN)
# # ]
1296 : : hf |= ZXDH_HF_MAC_VLAN_ETH;
1297 [ # # # # : 0 : if (hw_hf & ZXDH_HF_F3)
# # ]
1298 : 0 : hf |= ZXDH_HF_F3_ETH;
1299 [ # # # # : 0 : if (hw_hf & ZXDH_HF_F5)
# # ]
1300 : 0 : hf |= ZXDH_HF_F5_ETH;
1301 : :
1302 : : return hf;
1303 : : }
1304 : :
1305 : : int
1306 : 0 : zxdh_rss_hash_update(struct rte_eth_dev *dev,
1307 : : struct rte_eth_rss_conf *rss_conf)
1308 : : {
1309 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1310 : : struct rte_eth_rss_conf *old_rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
1311 : 0 : struct zxdh_msg_info msg = {0};
1312 : 0 : struct zxdh_port_attr_table port_attr = {0};
1313 : : uint32_t hw_hf_new, hw_hf_old;
1314 : : int need_update_hf = 0;
1315 : : int ret = 0;
1316 : :
1317 : 0 : ret = rss_conf->rss_hf & ZXDH_RSS_HF_MASK;
1318 [ # # ]: 0 : if (ret) {
1319 : 0 : PMD_DRV_LOG(ERR, "Not support some hash function (%08lx)", rss_conf->rss_hf);
1320 : 0 : return -EINVAL;
1321 : : }
1322 : :
1323 : : hw_hf_new = zxdh_rss_hf_to_hw(rss_conf->rss_hf);
1324 [ # # ]: 0 : hw_hf_old = zxdh_rss_hf_to_hw(old_rss_conf->rss_hf);
1325 : :
1326 [ # # # # ]: 0 : if (hw_hf_new != hw_hf_old || hw->rss_enable != !!rss_conf->rss_hf)
1327 : : need_update_hf = 1;
1328 : :
1329 : : if (need_update_hf) {
1330 [ # # ]: 0 : if (hw->is_pf) {
1331 : 0 : ret = zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
1332 : 0 : port_attr.rss_enable = !!rss_conf->rss_hf;
1333 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &port_attr);
1334 [ # # ]: 0 : if (ret) {
1335 : 0 : PMD_DRV_LOG(ERR, "rss enable set failed");
1336 : 0 : return -EINVAL;
1337 : : }
1338 : : } else {
1339 : 0 : msg.data.rss_enable.enable = !!rss_conf->rss_hf;
1340 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_ENABLE, &msg);
1341 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg,
1342 : : sizeof(struct zxdh_msg_info), NULL, 0);
1343 [ # # ]: 0 : if (ret) {
1344 : 0 : PMD_DRV_LOG(ERR, "rss enable set failed");
1345 : 0 : return -EINVAL;
1346 : : }
1347 : : }
1348 [ # # ]: 0 : if (hw->is_pf) {
1349 : 0 : hw->rss_enable = !!rss_conf->rss_hf;
1350 [ # # ]: 0 : if (rss_conf->rss_hf == 0)
1351 : : return 0;
1352 : 0 : ret = zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
1353 : 0 : port_attr.rss_hash_factor = hw_hf_new;
1354 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &port_attr);
1355 [ # # ]: 0 : if (ret) {
1356 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1357 : 0 : return -EINVAL;
1358 : : }
1359 : : } else {
1360 : 0 : msg.data.rss_hf.rss_hf = hw_hf_new;
1361 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_HF_SET, &msg);
1362 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg,
1363 : : sizeof(struct zxdh_msg_info), NULL, 0);
1364 [ # # ]: 0 : if (ret) {
1365 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1366 : 0 : return -EINVAL;
1367 : : }
1368 : : }
1369 : 0 : old_rss_conf->rss_hf = rss_conf->rss_hf;
1370 : : }
1371 : :
1372 : : return 0;
1373 : : }
1374 : :
1375 : : int
1376 : 0 : zxdh_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf)
1377 : : {
1378 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1379 : : struct rte_eth_rss_conf *old_rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
1380 : 0 : struct zxdh_msg_info msg = {0};
1381 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
1382 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
1383 : : void *rss_hf_msg_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, rss_hf_msg);
1384 : 0 : struct zxdh_port_attr_table port_attr = {0};
1385 : : uint64_t rss_hf = 0;
1386 : : uint64_t hw_hf = 0;
1387 : : uint8_t need_update_hf = 0;
1388 : : int ret;
1389 : :
1390 [ # # ]: 0 : if (rss_conf == NULL) {
1391 : 0 : PMD_DRV_LOG(ERR, "rss conf is NULL");
1392 : 0 : return -ENOMEM;
1393 : : }
1394 : :
1395 [ # # ]: 0 : if (hw->rss_enable == 0) {
1396 : 0 : rss_conf->rss_hf = 0;
1397 : 0 : return 0;
1398 : : }
1399 : :
1400 [ # # ]: 0 : if (old_rss_conf->rss_hf == 0)
1401 : : need_update_hf = 1;
1402 : :
1403 : : if (!need_update_hf) {
1404 [ # # ]: 0 : hw_hf = zxdh_rss_hf_to_hw(old_rss_conf->rss_hf);
1405 : 0 : rss_conf->rss_hf = zxdh_rss_hf_to_eth(hw_hf);
1406 : : }
1407 : :
1408 [ # # ]: 0 : if (need_update_hf) {
1409 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_HF_GET, &msg);
1410 [ # # ]: 0 : if (hw->is_pf) {
1411 : 0 : ret = zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
1412 [ # # ]: 0 : if (ret) {
1413 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1414 : 0 : return -EINVAL;
1415 : : }
1416 : 0 : ZXDH_SET(rss_hf, rss_hf_msg_addr, rss_hf, port_attr.rss_hash_factor);
1417 : : } else {
1418 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info),
1419 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info));
1420 [ # # ]: 0 : if (ret) {
1421 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1422 : 0 : return -EINVAL;
1423 : : }
1424 : : }
1425 : 0 : rss_hf = ZXDH_GET(rss_hf, rss_hf_msg_addr, rss_hf);
1426 [ # # ]: 0 : rss_conf->rss_hf = zxdh_rss_hf_to_eth(rss_hf);
1427 : 0 : old_rss_conf->rss_hf = zxdh_rss_hf_to_eth(hw_hf);
1428 : : }
1429 : :
1430 : : return 0;
1431 : : }
1432 : :
1433 : : static int
1434 : : zxdh_get_rss_enable_conf(struct rte_eth_dev *dev)
1435 : : {
1436 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode == RTE_ETH_MQ_RX_RSS)
1437 : 0 : return dev->data->nb_rx_queues == 1 ? 0 : 1;
1438 : : else if (dev->data->dev_conf.rxmode.mq_mode == RTE_ETH_MQ_RX_NONE)
1439 : : return 0;
1440 : :
1441 : : return 0;
1442 : : }
1443 : :
1444 : : int
1445 : 0 : zxdh_rss_configure(struct rte_eth_dev *dev)
1446 : : {
1447 : 0 : struct rte_eth_dev_data *dev_data = dev->data;
1448 : 0 : struct zxdh_hw *hw = (struct zxdh_hw *)dev->data->dev_private;
1449 : 0 : struct zxdh_port_attr_table port_attr = {0};
1450 : 0 : struct zxdh_msg_info msg = {0};
1451 : : int ret = 0;
1452 : : uint32_t hw_hf;
1453 : : uint32_t i;
1454 : :
1455 [ # # ]: 0 : if (dev->data->nb_rx_queues == 0) {
1456 : 0 : PMD_DRV_LOG(ERR, "port %u nb_rx_queues is 0", dev->data->port_id);
1457 : 0 : return -1;
1458 : : }
1459 : :
1460 : : /* config rss enable */
1461 : 0 : uint8_t curr_rss_enable = zxdh_get_rss_enable_conf(dev);
1462 : :
1463 [ # # ]: 0 : if (hw->rss_enable != curr_rss_enable) {
1464 [ # # ]: 0 : if (hw->is_pf) {
1465 : 0 : ret = zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
1466 : 0 : port_attr.rss_enable = curr_rss_enable;
1467 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &port_attr);
1468 [ # # ]: 0 : if (ret) {
1469 : 0 : PMD_DRV_LOG(ERR, "rss enable set failed");
1470 : 0 : return -EINVAL;
1471 : : }
1472 : : } else {
1473 : 0 : msg.data.rss_enable.enable = curr_rss_enable;
1474 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_ENABLE, &msg);
1475 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg,
1476 : : sizeof(struct zxdh_msg_info), NULL, 0);
1477 [ # # ]: 0 : if (ret) {
1478 : 0 : PMD_DRV_LOG(ERR, "rss enable set failed");
1479 : 0 : return -EINVAL;
1480 : : }
1481 : : }
1482 : 0 : hw->rss_enable = curr_rss_enable;
1483 : : }
1484 : :
1485 [ # # # # ]: 0 : if (curr_rss_enable && hw->rss_init == 0) {
1486 : : /* config hash factor */
1487 [ # # ]: 0 : hw_hf = zxdh_rss_hf_to_hw(dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf);
1488 : : memset(&msg, 0, sizeof(msg));
1489 [ # # ]: 0 : if (hw->is_pf) {
1490 : 0 : ret = zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
1491 : 0 : port_attr.rss_hash_factor = hw_hf;
1492 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &port_attr);
1493 [ # # ]: 0 : if (ret) {
1494 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1495 : 0 : return -EINVAL;
1496 : : }
1497 : : } else {
1498 : 0 : msg.data.rss_hf.rss_hf = hw_hf;
1499 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_HF_SET, &msg);
1500 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg,
1501 : : sizeof(struct zxdh_msg_info), NULL, 0);
1502 [ # # ]: 0 : if (ret) {
1503 : 0 : PMD_DRV_LOG(ERR, "rss hash factor set failed");
1504 : 0 : return -EINVAL;
1505 : : }
1506 : : }
1507 : 0 : hw->rss_init = 1;
1508 : : }
1509 : :
1510 [ # # ]: 0 : if (!hw->rss_reta) {
1511 : 0 : hw->rss_reta = rte_calloc(NULL, RTE_ETH_RSS_RETA_SIZE_256, sizeof(uint16_t), 0);
1512 [ # # ]: 0 : if (hw->rss_reta == NULL) {
1513 : 0 : PMD_DRV_LOG(ERR, "alloc memory fail");
1514 : 0 : return -1;
1515 : : }
1516 : : }
1517 [ # # ]: 0 : for (i = 0; i < RTE_ETH_RSS_RETA_SIZE_256; i++)
1518 : 0 : hw->rss_reta[i] = i % dev_data->nb_rx_queues;
1519 : :
1520 : : /* hw config reta */
1521 : 0 : zxdh_msg_head_build(hw, ZXDH_RSS_RETA_SET, &msg);
1522 [ # # ]: 0 : for (i = 0; i < RTE_ETH_RSS_RETA_SIZE_256; i++)
1523 : 0 : msg.data.rss_reta.reta[i] =
1524 : 0 : hw->channel_context[hw->rss_reta[i] * 2].ph_chno;
1525 : :
1526 [ # # ]: 0 : if (hw->is_pf) {
1527 : 0 : ret = zxdh_rss_table_set(hw, hw->vport.vport, &msg.data.rss_reta);
1528 [ # # ]: 0 : if (ret) {
1529 : 0 : PMD_DRV_LOG(ERR, "rss reta table set failed");
1530 : 0 : return -EINVAL;
1531 : : }
1532 : : } else {
1533 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg, sizeof(struct zxdh_msg_info), NULL, 0);
1534 [ # # ]: 0 : if (ret) {
1535 : 0 : PMD_DRV_LOG(ERR, "vf rss reta table set failed");
1536 : 0 : return -EINVAL;
1537 : : }
1538 : : }
1539 : : return 0;
1540 : : }
1541 : :
1542 : : static int32_t
1543 : 0 : zxdh_hw_vqm_stats_get(struct rte_eth_dev *dev, enum zxdh_agent_msg_type opcode,
1544 : : struct zxdh_hw_vqm_stats *hw_stats)
1545 : : {
1546 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1547 : 0 : struct zxdh_msg_info msg_info = {0};
1548 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
1549 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
1550 : : enum ZXDH_BAR_MODULE_ID module_id;
1551 : : int ret = 0;
1552 : :
1553 [ # # # ]: 0 : switch (opcode) {
1554 : : case ZXDH_VQM_DEV_STATS_GET:
1555 : : case ZXDH_VQM_QUEUE_STATS_GET:
1556 : : case ZXDH_VQM_QUEUE_STATS_RESET:
1557 : : module_id = ZXDH_BAR_MODULE_VQM;
1558 : : break;
1559 : 0 : case ZXDH_MAC_STATS_GET:
1560 : : case ZXDH_MAC_STATS_RESET:
1561 : : module_id = ZXDH_BAR_MODULE_MAC;
1562 : 0 : break;
1563 : 0 : default:
1564 : 0 : PMD_DRV_LOG(ERR, "invalid opcode %u", opcode);
1565 : 0 : return -1;
1566 : : }
1567 : :
1568 : 0 : zxdh_agent_msg_build(hw, opcode, &msg_info);
1569 : :
1570 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
1571 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info), module_id);
1572 [ # # ]: 0 : if (ret) {
1573 : 0 : PMD_DRV_LOG(ERR, "Failed to get hw stats");
1574 : 0 : return -1;
1575 : : }
1576 : :
1577 : : void *hw_vqm_stats = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, vqm_stats);
1578 : : memcpy(hw_stats, hw_vqm_stats, sizeof(struct zxdh_hw_vqm_stats));
1579 : :
1580 : 0 : return 0;
1581 : : }
1582 : :
1583 : : static int
1584 : 0 : zxdh_hw_mac_stats_get(struct rte_eth_dev *dev,
1585 : : struct zxdh_hw_mac_stats *mac_stats,
1586 : : struct zxdh_hw_mac_bytes *mac_bytes)
1587 : : {
1588 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1589 : 0 : uint64_t virt_addr = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] + ZXDH_MAC_OFFSET);
1590 : : uint64_t stats_addr = 0;
1591 : : uint64_t bytes_addr = 0;
1592 : :
1593 [ # # ]: 0 : if (hw->speed <= RTE_ETH_SPEED_NUM_25G) {
1594 : 0 : stats_addr = virt_addr + ZXDH_MAC_STATS_OFFSET + 352 * (hw->phyport % 4);
1595 : 0 : bytes_addr = virt_addr + ZXDH_MAC_BYTES_OFFSET + 32 * (hw->phyport % 4);
1596 : : } else {
1597 : 0 : stats_addr = virt_addr + ZXDH_MAC_STATS_OFFSET + 352 * 4;
1598 : 0 : bytes_addr = virt_addr + ZXDH_MAC_BYTES_OFFSET + 32 * 4;
1599 : : }
1600 : :
1601 : 0 : memcpy(mac_stats, (void *)stats_addr, sizeof(struct zxdh_hw_mac_stats));
1602 : 0 : memcpy(mac_bytes, (void *)bytes_addr, sizeof(struct zxdh_hw_mac_bytes));
1603 : 0 : return 0;
1604 : : }
1605 : :
1606 : : void
1607 : 0 : zxdh_data_hi_to_lo(uint64_t *data)
1608 : : {
1609 : : uint32_t n_data_hi;
1610 : : uint32_t n_data_lo;
1611 : :
1612 : 0 : n_data_lo = *data >> 32;
1613 : : n_data_hi = *data;
1614 : 0 : *data = (uint64_t)(rte_le_to_cpu_32(n_data_hi)) << 32 |
1615 : : rte_le_to_cpu_32(n_data_lo);
1616 : 0 : }
1617 : :
1618 : : static int
1619 : 0 : zxdh_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *np_stats)
1620 : : {
1621 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1622 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1623 : : struct zxdh_np_stats_data stats_data;
1624 : 0 : uint32_t stats_id = zxdh_vport_to_vfid(hw->vport);
1625 : : uint32_t idx = 0;
1626 : : int ret = 0;
1627 : :
1628 : 0 : idx = stats_id + ZXDH_BROAD_STATS_EGRESS_BASE;
1629 : : memset(&stats_data, 0, sizeof(stats_data));
1630 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1631 : : 0, idx, (uint32_t *)&stats_data);
1632 [ # # ]: 0 : if (ret)
1633 : : return ret;
1634 : 0 : np_stats->tx_broadcast_pkts = stats_data.n_pkts_dropped;
1635 : 0 : np_stats->tx_broadcast_bytes = stats_data.n_bytes_dropped;
1636 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_broadcast_pkts);
1637 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_broadcast_bytes);
1638 : :
1639 : 0 : idx = stats_id + ZXDH_BROAD_STATS_INGRESS_BASE;
1640 : : memset(&stats_data, 0, sizeof(stats_data));
1641 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1642 : : 0, idx, (uint32_t *)&stats_data);
1643 [ # # ]: 0 : if (ret)
1644 : : return ret;
1645 : 0 : np_stats->rx_broadcast_pkts = stats_data.n_pkts_dropped;
1646 : 0 : np_stats->rx_broadcast_bytes = stats_data.n_bytes_dropped;
1647 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_broadcast_pkts);
1648 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_broadcast_bytes);
1649 : :
1650 : 0 : idx = stats_id + ZXDH_MULTICAST_STATS_EGRESS_BASE;
1651 : : memset(&stats_data, 0, sizeof(stats_data));
1652 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1653 : : 0, idx, (uint32_t *)&stats_data);
1654 [ # # ]: 0 : if (ret)
1655 : : return ret;
1656 : 0 : np_stats->tx_multicast_pkts = stats_data.n_pkts_dropped;
1657 : 0 : np_stats->tx_multicast_bytes = stats_data.n_bytes_dropped;
1658 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_multicast_pkts);
1659 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_multicast_bytes);
1660 : :
1661 : 0 : idx = stats_id + ZXDH_MULTICAST_STATS_INGRESS_BASE;
1662 : : memset(&stats_data, 0, sizeof(stats_data));
1663 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1664 : : 0, idx, (uint32_t *)&stats_data);
1665 [ # # ]: 0 : if (ret)
1666 : : return ret;
1667 : 0 : np_stats->rx_multicast_pkts = stats_data.n_pkts_dropped;
1668 : 0 : np_stats->rx_multicast_bytes = stats_data.n_bytes_dropped;
1669 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_multicast_pkts);
1670 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_multicast_bytes);
1671 : :
1672 : 0 : idx = stats_id + ZXDH_UNICAST_STATS_EGRESS_BASE;
1673 : : memset(&stats_data, 0, sizeof(stats_data));
1674 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1675 : : 0, idx, (uint32_t *)&stats_data);
1676 [ # # ]: 0 : if (ret)
1677 : : return ret;
1678 : 0 : np_stats->tx_unicast_pkts = stats_data.n_pkts_dropped;
1679 : 0 : np_stats->tx_unicast_bytes = stats_data.n_bytes_dropped;
1680 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_unicast_pkts);
1681 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_unicast_bytes);
1682 : :
1683 : 0 : idx = stats_id + ZXDH_UNICAST_STATS_INGRESS_BASE;
1684 : : memset(&stats_data, 0, sizeof(stats_data));
1685 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1686 : : 0, idx, (uint32_t *)&stats_data);
1687 [ # # ]: 0 : if (ret)
1688 : : return ret;
1689 : 0 : np_stats->rx_unicast_pkts = stats_data.n_pkts_dropped;
1690 : 0 : np_stats->rx_unicast_bytes = stats_data.n_bytes_dropped;
1691 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_unicast_pkts);
1692 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_unicast_bytes);
1693 : :
1694 : 0 : idx = stats_id + ZXDH_MTU_STATS_EGRESS_BASE;
1695 : : memset(&stats_data, 0, sizeof(stats_data));
1696 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1697 : : 1, idx, (uint32_t *)&stats_data);
1698 [ # # ]: 0 : if (ret)
1699 : : return ret;
1700 : 0 : np_stats->tx_mtu_drop_pkts = stats_data.n_pkts_dropped;
1701 : 0 : np_stats->tx_mtu_drop_bytes = stats_data.n_bytes_dropped;
1702 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_mtu_drop_pkts);
1703 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_mtu_drop_bytes);
1704 : :
1705 : 0 : idx = stats_id + ZXDH_MTU_STATS_INGRESS_BASE;
1706 : : memset(&stats_data, 0, sizeof(stats_data));
1707 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1708 : : 1, idx, (uint32_t *)&stats_data);
1709 [ # # ]: 0 : if (ret)
1710 : : return ret;
1711 : 0 : np_stats->rx_mtu_drop_pkts = stats_data.n_pkts_dropped;
1712 : 0 : np_stats->rx_mtu_drop_bytes = stats_data.n_bytes_dropped;
1713 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_mtu_drop_pkts);
1714 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_mtu_drop_bytes);
1715 : :
1716 : 0 : idx = stats_id + ZXDH_MTR_STATS_EGRESS_BASE;
1717 : : memset(&stats_data, 0, sizeof(stats_data));
1718 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1719 : : 1, idx, (uint32_t *)&stats_data);
1720 [ # # ]: 0 : if (ret)
1721 : : return ret;
1722 : 0 : np_stats->tx_mtr_drop_pkts = stats_data.n_pkts_dropped;
1723 : 0 : np_stats->tx_mtr_drop_bytes = stats_data.n_bytes_dropped;
1724 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_mtr_drop_pkts);
1725 : 0 : zxdh_data_hi_to_lo(&np_stats->tx_mtr_drop_bytes);
1726 : :
1727 : 0 : idx = stats_id + ZXDH_MTR_STATS_INGRESS_BASE;
1728 : : memset(&stats_data, 0, sizeof(stats_data));
1729 : 0 : ret = zxdh_np_dtb_stats_get(hw->dev_id, dtb_data->queueid,
1730 : : 1, idx, (uint32_t *)&stats_data);
1731 [ # # ]: 0 : if (ret)
1732 : : return ret;
1733 : 0 : np_stats->rx_mtr_drop_pkts = stats_data.n_pkts_dropped;
1734 : 0 : np_stats->rx_mtr_drop_bytes = stats_data.n_bytes_dropped;
1735 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_mtr_drop_pkts);
1736 : 0 : zxdh_data_hi_to_lo(&np_stats->rx_mtr_drop_bytes);
1737 : :
1738 : 0 : return 0;
1739 : : }
1740 : :
1741 : : static int
1742 : 0 : zxdh_hw_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *np_stats)
1743 : : {
1744 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1745 : 0 : struct zxdh_msg_info msg_info = {0};
1746 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
1747 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
1748 : : void *hw_stas_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, hw_stats);
1749 : : int ret = 0;
1750 : :
1751 [ # # ]: 0 : if (hw->is_pf) {
1752 : 0 : ret = zxdh_np_stats_get(dev, np_stats);
1753 [ # # ]: 0 : if (ret) {
1754 : 0 : PMD_DRV_LOG(ERR, "get np stats failed");
1755 : 0 : return -1;
1756 : : }
1757 : : } else {
1758 : 0 : zxdh_msg_head_build(hw, ZXDH_GET_NP_STATS, &msg_info);
1759 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(struct zxdh_msg_info),
1760 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info));
1761 [ # # ]: 0 : if (ret) {
1762 : 0 : PMD_DRV_LOG(ERR,
1763 : : "Failed to send msg: port 0x%x msg type", hw->vport.vport);
1764 : 0 : return -1;
1765 : : }
1766 : : memcpy(np_stats, hw_stas_addr, sizeof(struct zxdh_hw_np_stats));
1767 : : }
1768 : : return ret;
1769 : : }
1770 : :
1771 : : int
1772 : 0 : zxdh_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
1773 : : struct eth_queue_stats *qstats)
1774 : : {
1775 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1776 : 0 : struct zxdh_hw_vqm_stats vqm_stats = {0};
1777 : 0 : struct zxdh_hw_np_stats np_stats = {0};
1778 : 0 : struct zxdh_hw_mac_stats mac_stats = {0};
1779 : 0 : struct zxdh_hw_mac_bytes mac_bytes = {0};
1780 : : uint32_t i = 0;
1781 : :
1782 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1783 : 0 : zxdh_hw_vqm_stats_get(dev, ZXDH_VQM_DEV_STATS_GET, &vqm_stats);
1784 [ # # ]: 0 : if (hw->is_pf)
1785 : 0 : zxdh_hw_mac_stats_get(dev, &mac_stats, &mac_bytes);
1786 : :
1787 : 0 : zxdh_hw_np_stats_get(dev, &np_stats);
1788 : :
1789 : 0 : stats->ipackets = vqm_stats.rx_total;
1790 : 0 : stats->opackets = vqm_stats.tx_total;
1791 : 0 : stats->ibytes = vqm_stats.rx_bytes;
1792 : 0 : stats->obytes = vqm_stats.tx_bytes;
1793 : 0 : stats->imissed = vqm_stats.rx_drop + mac_stats.rx_drop;
1794 : 0 : stats->ierrors = vqm_stats.rx_error +
1795 : 0 : mac_stats.rx_error + np_stats.rx_mtu_drop_pkts;
1796 : 0 : stats->oerrors = vqm_stats.tx_error +
1797 : 0 : mac_stats.tx_error + np_stats.tx_mtu_drop_pkts;
1798 : :
1799 [ # # ]: 0 : if (hw->i_mtr_en || hw->e_mtr_en)
1800 : 0 : stats->imissed += np_stats.rx_mtr_drop_pkts;
1801 : : }
1802 : :
1803 : 0 : stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
1804 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1805 : 0 : struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[i];
1806 : :
1807 [ # # ]: 0 : if (rxvq == NULL)
1808 : 0 : continue;
1809 [ # # ]: 0 : if (qstats != NULL) {
1810 : 0 : qstats[i].q_ipackets = *(uint64_t *)(((char *)rxvq) +
1811 : : zxdh_rxq_stat_strings[0].offset);
1812 : 0 : qstats[i].q_ibytes = *(uint64_t *)(((char *)rxvq) +
1813 : : zxdh_rxq_stat_strings[1].offset);
1814 : : }
1815 : : }
1816 : :
1817 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
1818 : 0 : struct zxdh_virtnet_tx *txvq = dev->data->tx_queues[i];
1819 : :
1820 [ # # ]: 0 : if (txvq == NULL)
1821 : 0 : continue;
1822 [ # # ]: 0 : if (qstats != NULL) {
1823 : 0 : qstats[i].q_opackets = *(uint64_t *)(((char *)txvq) +
1824 : : zxdh_txq_stat_strings[0].offset);
1825 : 0 : qstats[i].q_obytes = *(uint64_t *)(((char *)txvq) +
1826 : : zxdh_txq_stat_strings[1].offset);
1827 : : }
1828 : : }
1829 : 0 : return 0;
1830 : : }
1831 : :
1832 : : static int
1833 : 0 : zxdh_hw_stats_reset(struct rte_eth_dev *dev, enum zxdh_agent_msg_type opcode)
1834 : : {
1835 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1836 : 0 : struct zxdh_msg_info msg_info = {0};
1837 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
1838 : : enum ZXDH_BAR_MODULE_ID module_id;
1839 : : int ret = 0;
1840 : :
1841 [ # # # ]: 0 : switch (opcode) {
1842 : : case ZXDH_VQM_DEV_STATS_RESET:
1843 : : module_id = ZXDH_BAR_MODULE_VQM;
1844 : : break;
1845 : 0 : case ZXDH_MAC_STATS_RESET:
1846 : : module_id = ZXDH_BAR_MODULE_MAC;
1847 : 0 : break;
1848 : 0 : default:
1849 : 0 : PMD_DRV_LOG(ERR, "invalid opcode %u", opcode);
1850 : 0 : return -1;
1851 : : }
1852 : :
1853 : 0 : zxdh_agent_msg_build(hw, opcode, &msg_info);
1854 : :
1855 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
1856 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info), module_id);
1857 [ # # ]: 0 : if (ret) {
1858 : 0 : PMD_DRV_LOG(ERR, "Failed to reset hw stats");
1859 : 0 : return -1;
1860 : : }
1861 : : return 0;
1862 : : }
1863 : :
1864 : : int
1865 : 0 : zxdh_hw_np_stats_pf_reset(struct rte_eth_dev *dev, uint32_t stats_id)
1866 : : {
1867 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1868 : : struct zxdh_hw_stats_data stats_data;
1869 : : uint32_t idx = 0;
1870 : : int ret = 0;
1871 : :
1872 : 0 : idx = stats_id + ZXDH_UNICAST_STATS_EGRESS_BASE;
1873 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1874 : : 1, (uint32_t *)&stats_data);
1875 [ # # ]: 0 : if (ret)
1876 : : return ret;
1877 : :
1878 : 0 : idx = stats_id + ZXDH_UNICAST_STATS_INGRESS_BASE;
1879 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1880 : : 1, (uint32_t *)&stats_data);
1881 [ # # ]: 0 : if (ret)
1882 : : return ret;
1883 : :
1884 : 0 : idx = stats_id + ZXDH_MULTICAST_STATS_EGRESS_BASE;
1885 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1886 : : 1, (uint32_t *)&stats_data);
1887 [ # # ]: 0 : if (ret)
1888 : : return ret;
1889 : :
1890 : 0 : idx = stats_id + ZXDH_MULTICAST_STATS_INGRESS_BASE;
1891 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1892 : : 1, (uint32_t *)&stats_data);
1893 [ # # ]: 0 : if (ret)
1894 : : return ret;
1895 : :
1896 : 0 : idx = stats_id + ZXDH_BROAD_STATS_EGRESS_BASE;
1897 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1898 : : 1, (uint32_t *)&stats_data);
1899 [ # # ]: 0 : if (ret)
1900 : : return ret;
1901 : :
1902 : 0 : idx = stats_id + ZXDH_BROAD_STATS_INGRESS_BASE;
1903 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1904 : : 1, (uint32_t *)&stats_data);
1905 [ # # ]: 0 : if (ret)
1906 : : return ret;
1907 : :
1908 : 0 : idx = stats_id + ZXDH_MTU_STATS_EGRESS_BASE;
1909 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1910 : : 1, (uint32_t *)&stats_data);
1911 [ # # ]: 0 : if (ret)
1912 : : return ret;
1913 : :
1914 : 0 : idx = stats_id + ZXDH_MTU_STATS_INGRESS_BASE;
1915 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1916 : : 1, (uint32_t *)&stats_data);
1917 [ # # ]: 0 : if (ret)
1918 : : return ret;
1919 : :
1920 : 0 : idx = stats_id + ZXDH_MTR_STATS_EGRESS_BASE;
1921 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1922 : : 1, (uint32_t *)&stats_data);
1923 [ # # ]: 0 : if (ret)
1924 : : return ret;
1925 : :
1926 : 0 : idx = stats_id + ZXDH_MTR_STATS_INGRESS_BASE;
1927 : 0 : ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
1928 : : 1, (uint32_t *)&stats_data);
1929 : :
1930 : 0 : return ret;
1931 : : }
1932 : :
1933 : : static int
1934 : 0 : zxdh_hw_np_stats_vf_reset(struct rte_eth_dev *dev)
1935 : : {
1936 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1937 : 0 : struct zxdh_msg_info msg_info = {0};
1938 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
1939 : : int ret = 0;
1940 : :
1941 : 0 : msg_info.data.np_stats_query.clear_mode = 1;
1942 : 0 : zxdh_msg_head_build(hw, ZXDH_GET_NP_STATS, &msg_info);
1943 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(struct zxdh_msg_info),
1944 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info));
1945 [ # # ]: 0 : if (ret)
1946 : 0 : PMD_DRV_LOG(ERR, "Failed to send ZXDH_PORT_METER_STAT_GET msg. code:%d", ret);
1947 : :
1948 : 0 : return ret;
1949 : : }
1950 : :
1951 : : static int
1952 : 0 : zxdh_np_stats_reset(struct rte_eth_dev *dev)
1953 : : {
1954 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1955 : 0 : uint32_t stats_id = zxdh_vport_to_vfid(hw->vport);
1956 : : int ret;
1957 : :
1958 [ # # ]: 0 : if (hw->is_pf)
1959 : 0 : ret = zxdh_hw_np_stats_pf_reset(dev, stats_id);
1960 : : else
1961 : 0 : ret = zxdh_hw_np_stats_vf_reset(dev);
1962 : 0 : return ret;
1963 : : }
1964 : :
1965 : 0 : int zxdh_dev_stats_reset(struct rte_eth_dev *dev)
1966 : : {
1967 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1968 : : int i = 0;
1969 : :
1970 : 0 : zxdh_hw_stats_reset(dev, ZXDH_VQM_DEV_STATS_RESET);
1971 [ # # ]: 0 : if (hw->is_pf)
1972 : 0 : zxdh_hw_stats_reset(dev, ZXDH_MAC_STATS_RESET);
1973 : 0 : zxdh_np_stats_reset(dev);
1974 [ # # ]: 0 : for (i = 0; (i < dev->data->nb_rx_queues); i++) {
1975 : 0 : struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[i];
1976 [ # # ]: 0 : if (rxvq == NULL)
1977 : 0 : continue;
1978 : 0 : memset(&rxvq->stats, 0, sizeof(struct zxdh_virtnet_stats));
1979 : : }
1980 [ # # ]: 0 : for (i = 0; (i < dev->data->nb_tx_queues); i++) {
1981 : 0 : struct zxdh_virtnet_tx *txvq = dev->data->tx_queues[i];
1982 [ # # ]: 0 : if (txvq == NULL)
1983 : 0 : continue;
1984 : 0 : memset(&txvq->stats, 0, sizeof(struct zxdh_virtnet_stats));
1985 : : }
1986 : :
1987 : 0 : return 0;
1988 : : }
1989 : :
1990 : 0 : int zxdh_dev_mtu_set(struct rte_eth_dev *dev, uint16_t new_mtu)
1991 : : {
1992 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1993 : 0 : struct zxdh_panel_table panel = {0};
1994 : 0 : struct zxdh_port_attr_table vport_att = {0};
1995 : 0 : uint16_t vfid = zxdh_vport_to_vfid(hw->vport);
1996 : : int ret;
1997 : :
1998 : : /* If device is started, refuse mtu that requires the support of
1999 : : * scattered packets when this feature has not been enabled before.
2000 : : */
2001 [ # # ]: 0 : if (dev->data->dev_started) {
2002 : 0 : uint32_t buf_size = dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM;
2003 : 0 : uint8_t need_scatter =
2004 [ # # ]: 0 : (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_SCATTER) ||
2005 [ # # ]: 0 : (uint32_t)ZXDH_MTU_TO_PKTLEN(new_mtu) > buf_size;
2006 : :
2007 [ # # # # ]: 0 : if (need_scatter && !dev->data->scattered_rx) {
2008 : 0 : PMD_DRV_LOG(ERR, "Stop port first.");
2009 : 0 : return -EINVAL;
2010 : : }
2011 : : }
2012 : :
2013 [ # # ]: 0 : if (hw->is_pf) {
2014 : 0 : ret = zxdh_get_panel_attr(dev, &panel);
2015 [ # # ]: 0 : if (ret != 0) {
2016 : 0 : PMD_DRV_LOG(ERR, "get_panel_attr failed ret:%d", ret);
2017 : 0 : return ret;
2018 : : }
2019 : :
2020 : 0 : ret = zxdh_get_port_attr(hw, hw->vport.vport, &vport_att);
2021 [ # # ]: 0 : if (ret != 0) {
2022 : 0 : PMD_DRV_LOG(ERR,
2023 : : "[vfid:%d] zxdh_dev_mtu, get vport failed ret:%d", vfid, ret);
2024 : 0 : return ret;
2025 : : }
2026 : :
2027 : 0 : panel.mtu = new_mtu;
2028 : 0 : panel.mtu_enable = 1;
2029 : 0 : ret = zxdh_set_panel_attr(dev, &panel);
2030 [ # # ]: 0 : if (ret != 0) {
2031 : 0 : PMD_DRV_LOG(ERR, "set zxdh_dev_mtu failed, ret:%u", ret);
2032 : 0 : return ret;
2033 : : }
2034 : :
2035 : 0 : vport_att.mtu_enable = 1;
2036 : 0 : vport_att.mtu = new_mtu;
2037 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &vport_att);
2038 [ # # ]: 0 : if (ret != 0) {
2039 : 0 : PMD_DRV_LOG(ERR,
2040 : : "[vfid:%d] zxdh_dev_mtu, set vport failed ret:%d", vfid, ret);
2041 : 0 : return ret;
2042 : : }
2043 : : } else {
2044 : 0 : struct zxdh_msg_info msg_info = {0};
2045 : : struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
2046 : :
2047 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
2048 : 0 : attr_msg->mode = ZXDH_PORT_MTU_OFFLOAD_EN_OFF_FLAG;
2049 : 0 : attr_msg->value = 1;
2050 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
2051 [ # # ]: 0 : if (ret) {
2052 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
2053 : : hw->vport.vport, ZXDH_PORT_MTU_OFFLOAD_EN_OFF_FLAG);
2054 : 0 : return ret;
2055 : : }
2056 : 0 : attr_msg->mode = ZXDH_PORT_MTU_FLAG;
2057 : 0 : attr_msg->value = new_mtu;
2058 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
2059 [ # # ]: 0 : if (ret) {
2060 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
2061 : : hw->vport.vport, ZXDH_PORT_MTU_FLAG);
2062 : 0 : return ret;
2063 : : }
2064 : : }
2065 : 0 : dev->data->mtu = new_mtu;
2066 : 0 : return 0;
2067 : : }
2068 : :
2069 : : int32_t
2070 : 0 : zxdh_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, uint32_t n)
2071 : : {
2072 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
2073 : 0 : struct zxdh_hw_np_stats np_stats = {0};
2074 : 0 : struct zxdh_hw_mac_stats mac_stats = {0};
2075 : 0 : struct zxdh_hw_mac_bytes mac_bytes = {0};
2076 : 0 : struct zxdh_hw_vqm_stats vqm_stats = {0};
2077 : 0 : uint32_t nstats = dev->data->nb_tx_queues * ZXDH_NB_TXQ_XSTATS +
2078 : 0 : dev->data->nb_rx_queues * ZXDH_NB_RXQ_XSTATS +
2079 : 0 : ZXDH_NP_XSTATS + ZXDH_VQM_XSTATS;
2080 : : uint32_t i = 0;
2081 : : uint32_t count = 0;
2082 : : uint32_t t = 0;
2083 : :
2084 [ # # ]: 0 : if (hw->is_pf)
2085 : 0 : nstats += ZXDH_MAC_XSTATS + ZXDH_MAC_BYTES;
2086 : :
2087 [ # # ]: 0 : if (n < nstats)
2088 : 0 : return nstats;
2089 : :
2090 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
2091 [ # # ]: 0 : if (hw->is_pf)
2092 : 0 : zxdh_hw_mac_stats_get(dev, &mac_stats, &mac_bytes);
2093 : :
2094 : 0 : zxdh_hw_vqm_stats_get(dev, ZXDH_VQM_DEV_STATS_GET, &vqm_stats);
2095 : 0 : zxdh_hw_np_stats_get(dev, &np_stats);
2096 : : }
2097 : :
2098 [ # # ]: 0 : for (i = 0; i < ZXDH_NP_XSTATS; i++) {
2099 : 0 : xstats[count].value = *(uint64_t *)(((char *)&np_stats)
2100 : 0 : + zxdh_np_stat_strings[i].offset);
2101 : 0 : xstats[count].id = count;
2102 : 0 : count++;
2103 : : }
2104 [ # # ]: 0 : if (hw->is_pf) {
2105 [ # # ]: 0 : for (i = 0; i < ZXDH_MAC_XSTATS; i++) {
2106 : 0 : xstats[count].value = *(uint64_t *)(((char *)&mac_stats)
2107 : 0 : + zxdh_mac_stat_strings[i].offset);
2108 : 0 : xstats[count].id = count;
2109 : 0 : count++;
2110 : : }
2111 [ # # ]: 0 : for (i = 0; i < ZXDH_MAC_BYTES; i++) {
2112 : 0 : xstats[count].value = *(uint64_t *)(((char *)&mac_bytes)
2113 : 0 : + zxdh_mac_bytes_strings[i].offset);
2114 : 0 : xstats[count].id = count;
2115 : 0 : count++;
2116 : : }
2117 : : }
2118 [ # # ]: 0 : for (i = 0; i < ZXDH_VQM_XSTATS; i++) {
2119 : 0 : xstats[count].value = *(uint64_t *)(((char *)&vqm_stats)
2120 : 0 : + zxdh_vqm_stat_strings[i].offset);
2121 : 0 : xstats[count].id = count;
2122 : 0 : count++;
2123 : : }
2124 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
2125 : 0 : struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[i];
2126 : :
2127 [ # # ]: 0 : if (rxvq == NULL)
2128 : 0 : continue;
2129 [ # # ]: 0 : for (t = 0; t < ZXDH_NB_RXQ_XSTATS; t++) {
2130 : 0 : xstats[count].value = *(uint64_t *)(((char *)rxvq)
2131 : 0 : + zxdh_rxq_stat_strings[t].offset);
2132 : 0 : xstats[count].id = count;
2133 : 0 : count++;
2134 : : }
2135 : : }
2136 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
2137 : 0 : struct zxdh_virtnet_tx *txvq = dev->data->tx_queues[i];
2138 : :
2139 [ # # ]: 0 : if (txvq == NULL)
2140 : 0 : continue;
2141 : :
2142 [ # # ]: 0 : for (t = 0; t < ZXDH_NB_TXQ_XSTATS; t++) {
2143 : 0 : xstats[count].value = *(uint64_t *)(((char *)txvq)
2144 : 0 : + zxdh_txq_stat_strings[t].offset);
2145 : 0 : xstats[count].id = count;
2146 : 0 : count++;
2147 : : }
2148 : : }
2149 : 0 : return count;
2150 : : }
2151 : :
2152 : :
2153 : : int32_t
2154 : 0 : zxdh_dev_xstats_get_names(struct rte_eth_dev *dev,
2155 : : struct rte_eth_xstat_name *xstats_names,
2156 : : __rte_unused unsigned int limit)
2157 : : {
2158 : : uint32_t i = 0;
2159 : : uint32_t count = 0;
2160 : : uint32_t t = 0;
2161 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
2162 : 0 : unsigned int nstats = dev->data->nb_tx_queues * ZXDH_NB_TXQ_XSTATS +
2163 : 0 : dev->data->nb_rx_queues * ZXDH_NB_RXQ_XSTATS +
2164 : 0 : ZXDH_NP_XSTATS + ZXDH_VQM_XSTATS;
2165 : :
2166 [ # # ]: 0 : if (hw->is_pf)
2167 : 0 : nstats += ZXDH_MAC_XSTATS + ZXDH_MAC_BYTES;
2168 : :
2169 [ # # ]: 0 : if (xstats_names != NULL) {
2170 [ # # ]: 0 : for (i = 0; i < ZXDH_NP_XSTATS; i++) {
2171 : 0 : snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),
2172 : 0 : "%s", zxdh_np_stat_strings[i].name);
2173 : 0 : count++;
2174 : : }
2175 [ # # ]: 0 : if (hw->is_pf) {
2176 [ # # ]: 0 : for (i = 0; i < ZXDH_MAC_XSTATS; i++) {
2177 : 0 : snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),
2178 : 0 : "%s", zxdh_mac_stat_strings[i].name);
2179 : 0 : count++;
2180 : : }
2181 [ # # ]: 0 : for (i = 0; i < ZXDH_MAC_BYTES; i++) {
2182 : 0 : snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),
2183 : 0 : "%s", zxdh_mac_bytes_strings[i].name);
2184 : 0 : count++;
2185 : : }
2186 : : }
2187 [ # # ]: 0 : for (i = 0; i < ZXDH_VQM_XSTATS; i++) {
2188 : 0 : snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),
2189 : 0 : "%s", zxdh_vqm_stat_strings[i].name);
2190 : 0 : count++;
2191 : : }
2192 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
2193 : 0 : struct virtnet_rx *rxvq = dev->data->rx_queues[i];
2194 : :
2195 [ # # ]: 0 : if (rxvq == NULL)
2196 : 0 : continue;
2197 [ # # ]: 0 : for (t = 0; t < ZXDH_NB_RXQ_XSTATS; t++) {
2198 : 0 : snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),
2199 : 0 : "rx_q%u_%s", i, zxdh_rxq_stat_strings[t].name);
2200 : 0 : count++;
2201 : : }
2202 : : }
2203 : :
2204 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
2205 : 0 : struct virtnet_tx *txvq = dev->data->tx_queues[i];
2206 : :
2207 [ # # ]: 0 : if (txvq == NULL)
2208 : 0 : continue;
2209 [ # # ]: 0 : for (t = 0; t < ZXDH_NB_TXQ_XSTATS; t++) {
2210 : 0 : snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),
2211 : 0 : "tx_q%u_%s", i, zxdh_txq_stat_strings[t].name);
2212 : 0 : count++;
2213 : : }
2214 : : }
2215 : 0 : return count;
2216 : : }
2217 : 0 : return nstats;
2218 : : }
2219 : :
2220 : : int
2221 : 0 : zxdh_dev_fw_version_get(struct rte_eth_dev *dev,
2222 : : char *fw_version, size_t fw_size __rte_unused)
2223 : : {
2224 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
2225 : 0 : struct zxdh_msg_info msg_info = {0};
2226 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
2227 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
2228 : : void *flash_msg_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, flash_msg);
2229 : 0 : char fw_ver[ZXDH_FWVERS_LEN] = {0};
2230 : : uint32_t ret = 0;
2231 : :
2232 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2233 : : return -EPERM;
2234 : :
2235 : 0 : zxdh_agent_msg_build(hw, ZXDH_FLASH_FIR_VERSION_GET, &msg_info);
2236 : :
2237 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
2238 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),
2239 : : ZXDH_MODULE_FLASH);
2240 [ # # ]: 0 : if (ret) {
2241 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
2242 : : hw->vport.vport, ZXDH_FLASH_FIR_VERSION_GET);
2243 : 0 : return -1;
2244 : : }
2245 : :
2246 : : memcpy(fw_ver, flash_msg_addr, ZXDH_FWVERS_LEN);
2247 : : snprintf(fw_version, ZXDH_FWVERS_LEN - 1, "%s", fw_ver);
2248 : :
2249 : 0 : return 0;
2250 : : }
2251 : :
2252 : : static uint8_t
2253 : 0 : zxdh_en_module_eeprom_read(struct rte_eth_dev *dev,
2254 : : struct zxdh_mac_module_eeprom_msg *query, uint8_t *data)
2255 : : {
2256 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
2257 : 0 : struct zxdh_msg_info msg_info = {0};
2258 : 0 : uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
2259 : : uint8_t ret = 0;
2260 : :
2261 : 0 : zxdh_agent_msg_build(hw, ZXDH_MAC_MODULE_EEPROM_READ, &msg_info);
2262 : :
2263 : 0 : msg_info.data.module_eeprom_msg.i2c_addr = query->i2c_addr;
2264 : 0 : msg_info.data.module_eeprom_msg.bank = query->bank;
2265 : 0 : msg_info.data.module_eeprom_msg.page = query->page;
2266 : 0 : msg_info.data.module_eeprom_msg.offset = query->offset;
2267 : 0 : msg_info.data.module_eeprom_msg.length = query->length;
2268 : :
2269 : 0 : ret = zxdh_send_msg_to_riscv(dev, &msg_info, sizeof(struct zxdh_msg_info),
2270 : : zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),
2271 : : ZXDH_BAR_MODULE_MAC);
2272 [ # # ]: 0 : if (ret) {
2273 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
2274 : : hw->vport.vport, ZXDH_MAC_MODULE_EEPROM_READ);
2275 : 0 : return -1;
2276 : : }
2277 : : void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
2278 : : void *module_eeprom_msg_addr =
2279 : : ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, module_eeprom_msg);
2280 : : void *agent_mac_module_eeprom_msg_data_addr =
2281 : : ZXDH_ADDR_OF(agent_mac_module_eeprom_msg, module_eeprom_msg_addr, data);
2282 : 0 : uint8_t length = ZXDH_GET(agent_mac_module_eeprom_msg, module_eeprom_msg_addr, length);
2283 [ # # ]: 0 : if (data)
2284 : : memcpy(data, agent_mac_module_eeprom_msg_data_addr, length);
2285 : :
2286 : : return length;
2287 : : }
2288 : :
2289 : : int
2290 : 0 : zxdh_dev_get_module_info(struct rte_eth_dev *dev,
2291 : : struct rte_eth_dev_module_info *modinfo)
2292 : : {
2293 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
2294 : 0 : struct zxdh_mac_module_eeprom_msg query = {0};
2295 : : uint8_t read_bytes;
2296 : 0 : uint8_t data[2] = {0};
2297 : :
2298 [ # # ]: 0 : if (!hw->is_pf)
2299 : : return -EOPNOTSUPP;
2300 : :
2301 : 0 : query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_LOW;
2302 : : query.page = 0;
2303 : : query.offset = 0;
2304 : 0 : query.length = 2;
2305 : :
2306 : 0 : read_bytes = zxdh_en_module_eeprom_read(dev, &query, data);
2307 [ # # ]: 0 : if (read_bytes != query.length) {
2308 : 0 : PMD_DRV_LOG(ERR, "zxdh_en_module_eeprom_read failed");
2309 : 0 : return -EIO;
2310 : : }
2311 : :
2312 [ # # # # ]: 0 : switch (data[0]) {
2313 : 0 : case ZXDH_MODULE_ID_SFP:
2314 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8472;
2315 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
2316 : 0 : break;
2317 : 0 : case ZXDH_MODULE_ID_QSFP:
2318 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8436;
2319 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN;
2320 : 0 : break;
2321 : 0 : case ZXDH_MODULE_ID_QSFP_PLUS:
2322 : : case ZXDH_MODULE_ID_QSFP28:
2323 [ # # ]: 0 : if (data[1] < 3) {
2324 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8436;
2325 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN;
2326 : : } else {
2327 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8636;
2328 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN;
2329 : : }
2330 : : break;
2331 : 0 : default:
2332 : 0 : PMD_DRV_LOG(ERR, "can not recognize module identifier 0x%x!", data[0]);
2333 : 0 : return -EINVAL;
2334 : : }
2335 : :
2336 : : return 0;
2337 : : }
2338 : :
2339 : :
2340 : : int
2341 : 0 : zxdh_dev_get_module_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *info)
2342 : : {
2343 : 0 : struct zxdh_mac_module_eeprom_msg query = {0};
2344 : 0 : uint32_t offset = info->offset;
2345 : 0 : uint32_t length = info->length;
2346 : : uint32_t offset_boundary = 0;
2347 : : uint32_t total_read_bytes = 0;
2348 : : uint8_t read_bytes = 0;
2349 : : uint8_t identifier;
2350 : : uint8_t *data = NULL;
2351 : :
2352 [ # # ]: 0 : if (!info->length)
2353 : : return -EINVAL;
2354 : :
2355 : 0 : data = info->data;
2356 : 0 : memset(data, 0, info->length);
2357 : :
2358 : 0 : query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_LOW;
2359 : 0 : query.bank = 0;
2360 : 0 : query.page = 0;
2361 : 0 : query.offset = 0;
2362 : 0 : query.length = 1;
2363 : 0 : read_bytes = zxdh_en_module_eeprom_read(dev, &query, &identifier);
2364 [ # # ]: 0 : if (read_bytes != query.length) {
2365 : 0 : PMD_DRV_LOG(ERR, "read eeprom failed(read_bytes %d != query.length %d)!",
2366 : : read_bytes, query.length);
2367 : 0 : return -EIO;
2368 : : }
2369 : :
2370 [ # # ]: 0 : while (total_read_bytes < info->length) {
2371 [ # # ]: 0 : if (identifier == ZXDH_MODULE_ID_SFP) {
2372 [ # # ]: 0 : if (offset < 256) {
2373 : 0 : query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_LOW;
2374 : 0 : query.page = 0;
2375 : 0 : query.offset = offset;
2376 : : } else {
2377 : 0 : query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_HIGH;
2378 : 0 : query.page = 0;
2379 : 0 : query.offset = offset - 256;
2380 : : }
2381 [ # # ]: 0 : offset_boundary = (query.offset < 128) ? 128 : 256;
2382 [ # # ]: 0 : query.length = ((query.offset + length) > offset_boundary) ?
2383 : 0 : (offset_boundary - query.offset) : length;
2384 : 0 : } else if (identifier == ZXDH_MODULE_ID_QSFP ||
2385 [ # # ]: 0 : identifier == ZXDH_MODULE_ID_QSFP_PLUS ||
2386 : : identifier == ZXDH_MODULE_ID_QSFP28) {
2387 : 0 : query.i2c_addr = ZXDH_SFF_I2C_ADDRESS_LOW;
2388 [ # # ]: 0 : if (offset < 256) {
2389 : 0 : query.page = 0;
2390 : 0 : query.offset = offset;
2391 : : } else {
2392 : 0 : query.page = (offset - 256) / 128 + 1;
2393 : 0 : query.offset = offset - 128 * query.page;
2394 : : }
2395 [ # # ]: 0 : offset_boundary = (query.offset < 128) ? 128 : 256;
2396 [ # # ]: 0 : query.length = ((query.offset + length) > offset_boundary) ?
2397 : 0 : (offset_boundary - query.offset) : length;
2398 : : } else {
2399 : 0 : PMD_DRV_LOG(ERR, "can not recognize module identifier 0x%x!", identifier);
2400 : 0 : return -EINVAL;
2401 : : }
2402 : :
2403 : 0 : read_bytes = zxdh_en_module_eeprom_read(dev, &query, data + total_read_bytes);
2404 [ # # ]: 0 : if (read_bytes != query.length) {
2405 : 0 : PMD_DRV_LOG(ERR, "read eeprom failed(read_bytes %d != query.length %d)",
2406 : : read_bytes, query.length);
2407 : 0 : return -EIO;
2408 : : }
2409 : 0 : total_read_bytes = (total_read_bytes + read_bytes) % UINT32_MAX;
2410 : 0 : offset += read_bytes;
2411 : 0 : length -= read_bytes;
2412 : : }
2413 : : return 0;
2414 : : }
|