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