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