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