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