Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright(c) 2019-2021 Xilinx, Inc.
4 : : * Copyright(c) 2009-2019 Solarflare Communications Inc.
5 : : */
6 : :
7 : : #include "efx.h"
8 : : #include "efx_impl.h"
9 : :
10 : : __checkReturn efx_rc_t
11 : 0 : efx_port_init(
12 : : __in efx_nic_t *enp)
13 : : {
14 : : efx_port_t *epp = &(enp->en_port);
15 : 0 : const efx_phy_ops_t *epop = epp->ep_epop;
16 : : efx_rc_t rc;
17 : :
18 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
19 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
20 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
21 : :
22 [ # # ]: 0 : if (enp->en_mod_flags & EFX_MOD_PORT) {
23 : : rc = EINVAL;
24 : 0 : goto fail1;
25 : : }
26 : :
27 : 0 : enp->en_mod_flags |= EFX_MOD_PORT;
28 : :
29 : 0 : epp->ep_mac_type = EFX_MAC_INVALID;
30 : 0 : epp->ep_link_mode = EFX_LINK_UNKNOWN;
31 : 0 : epp->ep_mac_drain = B_TRUE;
32 : :
33 : : /* Configure the MAC */
34 [ # # ]: 0 : if ((rc = efx_mac_select(enp)) != 0)
35 : 0 : goto fail1;
36 : :
37 : 0 : epp->ep_emop->emo_reconfigure(enp);
38 : :
39 : : /* Pick up current phy capababilities */
40 : 0 : (void) efx_port_poll(enp, NULL);
41 : :
42 : : /*
43 : : * Turn on the PHY if available, otherwise reset it, and
44 : : * reconfigure it with the current configuration.
45 : : */
46 [ # # ]: 0 : if (epop->epo_power != NULL) {
47 [ # # ]: 0 : if ((rc = epop->epo_power(enp, B_TRUE)) != 0)
48 : 0 : goto fail2;
49 : : } else {
50 [ # # ]: 0 : if ((rc = epop->epo_reset(enp)) != 0)
51 : 0 : goto fail2;
52 : : }
53 : :
54 [ # # ]: 0 : EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_PHY);
55 : 0 : enp->en_reset_flags &= ~EFX_RESET_PHY;
56 : :
57 [ # # ]: 0 : if ((rc = epop->epo_reconfigure(enp)) != 0)
58 : 0 : goto fail3;
59 : :
60 : : return (0);
61 : :
62 : : fail3:
63 : : EFSYS_PROBE(fail3);
64 : 0 : fail2:
65 : : EFSYS_PROBE(fail2);
66 : 0 : fail1:
67 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
68 : :
69 : 0 : enp->en_mod_flags &= ~EFX_MOD_PORT;
70 : :
71 : 0 : return (rc);
72 : : }
73 : :
74 : : __checkReturn efx_rc_t
75 : 0 : efx_port_poll(
76 : : __in efx_nic_t *enp,
77 : : __out_opt efx_link_mode_t *link_modep)
78 : : {
79 : : efx_port_t *epp = &(enp->en_port);
80 : 0 : const efx_mac_ops_t *emop = epp->ep_emop;
81 : : efx_link_mode_t ignore_link_mode;
82 : : efx_rc_t rc;
83 : :
84 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
85 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
86 : :
87 [ # # ]: 0 : EFSYS_ASSERT(emop != NULL);
88 : :
89 [ # # ]: 0 : if (link_modep == NULL)
90 : : link_modep = &ignore_link_mode;
91 : :
92 [ # # ]: 0 : if ((rc = emop->emo_poll(enp, link_modep)) != 0)
93 : 0 : goto fail1;
94 : :
95 : : return (0);
96 : :
97 : : fail1:
98 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
99 : :
100 : 0 : return (rc);
101 : : }
102 : :
103 : : #if EFSYS_OPT_LOOPBACK
104 : :
105 : : __checkReturn efx_rc_t
106 : 0 : efx_port_loopback_set(
107 : : __in efx_nic_t *enp,
108 : : __in efx_link_mode_t link_mode,
109 : : __in efx_loopback_type_t loopback_type)
110 : : {
111 : : efx_port_t *epp = &(enp->en_port);
112 : : efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
113 : 0 : const efx_mac_ops_t *emop = epp->ep_emop;
114 : : efx_rc_t rc;
115 : :
116 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
117 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
118 [ # # ]: 0 : EFSYS_ASSERT(emop != NULL);
119 : :
120 [ # # ]: 0 : EFSYS_ASSERT(link_mode < EFX_LINK_NMODES);
121 : :
122 [ # # # # ]: 0 : if (EFX_TEST_QWORD_BIT(encp->enc_loopback_types[link_mode],
123 : : (int)loopback_type) == 0) {
124 : : rc = ENOTSUP;
125 : 0 : goto fail1;
126 : : }
127 : :
128 [ # # ]: 0 : if (epp->ep_loopback_type == loopback_type &&
129 [ # # ]: 0 : epp->ep_loopback_link_mode == link_mode)
130 : : return (0);
131 : :
132 [ # # ]: 0 : if ((rc = emop->emo_loopback_set(enp, link_mode, loopback_type)) != 0)
133 : 0 : goto fail2;
134 : :
135 : : return (0);
136 : :
137 : : fail2:
138 : : EFSYS_PROBE(fail2);
139 : : fail1:
140 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
141 : :
142 : : return (rc);
143 : : }
144 : :
145 : : #if EFSYS_OPT_NAMES
146 : :
147 : : static const char * const __efx_loopback_type_name[] = {
148 : : "OFF",
149 : : "DATA",
150 : : "GMAC",
151 : : "XGMII",
152 : : "XGXS",
153 : : "XAUI",
154 : : "GMII",
155 : : "SGMII",
156 : : "XGBR",
157 : : "XFI",
158 : : "XAUI_FAR",
159 : : "GMII_FAR",
160 : : "SGMII_FAR",
161 : : "XFI_FAR",
162 : : "GPHY",
163 : : "PHY_XS",
164 : : "PCS",
165 : : "PMA_PMD",
166 : : "XPORT",
167 : : "XGMII_WS",
168 : : "XAUI_WS",
169 : : "XAUI_WS_FAR",
170 : : "XAUI_WS_NEAR",
171 : : "GMII_WS",
172 : : "XFI_WS",
173 : : "XFI_WS_FAR",
174 : : "PHYXS_WS",
175 : : "PMA_INT",
176 : : "SD_NEAR",
177 : : "SD_FAR",
178 : : "PMA_INT_WS",
179 : : "SD_FEP2_WS",
180 : : "SD_FEP1_5_WS",
181 : : "SD_FEP_WS",
182 : : "SD_FES_WS",
183 : : "AOE_INT_NEAR",
184 : : "DATA_WS",
185 : : "FORCE_EXT_LINK",
186 : : };
187 : :
188 : : __checkReturn const char *
189 : 0 : efx_loopback_type_name(
190 : : __in efx_nic_t *enp,
191 : : __in efx_loopback_type_t type)
192 : : {
193 : : EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__efx_loopback_type_name) ==
194 : : EFX_LOOPBACK_NTYPES);
195 : :
196 : : _NOTE(ARGUNUSED(enp))
197 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
198 [ # # ]: 0 : EFSYS_ASSERT3U(type, <, EFX_LOOPBACK_NTYPES);
199 : :
200 : 0 : return (__efx_loopback_type_name[type]);
201 : : }
202 : :
203 : : #endif /* EFSYS_OPT_NAMES */
204 : :
205 : : #endif /* EFSYS_OPT_LOOPBACK */
206 : :
207 : : __checkReturn efx_rc_t
208 : 0 : efx_port_vlan_strip_set(
209 : : __in efx_nic_t *enp,
210 : : __in boolean_t enabled)
211 : : {
212 : : efx_port_t *epp = &(enp->en_port);
213 : : efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
214 : 0 : uint32_t filter_count = 0;
215 : : efx_rc_t rc;
216 : :
217 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
218 : :
219 [ # # # # ]: 0 : if (enabled && !encp->enc_rx_vlan_stripping_supported) {
220 : : rc = ENOTSUP;
221 : 0 : goto fail1;
222 : : }
223 : :
224 [ # # ]: 0 : if ((rc = efx_filter_get_count(enp, &filter_count)) != 0)
225 : 0 : goto fail2;
226 : :
227 [ # # ]: 0 : if (filter_count != 0) {
228 : : rc = EINVAL;
229 : 0 : goto fail3;
230 : : }
231 : :
232 : 0 : epp->ep_vlan_strip = enabled;
233 : :
234 : 0 : return (0);
235 : :
236 : : fail3:
237 : : EFSYS_PROBE(fail3);
238 : : fail2:
239 : : EFSYS_PROBE(fail2);
240 : : fail1:
241 : : EFSYS_PROBE1(fail1, efx_rc_t, rc);
242 : :
243 : : return (rc);
244 : : }
245 : :
246 : : void
247 : 0 : efx_port_fini(
248 : : __in efx_nic_t *enp)
249 : : {
250 : : efx_port_t *epp = &(enp->en_port);
251 : 0 : const efx_phy_ops_t *epop = epp->ep_epop;
252 : :
253 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
254 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
255 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
256 [ # # ]: 0 : EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
257 : :
258 [ # # ]: 0 : EFSYS_ASSERT(epp->ep_mac_drain);
259 : :
260 : 0 : epp->ep_emop = NULL;
261 : 0 : epp->ep_mac_type = EFX_MAC_INVALID;
262 : 0 : epp->ep_mac_drain = B_FALSE;
263 : :
264 : : /* Turn off the PHY */
265 [ # # ]: 0 : if (epop->epo_power != NULL)
266 : 0 : (void) epop->epo_power(enp, B_FALSE);
267 : :
268 : 0 : enp->en_mod_flags &= ~EFX_MOD_PORT;
269 : 0 : }
|