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