net/ice: fix outer L4 checksum in scalar Rx
[dpdk.git] / drivers / net / cnxk / cnxk_link.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include "cnxk_ethdev.h"
6
7 void
8 cnxk_nix_toggle_flag_link_cfg(struct cnxk_eth_dev *dev, bool set)
9 {
10         if (set)
11                 dev->flags |= CNXK_LINK_CFG_IN_PROGRESS_F;
12         else
13                 dev->flags &= ~CNXK_LINK_CFG_IN_PROGRESS_F;
14
15         /* Update link info for LBK */
16         if (!set && roc_nix_is_lbk(&dev->nix)) {
17                 struct rte_eth_link link;
18
19                 link.link_status = RTE_ETH_LINK_UP;
20                 link.link_speed = RTE_ETH_SPEED_NUM_100G;
21                 link.link_autoneg = RTE_ETH_LINK_FIXED;
22                 link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
23                 rte_eth_linkstatus_set(dev->eth_dev, &link);
24         }
25
26         rte_wmb();
27 }
28
29 static inline int
30 nix_wait_for_link_cfg(struct cnxk_eth_dev *dev)
31 {
32         uint16_t wait = 1000;
33
34         do {
35                 rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
36                 if (!(dev->flags & CNXK_LINK_CFG_IN_PROGRESS_F))
37                         break;
38                 wait--;
39                 rte_delay_ms(1);
40         } while (wait);
41
42         return wait ? 0 : -1;
43 }
44
45 static void
46 nix_link_status_print(struct rte_eth_dev *eth_dev, struct rte_eth_link *link)
47 {
48         if (link && link->link_status)
49                 plt_info("Port %d: Link Up - speed %u Mbps - %s",
50                          (int)(eth_dev->data->port_id),
51                          (uint32_t)link->link_speed,
52                          link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX
53                                  ? "full-duplex"
54                                  : "half-duplex");
55         else
56                 plt_info("Port %d: Link Down", (int)(eth_dev->data->port_id));
57 }
58
59 void
60 cnxk_eth_dev_link_status_get_cb(struct roc_nix *nix,
61                                 struct roc_nix_link_info *link)
62 {
63         struct cnxk_eth_dev *dev = (struct cnxk_eth_dev *)nix;
64         struct rte_eth_link eth_link;
65         struct rte_eth_dev *eth_dev;
66
67         if (!link || !nix)
68                 return;
69
70         eth_dev = dev->eth_dev;
71         if (!eth_dev)
72                 return;
73
74         rte_eth_linkstatus_get(eth_dev, &eth_link);
75
76         link->status = eth_link.link_status;
77         link->speed = eth_link.link_speed;
78         link->autoneg = eth_link.link_autoneg;
79         link->full_duplex = eth_link.link_duplex;
80 }
81
82 void
83 cnxk_eth_dev_link_status_cb(struct roc_nix *nix, struct roc_nix_link_info *link)
84 {
85         struct cnxk_eth_dev *dev = (struct cnxk_eth_dev *)nix;
86         struct rte_eth_link eth_link;
87         struct rte_eth_dev *eth_dev;
88
89         if (!link || !nix)
90                 return;
91
92         eth_dev = dev->eth_dev;
93         if (!eth_dev || !eth_dev->data->dev_conf.intr_conf.lsc)
94                 return;
95
96         if (nix_wait_for_link_cfg(dev)) {
97                 plt_err("Timeout waiting for link_cfg to complete");
98                 return;
99         }
100
101         eth_link.link_status = link->status;
102         eth_link.link_speed = link->speed;
103         eth_link.link_autoneg = RTE_ETH_LINK_AUTONEG;
104         eth_link.link_duplex = link->full_duplex;
105
106         /* Print link info */
107         nix_link_status_print(eth_dev, &eth_link);
108
109         /* Update link info */
110         rte_eth_linkstatus_set(eth_dev, &eth_link);
111
112         /* Set the flag and execute application callbacks */
113         rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
114 }
115
116 int
117 cnxk_nix_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete)
118 {
119         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
120         struct roc_nix_link_info info;
121         struct rte_eth_link link;
122         int rc;
123
124         RTE_SET_USED(wait_to_complete);
125         memset(&link, 0, sizeof(struct rte_eth_link));
126
127         if (!eth_dev->data->dev_started || roc_nix_is_sdp(&dev->nix))
128                 return 0;
129
130         if (roc_nix_is_lbk(&dev->nix)) {
131                 link.link_status = RTE_ETH_LINK_UP;
132                 link.link_speed = RTE_ETH_SPEED_NUM_100G;
133                 link.link_autoneg = RTE_ETH_LINK_FIXED;
134                 link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
135         } else {
136                 rc = roc_nix_mac_link_info_get(&dev->nix, &info);
137                 if (rc)
138                         return rc;
139                 link.link_status = info.status;
140                 link.link_speed = info.speed;
141                 link.link_autoneg = RTE_ETH_LINK_AUTONEG;
142                 if (info.full_duplex)
143                         link.link_duplex = info.full_duplex;
144         }
145
146         return rte_eth_linkstatus_set(eth_dev, &link);
147 }