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