Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 Realtek Corporation. All rights reserved
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <errno.h>
7 : : #include <stdint.h>
8 : :
9 : : #include <rte_eal.h>
10 : :
11 : : #include <rte_common.h>
12 : : #include <rte_interrupts.h>
13 : : #include <rte_byteorder.h>
14 : : #include <rte_pci.h>
15 : : #include <bus_pci_driver.h>
16 : : #include <rte_ether.h>
17 : : #include <ethdev_driver.h>
18 : : #include <ethdev_pci.h>
19 : : #include <rte_memory.h>
20 : : #include <rte_malloc.h>
21 : : #include <dev_driver.h>
22 : :
23 : : #include "r8169_ethdev.h"
24 : : #include "r8169_compat.h"
25 : : #include "r8169_logs.h"
26 : : #include "r8169_hw.h"
27 : : #include "r8169_dash.h"
28 : :
29 : : static int rtl_dev_configure(struct rte_eth_dev *dev __rte_unused);
30 : : static int rtl_dev_start(struct rte_eth_dev *dev);
31 : : static int rtl_dev_stop(struct rte_eth_dev *dev);
32 : : static int rtl_dev_reset(struct rte_eth_dev *dev);
33 : : static int rtl_dev_close(struct rte_eth_dev *dev);
34 : : static int rtl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused);
35 : : static int rtl_dev_set_link_up(struct rte_eth_dev *dev);
36 : : static int rtl_dev_set_link_down(struct rte_eth_dev *dev);
37 : : static int rtl_dev_infos_get(struct rte_eth_dev *dev,
38 : : struct rte_eth_dev_info *dev_info);
39 : : static int rtl_dev_stats_get(struct rte_eth_dev *dev,
40 : : struct rte_eth_stats *rte_stats,
41 : : struct eth_queue_stats *qstats);
42 : : static int rtl_dev_stats_reset(struct rte_eth_dev *dev);
43 : : static int rtl_promiscuous_enable(struct rte_eth_dev *dev);
44 : : static int rtl_promiscuous_disable(struct rte_eth_dev *dev);
45 : : static int rtl_allmulticast_enable(struct rte_eth_dev *dev);
46 : : static int rtl_allmulticast_disable(struct rte_eth_dev *dev);
47 : : static int rtl_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
48 : : static int rtl_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
49 : : size_t fw_size);
50 : :
51 : : /*
52 : : * The set of PCI devices this driver supports
53 : : */
54 : : static const struct rte_pci_id pci_id_r8169_map[] = {
55 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125) },
56 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8162) },
57 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8126) },
58 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5000) },
59 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) },
60 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8127) },
61 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x0E10) },
62 : : {.vendor_id = 0, /* sentinel */ },
63 : : };
64 : :
65 : : static const struct rte_eth_desc_lim rx_desc_lim = {
66 : : .nb_max = RTL_MAX_RX_DESC,
67 : : .nb_min = RTL_MIN_RX_DESC,
68 : : .nb_align = RTL_DESC_ALIGN,
69 : : };
70 : :
71 : : static const struct rte_eth_desc_lim tx_desc_lim = {
72 : : .nb_max = RTL_MAX_TX_DESC,
73 : : .nb_min = RTL_MIN_TX_DESC,
74 : : .nb_align = RTL_DESC_ALIGN,
75 : : .nb_seg_max = RTL_MAX_TX_SEG,
76 : : .nb_mtu_seg_max = RTL_MAX_TX_SEG,
77 : : };
78 : :
79 : : static const struct eth_dev_ops rtl_eth_dev_ops = {
80 : : .dev_configure = rtl_dev_configure,
81 : : .dev_start = rtl_dev_start,
82 : : .dev_stop = rtl_dev_stop,
83 : : .dev_close = rtl_dev_close,
84 : : .dev_reset = rtl_dev_reset,
85 : : .dev_set_link_up = rtl_dev_set_link_up,
86 : : .dev_set_link_down = rtl_dev_set_link_down,
87 : : .dev_infos_get = rtl_dev_infos_get,
88 : :
89 : : .promiscuous_enable = rtl_promiscuous_enable,
90 : : .promiscuous_disable = rtl_promiscuous_disable,
91 : : .allmulticast_enable = rtl_allmulticast_enable,
92 : : .allmulticast_disable = rtl_allmulticast_disable,
93 : :
94 : : .link_update = rtl_dev_link_update,
95 : :
96 : : .stats_get = rtl_dev_stats_get,
97 : : .stats_reset = rtl_dev_stats_reset,
98 : :
99 : : .mtu_set = rtl_dev_mtu_set,
100 : :
101 : : .fw_version_get = rtl_fw_version_get,
102 : :
103 : : .rx_queue_setup = rtl_rx_queue_setup,
104 : : .rx_queue_release = rtl_rx_queue_release,
105 : : .rxq_info_get = rtl_rxq_info_get,
106 : :
107 : : .tx_queue_setup = rtl_tx_queue_setup,
108 : : .tx_queue_release = rtl_tx_queue_release,
109 : : .tx_done_cleanup = rtl_tx_done_cleanup,
110 : : .txq_info_get = rtl_txq_info_get,
111 : : };
112 : :
113 : : static int
114 : 0 : rtl_dev_configure(struct rte_eth_dev *dev __rte_unused)
115 : : {
116 : 0 : return 0;
117 : : }
118 : :
119 : : static void
120 : 0 : rtl_disable_intr(struct rtl_hw *hw)
121 : : {
122 : 0 : PMD_INIT_FUNC_TRACE();
123 [ # # ]: 0 : if (rtl_is_8125(hw)) {
124 : 0 : RTL_W32(hw, IMR0_8125, 0x0000);
125 : 0 : RTL_W32(hw, ISR0_8125, RTL_R32(hw, ISR0_8125));
126 : : } else {
127 : 0 : RTL_W16(hw, IntrMask, 0x0000);
128 : 0 : RTL_W16(hw, IntrStatus, RTL_R16(hw, IntrStatus));
129 : : }
130 : 0 : }
131 : :
132 : : static void
133 : 0 : rtl_enable_intr(struct rtl_hw *hw)
134 : : {
135 : 0 : PMD_INIT_FUNC_TRACE();
136 [ # # ]: 0 : if (rtl_is_8125(hw))
137 : 0 : RTL_W32(hw, IMR0_8125, LinkChg);
138 : : else
139 : 0 : RTL_W16(hw, IntrMask, LinkChg);
140 : 0 : }
141 : :
142 : : static int
143 : 0 : _rtl_setup_link(struct rte_eth_dev *dev)
144 : : {
145 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
146 : 0 : struct rtl_hw *hw = &adapter->hw;
147 : : u64 adv = 0;
148 : : u32 *link_speeds = &dev->data->dev_conf.link_speeds;
149 : : unsigned int speed_mode;
150 : :
151 : : /* Setup link speed and duplex */
152 [ # # ]: 0 : if (*link_speeds == RTE_ETH_LINK_SPEED_AUTONEG) {
153 [ # # ]: 0 : switch (hw->mcfg) {
154 : : case CFG_METHOD_48:
155 : : case CFG_METHOD_49:
156 : : case CFG_METHOD_50:
157 : : case CFG_METHOD_51:
158 : : case CFG_METHOD_52:
159 : : case CFG_METHOD_53:
160 : : case CFG_METHOD_54:
161 : : case CFG_METHOD_55:
162 : : case CFG_METHOD_56:
163 : : case CFG_METHOD_57:
164 : : case CFG_METHOD_58:
165 : : speed_mode = SPEED_2500;
166 : : break;
167 : : case CFG_METHOD_69:
168 : : case CFG_METHOD_70:
169 : : case CFG_METHOD_71:
170 : : speed_mode = SPEED_5000;
171 : : break;
172 : : case CFG_METHOD_91:
173 : : speed_mode = SPEED_10000;
174 : : break;
175 : : default:
176 : : speed_mode = SPEED_1000;
177 : : break;
178 : : }
179 : :
180 : 0 : rtl_set_link_option(hw, AUTONEG_ENABLE, speed_mode, DUPLEX_FULL,
181 : : rtl_fc_full);
182 : : } else if (*link_speeds != 0) {
183 [ # # ]: 0 : if (*link_speeds & ~(RTE_ETH_LINK_SPEED_10M_HD | RTE_ETH_LINK_SPEED_10M |
184 : : RTE_ETH_LINK_SPEED_100M_HD | RTE_ETH_LINK_SPEED_100M |
185 : : RTE_ETH_LINK_SPEED_1G | RTE_ETH_LINK_SPEED_2_5G |
186 : : RTE_ETH_LINK_SPEED_5G | RTE_ETH_LINK_SPEED_10G |
187 : : RTE_ETH_LINK_SPEED_FIXED))
188 : 0 : goto error_invalid_config;
189 : :
190 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_10M_HD) {
191 : 0 : hw->speed = SPEED_10;
192 : 0 : hw->duplex = DUPLEX_HALF;
193 : : adv |= ADVERTISE_10_HALF;
194 : : }
195 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_10M) {
196 : 0 : hw->speed = SPEED_10;
197 : 0 : hw->duplex = DUPLEX_FULL;
198 : 0 : adv |= ADVERTISE_10_FULL;
199 : : }
200 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_100M_HD) {
201 : 0 : hw->speed = SPEED_100;
202 : 0 : hw->duplex = DUPLEX_HALF;
203 : 0 : adv |= ADVERTISE_100_HALF;
204 : : }
205 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_100M) {
206 : 0 : hw->speed = SPEED_100;
207 : 0 : hw->duplex = DUPLEX_FULL;
208 : 0 : adv |= ADVERTISE_100_FULL;
209 : : }
210 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_1G) {
211 : 0 : hw->speed = SPEED_1000;
212 : 0 : hw->duplex = DUPLEX_FULL;
213 : 0 : adv |= ADVERTISE_1000_FULL;
214 : : }
215 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_2_5G) {
216 : 0 : hw->speed = SPEED_2500;
217 : 0 : hw->duplex = DUPLEX_FULL;
218 : 0 : adv |= ADVERTISE_2500_FULL;
219 : : }
220 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_5G) {
221 : 0 : hw->speed = SPEED_5000;
222 : 0 : hw->duplex = DUPLEX_FULL;
223 : 0 : adv |= ADVERTISE_5000_FULL;
224 : : }
225 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_10G) {
226 : 0 : hw->speed = SPEED_10000;
227 : 0 : hw->duplex = DUPLEX_FULL;
228 : 0 : adv |= ADVERTISE_10000_FULL;
229 : : }
230 : :
231 : 0 : hw->autoneg = AUTONEG_ENABLE;
232 : 0 : hw->advertising = adv;
233 : : }
234 : :
235 : 0 : rtl_set_speed(hw);
236 : :
237 : 0 : return 0;
238 : :
239 : : error_invalid_config:
240 : 0 : PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
241 : : dev->data->dev_conf.link_speeds, dev->data->port_id);
242 : 0 : rtl_stop_queues(dev);
243 : 0 : return -EINVAL;
244 : : }
245 : :
246 : : static int
247 : : rtl_setup_link(struct rte_eth_dev *dev)
248 : : {
249 : : #ifdef RTE_EXEC_ENV_FREEBSD
250 : : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
251 : : struct rtl_hw *hw = &adapter->hw;
252 : : struct rte_eth_link link;
253 : : int count;
254 : : #endif
255 : :
256 : 0 : _rtl_setup_link(dev);
257 : :
258 : : #ifdef RTE_EXEC_ENV_FREEBSD
259 : : for (count = 0; count < R8169_LINK_CHECK_TIMEOUT; count++) {
260 : : if (!(RTL_R16(hw, PHYstatus) & LinkStatus)) {
261 : : rte_delay_ms(R8169_LINK_CHECK_INTERVAL);
262 : : continue;
263 : : }
264 : :
265 : : rtl_dev_link_update(dev, 0);
266 : :
267 : : rte_eth_linkstatus_get(dev, &link);
268 : :
269 : : return 0;
270 : : }
271 : : #endif
272 : : return 0;
273 : : }
274 : :
275 : : /* Set PCI configuration space offset 0x79 to setting */
276 : : static void
277 : 0 : set_offset79(struct rte_pci_device *pdev, u8 setting)
278 : : {
279 : : u8 device_control;
280 : :
281 : 0 : PCI_READ_CONFIG_BYTE(pdev, &device_control, 0x79);
282 : 0 : device_control &= ~0x70;
283 : 0 : device_control |= setting;
284 : 0 : PCI_WRITE_CONFIG_BYTE(pdev, &device_control, 0x79);
285 : 0 : }
286 : :
287 : : /*
288 : : * Configure device link speed and setup link.
289 : : * It returns 0 on success.
290 : : */
291 : : static int
292 : 0 : rtl_dev_start(struct rte_eth_dev *dev)
293 : : {
294 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
295 : 0 : struct rtl_hw *hw = &adapter->hw;
296 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
297 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
298 : : int err;
299 : :
300 : : /* Disable uio/vfio intr/eventfd mapping */
301 : 0 : rte_intr_disable(intr_handle);
302 : :
303 : 0 : rtl_powerup_pll(hw);
304 : :
305 : 0 : rtl_hw_ephy_config(hw);
306 : :
307 : 0 : rtl_hw_phy_config(hw);
308 : :
309 : 0 : rtl_hw_config(hw);
310 : :
311 [ # # ]: 0 : if (!rtl_is_8125(hw))
312 : 0 : set_offset79(pci_dev, 0x40);
313 : :
314 : : /* Initialize transmission unit */
315 : 0 : rtl_tx_init(dev);
316 : :
317 : : /* This can fail when allocating mbufs for descriptor rings */
318 : 0 : err = rtl_rx_init(dev);
319 [ # # ]: 0 : if (err) {
320 : 0 : PMD_INIT_LOG(ERR, "Unable to initialize RX hardware");
321 : 0 : goto error;
322 : : }
323 : :
324 : : /* This can fail when allocating mem for tally counters */
325 : 0 : err = rtl_tally_init(dev);
326 [ # # ]: 0 : if (err)
327 : 0 : goto error;
328 : :
329 : : /* Enable uio/vfio intr/eventfd mapping */
330 : 0 : rte_intr_enable(intr_handle);
331 : :
332 : : /* Resume enabled intr since hw reset */
333 : 0 : rtl_enable_intr(hw);
334 : :
335 : : rtl_setup_link(dev);
336 : :
337 : 0 : rtl_mdio_write(hw, 0x1F, 0x0000);
338 : :
339 : 0 : return 0;
340 : 0 : error:
341 : 0 : rtl_stop_queues(dev);
342 : 0 : return -EIO;
343 : : }
344 : :
345 : : /*
346 : : * Stop device: disable RX and TX functions to allow for reconfiguring.
347 : : */
348 : : static int
349 : 0 : rtl_dev_stop(struct rte_eth_dev *dev)
350 : : {
351 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
352 : 0 : struct rtl_hw *hw = &adapter->hw;
353 : : struct rte_eth_link link;
354 : :
355 : 0 : rtl_disable_intr(hw);
356 : :
357 : 0 : rtl_nic_reset(hw);
358 : :
359 [ # # ]: 0 : if (rtl_is_8125(hw))
360 : 0 : rtl_mac_ocp_write(hw, 0xE00A, hw->mcu_pme_setting);
361 : :
362 : 0 : rtl_powerdown_pll(hw);
363 : :
364 : 0 : rtl_stop_queues(dev);
365 : :
366 : 0 : rtl_tally_free(dev);
367 : :
368 : : /* Clear the recorded link status */
369 : : memset(&link, 0, sizeof(link));
370 : 0 : rte_eth_linkstatus_set(dev, &link);
371 : :
372 : 0 : return 0;
373 : : }
374 : :
375 : : static int
376 : 0 : rtl_dev_set_link_up(struct rte_eth_dev *dev)
377 : : {
378 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
379 : 0 : struct rtl_hw *hw = &adapter->hw;
380 : :
381 : 0 : rtl_powerup_pll(hw);
382 : :
383 : 0 : return 0;
384 : : }
385 : :
386 : : static int
387 : 0 : rtl_dev_set_link_down(struct rte_eth_dev *dev)
388 : : {
389 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
390 : 0 : struct rtl_hw *hw = &adapter->hw;
391 : :
392 : : /* mcu pme intr masks */
393 [ # # ]: 0 : if (rtl_is_8125(hw))
394 : 0 : rtl_mac_ocp_write(hw, 0xE00A, hw->mcu_pme_setting & ~(BIT_11 | BIT_14));
395 : :
396 : 0 : rtl_powerdown_pll(hw);
397 : :
398 : 0 : return 0;
399 : : }
400 : :
401 : : static int
402 : 0 : rtl_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
403 : : {
404 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
405 : : struct rtl_hw *hw = &adapter->hw;
406 : :
407 : 0 : dev_info->min_rx_bufsize = 1024;
408 : 0 : dev_info->max_rx_pktlen = JUMBO_FRAME_9K;
409 : 0 : dev_info->max_mac_addrs = 1;
410 : :
411 : 0 : dev_info->max_rx_queues = 1;
412 : 0 : dev_info->max_tx_queues = 1;
413 : :
414 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
415 : : .rx_free_thresh = RTL_RX_FREE_THRESH,
416 : : };
417 : :
418 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
419 : : .tx_free_thresh = RTL_TX_FREE_THRESH,
420 : : };
421 : :
422 : 0 : dev_info->rx_desc_lim = rx_desc_lim;
423 : 0 : dev_info->tx_desc_lim = tx_desc_lim;
424 : :
425 : 0 : dev_info->speed_capa = RTE_ETH_LINK_SPEED_10M_HD | RTE_ETH_LINK_SPEED_10M |
426 : : RTE_ETH_LINK_SPEED_100M_HD | RTE_ETH_LINK_SPEED_100M |
427 : : RTE_ETH_LINK_SPEED_1G;
428 : :
429 [ # # # # ]: 0 : switch (hw->chipset_name) {
430 : 0 : case RTL8127:
431 : 0 : dev_info->speed_capa |= RTE_ETH_LINK_SPEED_10G;
432 : : /* fallthrough */
433 : 0 : case RTL8126A:
434 : 0 : dev_info->speed_capa |= RTE_ETH_LINK_SPEED_5G;
435 : : /* fallthrough */
436 : 0 : case RTL8125A:
437 : : case RTL8125B:
438 : : case RTL8125BP:
439 : : case RTL8125D:
440 : : case RTL8125CP:
441 : 0 : dev_info->speed_capa |= RTE_ETH_LINK_SPEED_2_5G;
442 : 0 : break;
443 : : }
444 : :
445 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
446 : 0 : dev_info->max_mtu = dev_info->max_rx_pktlen - RTL_ETH_OVERHEAD;
447 : :
448 : 0 : dev_info->rx_offload_capa = (rtl_get_rx_port_offloads() |
449 : 0 : dev_info->rx_queue_offload_capa);
450 : 0 : dev_info->tx_offload_capa = rtl_get_tx_port_offloads();
451 : :
452 : 0 : return 0;
453 : : }
454 : :
455 : : static int
456 : 0 : rtl_promiscuous_enable(struct rte_eth_dev *dev)
457 : : {
458 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
459 : : struct rtl_hw *hw = &adapter->hw;
460 : :
461 : : int rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys;
462 : :
463 : 0 : RTL_W32(hw, RxConfig, rx_mode | (RTL_R32(hw, RxConfig)));
464 : : rtl_allmulticast_enable(dev);
465 : :
466 : 0 : return 0;
467 : : }
468 : :
469 : : static int
470 : 0 : rtl_promiscuous_disable(struct rte_eth_dev *dev)
471 : : {
472 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
473 : : struct rtl_hw *hw = &adapter->hw;
474 : : int rx_mode = ~AcceptAllPhys;
475 : :
476 : 0 : RTL_W32(hw, RxConfig, rx_mode & (RTL_R32(hw, RxConfig)));
477 : :
478 [ # # ]: 0 : if (dev->data->all_multicast == 1)
479 : : rtl_allmulticast_enable(dev);
480 : : else
481 : : rtl_allmulticast_disable(dev);
482 : :
483 : 0 : return 0;
484 : : }
485 : :
486 : : static int
487 : 0 : rtl_allmulticast_enable(struct rte_eth_dev *dev)
488 : : {
489 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
490 : : struct rtl_hw *hw = &adapter->hw;
491 : :
492 : 0 : RTL_W32(hw, MAR0 + 0, 0xffffffff);
493 : 0 : RTL_W32(hw, MAR0 + 4, 0xffffffff);
494 : :
495 : 0 : return 0;
496 : : }
497 : :
498 : : static int
499 : 0 : rtl_allmulticast_disable(struct rte_eth_dev *dev)
500 : : {
501 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
502 : : struct rtl_hw *hw = &adapter->hw;
503 : :
504 [ # # # # ]: 0 : if (dev->data->promiscuous == 1)
505 : : return 0; /* Must remain in all_multicast mode */
506 : :
507 : 0 : RTL_W32(hw, MAR0 + 0, 0);
508 : 0 : RTL_W32(hw, MAR0 + 4, 0);
509 : :
510 : 0 : return 0;
511 : : }
512 : :
513 : : static int
514 : 0 : rtl_dev_stats_reset(struct rte_eth_dev *dev)
515 : : {
516 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
517 : 0 : struct rtl_hw *hw = &adapter->hw;
518 : :
519 : 0 : rtl_clear_tally_stats(hw);
520 : :
521 : 0 : memset(&adapter->sw_stats, 0, sizeof(adapter->sw_stats));
522 : :
523 : 0 : return 0;
524 : : }
525 : :
526 : : static void
527 : : rtl_sw_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
528 : : {
529 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
530 : : struct rtl_sw_stats *sw_stats = &adapter->sw_stats;
531 : :
532 : 0 : rte_stats->ibytes = sw_stats->rx_bytes;
533 : 0 : rte_stats->obytes = sw_stats->tx_bytes;
534 : : }
535 : :
536 : : static int
537 : 0 : rtl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
538 : : struct eth_queue_stats *qstats __rte_unused)
539 : : {
540 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
541 : 0 : struct rtl_hw *hw = &adapter->hw;
542 : :
543 : 0 : rtl_get_tally_stats(hw, rte_stats);
544 : : rtl_sw_stats_get(dev, rte_stats);
545 : :
546 : 0 : return 0;
547 : : }
548 : :
549 : : /* Return 0 means link status changed, -1 means not changed */
550 : : static int
551 : 0 : rtl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
552 : : {
553 : : struct rte_eth_link link, old;
554 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
555 : 0 : struct rtl_hw *hw = &adapter->hw;
556 : : u32 speed;
557 : : u16 status;
558 : :
559 : 0 : link.link_status = RTE_ETH_LINK_DOWN;
560 : 0 : link.link_speed = 0;
561 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
562 : 0 : link.link_autoneg = RTE_ETH_LINK_AUTONEG;
563 : :
564 : : memset(&old, 0, sizeof(old));
565 : :
566 : : /* Load old link status */
567 : 0 : rte_eth_linkstatus_get(dev, &old);
568 : :
569 : : /* Read current link status */
570 : 0 : status = RTL_R16(hw, PHYstatus);
571 : :
572 [ # # ]: 0 : if (status & LinkStatus) {
573 : 0 : link.link_status = RTE_ETH_LINK_UP;
574 : :
575 [ # # ]: 0 : if (status & FullDup) {
576 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
577 [ # # # # ]: 0 : if (!rtl_is_8125(hw) || hw->mcfg == CFG_METHOD_48)
578 : 0 : RTL_W32(hw, TxConfig, (RTL_R32(hw, TxConfig) |
579 : : (BIT_24 | BIT_25)) & ~BIT_19);
580 : : } else {
581 : 0 : link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
582 [ # # # # ]: 0 : if (!rtl_is_8125(hw) || hw->mcfg == CFG_METHOD_48)
583 : 0 : RTL_W32(hw, TxConfig, (RTL_R32(hw, TxConfig) | BIT_25) &
584 : : ~(BIT_19 | BIT_24));
585 : : }
586 : :
587 : : /*
588 : : * The PHYstatus register for the RTL8168 is 8 bits,
589 : : * while for the RTL8125, RTL8126 and RTL8127, it is 16 bits.
590 : : */
591 [ # # # # ]: 0 : if (status & _10000bpsF && rtl_is_8125(hw))
592 : : speed = 10000;
593 [ # # # # ]: 0 : else if (status & _5000bpsF && rtl_is_8125(hw))
594 : : speed = 5000;
595 [ # # # # ]: 0 : else if (status & _2500bpsF && rtl_is_8125(hw))
596 : : speed = 2500;
597 [ # # ]: 0 : else if (status & _1000bpsF)
598 : : speed = 1000;
599 [ # # ]: 0 : else if (status & _100bps)
600 : : speed = 100;
601 : : else
602 : : speed = 10;
603 : :
604 : 0 : link.link_speed = speed;
605 : : }
606 : :
607 [ # # ]: 0 : if (link.link_status == old.link_status)
608 : : return -1;
609 : :
610 : 0 : rte_eth_linkstatus_set(dev, &link);
611 : :
612 : 0 : return 0;
613 : : }
614 : :
615 : : static void
616 : 0 : rtl_dev_interrupt_handler(void *param)
617 : : {
618 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
619 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
620 : 0 : struct rtl_hw *hw = &adapter->hw;
621 : : uint32_t intr;
622 : :
623 [ # # ]: 0 : if (rtl_is_8125(hw))
624 : 0 : intr = RTL_R32(hw, ISR0_8125);
625 : : else
626 : 0 : intr = RTL_R16(hw, IntrStatus);
627 : :
628 : : /* Clear all cause mask */
629 : 0 : rtl_disable_intr(hw);
630 : :
631 [ # # ]: 0 : if (intr & LinkChg)
632 : 0 : rtl_dev_link_update(dev, 0);
633 : : else
634 : 0 : PMD_DRV_LOG(ERR, "r8169: interrupt unhandled.");
635 : :
636 : 0 : rtl_enable_intr(hw);
637 : 0 : }
638 : :
639 : : /*
640 : : * Reset and stop device.
641 : : */
642 : : static int
643 : 0 : rtl_dev_close(struct rte_eth_dev *dev)
644 : : {
645 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
646 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
647 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
648 : 0 : struct rtl_hw *hw = &adapter->hw;
649 : : int retries = 0;
650 : : int ret_unreg, ret_stp;
651 : :
652 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
653 : : return 0;
654 : :
655 [ # # ]: 0 : if (HW_DASH_SUPPORT_DASH(hw))
656 : 0 : rtl_driver_stop(hw);
657 : :
658 : 0 : ret_stp = rtl_dev_stop(dev);
659 : :
660 : 0 : rtl_free_queues(dev);
661 : :
662 : : /* Reprogram the RAR[0] in case user changed it. */
663 : 0 : rtl_rar_set(hw, hw->mac_addr);
664 : :
665 : : /* Disable uio intr before callback unregister */
666 : 0 : rte_intr_disable(intr_handle);
667 : :
668 : : do {
669 : 0 : ret_unreg = rte_intr_callback_unregister(intr_handle, rtl_dev_interrupt_handler,
670 : : dev);
671 [ # # ]: 0 : if (ret_unreg >= 0 || ret_unreg == -ENOENT)
672 : : break;
673 [ # # ]: 0 : else if (ret_unreg != -EAGAIN)
674 : 0 : PMD_DRV_LOG(ERR, "r8169: intr callback unregister failed: %d", ret_unreg);
675 : :
676 : : rte_delay_ms(100);
677 [ # # ]: 0 : } while (retries++ < (10 + 90));
678 : :
679 : : return ret_stp;
680 : : }
681 : :
682 : : static int
683 : 0 : rtl_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
684 : : {
685 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
686 : : struct rtl_hw *hw = &adapter->hw;
687 : : uint32_t frame_size = mtu + RTL_ETH_OVERHEAD;
688 : :
689 : 0 : hw->mtu = mtu;
690 : :
691 : 0 : RTL_W16(hw, RxMaxSize, frame_size);
692 : :
693 : 0 : return 0;
694 : : }
695 : :
696 : : static int
697 : 0 : rtl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
698 : : {
699 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
700 : : struct rtl_hw *hw = &adapter->hw;
701 : : int ret;
702 : :
703 [ # # ]: 0 : ret = snprintf(fw_version, fw_size, "0x%08x", hw->hw_ram_code_ver);
704 : :
705 : 0 : ret += 1; /* Add the size of '\0' */
706 [ # # ]: 0 : if (fw_size < (u32)ret)
707 : : return ret;
708 : : else
709 : 0 : return 0;
710 : : }
711 : :
712 : : static int
713 : 0 : rtl_dev_init(struct rte_eth_dev *dev)
714 : : {
715 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
716 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
717 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
718 : 0 : struct rtl_hw *hw = &adapter->hw;
719 : 0 : struct rte_ether_addr *perm_addr = (struct rte_ether_addr *)hw->mac_addr;
720 : : char buf[RTE_ETHER_ADDR_FMT_SIZE];
721 : :
722 : 0 : dev->dev_ops = &rtl_eth_dev_ops;
723 : 0 : dev->tx_pkt_burst = &rtl_xmit_pkts;
724 : 0 : dev->rx_pkt_burst = &rtl_recv_pkts;
725 : :
726 : : /* For secondary processes, the primary process has done all the work. */
727 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
728 [ # # ]: 0 : if (dev->data->scattered_rx)
729 : 0 : dev->rx_pkt_burst = &rtl_recv_scattered_pkts;
730 : 0 : return 0;
731 : : }
732 : :
733 : : /* R8169 uses BAR2 */
734 : 0 : hw->mmio_addr = (u8 *)pci_dev->mem_resource[2].addr;
735 : :
736 : 0 : rtl_get_mac_version(hw, pci_dev);
737 : :
738 [ # # ]: 0 : if (rtl_set_hw_ops(hw))
739 : : return -ENOTSUP;
740 : :
741 : 0 : rtl_disable_intr(hw);
742 : :
743 : 0 : rtl_hw_initialize(hw);
744 : :
745 : : /* Read the permanent MAC address out of ROM */
746 : 0 : rtl_get_mac_address(hw, perm_addr);
747 : :
748 : : if (!rte_is_valid_assigned_ether_addr(perm_addr)) {
749 : 0 : rte_eth_random_addr(&perm_addr->addr_bytes[0]);
750 : :
751 : 0 : rte_ether_format_addr(buf, sizeof(buf), perm_addr);
752 : :
753 : 0 : PMD_INIT_LOG(NOTICE, "r8169: Assign randomly generated MAC address %s", buf);
754 : : }
755 : :
756 : : /* Allocate memory for storing MAC addresses */
757 : 0 : dev->data->mac_addrs = rte_zmalloc("r8169", RTE_ETHER_ADDR_LEN, 0);
758 : :
759 [ # # ]: 0 : if (dev->data->mac_addrs == NULL) {
760 : 0 : PMD_INIT_LOG(ERR, "MAC Malloc failed");
761 : 0 : return -ENOMEM;
762 : : }
763 : :
764 : : /* Copy the permanent MAC address */
765 : : rte_ether_addr_copy(perm_addr, &dev->data->mac_addrs[0]);
766 : :
767 : 0 : rtl_rar_set(hw, &perm_addr->addr_bytes[0]);
768 : :
769 : 0 : rte_intr_callback_register(intr_handle, rtl_dev_interrupt_handler, dev);
770 : :
771 : : /* Enable uio/vfio intr/eventfd mapping */
772 : 0 : rte_intr_enable(intr_handle);
773 : :
774 : 0 : return 0;
775 : : }
776 : :
777 : : static int
778 : 0 : rtl_dev_uninit(struct rte_eth_dev *dev)
779 : : {
780 [ # # # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
781 : : return -EPERM;
782 : :
783 : 0 : rtl_dev_close(dev);
784 : :
785 : 0 : return 0;
786 : : }
787 : :
788 : : static int
789 : 0 : rtl_dev_reset(struct rte_eth_dev *dev)
790 : : {
791 : : int ret;
792 : :
793 : : ret = rtl_dev_uninit(dev);
794 : : if (ret)
795 : : return ret;
796 : :
797 : 0 : ret = rtl_dev_init(dev);
798 : :
799 : 0 : return ret;
800 : : }
801 : :
802 : : static int
803 : 0 : rtl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
804 : : struct rte_pci_device *pci_dev)
805 : : {
806 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct rtl_adapter),
807 : : rtl_dev_init);
808 : : }
809 : :
810 : : static int
811 : 0 : rtl_pci_remove(struct rte_pci_device *pci_dev)
812 : : {
813 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, rtl_dev_uninit);
814 : : }
815 : :
816 : : static struct rte_pci_driver rte_r8169_pmd = {
817 : : .id_table = pci_id_r8169_map,
818 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
819 : : .probe = rtl_pci_probe,
820 : : .remove = rtl_pci_remove,
821 : : };
822 : :
823 : 253 : RTE_PMD_REGISTER_PCI(net_r8169, rte_r8169_pmd);
824 : : RTE_PMD_REGISTER_PCI_TABLE(net_r8169, pci_id_r8169_map);
825 : : RTE_PMD_REGISTER_KMOD_DEP(net_r8169, "* igb_uio | uio_pci_generic | vfio-pci");
826 : :
827 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(r8169_logtype_init, init, NOTICE)
828 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(r8169_logtype_driver, driver, NOTICE)
829 : : #ifdef RTE_ETHDEV_DEBUG_RX
830 : : RTE_LOG_REGISTER_SUFFIX(r8169_logtype_rx, rx, DEBUG)
831 : : #endif
832 : : #ifdef RTE_ETHDEV_DEBUG_TX
833 : : RTE_LOG_REGISTER_SUFFIX(r8169_logtype_tx, tx, DEBUG)
834 : : #endif
|