Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2023 Mucse IC Design Ltd.
3 : : */
4 : :
5 : : #include <ethdev_pci.h>
6 : : #include <ethdev_driver.h>
7 : : #include <rte_io.h>
8 : : #include <rte_malloc.h>
9 : :
10 : : #include "rnp.h"
11 : : #include "rnp_logs.h"
12 : : #include "base/rnp_mbx.h"
13 : : #include "base/rnp_fw_cmd.h"
14 : : #include "base/rnp_mbx_fw.h"
15 : : #include "base/rnp_mac.h"
16 : : #include "base/rnp_eth_regs.h"
17 : : #include "base/rnp_common.h"
18 : : #include "base/rnp_dma_regs.h"
19 : : #include "base/rnp_mac_regs.h"
20 : : #include "rnp_rxtx.h"
21 : : #include "rnp_rss.h"
22 : : #include "rnp_link.h"
23 : :
24 : : static int rnp_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
25 : : static struct rte_eth_dev *
26 : 0 : rnp_alloc_eth_port(struct rte_pci_device *pci, char *name)
27 : : {
28 : : struct rte_eth_dev *eth_dev = NULL;
29 : : struct rnp_eth_port *port = NULL;
30 : :
31 : 0 : eth_dev = rte_eth_dev_allocate(name);
32 [ # # ]: 0 : if (!eth_dev) {
33 : 0 : RNP_PMD_ERR("Could not allocate eth_dev for %s", name);
34 : 0 : return NULL;
35 : : }
36 : 0 : port = rte_zmalloc_socket(name,
37 : : sizeof(*port),
38 : : RTE_CACHE_LINE_SIZE,
39 : : pci->device.numa_node);
40 [ # # ]: 0 : if (!port) {
41 : 0 : RNP_PMD_ERR("Could not allocate rnp_eth_port for %s", name);
42 : 0 : goto fail_calloc;
43 : : }
44 : 0 : rte_eth_copy_pci_info(eth_dev, pci);
45 : 0 : eth_dev->data->dev_private = port;
46 : 0 : eth_dev->device = &pci->device;
47 : :
48 : 0 : return eth_dev;
49 : : fail_calloc:
50 : 0 : rte_free(port);
51 : 0 : rte_eth_dev_release_port(eth_dev);
52 : :
53 : 0 : return NULL;
54 : : }
55 : :
56 : : static int
57 : 0 : rnp_mbx_fw_reply_handler(struct rnp_eth_adapter *adapter,
58 : : void *cmd)
59 : : {
60 : : struct rnp_mbx_fw_cmd_reply *reply = cmd;
61 : : struct rnp_mbx_req_cookie *cookie;
62 : :
63 : : RTE_SET_USED(adapter);
64 : : /* dbg_here; */
65 : 0 : cookie = reply->cookie;
66 [ # # # # ]: 0 : if (!cookie || cookie->magic != RNP_COOKIE_MAGIC) {
67 : 0 : RNP_PMD_ERR("invalid cookie:%p opcode:0x%x v0:0x%x",
68 : : cookie, reply->opcode, *((int *)reply));
69 : 0 : return -EIO;
70 : : }
71 [ # # ]: 0 : if (cookie->priv_len > 0)
72 : 0 : memcpy(cookie->priv, reply->data, RNP_FW_REP_DATA_NUM);
73 : :
74 : 0 : cookie->done = 1;
75 [ # # ]: 0 : if (reply->flags & RNP_FLAGS_ERR)
76 : 0 : cookie->errcode = reply->error_code;
77 : : else
78 : 0 : cookie->errcode = 0;
79 : :
80 : : return 0;
81 : : }
82 : :
83 : : static int rnp_mbx_fw_req_handler(struct rnp_eth_adapter *adapter,
84 : : void *cmd)
85 : : {
86 : : struct rnp_mbx_fw_cmd_req *req = cmd;
87 : :
88 [ # # ]: 0 : switch (req->opcode) {
89 : 0 : case RNP_LINK_STATUS_EVENT:
90 : 0 : rnp_link_event(adapter, req);
91 : 0 : break;
92 : : default:
93 : : break;
94 : : }
95 : :
96 : : return 0;
97 : : }
98 : :
99 : 0 : static int rnp_process_fw_msg(struct rnp_eth_adapter *adapter)
100 : : {
101 : 0 : const struct rnp_mbx_ops *ops = RNP_DEV_PP_TO_MBX_OPS(adapter->eth_dev);
102 : 0 : struct rnp_hw *hw = &adapter->hw;
103 : : void *msg_cmd = NULL;
104 : : uint16_t msg_flag;
105 : :
106 : 0 : msg_cmd = (void *)hw->msgbuf;
107 : : memset(msg_cmd, 0, sizeof(hw->msgbuf));
108 : : /* check fw req */
109 [ # # ]: 0 : if (!ops->check_for_msg(hw, RNP_MBX_FW)) {
110 : 0 : rnp_rcv_msg_from_fw(adapter, msg_cmd);
111 : 0 : msg_flag = hw->msgbuf[2] | hw->msgbuf[3];
112 [ # # ]: 0 : if (msg_flag & RNP_FLAGS_DD)
113 : 0 : rnp_mbx_fw_reply_handler(adapter, msg_cmd);
114 : : else
115 : : rnp_mbx_fw_req_handler(adapter, msg_cmd);
116 : : }
117 : :
118 : 0 : return 0;
119 : : }
120 : :
121 : 0 : static void rnp_dev_interrupt_handler(void *param)
122 : : {
123 : : struct rnp_eth_adapter *adapter = param;
124 : : uint16_t exp = RNP_PF_OP_DONE;
125 : :
126 [ # # ]: 0 : if (!rte_atomic_compare_exchange_strong_explicit(&adapter->pf_op, &exp,
127 : : RNP_PF_OP_PROCESS, rte_memory_order_acquire,
128 : : rte_memory_order_acquire))
129 : : return;
130 : 0 : rnp_process_fw_msg(adapter);
131 : 0 : rte_atomic_store_explicit(&adapter->pf_op, RNP_PF_OP_DONE,
132 : : rte_memory_order_release);
133 : : }
134 : :
135 : 0 : static void rnp_mac_rx_enable(struct rte_eth_dev *dev)
136 : : {
137 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
138 : 0 : uint16_t lane = port->attr.nr_lane;
139 : 0 : struct rnp_hw *hw = port->hw;
140 : : uint32_t mac_cfg;
141 : :
142 : 0 : rte_spinlock_lock(&port->rx_mac_lock);
143 : 0 : mac_cfg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_RX_CFG);
144 : : mac_cfg |= RNP_MAC_RE;
145 : :
146 [ # # ]: 0 : if (port->jumbo_en) {
147 : : mac_cfg |= RNP_MAC_JE;
148 : 0 : mac_cfg |= RNP_MAC_GPSLCE | RNP_MAC_WD;
149 : : } else {
150 : : mac_cfg &= ~RNP_MAC_JE;
151 : 0 : mac_cfg &= ~RNP_MAC_WD;
152 : : }
153 : 0 : mac_cfg &= ~RNP_MAC_GPSL_MASK;
154 : 0 : mac_cfg |= (RNP_MAC_MAX_GPSL << RNP_MAC_CPSL_SHIFT);
155 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_RX_CFG, mac_cfg);
156 : : rte_spinlock_unlock(&port->rx_mac_lock);
157 : 0 : }
158 : :
159 : 0 : static void rnp_mac_rx_disable(struct rte_eth_dev *dev)
160 : : {
161 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
162 : 0 : uint16_t lane = port->attr.nr_lane;
163 : 0 : struct rnp_hw *hw = port->hw;
164 : : uint32_t mac_cfg;
165 : :
166 : : /* to protect conflict hw resource */
167 : 0 : rte_spinlock_lock(&port->rx_mac_lock);
168 : 0 : mac_cfg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_RX_CFG);
169 : 0 : mac_cfg &= ~RNP_MAC_RE;
170 : :
171 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_RX_CFG, mac_cfg);
172 : : rte_spinlock_unlock(&port->rx_mac_lock);
173 : 0 : }
174 : :
175 : : static void rnp_mac_tx_enable(struct rte_eth_dev *dev)
176 : : {
177 : : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
178 : : uint16_t lane = port->attr.nr_lane;
179 : : struct rnp_hw *hw = port->hw;
180 : : uint32_t mac_cfg;
181 : :
182 : 0 : mac_cfg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_TX_CFG);
183 : 0 : mac_cfg |= RNP_MAC_TE;
184 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_TX_CFG, mac_cfg);
185 : : }
186 : :
187 : : static void rnp_mac_tx_disable(struct rte_eth_dev *dev)
188 : : {
189 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
190 : 0 : uint16_t lane = port->attr.nr_lane;
191 : 0 : struct rnp_hw *hw = port->hw;
192 : : uint32_t ctrl;
193 : :
194 : : /* must wait for tx side has send finish
195 : : * before fisable tx side
196 : : */
197 : 0 : ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_TX_CFG);
198 : 0 : ctrl &= ~RNP_MAC_TE;
199 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_TX_CFG, ctrl);
200 : : }
201 : :
202 : 0 : static void rnp_mac_init(struct rte_eth_dev *dev)
203 : : {
204 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
205 : 0 : uint16_t lane = port->attr.nr_lane;
206 : 0 : struct rnp_hw *hw = port->hw;
207 : : uint32_t mac_cfg;
208 : :
209 : : rnp_mac_tx_enable(dev);
210 : 0 : rnp_mac_rx_enable(dev);
211 : :
212 : 0 : mac_cfg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_LPI_CTRL);
213 : 0 : mac_cfg |= RNP_MAC_PLSDIS | RNP_MAC_PLS;
214 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_LPI_CTRL, mac_cfg);
215 : 0 : }
216 : :
217 : : static int
218 : 0 : rnp_rx_scattered_setup(struct rte_eth_dev *dev)
219 : : {
220 : 0 : uint16_t max_pkt_size =
221 : 0 : dev->data->dev_conf.rxmode.mtu + RNP_ETH_OVERHEAD;
222 : : struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
223 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
224 : 0 : struct rnp_hw *hw = port->hw;
225 : : struct rnp_rx_queue *rxq;
226 : : uint16_t dma_buf_size;
227 : : uint16_t queue_id;
228 : : uint32_t dma_ctrl;
229 : :
230 [ # # ]: 0 : if (dev->data->rx_queues == NULL)
231 : : return -ENOMEM;
232 [ # # ]: 0 : for (queue_id = 0; queue_id < dev->data->nb_rx_queues; queue_id++) {
233 : 0 : rxq = dev->data->rx_queues[queue_id];
234 [ # # ]: 0 : if (!rxq)
235 : 0 : continue;
236 [ # # ]: 0 : if (hw->min_dma_size == 0)
237 : 0 : hw->min_dma_size = rxq->rx_buf_len;
238 : : else
239 : 0 : hw->min_dma_size = RTE_MIN(hw->min_dma_size,
240 : : rxq->rx_buf_len);
241 : : }
242 [ # # ]: 0 : if (hw->min_dma_size < RNP_MIN_DMA_BUF_SIZE) {
243 : 0 : RNP_PMD_ERR("port[%d] scatter dma len is not support %d",
244 : : dev->data->port_id, hw->min_dma_size);
245 : 0 : return -ENOTSUP;
246 : : }
247 : : dma_buf_size = hw->min_dma_size;
248 [ # # # # ]: 0 : if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_SCATTER ||
249 : 0 : max_pkt_size > dma_buf_size ||
250 [ # # ]: 0 : dev->data->mtu + RNP_ETH_OVERHEAD > dma_buf_size)
251 : 0 : dev->data->scattered_rx = 1;
252 : : else
253 : 0 : dev->data->scattered_rx = 0;
254 : : /* Setup max dma scatter engine split size */
255 [ # # ]: 0 : if (max_pkt_size == dma_buf_size)
256 : 0 : dma_buf_size += (dma_buf_size % 16);
257 : 0 : RNP_PMD_INFO("PF[%d] MaxPktLen %d MbSize %d MbHeadRoom %d",
258 : : hw->mbx.pf_num, max_pkt_size,
259 : : dma_buf_size, RTE_PKTMBUF_HEADROOM);
260 : 0 : dma_ctrl = RNP_E_REG_RD(hw, RNP_DMA_CTRL);
261 : 0 : dma_ctrl &= ~RNP_DMA_SCATTER_MEM_MASK;
262 : 0 : dma_ctrl |= ((dma_buf_size / 16) << RNP_DMA_SCATTER_MEN_S);
263 : 0 : RNP_E_REG_WR(hw, RNP_DMA_CTRL, dma_ctrl);
264 : :
265 : 0 : return 0;
266 : : }
267 : :
268 : 0 : static int rnp_enable_all_rx_queue(struct rte_eth_dev *dev)
269 : : {
270 : : struct rnp_rx_queue *rxq;
271 : : uint16_t idx;
272 : : int ret = 0;
273 : :
274 [ # # ]: 0 : for (idx = 0; idx < dev->data->nb_rx_queues; idx++) {
275 : 0 : rxq = dev->data->rx_queues[idx];
276 [ # # # # ]: 0 : if (!rxq || rxq->rx_deferred_start)
277 : 0 : continue;
278 [ # # ]: 0 : if (dev->data->rx_queue_state[idx] ==
279 : : RTE_ETH_QUEUE_STATE_STOPPED) {
280 : 0 : ret = rnp_rx_queue_start(dev, idx);
281 [ # # ]: 0 : if (ret < 0)
282 : 0 : return ret;
283 : : }
284 : : }
285 : :
286 : : return ret;
287 : : }
288 : :
289 : 0 : static int rnp_enable_all_tx_queue(struct rte_eth_dev *dev)
290 : : {
291 : : struct rnp_tx_queue *txq;
292 : : uint16_t idx;
293 : : int ret = 0;
294 : :
295 [ # # ]: 0 : for (idx = 0; idx < dev->data->nb_tx_queues; idx++) {
296 : 0 : txq = dev->data->tx_queues[idx];
297 [ # # # # ]: 0 : if (!txq || txq->tx_deferred_start)
298 : 0 : continue;
299 [ # # ]: 0 : if (dev->data->tx_queue_state[idx] ==
300 : : RTE_ETH_QUEUE_STATE_STOPPED) {
301 : 0 : ret = rnp_tx_queue_start(dev, idx);
302 [ # # ]: 0 : if (ret < 0)
303 : 0 : return ret;
304 : : }
305 : : }
306 : :
307 : : return ret;
308 : : }
309 : :
310 : : static void
311 : 0 : rnp_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue,
312 : : int on)
313 : : {
314 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
315 : : struct rnp_rx_queue *rxq = NULL;
316 : 0 : struct rnp_hw *hw = port->hw;
317 : : uint16_t index;
318 : : uint32_t reg;
319 : :
320 : 0 : rxq = dev->data->rx_queues[queue];
321 [ # # ]: 0 : if (rxq) {
322 : 0 : index = rxq->attr.index;
323 : 0 : reg = RNP_E_REG_RD(hw, RNP_VLAN_Q_STRIP_CTRL(index));
324 [ # # ]: 0 : if (on) {
325 : 0 : reg |= 1 << (index % 32);
326 : 0 : rxq->rx_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
327 : : } else {
328 : 0 : reg &= ~(1 << (index % 32));
329 : 0 : rxq->rx_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
330 : : }
331 : 0 : RNP_E_REG_WR(hw, RNP_VLAN_Q_STRIP_CTRL(index), reg);
332 : : }
333 : 0 : }
334 : :
335 : : static void
336 : 0 : rnp_vlan_strip_enable(struct rnp_eth_port *port, bool en)
337 : : {
338 : : int i = 0;
339 : :
340 [ # # ]: 0 : for (i = 0; i < port->eth_dev->data->nb_rx_queues; i++) {
341 [ # # ]: 0 : if (port->eth_dev->data->rx_queues[i] == NULL) {
342 : 0 : RNP_PMD_ERR("Strip queue[%d] is NULL.", i);
343 : 0 : continue;
344 : : }
345 : 0 : rnp_vlan_strip_queue_set(port->eth_dev, i, en);
346 : : }
347 : 0 : }
348 : :
349 : : static void
350 : : rnp_double_vlan_enable(struct rnp_eth_port *port, bool on)
351 : : {
352 : 0 : uint16_t lane = port->attr.nr_lane;
353 : 0 : struct rnp_hw *hw = port->hw;
354 : : uint32_t ctrl;
355 : :
356 : : /* En Double Vlan Engine */
357 : 0 : ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_VLAN_TAG);
358 [ # # ]: 0 : if (on)
359 : 0 : ctrl |= RNP_MAC_VLAN_EDVLP | RNP_MAC_VLAN_ESVL;
360 : : else
361 : 0 : ctrl &= ~(RNP_MAC_VLAN_EDVLP | RNP_MAC_VLAN_ESVL);
362 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_VLAN_TAG, ctrl);
363 : 0 : }
364 : :
365 : : static int
366 : 0 : rnp_vlan_offload_set(struct rte_eth_dev *dev, int mask)
367 : : {
368 : 0 : struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
369 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
370 : :
371 [ # # ]: 0 : if (mask & RTE_ETH_QINQ_STRIP_MASK) {
372 : 0 : RNP_PMD_ERR("QinQ Strip isn't supported.");
373 : 0 : return -ENOTSUP;
374 : : }
375 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
376 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)
377 : 0 : rnp_rx_vlan_filter_en(port, true);
378 : : else
379 : :
380 : 0 : rnp_rx_vlan_filter_en(port, false);
381 : : }
382 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
383 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
384 : 0 : rnp_vlan_strip_enable(port, true);
385 : : else
386 : 0 : rnp_vlan_strip_enable(port, false);
387 : : }
388 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_EXTEND_MASK) {
389 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)
390 : : rnp_double_vlan_enable(port, true);
391 : : else
392 : : rnp_double_vlan_enable(port, false);
393 : : }
394 : :
395 : : return 0;
396 : : }
397 : :
398 : : static int
399 : 0 : rnp_vlan_filter_set(struct rte_eth_dev *dev,
400 : : uint16_t vlan_id, int on)
401 : : {
402 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
403 : :
404 : 0 : return rnp_update_vlan_filter(port, vlan_id, on);
405 : : }
406 : :
407 : 0 : static int rnp_dev_start(struct rte_eth_dev *eth_dev)
408 : : {
409 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
410 : : struct rte_eth_dev_data *data = eth_dev->data;
411 : 0 : uint16_t max_rx_pkt_len = eth_dev->data->mtu;
412 : 0 : bool lsc = data->dev_conf.intr_conf.lsc;
413 : 0 : struct rnp_hw *hw = port->hw;
414 : : uint16_t lane = 0;
415 : : uint16_t idx = 0;
416 : : int ret = 0;
417 : :
418 : 0 : PMD_INIT_FUNC_TRACE();
419 : 0 : lane = port->attr.nr_lane;
420 : 0 : ret = rnp_clock_valid_check(hw, lane);
421 [ # # ]: 0 : if (ret) {
422 : 0 : RNP_PMD_ERR("port[%d] function[%d] lane[%d] hw clock error",
423 : : data->port_id, hw->mbx.pf_num, lane);
424 : 0 : return ret;
425 : : }
426 : : /* disable eth rx flow */
427 : 0 : RNP_RX_ETH_DISABLE(hw, lane);
428 : 0 : ret = rnp_dev_rss_configure(eth_dev);
429 [ # # ]: 0 : if (ret)
430 : : return ret;
431 : 0 : ret = rnp_rx_scattered_setup(eth_dev);
432 [ # # ]: 0 : if (ret)
433 : : return ret;
434 : 0 : ret = rnp_mtu_set(eth_dev, max_rx_pkt_len);
435 [ # # ]: 0 : if (ret)
436 : : return ret;
437 : 0 : ret = rnp_enable_all_tx_queue(eth_dev);
438 [ # # ]: 0 : if (ret)
439 : 0 : goto txq_start_failed;
440 : 0 : ret = rnp_enable_all_rx_queue(eth_dev);
441 [ # # ]: 0 : if (ret)
442 : 0 : goto rxq_start_failed;
443 : 0 : rnp_mac_init(eth_dev);
444 : 0 : ret = rnp_mbx_fw_lane_link_event_en(port, lsc);
445 [ # # ]: 0 : if (ret < 0)
446 : 0 : goto rxq_start_failed;
447 [ # # ]: 0 : if (!lsc)
448 : 0 : rnp_run_link_poll_task(port);
449 : 0 : ret = rnp_dev_set_link_up(eth_dev);
450 [ # # ]: 0 : if (ret < 0)
451 : 0 : goto rxq_start_failed;
452 : : /* enable eth rx flow */
453 : 0 : RNP_RX_ETH_ENABLE(hw, lane);
454 : 0 : rnp_rx_func_select(eth_dev);
455 : 0 : rnp_tx_func_select(eth_dev);
456 : 0 : port->port_stopped = 0;
457 : :
458 : 0 : return 0;
459 : 0 : rxq_start_failed:
460 [ # # ]: 0 : for (idx = 0; idx < data->nb_rx_queues; idx++)
461 : 0 : rnp_rx_queue_stop(eth_dev, idx);
462 : 0 : txq_start_failed:
463 [ # # ]: 0 : for (idx = 0; idx < data->nb_tx_queues; idx++)
464 : 0 : rnp_tx_queue_stop(eth_dev, idx);
465 : :
466 : : return ret;
467 : : }
468 : :
469 : 0 : static int rnp_disable_all_rx_queue(struct rte_eth_dev *dev)
470 : : {
471 : : struct rnp_rx_queue *rxq;
472 : : uint16_t idx;
473 : : int ret = 0;
474 : :
475 [ # # ]: 0 : for (idx = 0; idx < dev->data->nb_rx_queues; idx++) {
476 : 0 : rxq = dev->data->rx_queues[idx];
477 [ # # # # ]: 0 : if (!rxq || rxq->rx_deferred_start)
478 : 0 : continue;
479 [ # # ]: 0 : if (dev->data->rx_queue_state[idx] ==
480 : : RTE_ETH_QUEUE_STATE_STARTED) {
481 : 0 : ret = rnp_rx_queue_stop(dev, idx);
482 [ # # ]: 0 : if (ret < 0)
483 : 0 : return ret;
484 : : }
485 : : }
486 : :
487 : : return ret;
488 : : }
489 : :
490 : 0 : static int rnp_disable_all_tx_queue(struct rte_eth_dev *dev)
491 : : {
492 : : struct rnp_tx_queue *txq;
493 : : uint16_t idx;
494 : : int ret = 0;
495 : :
496 [ # # ]: 0 : for (idx = 0; idx < dev->data->nb_tx_queues; idx++) {
497 : 0 : txq = dev->data->tx_queues[idx];
498 [ # # # # ]: 0 : if (!txq || txq->tx_deferred_start)
499 : 0 : continue;
500 [ # # ]: 0 : if (dev->data->tx_queue_state[idx] ==
501 : : RTE_ETH_QUEUE_STATE_STARTED) {
502 : 0 : ret = rnp_tx_queue_stop(dev, idx);
503 [ # # ]: 0 : if (ret < 0)
504 : 0 : return ret;
505 : : }
506 : : }
507 : :
508 : : return ret;
509 : : }
510 : :
511 : 0 : static void rnp_set_rx_cksum_offload(struct rte_eth_dev *dev)
512 : : {
513 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
514 : 0 : struct rnp_hw *hw = port->hw;
515 : : uint32_t cksum_ctrl;
516 : : uint64_t offloads;
517 : :
518 : 0 : offloads = dev->data->dev_conf.rxmode.offloads;
519 : : cksum_ctrl = RNP_HW_CHECK_ERR_MASK;
520 : : /* enable rx checksum feature */
521 [ # # ]: 0 : if (!rnp_pf_is_multiple_ports(hw->device_id)) {
522 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
523 : : /* Tunnel Option Cksum L4_Option */
524 : : cksum_ctrl &= ~RNP_HW_L4_CKSUM_ERR;
525 [ # # ]: 0 : if (offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
526 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM))
527 : : cksum_ctrl &= ~RNP_HW_INNER_L4_CKSUM_ERR;
528 : : else
529 : : cksum_ctrl |= RNP_HW_INNER_L4_CKSUM_ERR;
530 : : } else {
531 : : /* no tunnel option cksum l4_option */
532 : : cksum_ctrl |= RNP_HW_INNER_L4_CKSUM_ERR;
533 [ # # ]: 0 : if (offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
534 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM))
535 : : cksum_ctrl &= ~RNP_HW_L4_CKSUM_ERR;
536 : : else
537 : : cksum_ctrl |= RNP_HW_L4_CKSUM_ERR;
538 : : }
539 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
540 : : /* tunnel option cksum l3_option */
541 : 0 : cksum_ctrl &= ~RNP_HW_L3_CKSUM_ERR;
542 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM)
543 : 0 : cksum_ctrl &= ~RNP_HW_INNER_L3_CKSUM_ERR;
544 : : else
545 : 0 : cksum_ctrl |= RNP_HW_INNER_L3_CKSUM_ERR;
546 : : } else {
547 : : /* no tunnel option cksum l3_option */
548 : : cksum_ctrl |= RNP_HW_INNER_L3_CKSUM_ERR;
549 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM)
550 : 0 : cksum_ctrl &= ~RNP_HW_L3_CKSUM_ERR;
551 : : else
552 : 0 : cksum_ctrl |= RNP_HW_L3_CKSUM_ERR;
553 : : }
554 : : /* sctp option */
555 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_SCTP_CKSUM) {
556 : 0 : cksum_ctrl &= ~RNP_HW_SCTP_CKSUM_ERR;
557 : 0 : RNP_E_REG_WR(hw, RNP_HW_SCTP_CKSUM_CTRL, true);
558 : : } else {
559 : 0 : RNP_E_REG_WR(hw, RNP_HW_SCTP_CKSUM_CTRL, false);
560 : : }
561 : 0 : RNP_E_REG_WR(hw, RNP_HW_CHECK_ERR_CTRL, cksum_ctrl);
562 : : } else {
563 : : /* Enabled all support checksum features
564 : : * use software mode support per port rx checksum
565 : : * feature enabled/disabled for multiple port mode
566 : : */
567 : 0 : RNP_E_REG_WR(hw, RNP_HW_CHECK_ERR_CTRL, RNP_HW_ERR_RX_ALL_MASK);
568 : 0 : RNP_E_REG_WR(hw, RNP_HW_SCTP_CKSUM_CTRL, true);
569 : : }
570 : 0 : }
571 : :
572 : : static void
573 : 0 : rnp_qinq_insert_offload_en(struct rnp_eth_port *port, bool on)
574 : : {
575 : 0 : uint16_t lane = port->attr.nr_lane;
576 : 0 : struct rnp_hw *hw = port->hw;
577 : : uint32_t cvlan_ctrl, svlan_ctrl;
578 : :
579 : : /* en double vlan engine */
580 : : rnp_double_vlan_enable(port, on);
581 : : /* setup inner vlan mode*/
582 : 0 : cvlan_ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_INNER_VLAN_INCL);
583 [ # # ]: 0 : if (on) {
584 : : cvlan_ctrl |= RNP_MAC_VLAN_VLTI;
585 : 0 : cvlan_ctrl &= ~RNP_MAC_VLAN_CSVL;
586 [ # # ]: 0 : if (port->invlan_type == RNP_SVLAN_TYPE)
587 : 0 : cvlan_ctrl |= RNP_MAC_VLAN_INSERT_SVLAN;
588 : 0 : cvlan_ctrl &= ~RNP_MAC_VLAN_VLC;
589 : 0 : cvlan_ctrl |= RNP_MAC_VLAN_VLC_ADD;
590 : : } else {
591 : : cvlan_ctrl = 0;
592 : : }
593 : : /* setup outer vlan mode */
594 : 0 : svlan_ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_VLAN_INCL);
595 [ # # ]: 0 : if (on) {
596 : : svlan_ctrl |= RNP_MAC_VLAN_VLTI;
597 : 0 : svlan_ctrl &= ~RNP_MAC_VLAN_CSVL;
598 [ # # ]: 0 : if (port->outvlan_type == RNP_SVLAN_TYPE)
599 : 0 : svlan_ctrl |= RNP_MAC_VLAN_INSERT_SVLAN;
600 : 0 : svlan_ctrl &= ~RNP_MAC_VLAN_VLC;
601 : 0 : svlan_ctrl |= RNP_MAC_VLAN_VLC_ADD;
602 : : } else {
603 : : svlan_ctrl = 0;
604 : : }
605 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_INNER_VLAN_INCL, cvlan_ctrl);
606 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_VLAN_INCL, svlan_ctrl);
607 : 0 : }
608 : :
609 : : static void
610 : : rnp_vlan_insert_offload_en(struct rnp_eth_port *port, bool on)
611 : : {
612 : 0 : uint16_t lane = port->attr.nr_lane;
613 : 0 : struct rnp_hw *hw = port->hw;
614 : : uint32_t ctrl;
615 : :
616 : 0 : ctrl = RNP_MAC_REG_RD(hw, lane, RNP_MAC_VLAN_INCL);
617 : : if (on) {
618 : : ctrl |= RNP_MAC_VLAN_VLTI;
619 : 0 : ctrl &= ~RNP_MAC_VLAN_CSVL;
620 [ # # ]: 0 : if (port->invlan_type == RNP_SVLAN_TYPE)
621 : 0 : ctrl |= RNP_MAC_VLAN_INSERT_SVLAN;
622 : 0 : ctrl &= ~RNP_MAC_VLAN_VLC;
623 : 0 : ctrl |= RNP_MAC_VLAN_VLC_ADD;
624 : : } else {
625 : : ctrl = 0;
626 : : }
627 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_VLAN_INCL, ctrl);
628 : 0 : }
629 : :
630 : 0 : static int rnp_dev_configure(struct rte_eth_dev *eth_dev)
631 : : {
632 : 0 : struct rte_eth_txmode *txmode = ð_dev->data->dev_conf.txmode;
633 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
634 : :
635 [ # # ]: 0 : if (txmode->offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT &&
636 : : txmode->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT)
637 : 0 : rnp_qinq_insert_offload_en(port, true);
638 : : else
639 : 0 : rnp_qinq_insert_offload_en(port, false);
640 [ # # ]: 0 : if (txmode->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT &&
641 : : !(txmode->offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT))
642 : : rnp_vlan_insert_offload_en(port, true);
643 [ # # ]: 0 : if (!(txmode->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT))
644 : : rnp_vlan_insert_offload_en(port, false);
645 [ # # ]: 0 : if (port->last_rx_num != eth_dev->data->nb_rx_queues)
646 : 0 : port->rxq_num_changed = true;
647 : : else
648 : 0 : port->rxq_num_changed = false;
649 : 0 : port->last_rx_num = eth_dev->data->nb_rx_queues;
650 : 0 : rnp_set_rx_cksum_offload(eth_dev);
651 : :
652 : 0 : return 0;
653 : : }
654 : :
655 : 0 : static int rnp_dev_stop(struct rte_eth_dev *eth_dev)
656 : : {
657 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
658 : : const struct rte_eth_dev_data *data = eth_dev->data;
659 : 0 : bool lsc = eth_dev->data->dev_conf.intr_conf.lsc;
660 : : struct rte_eth_link link;
661 : : int ret;
662 : :
663 [ # # ]: 0 : if (port->port_stopped)
664 : : return 0;
665 : 0 : eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
666 : 0 : eth_dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
667 : 0 : eth_dev->tx_pkt_prepare = rte_eth_pkt_burst_dummy;
668 : :
669 : : /* clear the recorded link status */
670 : : memset(&link, 0, sizeof(link));
671 : 0 : rte_eth_linkstatus_set(eth_dev, &link);
672 : 0 : rnp_dev_set_link_down(eth_dev);
673 : 0 : ret = rnp_disable_all_tx_queue(eth_dev);
674 [ # # ]: 0 : if (ret < 0) {
675 : 0 : RNP_PMD_ERR("port[%u] disable tx queue failed", data->port_id);
676 : 0 : return ret;
677 : : }
678 : 0 : ret = rnp_disable_all_rx_queue(eth_dev);
679 [ # # ]: 0 : if (ret < 0) {
680 : 0 : RNP_PMD_ERR("port[%u] disable rx queue failed", data->port_id);
681 : 0 : return ret;
682 : : }
683 : : rnp_mac_tx_disable(eth_dev);
684 : 0 : rnp_mac_rx_disable(eth_dev);
685 [ # # ]: 0 : if (!lsc)
686 : 0 : rnp_cancel_link_poll_task(port);
687 : 0 : port->attr.link_ready = false;
688 : 0 : port->attr.speed = 0;
689 : :
690 : 0 : eth_dev->data->dev_started = 0;
691 : 0 : port->port_stopped = 1;
692 : :
693 : 0 : return 0;
694 : : }
695 : :
696 : : static void rnp_change_manage_port(struct rnp_eth_adapter *adapter)
697 : : {
698 : : uint16_t idx = 0;
699 : :
700 : 0 : adapter->eth_dev = NULL;
701 [ # # ]: 0 : for (idx = 0; idx < adapter->inited_ports; idx++) {
702 [ # # ]: 0 : if (adapter->ports[idx])
703 : 0 : adapter->eth_dev = adapter->ports[idx]->eth_dev;
704 : : }
705 : : }
706 : :
707 : 0 : static int rnp_dev_close(struct rte_eth_dev *eth_dev)
708 : : {
709 : 0 : struct rnp_eth_adapter *adapter = RNP_DEV_TO_ADAPTER(eth_dev);
710 : : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
711 : : uint16_t exp = RNP_PF_OP_DONE;
712 : : int ret = 0;
713 : :
714 : 0 : PMD_INIT_FUNC_TRACE();
715 : :
716 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
717 : : return 0;
718 : 0 : ret = rnp_dev_stop(eth_dev);
719 [ # # ]: 0 : if (ret < 0)
720 : : return ret;
721 : : do {
722 : 0 : ret = rte_atomic_compare_exchange_strong_explicit(&adapter->pf_op,
723 : : &exp, RNP_PF_OP_CLOSING, rte_memory_order_acquire,
724 : : rte_memory_order_acquire);
725 [ # # ]: 0 : } while (!ret);
726 : 0 : adapter->closed_ports++;
727 : 0 : adapter->ports[port->attr.sw_id] = NULL;
728 [ # # # # ]: 0 : if (adapter->intr_registered && adapter->eth_dev == eth_dev)
729 : : rnp_change_manage_port(adapter);
730 [ # # ]: 0 : if (adapter->closed_ports == adapter->inited_ports) {
731 : 0 : struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI((void *)eth_dev->device);
732 [ # # ]: 0 : if (adapter->intr_registered) {
733 : : /* disable uio irq before callback unregister */
734 : 0 : rte_intr_disable(pci_dev->intr_handle);
735 : 0 : rte_intr_callback_unregister(pci_dev->intr_handle,
736 : : rnp_dev_interrupt_handler,
737 : : (void *)eth_dev);
738 : 0 : adapter->intr_registered = false;
739 : : }
740 : 0 : rnp_dma_mem_free(&adapter->hw, &adapter->hw.fw_info.mem);
741 : 0 : rte_free(adapter);
742 : : }
743 : 0 : rte_atomic_store_explicit(&adapter->pf_op, RNP_PF_OP_DONE,
744 : : rte_memory_order_release);
745 : :
746 : 0 : return 0;
747 : : }
748 : :
749 : : static uint32_t
750 : 0 : rnp_get_speed_caps(struct rte_eth_dev *dev)
751 : : {
752 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
753 : : uint32_t speed_cap = 0;
754 : : uint32_t i = 0, speed;
755 : : uint32_t support_link;
756 : : uint32_t link_types;
757 : :
758 : 0 : support_link = port->attr.phy_meta.supported_link;
759 [ # # ]: 0 : link_types = rte_popcount64(support_link);
760 [ # # ]: 0 : if (!link_types)
761 : : return 0;
762 [ # # ]: 0 : for (i = 0; i < link_types; i++) {
763 [ # # ]: 0 : speed = ffs(support_link) - 1;
764 [ # # # # : 0 : switch (RTE_BIT32(speed)) {
# # # #
# ]
765 : 0 : case RNP_SPEED_CAP_10M_FULL:
766 : 0 : speed_cap |= RTE_ETH_LINK_SPEED_10M;
767 : 0 : break;
768 : 0 : case RNP_SPEED_CAP_100M_FULL:
769 : 0 : speed_cap |= RTE_ETH_LINK_SPEED_100M;
770 : 0 : break;
771 : 0 : case RNP_SPEED_CAP_1GB_FULL:
772 : 0 : speed_cap |= RTE_ETH_LINK_SPEED_1G;
773 : 0 : break;
774 : 0 : case RNP_SPEED_CAP_10GB_FULL:
775 : 0 : speed_cap |= RTE_ETH_LINK_SPEED_10G;
776 : 0 : break;
777 : 0 : case RNP_SPEED_CAP_40GB_FULL:
778 : 0 : speed_cap |= RTE_ETH_LINK_SPEED_40G;
779 : 0 : break;
780 : 0 : case RNP_SPEED_CAP_25GB_FULL:
781 : 0 : speed_cap |= RTE_ETH_LINK_SPEED_25G;
782 : 0 : break;
783 : 0 : case RNP_SPEED_CAP_10M_HALF:
784 : 0 : speed_cap |= RTE_ETH_LINK_SPEED_10M_HD;
785 : 0 : break;
786 : 0 : case RNP_SPEED_CAP_100M_HALF:
787 : 0 : speed_cap |= RTE_ETH_LINK_SPEED_100M_HD;
788 : 0 : break;
789 : : default:
790 : : speed_cap |= 0;
791 : : }
792 : 0 : support_link &= ~RTE_BIT32(speed);
793 : : }
794 [ # # ]: 0 : if (!port->attr.phy_meta.link_autoneg)
795 : 0 : speed_cap |= RTE_ETH_LINK_SPEED_FIXED;
796 : :
797 : : return speed_cap;
798 : : }
799 : :
800 : 0 : static int rnp_dev_infos_get(struct rte_eth_dev *eth_dev,
801 : : struct rte_eth_dev_info *dev_info)
802 : : {
803 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
804 : :
805 : 0 : PMD_INIT_FUNC_TRACE();
806 : :
807 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim){
808 : : .nb_max = RNP_MAX_BD_COUNT,
809 : : .nb_min = RNP_MIN_BD_COUNT,
810 : : .nb_align = RNP_BD_ALIGN,
811 : : .nb_seg_max = RNP_RX_MAX_SEG,
812 : : .nb_mtu_seg_max = RNP_RX_MAX_MTU_SEG,
813 : : };
814 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim){
815 : : .nb_max = RNP_MAX_BD_COUNT,
816 : : .nb_min = RNP_MIN_BD_COUNT,
817 : : .nb_align = RNP_BD_ALIGN,
818 : : .nb_seg_max = RNP_TX_MAX_SEG,
819 : : .nb_mtu_seg_max = RNP_TX_MAX_MTU_SEG,
820 : : };
821 : :
822 : 0 : dev_info->max_rx_pktlen = RNP_MAC_MAXFRM_SIZE;
823 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
824 : 0 : dev_info->max_mtu = dev_info->max_rx_pktlen - RNP_ETH_OVERHEAD;
825 : 0 : dev_info->min_rx_bufsize = RNP_MIN_DMA_BUF_SIZE;
826 : 0 : dev_info->max_rx_queues = port->attr.max_rx_queues;
827 : 0 : dev_info->max_tx_queues = port->attr.max_tx_queues;
828 : : /* mac filter info */
829 : 0 : dev_info->max_mac_addrs = port->attr.max_mac_addrs;
830 : : /* for RSS offload just support four tuple */
831 : 0 : dev_info->flow_type_rss_offloads = RNP_SUPPORT_RSS_OFFLOAD_ALL;
832 : 0 : dev_info->hash_key_size = RNP_MAX_HASH_KEY_SIZE * sizeof(uint32_t);
833 : 0 : dev_info->reta_size = RNP_RSS_INDIR_SIZE;
834 : : /* speed cap info */
835 : 0 : dev_info->speed_capa = rnp_get_speed_caps(eth_dev);
836 : : /* per queue offload */
837 : 0 : dev_info->rx_queue_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
838 : : /* rx support offload cap */
839 : : dev_info->rx_offload_capa = RNP_RX_CHECKSUM_SUPPORT |
840 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
841 : : RTE_ETH_RX_OFFLOAD_SCATTER;
842 : 0 : dev_info->rx_offload_capa |= dev_info->rx_queue_offload_capa;
843 : : /* tx support offload cap */
844 : 0 : dev_info->tx_offload_capa = 0 |
845 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
846 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
847 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
848 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
849 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
850 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
851 : : RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
852 : : RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
853 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
854 : : RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
855 : : RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
856 : : /* default ring configure */
857 : 0 : dev_info->default_rxportconf.burst_size = 32;
858 : 0 : dev_info->default_txportconf.burst_size = 32;
859 : 0 : dev_info->default_rxportconf.nb_queues = 1;
860 : 0 : dev_info->default_txportconf.nb_queues = 1;
861 : 0 : dev_info->default_rxportconf.ring_size = 256;
862 : 0 : dev_info->default_txportconf.ring_size = 256;
863 : : /* default port configure */
864 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
865 : : .rx_drop_en = 0,
866 : : .rx_thresh = {
867 : : .pthresh = RNP_RX_DESC_FETCH_TH,
868 : : .hthresh = RNP_RX_DESC_FETCH_BURST,
869 : : },
870 : : .rx_free_thresh = RNP_DEFAULT_RX_FREE_THRESH,
871 : : .offloads = 0,
872 : : };
873 : :
874 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
875 : : .tx_thresh = {
876 : : .pthresh = RNP_TX_DESC_FETCH_TH,
877 : : .hthresh = RNP_TX_DESC_FETCH_BURST,
878 : : },
879 : : .tx_free_thresh = RNP_DEFAULT_TX_FREE_THRESH,
880 : : .tx_rs_thresh = RNP_DEFAULT_TX_RS_THRESH,
881 : : .offloads = 0,
882 : : };
883 : :
884 : 0 : return 0;
885 : : }
886 : :
887 : 0 : static int rnp_promiscuous_enable(struct rte_eth_dev *eth_dev)
888 : : {
889 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
890 : :
891 : 0 : PMD_INIT_FUNC_TRACE();
892 : :
893 : 0 : return rnp_update_mpfm(port, RNP_MPF_MODE_PROMISC, 1);
894 : : }
895 : :
896 : 0 : static int rnp_promiscuous_disable(struct rte_eth_dev *eth_dev)
897 : : {
898 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
899 : :
900 : 0 : PMD_INIT_FUNC_TRACE();
901 : :
902 : 0 : return rnp_update_mpfm(port, RNP_MPF_MODE_PROMISC, 0);
903 : : }
904 : :
905 : 0 : static int rnp_allmulticast_enable(struct rte_eth_dev *eth_dev)
906 : : {
907 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
908 : :
909 : 0 : PMD_INIT_FUNC_TRACE();
910 : :
911 : 0 : return rnp_update_mpfm(port, RNP_MPF_MODE_ALLMULTI, 1);
912 : : }
913 : :
914 : 0 : static int rnp_allmulticast_disable(struct rte_eth_dev *eth_dev)
915 : : {
916 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
917 : :
918 : 0 : PMD_INIT_FUNC_TRACE();
919 [ # # ]: 0 : if (eth_dev->data->promiscuous == 1)
920 : : return 0;
921 : 0 : return rnp_update_mpfm(port, RNP_MPF_MODE_ALLMULTI, 0);
922 : : }
923 : :
924 : : static bool
925 : 0 : rnp_verify_pf_scatter(struct rnp_eth_adapter *adapter)
926 : : {
927 : : struct rnp_hw *hw = &adapter->hw;
928 : : struct rte_eth_dev *eth_dev;
929 : : uint8_t i = 0;
930 : :
931 [ # # ]: 0 : for (i = 0; i < hw->max_port_num; i++) {
932 [ # # ]: 0 : if (adapter->ports[i] == NULL)
933 : 0 : continue;
934 : 0 : eth_dev = adapter->ports[i]->eth_dev;
935 [ # # ]: 0 : if (eth_dev->data == NULL)
936 : 0 : continue;
937 : : /* sub port of pf eth_dev state is not
938 : : * started so the scatter_rx attr isn't
939 : : * setup don't check this sub port.
940 : : */
941 [ # # ]: 0 : if (!eth_dev->data->dev_started)
942 : 0 : continue;
943 [ # # ]: 0 : if (!eth_dev->data->scattered_rx)
944 : : return false;
945 : : }
946 : :
947 : : return true;
948 : : }
949 : :
950 : : static int
951 : 0 : rnp_update_valid_mtu(struct rnp_eth_port *port, uint16_t *set_mtu)
952 : : {
953 : 0 : struct rnp_eth_adapter *adapter = port->hw->back;
954 : : struct rnp_eth_port *sub_port = NULL;
955 : : struct rnp_hw *hw = port->hw;
956 : : uint16_t origin_mtu = 0;
957 : : uint16_t mtu = 0;
958 : : uint8_t i = 0;
959 : :
960 [ # # ]: 0 : if (hw->max_port_num == 1) {
961 : 0 : port->cur_mtu = *set_mtu;
962 : :
963 : 0 : return 0;
964 : : }
965 : 0 : origin_mtu = port->cur_mtu;
966 : 0 : port->cur_mtu = *set_mtu;
967 : : mtu = *set_mtu;
968 [ # # ]: 0 : for (i = 0; i < hw->max_port_num; i++) {
969 : 0 : sub_port = adapter->ports[i];
970 [ # # ]: 0 : if (sub_port == NULL)
971 : 0 : continue;
972 : 0 : mtu = RTE_MAX(mtu, sub_port->cur_mtu);
973 : : }
974 [ # # ]: 0 : if (hw->max_port_num > 1 &&
975 [ # # ]: 0 : mtu + RNP_ETH_OVERHEAD > hw->min_dma_size) {
976 [ # # ]: 0 : if (!rnp_verify_pf_scatter(adapter)) {
977 : 0 : RNP_PMD_ERR("single pf multiple port max_frame_sz "
978 : : "is bigger than min_dma_size please "
979 : : "stop all pf port before set mtu.");
980 : 0 : port->cur_mtu = origin_mtu;
981 : 0 : return -EINVAL;
982 : : }
983 : : }
984 : 0 : *set_mtu = mtu;
985 : :
986 : 0 : return 0;
987 : : }
988 : :
989 : : static int
990 : 0 : rnp_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
991 : : {
992 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
993 : 0 : uint32_t frame_size = mtu + RNP_ETH_OVERHEAD;
994 : 0 : uint16_t lane = port->attr.nr_lane;
995 : 0 : struct rnp_hw *hw = port->hw;
996 : : bool jumbo_en = false;
997 : : uint32_t reg;
998 : : int ret = 0;
999 : :
1000 : 0 : PMD_INIT_FUNC_TRACE();
1001 : : /* check that mtu is within the allowed range */
1002 [ # # ]: 0 : if (frame_size < RTE_ETHER_MIN_LEN ||
1003 : : frame_size > RNP_MAC_MAXFRM_SIZE) {
1004 : 0 : RNP_PMD_ERR("valid packet length must be "
1005 : : "range from %u to %u, "
1006 : : "when Jumbo Frame Feature disabled",
1007 : : (uint32_t)RTE_ETHER_MIN_LEN,
1008 : : (uint32_t)RTE_ETHER_MAX_LEN);
1009 : 0 : return -EINVAL;
1010 : : }
1011 : : /*
1012 : : * Refuse mtu that requires the support of scattered packets
1013 : : * when this feature has not been enabled before.
1014 : : */
1015 [ # # ]: 0 : if (dev->data->dev_started && !dev->data->scattered_rx &&
1016 [ # # ]: 0 : frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) {
1017 : 0 : RNP_PMD_ERR("port %d mtu update must be stopped "
1018 : : "before configuration when scatter rx off.",
1019 : : dev->data->port_id);
1020 : :
1021 : 0 : return -EBUSY;
1022 : : }
1023 : : /* For one pf multiple port the mtu we must set
1024 : : * the biggest mtu the ports selong to pf
1025 : : * because of the control button is only one
1026 : : */
1027 : 0 : ret = rnp_update_valid_mtu(port, &mtu);
1028 [ # # ]: 0 : if (ret < 0)
1029 : : return ret;
1030 : 0 : frame_size = mtu + RNP_ETH_OVERHEAD;
1031 [ # # ]: 0 : if (frame_size > RTE_ETHER_MAX_LEN)
1032 : : jumbo_en = true;
1033 : : /* setting the MTU */
1034 : 0 : RNP_E_REG_WR(hw, RNP_MAX_FRAME_CTRL, frame_size);
1035 : 0 : RNP_E_REG_WR(hw, RNP_MIN_FRAME_CTRL, 60);
1036 [ # # ]: 0 : if (jumbo_en) {
1037 : : /* To protect conflict hw resource */
1038 : 0 : rte_spinlock_lock(&port->rx_mac_lock);
1039 : 0 : reg = RNP_MAC_REG_RD(hw, lane, RNP_MAC_RX_CFG);
1040 : 0 : reg |= RNP_MAC_JE;
1041 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MAC_RX_CFG, reg);
1042 : : rte_spinlock_unlock(&port->rx_mac_lock);
1043 : : }
1044 : 0 : port->jumbo_en = jumbo_en;
1045 : :
1046 : 0 : return 0;
1047 : : }
1048 : :
1049 : : struct rte_rnp_xstats_name_off {
1050 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
1051 : : uint32_t offset;
1052 : : uint32_t reg_base;
1053 : : bool hi_addr_en;
1054 : : };
1055 : :
1056 : : static const struct rte_rnp_xstats_name_off rte_rnp_rx_eth_stats_str[] = {
1057 : : {"rx_trans_drop", offsetof(struct rnp_hw_eth_stats,
1058 : : rx_trans_drop), RNP_ETH_RXTRANS_DROP, false},
1059 : : {"rx_trunc_drop", offsetof(struct rnp_hw_eth_stats,
1060 : : rx_trunc_drop), RNP_ETH_RXTRUNC_DROP, false},
1061 : : {"rx_undersize_err_packets", offsetof(struct rnp_hw_eth_stats,
1062 : : rx_slen_drop), RNP_ETH_RXSLAN_DROP, false},
1063 : : {"rx_oversize_err_packets", offsetof(struct rnp_hw_eth_stats,
1064 : : rx_glen_drop), RNP_ETH_RXGLAN_DROP, false},
1065 : : {"rx_iph_err_packet", offsetof(struct rnp_hw_eth_stats,
1066 : : rx_cksum_e_drop), RNP_ETH_RXCKSUM_E_DROP, false},
1067 : : {"rx_cksum_err_packet", offsetof(struct rnp_hw_eth_stats,
1068 : : rx_iph_e_drop), RNP_ETH_RXIPH_E_DROP, false},
1069 : : };
1070 : :
1071 : : static const struct rte_rnp_xstats_name_off rte_rnp_mac_stats_str[] = {
1072 : : {"rx_packets", offsetof(struct rnp_hw_mac_stats,
1073 : : rx_all_pkts), RNP_MMC_RX_GBFRMB, true},
1074 : : {"rx_bytes", offsetof(struct rnp_hw_mac_stats,
1075 : : rx_all_bytes), RNP_MMC_RX_GBOCTGB, true},
1076 : : {"rx_unicast_packets", offsetof(struct rnp_hw_mac_stats,
1077 : : rx_unicast), RNP_MMC_RX_UCASTGB, true},
1078 : : {"rx_broadcast_packets", offsetof(struct rnp_hw_mac_stats,
1079 : : rx_broadcast), RNP_MMC_RX_BCASTGB, true},
1080 : : {"rx_multicast_packets", offsetof(struct rnp_hw_mac_stats,
1081 : : rx_multicast), RNP_MMC_RX_MCASTGB, true},
1082 : : {"rx_pause_packets", offsetof(struct rnp_hw_mac_stats,
1083 : : rx_pause), RNP_MMC_RX_PAUSEB, true},
1084 : : {"rx_vlan_packets", offsetof(struct rnp_hw_mac_stats,
1085 : : rx_vlan), RNP_MMC_RX_VLANGB, true},
1086 : : {"rx_64_byte_packets", offsetof(struct rnp_hw_mac_stats,
1087 : : rx_64octes_pkts), RNP_MMC_RX_64_BYTESB, true},
1088 : : {"rx_65_to_127_byte_packets", offsetof(struct rnp_hw_mac_stats,
1089 : : rx_65to127_octes_pkts), RNP_MMC_RX_65TO127_BYTESB, true},
1090 : : {"rx_128_to_255_byte_packets", offsetof(struct rnp_hw_mac_stats,
1091 : : rx_128to255_octes_pkts), RNP_MMC_RX_128TO255_BYTESB, true},
1092 : : {"rx_256_to_511_byte_packets", offsetof(struct rnp_hw_mac_stats,
1093 : : rx_256to511_octes_pkts), RNP_MMC_RX_256TO511_BYTESB, true},
1094 : : {"rx_512_to_1023_byte_packets", offsetof(struct rnp_hw_mac_stats,
1095 : : rx_512to1023_octes_pkts), RNP_MMC_RX_512TO1203_BYTESB, true},
1096 : : {"rx_1024_to_max_byte_packets", offsetof(struct rnp_hw_mac_stats,
1097 : : rx_1024tomax_octes_pkts), RNP_MMC_RX_1024TOMAX_BYTESB, true},
1098 : : {"rx_len_over_9k", offsetof(struct rnp_hw_mac_stats,
1099 : : rx_oversize_9k), RNP_MMC_RX_OSIZEGB, false},
1100 : : {"rx_crc_errors", offsetof(struct rnp_hw_mac_stats,
1101 : : rx_crc_err), RNP_MMC_RX_CRCERB, true},
1102 : : {"rx_crc_errors_small_packets", offsetof(struct rnp_hw_mac_stats,
1103 : : rx_runt_err), RNP_MMC_RX_RUNTERB, false},
1104 : : {"rx_jabber_errors", offsetof(struct rnp_hw_mac_stats,
1105 : : rx_jabber_err), RNP_MMC_RX_JABBER_ERR, false},
1106 : : {"rx_length_errors", offsetof(struct rnp_hw_mac_stats,
1107 : : rx_len_err), RNP_MMC_RX_LENERRB, true},
1108 : : {"rx_out_of_range_errors", offsetof(struct rnp_hw_mac_stats,
1109 : : rx_len_invalid), RNP_MMC_RX_OUTOF_RANGE, true},
1110 : : {"rx_watchdog_errors", offsetof(struct rnp_hw_mac_stats,
1111 : : rx_watchdog_err), RNP_MMC_RX_WDOGERRB, true},
1112 : :
1113 : : {"tx_packets", offsetof(struct rnp_hw_mac_stats,
1114 : : tx_all_pkts), RNP_MMC_TX_GBFRMB, true},
1115 : : {"tx_bytes", offsetof(struct rnp_hw_mac_stats,
1116 : : tx_all_bytes), RNP_MMC_TX_GBOCTGB, true},
1117 : : {"tx_unicast_packets", offsetof(struct rnp_hw_mac_stats,
1118 : : tx_all_unicast), RNP_MMC_TX_GBUCASTB, true},
1119 : : {"tx_broadcast_packets", offsetof(struct rnp_hw_mac_stats,
1120 : : tx_all_broadcast), RNP_MMC_TX_BCASTB, true},
1121 : : {"tx_multicast_packets", offsetof(struct rnp_hw_mac_stats,
1122 : : tx_all_multicast), RNP_MMC_TX_MCASTB, true},
1123 : : {"tx_vlan_packets", offsetof(struct rnp_hw_mac_stats,
1124 : : tx_vlan_pkts), RNP_MMC_TX_VLANB, true},
1125 : : {"tx_pause_packets", offsetof(struct rnp_hw_mac_stats,
1126 : : tx_pause_pkts), RNP_MMC_TX_PAUSEB, true},
1127 : : {"tx_64_byte_packets", offsetof(struct rnp_hw_mac_stats,
1128 : : tx_64octes_pkts), RNP_MMC_TX_64_BYTESB, true},
1129 : : {"tx_65_to_127_byte_packets", offsetof(struct rnp_hw_mac_stats,
1130 : : tx_65to127_octes_pkts), RNP_MMC_TX_65TO127_BYTESB, true},
1131 : : {"tx_128_to_255_byte_packets", offsetof(struct rnp_hw_mac_stats,
1132 : : tx_128to255_octes_pkts), RNP_MMC_TX_128TO255_BYTEB, true},
1133 : : {"tx_256_to_511_byte_packets", offsetof(struct rnp_hw_mac_stats,
1134 : : tx_256to511_octes_pkts), RNP_MMC_TX_256TO511_BYTEB, true},
1135 : : {"tx_512_to_1023_byte_packets", offsetof(struct rnp_hw_mac_stats,
1136 : : tx_512to1023_octes_pkts), RNP_MMC_TX_512TO1023_BYTEB, true},
1137 : : {"tx_1024_to_max_byte_packets", offsetof(struct rnp_hw_mac_stats,
1138 : : tx_1024tomax_octes_pkts), RNP_MMC_TX_1024TOMAX_BYTEB, true},
1139 : : {"tx_underflow_errors", offsetof(struct rnp_hw_mac_stats,
1140 : : tx_underflow_err), RNP_MMC_TX_UNDRFLWB, true},
1141 : : };
1142 : :
1143 : : #define RNP_NB_HW_MAC_STATS (RTE_DIM(rte_rnp_mac_stats_str))
1144 : : #define RNP_NB_RX_HW_ETH_STATS (RTE_DIM(rte_rnp_rx_eth_stats_str))
1145 : : #define RNP_GET_E_HW_COUNT(stats, offset) \
1146 : : ((uint64_t *)(((char *)(stats)) + (offset)))
1147 : : #define RNP_ADD_INCL_COUNT(stats, offset, val) \
1148 : : ((*(RNP_GET_E_HW_COUNT((stats), (offset)))) += (val))
1149 : : static inline void
1150 : : rnp_store_hw_stats(struct rnp_hw_mac_stats *stats,
1151 : : uint32_t offset, uint64_t val)
1152 : : {
1153 : 0 : *(uint64_t *)(((char *)stats) + offset) = val;
1154 : 0 : }
1155 : :
1156 : : static int rnp_dev_cal_xstats_num(void)
1157 : : {
1158 : : int cnt = RNP_NB_HW_MAC_STATS + RNP_NB_RX_HW_ETH_STATS;
1159 : :
1160 : : return cnt;
1161 : : }
1162 : :
1163 : : static inline void
1164 : : rnp_update_eth_stats_32bit(struct rnp_hw_eth_stats *new,
1165 : : struct rnp_hw_eth_stats *old,
1166 : : uint32_t offset, uint32_t val)
1167 : : {
1168 : : uint64_t *last_count = NULL;
1169 : :
1170 : 0 : last_count = RNP_GET_E_HW_COUNT(old, offset);
1171 : 0 : if (val >= *last_count)
1172 : 0 : RNP_ADD_INCL_COUNT(new, offset, val - (*last_count));
1173 : : else
1174 : 0 : RNP_ADD_INCL_COUNT(new, offset, val + UINT32_MAX);
1175 : 0 : *last_count = val;
1176 : 0 : }
1177 : :
1178 : 0 : static void rnp_get_eth_count(struct rnp_hw *hw,
1179 : : uint16_t lane,
1180 : : struct rnp_hw_eth_stats *new,
1181 : : struct rnp_hw_eth_stats *old,
1182 : : const struct rte_rnp_xstats_name_off *ptr)
1183 : : {
1184 : : uint64_t val = 0;
1185 : :
1186 [ # # ]: 0 : if (ptr->reg_base) {
1187 : 0 : val = RNP_E_REG_RD(hw, ptr->reg_base + 0x40 * lane);
1188 [ # # ]: 0 : rnp_update_eth_stats_32bit(new, old, ptr->offset, val);
1189 : : }
1190 : 0 : }
1191 : :
1192 : : static void
1193 : 0 : rnp_get_mmc_info(struct rnp_hw *hw,
1194 : : uint16_t lane,
1195 : : struct rnp_hw_mac_stats *stats,
1196 : : const struct rte_rnp_xstats_name_off *ptr)
1197 : : {
1198 : : uint64_t count = 0;
1199 : : uint32_t offset;
1200 : : uint64_t hi_reg;
1201 : :
1202 [ # # ]: 0 : if (ptr->reg_base) {
1203 : 0 : count = RNP_MAC_REG_RD(hw, lane, ptr->reg_base);
1204 [ # # ]: 0 : if (ptr->hi_addr_en) {
1205 : 0 : offset = ptr->reg_base + 4;
1206 : 0 : hi_reg = RNP_MAC_REG_RD(hw, lane, offset);
1207 : 0 : count += (hi_reg << 32);
1208 : : }
1209 : 0 : rnp_store_hw_stats(stats, ptr->offset, count);
1210 : : }
1211 : 0 : }
1212 : :
1213 : 0 : static void rnp_get_hw_stats(struct rte_eth_dev *dev)
1214 : : {
1215 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
1216 : 0 : struct rnp_hw_eth_stats *old = &port->eth_stats_old;
1217 : 0 : struct rnp_hw_eth_stats *new = &port->eth_stats;
1218 : 0 : struct rnp_hw_mac_stats *stats = &port->mac_stats;
1219 : : const struct rte_rnp_xstats_name_off *ptr;
1220 : 0 : uint16_t lane = port->attr.nr_lane;
1221 : 0 : struct rnp_hw *hw = port->hw;
1222 : : uint32_t i;
1223 : :
1224 [ # # ]: 0 : for (i = 0; i < RNP_NB_RX_HW_ETH_STATS; i++) {
1225 : 0 : ptr = &rte_rnp_rx_eth_stats_str[i];
1226 : 0 : rnp_get_eth_count(hw, lane, new, old, ptr);
1227 : : }
1228 [ # # ]: 0 : for (i = 0; i < RNP_NB_HW_MAC_STATS; i++) {
1229 : 0 : ptr = &rte_rnp_mac_stats_str[i];
1230 : 0 : rnp_get_mmc_info(hw, lane, stats, ptr);
1231 : : }
1232 : 0 : }
1233 : :
1234 : : static int
1235 : 0 : rnp_dev_stats_get(struct rte_eth_dev *dev,
1236 : : struct rte_eth_stats *stats)
1237 : : {
1238 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
1239 : : struct rnp_hw_eth_stats *eth_stats = &port->eth_stats;
1240 : : struct rnp_hw_mac_stats *mac_stats = &port->mac_stats;
1241 : : struct rte_eth_dev_data *data = dev->data;
1242 : : uint16_t i = 0;
1243 : :
1244 : 0 : PMD_INIT_FUNC_TRACE();
1245 : 0 : rnp_get_hw_stats(dev);
1246 : :
1247 [ # # ]: 0 : for (i = 0; i < data->nb_rx_queues; i++) {
1248 : 0 : const struct rnp_rx_queue *rxq = dev->data->rx_queues[i];
1249 : :
1250 [ # # ]: 0 : if (!rxq)
1251 : 0 : continue;
1252 : 0 : stats->ipackets += rxq->stats.ipackets;
1253 : 0 : stats->ibytes += rxq->stats.ibytes;
1254 [ # # ]: 0 : if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
1255 : 0 : stats->q_ipackets[i] = rxq->stats.ipackets;
1256 : 0 : stats->q_ibytes[i] = rxq->stats.ibytes;
1257 : : }
1258 : : }
1259 : :
1260 [ # # ]: 0 : for (i = 0; i < data->nb_tx_queues; i++) {
1261 : 0 : const struct rnp_tx_queue *txq = dev->data->tx_queues[i];
1262 : :
1263 [ # # ]: 0 : if (!txq)
1264 : 0 : continue;
1265 : 0 : stats->opackets += txq->stats.opackets;
1266 : 0 : stats->obytes += txq->stats.obytes;
1267 : 0 : stats->oerrors += txq->stats.errors;
1268 [ # # ]: 0 : if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
1269 : 0 : stats->q_opackets[i] = txq->stats.opackets;
1270 : 0 : stats->q_obytes[i] = txq->stats.obytes;
1271 : : }
1272 : : }
1273 : 0 : stats->imissed = eth_stats->rx_trans_drop + eth_stats->rx_trunc_drop;
1274 : 0 : stats->ierrors = mac_stats->rx_crc_err + mac_stats->rx_len_err;
1275 : 0 : stats->ierrors += mac_stats->rx_watchdog_err;
1276 : 0 : stats->oerrors += mac_stats->tx_underflow_err;
1277 : :
1278 : 0 : return 0;
1279 : : }
1280 : :
1281 : : static int
1282 : 0 : rnp_dev_stats_reset(struct rte_eth_dev *dev)
1283 : : {
1284 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
1285 : 0 : struct rnp_hw_eth_stats *eth_stats = &port->eth_stats;
1286 : : uint16_t idx;
1287 : :
1288 : 0 : PMD_INIT_FUNC_TRACE();
1289 : : memset(eth_stats, 0, sizeof(*eth_stats));
1290 [ # # ]: 0 : for (idx = 0; idx < dev->data->nb_rx_queues; idx++) {
1291 : 0 : struct rnp_rx_queue *rxq = dev->data->rx_queues[idx];
1292 : :
1293 [ # # ]: 0 : if (!rxq)
1294 : 0 : continue;
1295 : 0 : memset(&rxq->stats, 0, sizeof(struct rnp_queue_stats));
1296 : : }
1297 [ # # ]: 0 : for (idx = 0; idx < dev->data->nb_tx_queues; idx++) {
1298 : 0 : struct rnp_tx_queue *txq = dev->data->tx_queues[idx];
1299 : :
1300 [ # # ]: 0 : if (!txq)
1301 : 0 : continue;
1302 : 0 : memset(&txq->stats, 0, sizeof(struct rnp_queue_stats));
1303 : : }
1304 : :
1305 : 0 : return 0;
1306 : : }
1307 : :
1308 : : static inline uint64_t
1309 : : rnp_get_statistic_value(void *stats_ptr, uint32_t offset)
1310 : : {
1311 : 0 : stats_ptr = (char *)stats_ptr + offset;
1312 : :
1313 : 0 : return *((uint64_t *)stats_ptr);
1314 : : }
1315 : :
1316 : : static int
1317 : 0 : rnp_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
1318 : : unsigned int n __rte_unused)
1319 : : {
1320 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
1321 : 0 : struct rnp_hw_eth_stats *eth_stats = &port->eth_stats;
1322 : 0 : struct rnp_hw_mac_stats *mac_stats = &port->mac_stats;
1323 : : int count = 0;
1324 : : uint32_t i;
1325 : :
1326 [ # # ]: 0 : if (xstats != NULL) {
1327 : 0 : rnp_get_hw_stats(dev);
1328 [ # # ]: 0 : for (i = 0; i < RNP_NB_RX_HW_ETH_STATS; i++) {
1329 : 0 : xstats[count].value = rnp_get_statistic_value(eth_stats,
1330 : 0 : rte_rnp_rx_eth_stats_str[i].offset);
1331 : 0 : xstats[count].id = count;
1332 : 0 : count++;
1333 : : }
1334 [ # # ]: 0 : for (i = 0; i < RNP_NB_HW_MAC_STATS; i++) {
1335 : 0 : xstats[count].value = rnp_get_statistic_value(mac_stats,
1336 : 0 : rte_rnp_mac_stats_str[i].offset);
1337 : 0 : xstats[count].id = count;
1338 : 0 : count++;
1339 : : }
1340 : : } else {
1341 : : return rnp_dev_cal_xstats_num();
1342 : : }
1343 : :
1344 : : return count;
1345 : : }
1346 : :
1347 : : static int
1348 : 0 : rnp_dev_xstats_reset(struct rte_eth_dev *dev)
1349 : : {
1350 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
1351 : 0 : uint16_t lane = port->attr.nr_lane;
1352 : 0 : struct rnp_hw *hw = port->hw;
1353 : : uint32_t reg;
1354 : :
1355 : : /* set MMC reset hw counter when read event */
1356 : 0 : reg = RNP_MAC_REG_RD(hw, lane, RNP_MMC_CTRL);
1357 : 0 : reg |= RNP_MMC_RSTONRD;
1358 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MMC_CTRL, reg);
1359 : :
1360 : 0 : rnp_dev_stats_reset(dev);
1361 : 0 : rnp_get_hw_stats(dev);
1362 : 0 : reg = RNP_MAC_REG_RD(hw, lane, RNP_MMC_CTRL);
1363 : 0 : reg &= ~RNP_MMC_RSTONRD;
1364 : 0 : RNP_MAC_REG_WR(hw, lane, RNP_MMC_CTRL, reg);
1365 : :
1366 : 0 : return 0;
1367 : : }
1368 : :
1369 : : static int
1370 : 0 : rnp_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
1371 : : struct rte_eth_xstat_name *xstats_names,
1372 : : __rte_unused unsigned int size)
1373 : : {
1374 : : int count = 0;
1375 : : uint32_t i;
1376 : :
1377 [ # # ]: 0 : if (xstats_names == NULL)
1378 : : return rnp_dev_cal_xstats_num();
1379 : :
1380 [ # # ]: 0 : for (i = 0; i < RNP_NB_RX_HW_ETH_STATS; i++) {
1381 : 0 : strlcpy(xstats_names[count].name,
1382 : : rte_rnp_rx_eth_stats_str[i].name,
1383 : : sizeof(xstats_names[count].name));
1384 : 0 : count++;
1385 : : }
1386 [ # # ]: 0 : for (i = 0; i < RNP_NB_HW_MAC_STATS; i++) {
1387 : 0 : strlcpy(xstats_names[count].name,
1388 : : rte_rnp_mac_stats_str[i].name,
1389 : : sizeof(xstats_names[count].name));
1390 : 0 : count++;
1391 : : }
1392 : :
1393 : : return count;
1394 : : }
1395 : :
1396 : : static int
1397 : 0 : rnp_dev_mac_addr_set(struct rte_eth_dev *dev,
1398 : : struct rte_ether_addr *mac_addr)
1399 : : {
1400 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
1401 : :
1402 : 0 : return rnp_set_macaddr(port, (u8 *)mac_addr, 0);
1403 : : }
1404 : :
1405 : : static int
1406 : 0 : rnp_dev_mac_addr_add(struct rte_eth_dev *dev,
1407 : : struct rte_ether_addr *mac_addr,
1408 : : uint32_t index,
1409 : : uint32_t vmdq __rte_unused)
1410 : : {
1411 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
1412 : :
1413 [ # # ]: 0 : if (index >= port->attr.max_mac_addrs) {
1414 : 0 : RNP_PMD_ERR("mac add index %u is of range", index);
1415 : 0 : return -EINVAL;
1416 : : }
1417 : :
1418 : 0 : return rnp_set_macaddr(port, (u8 *)mac_addr, index);
1419 : : }
1420 : :
1421 : : static void
1422 : 0 : rnp_dev_mac_addr_remove(struct rte_eth_dev *dev,
1423 : : uint32_t index)
1424 : : {
1425 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
1426 : :
1427 [ # # ]: 0 : if (index >= port->attr.max_mac_addrs) {
1428 : 0 : RNP_PMD_ERR("mac add index %u is of range", index);
1429 : 0 : return;
1430 : : }
1431 : 0 : rnp_clear_macaddr(port, index);
1432 : : }
1433 : :
1434 : : static int
1435 : 0 : rnp_dev_set_mc_addr_list(struct rte_eth_dev *dev,
1436 : : struct rte_ether_addr *mc_addr_list,
1437 : : uint32_t nb_mc_addr)
1438 : : {
1439 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
1440 : : uint32_t idx = 0;
1441 : :
1442 [ # # ]: 0 : if (nb_mc_addr > port->attr.max_mc_mac_hash)
1443 : : return -EINVAL;
1444 : 0 : rnp_clear_mc_hash(port);
1445 [ # # ]: 0 : for (idx = 0; idx < nb_mc_addr; idx++) {
1446 [ # # ]: 0 : if (!rte_is_multicast_ether_addr(&mc_addr_list[idx])) {
1447 : 0 : RNP_PMD_ERR("mc_list[%d] isn't a valid multicast", idx);
1448 : 0 : return -EINVAL;
1449 : : }
1450 : : }
1451 [ # # ]: 0 : for (idx = 0; idx < nb_mc_addr; idx++)
1452 : 0 : rnp_update_mc_hash(port, (uint8_t *)&mc_addr_list[idx]);
1453 : :
1454 : : return 0;
1455 : : }
1456 : :
1457 : : static uint32_t *rnp_support_ptypes_get(void)
1458 : : {
1459 : : static uint32_t ptypes[] = {
1460 : : RTE_PTYPE_L2_ETHER,
1461 : : RTE_PTYPE_L2_ETHER_TIMESYNC,
1462 : : RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1463 : : RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
1464 : : RTE_PTYPE_L4_TCP,
1465 : : RTE_PTYPE_L4_UDP,
1466 : : RTE_PTYPE_L4_SCTP,
1467 : : RTE_PTYPE_TUNNEL_VXLAN,
1468 : : RTE_PTYPE_TUNNEL_GRE,
1469 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
1470 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
1471 : : RTE_PTYPE_INNER_L4_TCP,
1472 : : RTE_PTYPE_INNER_L4_UDP,
1473 : : RTE_PTYPE_INNER_L4_SCTP,
1474 : : RTE_PTYPE_UNKNOWN,
1475 : : };
1476 : :
1477 : : return ptypes;
1478 : : }
1479 : :
1480 : : static const uint32_t *
1481 : 0 : rnp_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused,
1482 : : size_t *no_of_elements __rte_unused)
1483 : : {
1484 : 0 : return rnp_support_ptypes_get();
1485 : : }
1486 : :
1487 : : /* Features supported by this driver */
1488 : : static const struct eth_dev_ops rnp_eth_dev_ops = {
1489 : : .dev_configure = rnp_dev_configure,
1490 : : .dev_close = rnp_dev_close,
1491 : : .dev_start = rnp_dev_start,
1492 : : .dev_stop = rnp_dev_stop,
1493 : : .dev_infos_get = rnp_dev_infos_get,
1494 : :
1495 : : /* PROMISC */
1496 : : .promiscuous_enable = rnp_promiscuous_enable,
1497 : : .promiscuous_disable = rnp_promiscuous_disable,
1498 : : .allmulticast_enable = rnp_allmulticast_enable,
1499 : : .allmulticast_disable = rnp_allmulticast_disable,
1500 : :
1501 : : .mtu_set = rnp_mtu_set,
1502 : : .rx_queue_setup = rnp_rx_queue_setup,
1503 : : .rx_queue_release = rnp_dev_rx_queue_release,
1504 : : .rx_queue_stop = rnp_rx_queue_stop,
1505 : : .rx_queue_start = rnp_rx_queue_start,
1506 : : .rxq_info_get = rnp_rx_queue_info_get,
1507 : : .rx_burst_mode_get = rnp_rx_burst_mode_get,
1508 : : .tx_queue_setup = rnp_tx_queue_setup,
1509 : : .tx_queue_release = rnp_dev_tx_queue_release,
1510 : : .tx_queue_stop = rnp_tx_queue_stop,
1511 : : .tx_queue_start = rnp_tx_queue_start,
1512 : : .txq_info_get = rnp_tx_queue_info_get,
1513 : : .tx_burst_mode_get = rnp_tx_burst_mode_get,
1514 : : /* rss impl */
1515 : : .reta_update = rnp_dev_rss_reta_update,
1516 : : .reta_query = rnp_dev_rss_reta_query,
1517 : : .rss_hash_update = rnp_dev_rss_hash_update,
1518 : : .rss_hash_conf_get = rnp_dev_rss_hash_conf_get,
1519 : : /* stats */
1520 : : .stats_get = rnp_dev_stats_get,
1521 : : .stats_reset = rnp_dev_stats_reset,
1522 : : .xstats_get = rnp_dev_xstats_get,
1523 : : .xstats_reset = rnp_dev_xstats_reset,
1524 : : .xstats_get_names = rnp_dev_xstats_get_names,
1525 : : /* link impl */
1526 : : .link_update = rnp_dev_link_update,
1527 : : .dev_set_link_up = rnp_dev_set_link_up,
1528 : : .dev_set_link_down = rnp_dev_set_link_down,
1529 : : /* mac address filter */
1530 : : .mac_addr_set = rnp_dev_mac_addr_set,
1531 : : .mac_addr_add = rnp_dev_mac_addr_add,
1532 : : .mac_addr_remove = rnp_dev_mac_addr_remove,
1533 : : .set_mc_addr_list = rnp_dev_set_mc_addr_list,
1534 : : /* vlan offload */
1535 : : .vlan_offload_set = rnp_vlan_offload_set,
1536 : : .vlan_strip_queue_set = rnp_vlan_strip_queue_set,
1537 : : .vlan_filter_set = rnp_vlan_filter_set,
1538 : : .dev_supported_ptypes_get = rnp_dev_supported_ptypes_get,
1539 : : };
1540 : :
1541 : : static void
1542 : 0 : rnp_setup_port_attr(struct rnp_eth_port *port,
1543 : : struct rte_eth_dev *eth_dev,
1544 : : uint8_t sw_id)
1545 : : {
1546 : : struct rnp_port_attr *attr = &port->attr;
1547 : 0 : struct rnp_hw *hw = port->hw;
1548 : : uint32_t lane;
1549 : :
1550 : 0 : PMD_INIT_FUNC_TRACE();
1551 : :
1552 : 0 : lane = hw->phy_port_ids[sw_id] & (hw->max_port_num - 1);
1553 : 0 : attr->port_id = eth_dev->data->port_id;
1554 : 0 : attr->port_offset = RNP_E_REG_RD(hw, RNP_TC_PORT_OFFSET(lane));
1555 : 0 : attr->nr_lane = lane;
1556 : 0 : attr->sw_id = sw_id;
1557 : :
1558 : 0 : attr->max_rx_queues = RNP_MAX_RX_QUEUE_NUM / hw->max_port_num;
1559 : 0 : attr->max_tx_queues = RNP_MAX_TX_QUEUE_NUM / hw->max_port_num;
1560 : :
1561 [ # # ]: 0 : if (hw->nic_mode > RNP_SINGLE_10G) {
1562 : 0 : attr->max_mac_addrs = RNP_PORT_MAX_MACADDR;
1563 : 0 : attr->max_uc_mac_hash = 0;
1564 : 0 : attr->max_mc_mac_hash = RNP_PORT_MAX_MC_MAC_SIZE;
1565 : 0 : attr->uc_hash_tb_size = 0;
1566 : 0 : attr->mc_hash_tb_size = RNP_PORT_MAX_MC_HASH_TB;
1567 : 0 : attr->hash_table_shift = RNP_PORT_HASH_SHIFT;
1568 : : } else {
1569 : 0 : attr->max_mac_addrs = RNP_MAX_MAC_ADDRS;
1570 : 0 : attr->max_uc_mac_hash = RNP_MAX_HASH_UC_MAC_SIZE;
1571 : 0 : attr->max_mc_mac_hash = RNP_MAX_HASH_MC_MAC_SIZE;
1572 : 0 : attr->uc_hash_tb_size = RNP_MAX_UC_HASH_TABLE;
1573 : 0 : attr->mc_hash_tb_size = RNP_MAC_MC_HASH_TABLE;
1574 : 0 : attr->hash_table_shift = 0;
1575 : : }
1576 : 0 : port->outvlan_type = RNP_SVLAN_TYPE;
1577 : 0 : port->invlan_type = RNP_CVLAN_TYPE;
1578 : :
1579 : 0 : rnp_mbx_fw_get_lane_stat(port);
1580 : :
1581 : 0 : RNP_PMD_INFO("PF[%d] SW-ETH-PORT[%d]<->PHY_LANE[%d]",
1582 : : hw->mbx.pf_num, sw_id, lane);
1583 : 0 : }
1584 : :
1585 : : static int
1586 : 0 : rnp_init_port_resource(struct rnp_eth_adapter *adapter,
1587 : : struct rte_eth_dev *eth_dev,
1588 : : char *name,
1589 : : uint8_t p_id)
1590 : : {
1591 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
1592 : 0 : struct rte_pci_device *pci_dev = adapter->pdev;
1593 : 0 : char mac_str[RTE_ETHER_ADDR_FMT_SIZE] = " ";
1594 : :
1595 : 0 : PMD_INIT_FUNC_TRACE();
1596 : :
1597 : 0 : port->eth_dev = eth_dev;
1598 : 0 : port->hw = &adapter->hw;
1599 : :
1600 : 0 : eth_dev->dev_ops = &rnp_eth_dev_ops;
1601 : 0 : eth_dev->device = &pci_dev->device;
1602 : 0 : eth_dev->data->mtu = RTE_ETHER_MTU;
1603 : :
1604 : 0 : rnp_setup_port_attr(port, eth_dev, p_id);
1605 : 0 : eth_dev->data->mac_addrs = rte_zmalloc(name,
1606 : : sizeof(struct rte_ether_addr) *
1607 : 0 : port->attr.max_mac_addrs, 0);
1608 [ # # ]: 0 : if (!eth_dev->data->mac_addrs) {
1609 : 0 : RNP_PMD_ERR("zmalloc for mac failed! Exiting.");
1610 : 0 : return -ENOMEM;
1611 : : }
1612 : 0 : rnp_get_mac_addr(port, port->mac_addr.addr_bytes);
1613 : 0 : rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
1614 : 0 : &port->mac_addr);
1615 : 0 : RNP_PMD_INFO("get mac addr from firmware %s", mac_str);
1616 : : if (!rte_is_valid_assigned_ether_addr(&port->mac_addr)) {
1617 : 0 : RNP_PMD_WARN("get mac_addr is invalid, just use random");
1618 : 0 : rte_eth_random_addr(port->mac_addr.addr_bytes);
1619 : : }
1620 : 0 : rte_ether_addr_copy(&port->mac_addr, ð_dev->data->mac_addrs[0]);
1621 : 0 : rnp_set_macaddr(port, (u8 *)&port->mac_addr, 0);
1622 : :
1623 : : rte_spinlock_init(&port->rx_mac_lock);
1624 : 0 : adapter->ports[p_id] = port;
1625 : 0 : adapter->inited_ports++;
1626 : :
1627 : 0 : return 0;
1628 : : }
1629 : :
1630 : : static int
1631 : : rnp_proc_priv_init(struct rte_eth_dev *dev)
1632 : : {
1633 : : struct rnp_proc_priv *priv;
1634 : :
1635 : 0 : priv = rte_zmalloc_socket("rnp_proc_priv",
1636 : : sizeof(struct rnp_proc_priv),
1637 : : RTE_CACHE_LINE_SIZE,
1638 : 0 : dev->device->numa_node);
1639 [ # # # # ]: 0 : if (!priv)
1640 : : return -ENOMEM;
1641 : 0 : dev->process_private = priv;
1642 : :
1643 : : return 0;
1644 : : }
1645 : :
1646 : : static int
1647 : 0 : rnp_rx_reset_pool_setup(struct rnp_eth_adapter *adapter)
1648 : : {
1649 : 0 : struct rte_eth_dev *eth_dev = adapter->eth_dev;
1650 : : char name[RTE_MEMPOOL_NAMESIZE];
1651 : :
1652 : 0 : snprintf(name, sizeof(name), "rx_reset_pool_%d:%d",
1653 : 0 : eth_dev->data->port_id, eth_dev->device->numa_node);
1654 : :
1655 : 0 : adapter->reset_pool = rte_pktmbuf_pool_create(name, 2,
1656 : : 0, 0, RTE_MBUF_DEFAULT_BUF_SIZE,
1657 : 0 : eth_dev->device->numa_node);
1658 [ # # ]: 0 : if (adapter->reset_pool == NULL) {
1659 : 0 : RNP_PMD_ERR("mempool %s create failed", name);
1660 : 0 : return -ENOMEM;
1661 : : }
1662 : :
1663 : : return 0;
1664 : : }
1665 : :
1666 : : static int
1667 : 0 : rnp_eth_dev_init(struct rte_eth_dev *eth_dev)
1668 : : {
1669 : 0 : struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI((void *)eth_dev->device);
1670 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
1671 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
1672 : 0 : char name[RTE_ETH_NAME_MAX_LEN] = " ";
1673 : : struct rnp_eth_adapter *adapter;
1674 : : struct rte_eth_dev *sub_eth_dev;
1675 : : struct rnp_hw *hw;
1676 : : uint16_t p_id;
1677 : : int ret = -1;
1678 : :
1679 : 0 : PMD_INIT_FUNC_TRACE();
1680 : :
1681 : 0 : snprintf(name, sizeof(name), "rnp_adapter_%d", eth_dev->data->port_id);
1682 : 0 : adapter = rte_zmalloc(name, sizeof(struct rnp_eth_adapter), 0);
1683 [ # # ]: 0 : if (!adapter) {
1684 : 0 : RNP_PMD_ERR("rnp_adapter zmalloc mem failed");
1685 : 0 : return -ENOMEM;
1686 : : }
1687 : 0 : hw = &adapter->hw;
1688 : 0 : adapter->pdev = pci_dev;
1689 : 0 : adapter->eth_dev = eth_dev;
1690 : 0 : adapter->ports[0] = port;
1691 : 0 : hw->back = (void *)adapter;
1692 : 0 : port->eth_dev = eth_dev;
1693 : 0 : port->hw = hw;
1694 : :
1695 : 0 : hw->e_ctrl = (u8 *)pci_dev->mem_resource[4].addr;
1696 : 0 : hw->c_ctrl = (u8 *)pci_dev->mem_resource[0].addr;
1697 : 0 : hw->c_blen = pci_dev->mem_resource[0].len;
1698 : 0 : hw->device_id = pci_dev->id.device_id;
1699 : 0 : hw->vendor_id = pci_dev->id.vendor_id;
1700 : 0 : hw->mbx.en_vfs = pci_dev->max_vfs;
1701 [ # # ]: 0 : if (hw->mbx.en_vfs > hw->max_vfs) {
1702 : : ret = -EINVAL;
1703 : 0 : RNP_PMD_ERR("sriov vfs max support 64");
1704 : 0 : goto free_ad;
1705 : : }
1706 : :
1707 : 0 : strlcpy(hw->device_name, pci_dev->device.name,
1708 : : strlen(pci_dev->device.name) + 1);
1709 : : ret = rnp_proc_priv_init(eth_dev);
1710 : : if (ret < 0) {
1711 : 0 : RNP_PMD_ERR("proc_priv_alloc failed");
1712 : 0 : goto free_ad;
1713 : : }
1714 : 0 : ret = rnp_init_mbx_pf(hw);
1715 [ # # ]: 0 : if (ret < 0) {
1716 : 0 : RNP_PMD_ERR("mailbox hardware init failed");
1717 : 0 : goto free_ad;
1718 : : }
1719 : 0 : ret = rnp_init_hw(hw);
1720 [ # # ]: 0 : if (ret < 0) {
1721 : 0 : RNP_PMD_ERR("Hardware initialization failed");
1722 : 0 : goto free_ad;
1723 : : }
1724 : 0 : ret = rnp_setup_common_ops(hw);
1725 [ # # ]: 0 : if (ret < 0) {
1726 : 0 : RNP_PMD_ERR("hardware common ops setup failed");
1727 : 0 : goto free_ad;
1728 : : }
1729 : 0 : rnp_mbx_fw_pf_link_event_en(port, false);
1730 [ # # ]: 0 : for (p_id = 0; p_id < hw->max_port_num; p_id++) {
1731 : : /* port 0 resource has been allocated when probe */
1732 [ # # ]: 0 : if (!p_id) {
1733 : : sub_eth_dev = eth_dev;
1734 : : } else {
1735 [ # # ]: 0 : if (strlen(hw->device_name) + 4 > sizeof(name))
1736 : : return -EINVAL;
1737 : 0 : snprintf(name, sizeof(name),
1738 : : "%s_%d", hw->device_name, p_id);
1739 : 0 : sub_eth_dev = rnp_alloc_eth_port(pci_dev, name);
1740 [ # # ]: 0 : if (!sub_eth_dev) {
1741 : 0 : RNP_PMD_ERR("%s sub_eth alloc failed",
1742 : : hw->device_name);
1743 : : ret = -ENOMEM;
1744 : 0 : goto eth_alloc_error;
1745 : : }
1746 : : ret = rnp_proc_priv_init(sub_eth_dev);
1747 : : if (ret < 0) {
1748 : 0 : RNP_PMD_ERR("proc_priv_alloc failed");
1749 : 0 : goto eth_alloc_error;
1750 : : }
1751 : : memcpy(sub_eth_dev->process_private,
1752 : 0 : eth_dev->process_private,
1753 : : sizeof(struct rnp_proc_priv));
1754 : : }
1755 : 0 : ret = rnp_init_port_resource(adapter, sub_eth_dev, name, p_id);
1756 [ # # ]: 0 : if (ret)
1757 : 0 : goto eth_alloc_error;
1758 : 0 : rnp_mac_rx_disable(sub_eth_dev);
1759 : : rnp_mac_tx_disable(sub_eth_dev);
1760 [ # # ]: 0 : if (p_id) {
1761 : : /* port 0 will be probe by platform */
1762 : 0 : rte_eth_dev_probing_finish(sub_eth_dev);
1763 : : }
1764 : : }
1765 : 0 : ret = rnp_rx_reset_pool_setup(adapter);
1766 [ # # ]: 0 : if (ret)
1767 : 0 : goto eth_alloc_error;
1768 : : /* enable link update event interrupt */
1769 : 0 : rte_intr_callback_register(intr_handle,
1770 : : rnp_dev_interrupt_handler, adapter);
1771 : 0 : rte_intr_enable(intr_handle);
1772 : 0 : rnp_mbx_fw_pf_link_event_en(port, true);
1773 : :
1774 : 0 : return 0;
1775 : :
1776 : 0 : eth_alloc_error:
1777 [ # # ]: 0 : for (p_id = 0; p_id < adapter->inited_ports; p_id++) {
1778 : 0 : port = adapter->ports[p_id];
1779 [ # # ]: 0 : if (!port)
1780 : 0 : continue;
1781 [ # # ]: 0 : if (port->eth_dev) {
1782 : 0 : rnp_dev_close(port->eth_dev);
1783 : : /* just release eth_dev allocated by myself */
1784 [ # # ]: 0 : if (port->eth_dev != adapter->eth_dev)
1785 : 0 : rte_eth_dev_release_port(port->eth_dev);
1786 : : }
1787 : : }
1788 : 0 : free_ad:
1789 [ # # ]: 0 : if (hw->fw_info.cookie_pool)
1790 : 0 : rnp_dma_mem_free(hw, &hw->fw_info.mem);
1791 : 0 : rte_free(adapter);
1792 : :
1793 : 0 : return ret;
1794 : :
1795 : : }
1796 : :
1797 : : static int
1798 : 0 : rnp_eth_dev_uninit(struct rte_eth_dev *eth_dev)
1799 : : {
1800 : 0 : struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI((void *)eth_dev->device);
1801 : : uint16_t port_id;
1802 : : int err = 0;
1803 : :
1804 : : /* Free up other ports and all resources */
1805 [ # # ]: 0 : RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device)
1806 : 0 : err |= rte_eth_dev_close(port_id);
1807 : :
1808 [ # # ]: 0 : return err == 0 ? 0 : -EIO;
1809 : : }
1810 : :
1811 : : static int
1812 : 0 : rnp_pci_remove(struct rte_pci_device *pci_dev)
1813 : : {
1814 : 0 : char device_name[RTE_ETH_NAME_MAX_LEN] = "";
1815 : : struct rte_eth_dev *eth_dev = NULL;
1816 : : uint16_t idx = 0;
1817 : :
1818 : : /* Find a port belong to pf that not be called dev_close */
1819 [ # # ]: 0 : for (idx = 0; idx < RNP_MAX_PORT_OF_PF; idx++) {
1820 [ # # ]: 0 : if (idx)
1821 : 0 : snprintf(device_name, sizeof(device_name), "%s_%d",
1822 : : pci_dev->device.name,
1823 : : idx);
1824 : : else
1825 : 0 : snprintf(device_name, sizeof(device_name), "%s",
1826 : : pci_dev->device.name);
1827 : 0 : eth_dev = rte_eth_dev_allocated(device_name);
1828 [ # # ]: 0 : if (eth_dev)
1829 : : break;
1830 : : }
1831 [ # # ]: 0 : if (eth_dev)
1832 : : /* Cleanup eth dev */
1833 : 0 : return rnp_eth_dev_uninit(eth_dev);
1834 : : return -ENODEV;
1835 : : }
1836 : :
1837 : : static int
1838 : 0 : rnp_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
1839 : : {
1840 : : int rc;
1841 : :
1842 : : RTE_SET_USED(pci_drv);
1843 : :
1844 : 0 : rc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct rnp_eth_port),
1845 : : rnp_eth_dev_init);
1846 : :
1847 : 0 : return rc;
1848 : : }
1849 : :
1850 : : static const struct rte_pci_id pci_id_rnp_map[] = {
1851 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_MUCSE, RNP_DEV_ID_N10G_X2) },
1852 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_MUCSE, RNP_DEV_ID_N10G_X4) },
1853 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_MUCSE, RNP_DEV_ID_N10G_X8) },
1854 : : { .vendor_id = 0, },
1855 : : };
1856 : :
1857 : : static struct rte_pci_driver rte_rnp_pmd = {
1858 : : .id_table = pci_id_rnp_map,
1859 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
1860 : : .probe = rnp_pci_probe,
1861 : : .remove = rnp_pci_remove,
1862 : : };
1863 : :
1864 [ - + ]: 254 : RTE_LOG_REGISTER_SUFFIX(rnp_init_logtype, init, NOTICE);
1865 : :
1866 : 254 : RTE_PMD_REGISTER_PCI(net_rnp, rte_rnp_pmd);
1867 : : RTE_PMD_REGISTER_PCI_TABLE(net_rnp, pci_id_rnp_map);
1868 : : RTE_PMD_REGISTER_KMOD_DEP(net_rnp, "igb_uio | uio_pci_generic | vfio-pci");
|