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 : : case RTL8125BP:
382 : : case RTL8125D:
383 : 0 : dev_info->speed_capa |= RTE_ETH_LINK_SPEED_2_5G;
384 : 0 : break;
385 : : }
386 : :
387 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
388 : 0 : dev_info->max_mtu = dev_info->max_rx_pktlen - RTL_ETH_OVERHEAD;
389 : :
390 : 0 : dev_info->rx_offload_capa = (rtl_get_rx_port_offloads() |
391 : 0 : dev_info->rx_queue_offload_capa);
392 : 0 : dev_info->tx_offload_capa = rtl_get_tx_port_offloads();
393 : :
394 : 0 : return 0;
395 : : }
396 : :
397 : : static int
398 : 0 : rtl_promiscuous_enable(struct rte_eth_dev *dev)
399 : : {
400 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
401 : : struct rtl_hw *hw = &adapter->hw;
402 : :
403 : : int rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys;
404 : :
405 : 0 : RTL_W32(hw, RxConfig, rx_mode | (RTL_R32(hw, RxConfig)));
406 : : rtl_allmulticast_enable(dev);
407 : :
408 : 0 : return 0;
409 : : }
410 : :
411 : : static int
412 : 0 : rtl_promiscuous_disable(struct rte_eth_dev *dev)
413 : : {
414 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
415 : : struct rtl_hw *hw = &adapter->hw;
416 : : int rx_mode = ~AcceptAllPhys;
417 : :
418 : 0 : RTL_W32(hw, RxConfig, rx_mode & (RTL_R32(hw, RxConfig)));
419 : :
420 [ # # ]: 0 : if (dev->data->all_multicast == 1)
421 : : rtl_allmulticast_enable(dev);
422 : : else
423 : : rtl_allmulticast_disable(dev);
424 : :
425 : 0 : return 0;
426 : : }
427 : :
428 : : static int
429 : 0 : rtl_allmulticast_enable(struct rte_eth_dev *dev)
430 : : {
431 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
432 : : struct rtl_hw *hw = &adapter->hw;
433 : :
434 : 0 : RTL_W32(hw, MAR0 + 0, 0xffffffff);
435 : 0 : RTL_W32(hw, MAR0 + 4, 0xffffffff);
436 : :
437 : 0 : return 0;
438 : : }
439 : :
440 : : static int
441 : 0 : rtl_allmulticast_disable(struct rte_eth_dev *dev)
442 : : {
443 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
444 : : struct rtl_hw *hw = &adapter->hw;
445 : :
446 [ # # # # ]: 0 : if (dev->data->promiscuous == 1)
447 : : return 0; /* Must remain in all_multicast mode */
448 : :
449 : 0 : RTL_W32(hw, MAR0 + 0, 0);
450 : 0 : RTL_W32(hw, MAR0 + 4, 0);
451 : :
452 : 0 : return 0;
453 : : }
454 : :
455 : : static int
456 : 0 : rtl_dev_stats_reset(struct rte_eth_dev *dev)
457 : : {
458 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
459 : 0 : struct rtl_hw *hw = &adapter->hw;
460 : :
461 : 0 : rtl_clear_tally_stats(hw);
462 : :
463 : 0 : memset(&adapter->sw_stats, 0, sizeof(adapter->sw_stats));
464 : :
465 : 0 : return 0;
466 : : }
467 : :
468 : : static void
469 : : rtl_sw_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
470 : : {
471 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
472 : : struct rtl_sw_stats *sw_stats = &adapter->sw_stats;
473 : :
474 : 0 : rte_stats->ibytes = sw_stats->rx_bytes;
475 : 0 : rte_stats->obytes = sw_stats->tx_bytes;
476 : : }
477 : :
478 : : static int
479 : 0 : rtl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
480 : : {
481 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
482 : 0 : struct rtl_hw *hw = &adapter->hw;
483 : :
484 : 0 : rtl_get_tally_stats(hw, rte_stats);
485 : : rtl_sw_stats_get(dev, rte_stats);
486 : :
487 : 0 : return 0;
488 : : }
489 : :
490 : : /* Return 0 means link status changed, -1 means not changed */
491 : : static int
492 : 0 : rtl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
493 : : {
494 : : struct rte_eth_link link, old;
495 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
496 : : struct rtl_hw *hw = &adapter->hw;
497 : : u32 speed;
498 : : u16 status;
499 : :
500 : 0 : link.link_status = RTE_ETH_LINK_DOWN;
501 : 0 : link.link_speed = 0;
502 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
503 : 0 : link.link_autoneg = RTE_ETH_LINK_AUTONEG;
504 : :
505 : : memset(&old, 0, sizeof(old));
506 : :
507 : : /* Load old link status */
508 : 0 : rte_eth_linkstatus_get(dev, &old);
509 : :
510 : : /* Read current link status */
511 : 0 : status = RTL_R16(hw, PHYstatus);
512 : :
513 [ # # ]: 0 : if (status & LinkStatus) {
514 : 0 : link.link_status = RTE_ETH_LINK_UP;
515 : :
516 [ # # ]: 0 : if (status & FullDup) {
517 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
518 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_2)
519 : 0 : RTL_W32(hw, TxConfig, (RTL_R32(hw, TxConfig) |
520 : : (BIT_24 | BIT_25)) & ~BIT_19);
521 : :
522 : : } else {
523 : 0 : link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
524 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_2)
525 : 0 : RTL_W32(hw, TxConfig, (RTL_R32(hw, TxConfig) | BIT_25) &
526 : : ~(BIT_19 | BIT_24));
527 : : }
528 : :
529 [ # # ]: 0 : if (status & _5000bpsF)
530 : : speed = 5000;
531 [ # # ]: 0 : else if (status & _2500bpsF)
532 : : speed = 2500;
533 [ # # ]: 0 : else if (status & _1000bpsF)
534 : : speed = 1000;
535 [ # # ]: 0 : else if (status & _100bps)
536 : : speed = 100;
537 : : else
538 : : speed = 10;
539 : :
540 : 0 : link.link_speed = speed;
541 : : }
542 : :
543 [ # # ]: 0 : if (link.link_status == old.link_status)
544 : : return -1;
545 : :
546 : 0 : rte_eth_linkstatus_set(dev, &link);
547 : :
548 : 0 : return 0;
549 : : }
550 : :
551 : : static void
552 : 0 : rtl_dev_interrupt_handler(void *param)
553 : : {
554 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
555 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
556 : 0 : struct rtl_hw *hw = &adapter->hw;
557 : : uint32_t intr;
558 : :
559 : 0 : intr = RTL_R32(hw, ISR0_8125);
560 : :
561 : : /* Clear all cause mask */
562 : 0 : rtl_disable_intr(hw);
563 : :
564 [ # # ]: 0 : if (intr & LinkChg)
565 : 0 : rtl_dev_link_update(dev, 0);
566 : : else
567 : 0 : PMD_DRV_LOG(ERR, "r8169: interrupt unhandled.");
568 : :
569 : 0 : rtl_enable_intr(hw);
570 : 0 : }
571 : :
572 : : /*
573 : : * Reset and stop device.
574 : : */
575 : : static int
576 : 0 : rtl_dev_close(struct rte_eth_dev *dev)
577 : : {
578 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
579 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
580 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
581 : 0 : struct rtl_hw *hw = &adapter->hw;
582 : : int retries = 0;
583 : : int ret_unreg, ret_stp;
584 : :
585 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
586 : : return 0;
587 : :
588 [ # # ]: 0 : if (HW_DASH_SUPPORT_DASH(hw))
589 : 0 : rtl8125_driver_stop(hw);
590 : :
591 : 0 : ret_stp = rtl_dev_stop(dev);
592 : :
593 : 0 : rtl_free_queues(dev);
594 : :
595 : : /* Reprogram the RAR[0] in case user changed it. */
596 : 0 : rtl_rar_set(hw, hw->mac_addr);
597 : :
598 : : /* Disable uio intr before callback unregister */
599 : 0 : rte_intr_disable(intr_handle);
600 : :
601 : : do {
602 : 0 : ret_unreg = rte_intr_callback_unregister(intr_handle, rtl_dev_interrupt_handler,
603 : : dev);
604 [ # # ]: 0 : if (ret_unreg >= 0 || ret_unreg == -ENOENT)
605 : : break;
606 [ # # ]: 0 : else if (ret_unreg != -EAGAIN)
607 : 0 : PMD_DRV_LOG(ERR, "r8169: intr callback unregister failed: %d", ret_unreg);
608 : :
609 : : rte_delay_ms(100);
610 [ # # ]: 0 : } while (retries++ < (10 + 90));
611 : :
612 : : return ret_stp;
613 : : }
614 : :
615 : : static int
616 : 0 : rtl_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
617 : : {
618 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
619 : : struct rtl_hw *hw = &adapter->hw;
620 : : uint32_t frame_size = mtu + RTL_ETH_OVERHEAD;
621 : :
622 : 0 : hw->mtu = mtu;
623 : :
624 : 0 : RTL_W16(hw, RxMaxSize, frame_size);
625 : :
626 : 0 : return 0;
627 : : }
628 : :
629 : : static int
630 : 0 : rtl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
631 : : {
632 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
633 : : struct rtl_hw *hw = &adapter->hw;
634 : : int ret;
635 : :
636 [ # # ]: 0 : ret = snprintf(fw_version, fw_size, "0x%08x", hw->hw_ram_code_ver);
637 : :
638 : 0 : ret += 1; /* Add the size of '\0' */
639 [ # # ]: 0 : if (fw_size < (u32)ret)
640 : : return ret;
641 : : else
642 : 0 : return 0;
643 : : }
644 : :
645 : : static int
646 : 0 : rtl_dev_init(struct rte_eth_dev *dev)
647 : : {
648 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
649 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
650 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
651 : 0 : struct rtl_hw *hw = &adapter->hw;
652 : 0 : struct rte_ether_addr *perm_addr = (struct rte_ether_addr *)hw->mac_addr;
653 : : char buf[RTE_ETHER_ADDR_FMT_SIZE];
654 : :
655 : 0 : dev->dev_ops = &rtl_eth_dev_ops;
656 : 0 : dev->tx_pkt_burst = &rtl_xmit_pkts;
657 : 0 : dev->rx_pkt_burst = &rtl_recv_pkts;
658 : :
659 : : /* For secondary processes, the primary process has done all the work */
660 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
661 [ # # ]: 0 : if (dev->data->scattered_rx)
662 : 0 : dev->rx_pkt_burst = &rtl_recv_scattered_pkts;
663 : 0 : return 0;
664 : : }
665 : :
666 : 0 : hw->mmio_addr = (u8 *)pci_dev->mem_resource[2].addr; /* RTL8169 uses BAR2 */
667 : :
668 : 0 : rtl_get_mac_version(hw, pci_dev);
669 : :
670 [ # # ]: 0 : if (rtl_set_hw_ops(hw))
671 : : return -ENOTSUP;
672 : :
673 : 0 : rtl_disable_intr(hw);
674 : :
675 : 0 : rtl_hw_initialize(hw);
676 : :
677 : : /* Read the permanent MAC address out of ROM */
678 : 0 : rtl_get_mac_address(hw, perm_addr);
679 : :
680 : : if (!rte_is_valid_assigned_ether_addr(perm_addr)) {
681 : 0 : rte_eth_random_addr(&perm_addr->addr_bytes[0]);
682 : :
683 : 0 : rte_ether_format_addr(buf, sizeof(buf), perm_addr);
684 : :
685 : 0 : PMD_INIT_LOG(NOTICE, "r8169: Assign randomly generated MAC address %s", buf);
686 : : }
687 : :
688 : : /* Allocate memory for storing MAC addresses */
689 : 0 : dev->data->mac_addrs = rte_zmalloc("r8169", RTE_ETHER_ADDR_LEN, 0);
690 : :
691 [ # # ]: 0 : if (dev->data->mac_addrs == NULL) {
692 : 0 : PMD_INIT_LOG(ERR, "MAC Malloc failed");
693 : 0 : return -ENOMEM;
694 : : }
695 : :
696 : : /* Copy the permanent MAC address */
697 : : rte_ether_addr_copy(perm_addr, &dev->data->mac_addrs[0]);
698 : :
699 : 0 : rtl_rar_set(hw, &perm_addr->addr_bytes[0]);
700 : :
701 : 0 : rte_intr_callback_register(intr_handle, rtl_dev_interrupt_handler, dev);
702 : :
703 : : /* Enable uio/vfio intr/eventfd mapping */
704 : 0 : rte_intr_enable(intr_handle);
705 : :
706 : 0 : return 0;
707 : : }
708 : :
709 : : static int
710 : 0 : rtl_dev_uninit(struct rte_eth_dev *dev)
711 : : {
712 [ # # # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
713 : : return -EPERM;
714 : :
715 : 0 : rtl_dev_close(dev);
716 : :
717 : 0 : return 0;
718 : : }
719 : :
720 : : static int
721 : 0 : rtl_dev_reset(struct rte_eth_dev *dev)
722 : : {
723 : : int ret;
724 : :
725 : : ret = rtl_dev_uninit(dev);
726 : : if (ret)
727 : : return ret;
728 : :
729 : 0 : ret = rtl_dev_init(dev);
730 : :
731 : 0 : return ret;
732 : : }
733 : :
734 : : static int
735 : 0 : rtl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
736 : : struct rte_pci_device *pci_dev)
737 : : {
738 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct rtl_adapter),
739 : : rtl_dev_init);
740 : : }
741 : :
742 : : static int
743 : 0 : rtl_pci_remove(struct rte_pci_device *pci_dev)
744 : : {
745 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, rtl_dev_uninit);
746 : : }
747 : :
748 : : static struct rte_pci_driver rte_r8169_pmd = {
749 : : .id_table = pci_id_r8169_map,
750 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
751 : : .probe = rtl_pci_probe,
752 : : .remove = rtl_pci_remove,
753 : : };
754 : :
755 : 252 : RTE_PMD_REGISTER_PCI(net_r8169, rte_r8169_pmd);
756 : : RTE_PMD_REGISTER_PCI_TABLE(net_r8169, pci_id_r8169_map);
757 : : RTE_PMD_REGISTER_KMOD_DEP(net_r8169, "* igb_uio | uio_pci_generic | vfio-pci");
758 : :
759 [ - + ]: 252 : RTE_LOG_REGISTER_SUFFIX(r8169_logtype_init, init, NOTICE)
760 [ - + ]: 252 : RTE_LOG_REGISTER_SUFFIX(r8169_logtype_driver, driver, NOTICE)
761 : : #ifdef RTE_ETHDEV_DEBUG_RX
762 : : RTE_LOG_REGISTER_SUFFIX(r8169_logtype_rx, rx, DEBUG)
763 : : #endif
764 : : #ifdef RTE_ETHDEV_DEBUG_TX
765 : : RTE_LOG_REGISTER_SUFFIX(r8169_logtype_tx, tx, DEBUG)
766 : : #endif
|