efx_mac.c (4d846d26) efx_mac.c (e948693e)
1/*-
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
2 * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
3 *
3 *
4 * Copyright (c) 2007-2016 Solarflare Communications Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
4 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
9 *
12 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * The views and conclusions contained in the software and documentation are
29 * those of the authors and should not be interpreted as representing official
30 * policies, either expressed or implied, of the FreeBSD Project.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
31 */
32
24 */
25
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD$");
35
26#include "efsys.h"
36#include "efx.h"
27#include "efx.h"
28#include "efx_types.h"
37#include "efx_impl.h"
38
29#include "efx_impl.h"
30
39#if EFSYS_OPT_SIENA
31#if EFSYS_OPT_MAC_FALCON_GMAC
32#include "falcon_gmac.h"
33#endif
40
34
41static __checkReturn efx_rc_t
42siena_mac_multicast_list_set(
43 __in efx_nic_t *enp);
35#if EFSYS_OPT_MAC_FALCON_XMAC
36#include "falcon_xmac.h"
37#endif
44
38
45#endif /* EFSYS_OPT_SIENA */
39#if EFSYS_OPT_MAC_FALCON_GMAC
40static efx_mac_ops_t __cs __efx_falcon_gmac_ops = {
41 falcon_gmac_reset, /* emo_reset */
42 falcon_mac_poll, /* emo_poll */
43 falcon_mac_up, /* emo_up */
44 falcon_gmac_reconfigure, /* emo_reconfigure */
45#if EFSYS_OPT_LOOPBACK
46 falcon_mac_loopback_set, /* emo_loopback_set */
47#endif /* EFSYS_OPT_LOOPBACK */
48#if EFSYS_OPT_MAC_STATS
49 falcon_mac_stats_upload, /* emo_stats_upload */
50 NULL, /* emo_stats_periodic */
51 falcon_gmac_stats_update /* emo_stats_update */
52#endif /* EFSYS_OPT_MAC_STATS */
53};
54#endif /* EFSYS_OPT_MAC_FALCON_GMAC */
46
55
47#if EFSYS_OPT_SIENA
48static const efx_mac_ops_t __efx_mac_siena_ops = {
49 siena_mac_poll, /* emo_poll */
50 siena_mac_up, /* emo_up */
51 siena_mac_reconfigure, /* emo_addr_set */
52 siena_mac_reconfigure, /* emo_pdu_set */
53 siena_mac_pdu_get, /* emo_pdu_get */
54 siena_mac_reconfigure, /* emo_reconfigure */
55 siena_mac_multicast_list_set, /* emo_multicast_list_set */
56 NULL, /* emo_filter_set_default_rxq */
57 NULL, /* emo_filter_default_rxq_clear */
56#if EFSYS_OPT_MAC_FALCON_XMAC
57static efx_mac_ops_t __cs __efx_falcon_xmac_ops = {
58 falcon_xmac_reset, /* emo_reset */
59 falcon_mac_poll, /* emo_poll */
60 falcon_mac_up, /* emo_up */
61 falcon_xmac_reconfigure, /* emo_reconfigure */
58#if EFSYS_OPT_LOOPBACK
62#if EFSYS_OPT_LOOPBACK
59 siena_mac_loopback_set, /* emo_loopback_set */
63 falcon_mac_loopback_set, /* emo_loopback_set */
60#endif /* EFSYS_OPT_LOOPBACK */
61#if EFSYS_OPT_MAC_STATS
64#endif /* EFSYS_OPT_LOOPBACK */
65#if EFSYS_OPT_MAC_STATS
62 siena_mac_stats_get_mask, /* emo_stats_get_mask */
63 efx_mcdi_mac_stats_clear, /* emo_stats_clear */
64 efx_mcdi_mac_stats_upload, /* emo_stats_upload */
65 efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
66 siena_mac_stats_update /* emo_stats_update */
66 falcon_mac_stats_upload, /* emo_stats_upload */
67 NULL, /* emo_stats_periodic */
68 falcon_xmac_stats_update /* emo_stats_update */
67#endif /* EFSYS_OPT_MAC_STATS */
68};
69#endif /* EFSYS_OPT_MAC_STATS */
70};
69#endif /* EFSYS_OPT_SIENA */
71#endif /* EFSYS_OPT_MAC_FALCON_XMAC */
70
72
71#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
72static const efx_mac_ops_t __efx_mac_ef10_ops = {
73 ef10_mac_poll, /* emo_poll */
74 ef10_mac_up, /* emo_up */
75 ef10_mac_addr_set, /* emo_addr_set */
76 ef10_mac_pdu_set, /* emo_pdu_set */
77 ef10_mac_pdu_get, /* emo_pdu_get */
78 ef10_mac_reconfigure, /* emo_reconfigure */
79 ef10_mac_multicast_list_set, /* emo_multicast_list_set */
80 ef10_mac_filter_default_rxq_set, /* emo_filter_default_rxq_set */
81 ef10_mac_filter_default_rxq_clear,
82 /* emo_filter_default_rxq_clear */
73#if EFSYS_OPT_SIENA
74static efx_mac_ops_t __cs __efx_siena_mac_ops = {
75 NULL, /* emo_reset */
76 siena_mac_poll, /* emo_poll */
77 siena_mac_up, /* emo_up */
78 siena_mac_reconfigure, /* emo_reconfigure */
83#if EFSYS_OPT_LOOPBACK
79#if EFSYS_OPT_LOOPBACK
84 ef10_mac_loopback_set, /* emo_loopback_set */
80 siena_mac_loopback_set, /* emo_loopback_set */
85#endif /* EFSYS_OPT_LOOPBACK */
86#if EFSYS_OPT_MAC_STATS
81#endif /* EFSYS_OPT_LOOPBACK */
82#if EFSYS_OPT_MAC_STATS
87 ef10_mac_stats_get_mask, /* emo_stats_get_mask */
88 efx_mcdi_mac_stats_clear, /* emo_stats_clear */
89 efx_mcdi_mac_stats_upload, /* emo_stats_upload */
90 efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
91 ef10_mac_stats_update /* emo_stats_update */
83 siena_mac_stats_upload, /* emo_stats_upload */
84 siena_mac_stats_periodic, /* emo_stats_periodic */
85 siena_mac_stats_update /* emo_stats_update */
92#endif /* EFSYS_OPT_MAC_STATS */
93};
86#endif /* EFSYS_OPT_MAC_STATS */
87};
94#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
88#endif /* EFSYS_OPT_SIENA */
95
89
96 __checkReturn efx_rc_t
90static efx_mac_ops_t __cs * __cs __efx_mac_ops[] = {
91 NULL,
92#if EFSYS_OPT_MAC_FALCON_GMAC
93 &__efx_falcon_gmac_ops,
94#else
95 NULL,
96#endif /* EFSYS_OPT_MAC_FALCON_GMAC */
97#if EFSYS_OPT_MAC_FALCON_XMAC
98 &__efx_falcon_xmac_ops,
99#else
100 NULL,
101#endif /* EFSYS_OPT_MAC_FALCON_XMAC */
102#if EFSYS_OPT_SIENA
103 &__efx_siena_mac_ops,
104#else
105 NULL,
106#endif /* EFSYS_OPT_SIENA */
107};
108
109 __checkReturn int
97efx_mac_pdu_set(
98 __in efx_nic_t *enp,
99 __in size_t pdu)
100{
101 efx_port_t *epp = &(enp->en_port);
110efx_mac_pdu_set(
111 __in efx_nic_t *enp,
112 __in size_t pdu)
113{
114 efx_port_t *epp = &(enp->en_port);
102 const efx_mac_ops_t *emop = epp->ep_emop;
115 efx_mac_ops_t *emop = epp->ep_emop;
103 uint32_t old_pdu;
116 uint32_t old_pdu;
104 efx_rc_t rc;
117 int rc;
105
106 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
107 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
108 EFSYS_ASSERT(emop != NULL);
109
110 if (pdu < EFX_MAC_PDU_MIN) {
111 rc = EINVAL;
112 goto fail1;
113 }
114
115 if (pdu > EFX_MAC_PDU_MAX) {
116 rc = EINVAL;
117 goto fail2;
118 }
119
120 old_pdu = epp->ep_mac_pdu;
121 epp->ep_mac_pdu = (uint32_t)pdu;
118
119 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
120 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
121 EFSYS_ASSERT(emop != NULL);
122
123 if (pdu < EFX_MAC_PDU_MIN) {
124 rc = EINVAL;
125 goto fail1;
126 }
127
128 if (pdu > EFX_MAC_PDU_MAX) {
129 rc = EINVAL;
130 goto fail2;
131 }
132
133 old_pdu = epp->ep_mac_pdu;
134 epp->ep_mac_pdu = (uint32_t)pdu;
122 if ((rc = emop->emo_pdu_set(enp)) != 0)
135 if ((rc = emop->emo_reconfigure(enp)) != 0)
123 goto fail3;
124
125 return (0);
126
127fail3:
128 EFSYS_PROBE(fail3);
129
130 epp->ep_mac_pdu = old_pdu;
131
132fail2:
133 EFSYS_PROBE(fail2);
134fail1:
136 goto fail3;
137
138 return (0);
139
140fail3:
141 EFSYS_PROBE(fail3);
142
143 epp->ep_mac_pdu = old_pdu;
144
145fail2:
146 EFSYS_PROBE(fail2);
147fail1:
135 EFSYS_PROBE1(fail1, efx_rc_t, rc);
148 EFSYS_PROBE1(fail1, int, rc);
136
137 return (rc);
138}
139
149
150 return (rc);
151}
152
140 __checkReturn efx_rc_t
141efx_mac_pdu_get(
142 __in efx_nic_t *enp,
143 __out size_t *pdu)
144{
145 efx_port_t *epp = &(enp->en_port);
146 const efx_mac_ops_t *emop = epp->ep_emop;
147 efx_rc_t rc;
148
149 if ((rc = emop->emo_pdu_get(enp, pdu)) != 0)
150 goto fail1;
151
152 return (0);
153
154fail1:
155 EFSYS_PROBE1(fail1, efx_rc_t, rc);
156
157 return (rc);
158}
159
160 __checkReturn efx_rc_t
153 __checkReturn int
161efx_mac_addr_set(
162 __in efx_nic_t *enp,
163 __in uint8_t *addr)
164{
165 efx_port_t *epp = &(enp->en_port);
154efx_mac_addr_set(
155 __in efx_nic_t *enp,
156 __in uint8_t *addr)
157{
158 efx_port_t *epp = &(enp->en_port);
166 const efx_mac_ops_t *emop = epp->ep_emop;
159 efx_mac_ops_t *emop = epp->ep_emop;
167 uint8_t old_addr[6];
168 uint32_t oui;
160 uint8_t old_addr[6];
161 uint32_t oui;
169 efx_rc_t rc;
162 int rc;
170
171 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
172 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
173
163
164 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
165 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
166
174 if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
167 if (addr[0] & 0x01) {
175 rc = EINVAL;
176 goto fail1;
177 }
178
179 oui = addr[0] << 16 | addr[1] << 8 | addr[2];
180 if (oui == 0x000000) {
181 rc = EINVAL;
182 goto fail2;
183 }
184
185 EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
186 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
168 rc = EINVAL;
169 goto fail1;
170 }
171
172 oui = addr[0] << 16 | addr[1] << 8 | addr[2];
173 if (oui == 0x000000) {
174 rc = EINVAL;
175 goto fail2;
176 }
177
178 EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
179 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
187 if ((rc = emop->emo_addr_set(enp)) != 0)
180 if ((rc = emop->emo_reconfigure(enp)) != 0)
188 goto fail3;
189
190 return (0);
191
192fail3:
193 EFSYS_PROBE(fail3);
194
195 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
196
197fail2:
198 EFSYS_PROBE(fail2);
199fail1:
181 goto fail3;
182
183 return (0);
184
185fail3:
186 EFSYS_PROBE(fail3);
187
188 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
189
190fail2:
191 EFSYS_PROBE(fail2);
192fail1:
200 EFSYS_PROBE1(fail1, efx_rc_t, rc);
193 EFSYS_PROBE1(fail1, int, rc);
201
202 return (rc);
203}
204
194
195 return (rc);
196}
197
205 __checkReturn efx_rc_t
198 __checkReturn int
206efx_mac_filter_set(
207 __in efx_nic_t *enp,
199efx_mac_filter_set(
200 __in efx_nic_t *enp,
208 __in boolean_t all_unicst,
209 __in boolean_t mulcst,
210 __in boolean_t all_mulcst,
201 __in boolean_t unicst,
211 __in boolean_t brdcst)
212{
213 efx_port_t *epp = &(enp->en_port);
202 __in boolean_t brdcst)
203{
204 efx_port_t *epp = &(enp->en_port);
214 const efx_mac_ops_t *emop = epp->ep_emop;
215 boolean_t old_all_unicst;
216 boolean_t old_mulcst;
217 boolean_t old_all_mulcst;
205 efx_mac_ops_t *emop = epp->ep_emop;
206 boolean_t old_unicst;
218 boolean_t old_brdcst;
207 boolean_t old_brdcst;
219 efx_rc_t rc;
208 int rc;
220
221 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
222 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
223
209
210 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
211 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
212
224 old_all_unicst = epp->ep_all_unicst;
225 old_mulcst = epp->ep_mulcst;
226 old_all_mulcst = epp->ep_all_mulcst;
227 old_brdcst = epp->ep_brdcst;
213 old_unicst = unicst;
214 old_brdcst = brdcst;
228
215
229 epp->ep_all_unicst = all_unicst;
230 epp->ep_mulcst = mulcst;
231 epp->ep_all_mulcst = all_mulcst;
216 epp->ep_unicst = unicst;
232 epp->ep_brdcst = brdcst;
233
234 if ((rc = emop->emo_reconfigure(enp)) != 0)
235 goto fail1;
236
237 return (0);
238
239fail1:
217 epp->ep_brdcst = brdcst;
218
219 if ((rc = emop->emo_reconfigure(enp)) != 0)
220 goto fail1;
221
222 return (0);
223
224fail1:
240 EFSYS_PROBE1(fail1, efx_rc_t, rc);
225 EFSYS_PROBE1(fail1, int, rc);
241
226
242 epp->ep_all_unicst = old_all_unicst;
243 epp->ep_mulcst = old_mulcst;
244 epp->ep_all_mulcst = old_all_mulcst;
227 epp->ep_unicst = old_unicst;
245 epp->ep_brdcst = old_brdcst;
246
247 return (rc);
248}
249
228 epp->ep_brdcst = old_brdcst;
229
230 return (rc);
231}
232
250 __checkReturn efx_rc_t
233 __checkReturn int
251efx_mac_drain(
252 __in efx_nic_t *enp,
253 __in boolean_t enabled)
254{
255 efx_port_t *epp = &(enp->en_port);
234efx_mac_drain(
235 __in efx_nic_t *enp,
236 __in boolean_t enabled)
237{
238 efx_port_t *epp = &(enp->en_port);
256 const efx_mac_ops_t *emop = epp->ep_emop;
257 efx_rc_t rc;
239 efx_mac_ops_t *emop = epp->ep_emop;
240 int rc;
258
259 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
260 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
261 EFSYS_ASSERT(emop != NULL);
262
263 if (epp->ep_mac_drain == enabled)
264 return (0);
265
266 epp->ep_mac_drain = enabled;
267
241
242 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
243 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
244 EFSYS_ASSERT(emop != NULL);
245
246 if (epp->ep_mac_drain == enabled)
247 return (0);
248
249 epp->ep_mac_drain = enabled;
250
251 if (enabled && emop->emo_reset != NULL) {
252 if ((rc = emop->emo_reset(enp)) != 0)
253 goto fail1;
254
255 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
256 enp->en_reset_flags &= ~EFX_RESET_PHY;
257 }
258
268 if ((rc = emop->emo_reconfigure(enp)) != 0)
259 if ((rc = emop->emo_reconfigure(enp)) != 0)
269 goto fail1;
260 goto fail2;
270
271 return (0);
272
261
262 return (0);
263
264fail2:
265 EFSYS_PROBE(fail2);
273fail1:
266fail1:
274 EFSYS_PROBE1(fail1, efx_rc_t, rc);
267 EFSYS_PROBE1(fail1, int, rc);
275
276 return (rc);
277}
278
268
269 return (rc);
270}
271
279 __checkReturn efx_rc_t
272 __checkReturn int
280efx_mac_up(
281 __in efx_nic_t *enp,
282 __out boolean_t *mac_upp)
283{
284 efx_port_t *epp = &(enp->en_port);
273efx_mac_up(
274 __in efx_nic_t *enp,
275 __out boolean_t *mac_upp)
276{
277 efx_port_t *epp = &(enp->en_port);
285 const efx_mac_ops_t *emop = epp->ep_emop;
286 efx_rc_t rc;
278 efx_mac_ops_t *emop = epp->ep_emop;
279 int rc;
287
288 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
289 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
290
291 if ((rc = emop->emo_up(enp, mac_upp)) != 0)
292 goto fail1;
293
294 return (0);
295
296fail1:
280
281 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
282 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
283
284 if ((rc = emop->emo_up(enp, mac_upp)) != 0)
285 goto fail1;
286
287 return (0);
288
289fail1:
297 EFSYS_PROBE1(fail1, efx_rc_t, rc);
290 EFSYS_PROBE1(fail1, int, rc);
298
299 return (rc);
300}
301
291
292 return (rc);
293}
294
302 __checkReturn efx_rc_t
295 __checkReturn int
303efx_mac_fcntl_set(
304 __in efx_nic_t *enp,
305 __in unsigned int fcntl,
306 __in boolean_t autoneg)
307{
308 efx_port_t *epp = &(enp->en_port);
296efx_mac_fcntl_set(
297 __in efx_nic_t *enp,
298 __in unsigned int fcntl,
299 __in boolean_t autoneg)
300{
301 efx_port_t *epp = &(enp->en_port);
309 const efx_mac_ops_t *emop = epp->ep_emop;
310 const efx_phy_ops_t *epop = epp->ep_epop;
302 efx_mac_ops_t *emop = epp->ep_emop;
303 efx_phy_ops_t *epop = epp->ep_epop;
311 unsigned int old_fcntl;
312 boolean_t old_autoneg;
313 unsigned int old_adv_cap;
304 unsigned int old_fcntl;
305 boolean_t old_autoneg;
306 unsigned int old_adv_cap;
314 efx_rc_t rc;
307 int rc;
315
316 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
317 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
318
319 if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
320 rc = EINVAL;
321 goto fail1;
322 }
323
324 /*
308
309 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
310 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
311
312 if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
313 rc = EINVAL;
314 goto fail1;
315 }
316
317 /*
325 * Ignore a request to set flow control auto-negotiation
318 * Ignore a request to set flow control autonegotiation
326 * if the PHY doesn't support it.
327 */
328 if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
329 autoneg = B_FALSE;
330
331 old_fcntl = epp->ep_fcntl;
319 * if the PHY doesn't support it.
320 */
321 if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
322 autoneg = B_FALSE;
323
324 old_fcntl = epp->ep_fcntl;
332 old_autoneg = epp->ep_fcntl_autoneg;
325 old_autoneg = autoneg;
333 old_adv_cap = epp->ep_adv_cap_mask;
334
335 epp->ep_fcntl = fcntl;
336 epp->ep_fcntl_autoneg = autoneg;
337
338 /*
326 old_adv_cap = epp->ep_adv_cap_mask;
327
328 epp->ep_fcntl = fcntl;
329 epp->ep_fcntl_autoneg = autoneg;
330
331 /*
339 * Always encode the flow control settings in the advertised
340 * capabilities even if we are not trying to auto-negotiate
341 * them and reconfigure both the PHY and the MAC.
332 * If the PHY supports autonegotiation, then encode the flow control
333 * settings in the advertised capabilities, and restart AN. Otherwise,
334 * just push the new settings directly to the MAC.
342 */
335 */
343 if (fcntl & EFX_FCNTL_RESPOND)
344 epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE |
345 1 << EFX_PHY_CAP_ASYM);
346 else
347 epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE |
348 1 << EFX_PHY_CAP_ASYM);
336 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
337 if (fcntl & EFX_FCNTL_RESPOND)
338 epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE |
339 1 << EFX_PHY_CAP_ASYM);
340 else
341 epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE |
342 1 << EFX_PHY_CAP_ASYM);
349
343
350 if (fcntl & EFX_FCNTL_GENERATE)
351 epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
344 if (fcntl & EFX_FCNTL_GENERATE)
345 epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
352
346
353 if ((rc = epop->epo_reconfigure(enp)) != 0)
354 goto fail2;
347 if ((rc = epop->epo_reconfigure(enp)) != 0)
348 goto fail2;
355
349
356 if ((rc = emop->emo_reconfigure(enp)) != 0)
357 goto fail3;
350 } else {
351 if ((rc = emop->emo_reconfigure(enp)) != 0)
352 goto fail2;
353 }
358
359 return (0);
360
354
355 return (0);
356
361fail3:
362 EFSYS_PROBE(fail3);
363
364fail2:
365 EFSYS_PROBE(fail2);
366
367 epp->ep_fcntl = old_fcntl;
368 epp->ep_fcntl_autoneg = old_autoneg;
369 epp->ep_adv_cap_mask = old_adv_cap;
370
371fail1:
357fail2:
358 EFSYS_PROBE(fail2);
359
360 epp->ep_fcntl = old_fcntl;
361 epp->ep_fcntl_autoneg = old_autoneg;
362 epp->ep_adv_cap_mask = old_adv_cap;
363
364fail1:
372 EFSYS_PROBE1(fail1, efx_rc_t, rc);
365 EFSYS_PROBE1(fail1, int, rc);
373
374 return (rc);
375}
376
377 void
378efx_mac_fcntl_get(
379 __in efx_nic_t *enp,
380 __out unsigned int *fcntl_wantedp,
381 __out unsigned int *fcntl_linkp)
382{
383 efx_port_t *epp = &(enp->en_port);
366
367 return (rc);
368}
369
370 void
371efx_mac_fcntl_get(
372 __in efx_nic_t *enp,
373 __out unsigned int *fcntl_wantedp,
374 __out unsigned int *fcntl_linkp)
375{
376 efx_port_t *epp = &(enp->en_port);
384 unsigned int wanted = 0;
377 unsigned int wanted;
385
386 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
387 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
388
389 /*
378
379 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
380 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
381
382 /*
390 * Decode the requested flow control settings from the PHY
391 * advertised capabilities.
383 * If the PHY supports auto negotiation, then the requested flow
384 * control settings are encoded in the advertised capabilities.
392 */
385 */
393 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
394 wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
395 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
396 wanted ^= EFX_FCNTL_GENERATE;
386 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
387 wanted = 0;
397
388
389 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
390 wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
391 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
392 wanted ^= EFX_FCNTL_GENERATE;
393 } else
394 wanted = epp->ep_fcntl;
395
398 *fcntl_linkp = epp->ep_fcntl;
399 *fcntl_wantedp = wanted;
400}
401
396 *fcntl_linkp = epp->ep_fcntl;
397 *fcntl_wantedp = wanted;
398}
399
402 __checkReturn efx_rc_t
403efx_mac_multicast_list_set(
400 __checkReturn int
401efx_mac_hash_set(
404 __in efx_nic_t *enp,
402 __in efx_nic_t *enp,
405 __in_ecount(6*count) uint8_t const *addrs,
406 __in int count)
403 __in_ecount(EFX_MAC_HASH_BITS) unsigned int const *bucket)
407{
408 efx_port_t *epp = &(enp->en_port);
404{
405 efx_port_t *epp = &(enp->en_port);
409 const efx_mac_ops_t *emop = epp->ep_emop;
410 uint8_t *old_mulcst_addr_list = NULL;
411 uint32_t old_mulcst_addr_count;
412 efx_rc_t rc;
406 efx_mac_ops_t *emop = epp->ep_emop;
407 efx_oword_t old_hash[2];
408 unsigned int index;
409 int rc;
413
414 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
415 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
416
410
411 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
412 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
413
417 if (count > EFX_MAC_MULTICAST_LIST_MAX) {
418 rc = EINVAL;
419 goto fail1;
420 }
414 memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
421
415
422 old_mulcst_addr_count = epp->ep_mulcst_addr_count;
423 if (old_mulcst_addr_count > 0) {
424 /* Allocate memory to store old list (instead of using stack) */
425 EFSYS_KMEM_ALLOC(enp->en_esip,
426 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
427 old_mulcst_addr_list);
428 if (old_mulcst_addr_list == NULL) {
429 rc = ENOMEM;
430 goto fail2;
431 }
432
433 /* Save the old list in case we need to rollback */
434 memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
435 old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
416 /* Set the lower 128 bits of the hash */
417 EFX_ZERO_OWORD(epp->ep_multicst_hash[0]);
418 for (index = 0; index < 128; index++) {
419 if (bucket[index] != 0)
420 EFX_SET_OWORD_BIT(epp->ep_multicst_hash[0], index);
436 }
437
421 }
422
438 /* Store the new list */
439 memcpy(epp->ep_mulcst_addr_list, addrs,
440 count * EFX_MAC_ADDR_LEN);
441 epp->ep_mulcst_addr_count = count;
442
443 if ((rc = emop->emo_multicast_list_set(enp)) != 0)
444 goto fail3;
445
446 if (old_mulcst_addr_count > 0) {
447 EFSYS_KMEM_FREE(enp->en_esip,
448 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
449 old_mulcst_addr_list);
423 /* Set the upper 128 bits of the hash */
424 EFX_ZERO_OWORD(epp->ep_multicst_hash[1]);
425 for (index = 0; index < 128; index++) {
426 if (bucket[index + 128] != 0)
427 EFX_SET_OWORD_BIT(epp->ep_multicst_hash[1], index);
450 }
451
428 }
429
452 return (0);
430 if ((rc = emop->emo_reconfigure(enp)) != 0)
431 goto fail1;
453
432
454fail3:
455 EFSYS_PROBE(fail3);
456
457 /* Restore original list on failure */
458 epp->ep_mulcst_addr_count = old_mulcst_addr_count;
459 if (old_mulcst_addr_count > 0) {
460 memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
461 old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
462
463 EFSYS_KMEM_FREE(enp->en_esip,
464 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
465 old_mulcst_addr_list);
466 }
467
468fail2:
469 EFSYS_PROBE(fail2);
470
471fail1:
472 EFSYS_PROBE1(fail1, efx_rc_t, rc);
473
474 return (rc);
475
476}
477
478 __checkReturn efx_rc_t
479efx_mac_filter_default_rxq_set(
480 __in efx_nic_t *enp,
481 __in efx_rxq_t *erp,
482 __in boolean_t using_rss)
483{
484 efx_port_t *epp = &(enp->en_port);
485 const efx_mac_ops_t *emop = epp->ep_emop;
486 efx_rc_t rc;
487
488 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
489 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
490
491 if (emop->emo_filter_default_rxq_set != NULL) {
492 rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
493 if (rc != 0)
494 goto fail1;
495 }
496
497 return (0);
498
499fail1:
433 return (0);
434
435fail1:
500 EFSYS_PROBE1(fail1, efx_rc_t, rc);
436 EFSYS_PROBE1(fail1, int, rc);
501
437
438 memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
439
502 return (rc);
503}
504
440 return (rc);
441}
442
505 void
506efx_mac_filter_default_rxq_clear(
507 __in efx_nic_t *enp)
508{
509 efx_port_t *epp = &(enp->en_port);
510 const efx_mac_ops_t *emop = epp->ep_emop;
511
512 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
513 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
514
515 if (emop->emo_filter_default_rxq_clear != NULL)
516 emop->emo_filter_default_rxq_clear(enp);
517}
518
519#if EFSYS_OPT_MAC_STATS
520
521#if EFSYS_OPT_NAMES
522
443#if EFSYS_OPT_MAC_STATS
444
445#if EFSYS_OPT_NAMES
446
523/* START MKCONFIG GENERATED EfxMacStatNamesBlock 1a45a82fcfb30c1b */
524static const char * const __efx_mac_stat_name[] = {
447/* START MKCONFIG GENERATED EfxMacStatNamesBlock adf707adba80813e */
448static const char __cs * __cs __efx_mac_stat_name[] = {
525 "rx_octets",
526 "rx_pkts",
527 "rx_unicst_pkts",
528 "rx_multicst_pkts",
529 "rx_brdcst_pkts",
530 "rx_pause_pkts",
531 "rx_le_64_pkts",
532 "rx_65_to_127_pkts",

--- 35 unchanged lines hidden (view full) ---

568 "tx_ge_15xx_pkts",
569 "tx_errors",
570 "tx_sgl_col_pkts",
571 "tx_mult_col_pkts",
572 "tx_ex_col_pkts",
573 "tx_late_col_pkts",
574 "tx_def_pkts",
575 "tx_ex_def_pkts",
449 "rx_octets",
450 "rx_pkts",
451 "rx_unicst_pkts",
452 "rx_multicst_pkts",
453 "rx_brdcst_pkts",
454 "rx_pause_pkts",
455 "rx_le_64_pkts",
456 "rx_65_to_127_pkts",

--- 35 unchanged lines hidden (view full) ---

492 "tx_ge_15xx_pkts",
493 "tx_errors",
494 "tx_sgl_col_pkts",
495 "tx_mult_col_pkts",
496 "tx_ex_col_pkts",
497 "tx_late_col_pkts",
498 "tx_def_pkts",
499 "tx_ex_def_pkts",
576 "pm_trunc_bb_overflow",
577 "pm_discard_bb_overflow",
578 "pm_trunc_vfifo_full",
579 "pm_discard_vfifo_full",
580 "pm_trunc_qbb",
581 "pm_discard_qbb",
582 "pm_discard_mapping",
583 "rxdp_q_disabled_pkts",
584 "rxdp_di_dropped_pkts",
585 "rxdp_streaming_pkts",
586 "rxdp_hlb_fetch",
587 "rxdp_hlb_wait",
588 "vadapter_rx_unicast_packets",
589 "vadapter_rx_unicast_bytes",
590 "vadapter_rx_multicast_packets",
591 "vadapter_rx_multicast_bytes",
592 "vadapter_rx_broadcast_packets",
593 "vadapter_rx_broadcast_bytes",
594 "vadapter_rx_bad_packets",
595 "vadapter_rx_bad_bytes",
596 "vadapter_rx_overflow",
597 "vadapter_tx_unicast_packets",
598 "vadapter_tx_unicast_bytes",
599 "vadapter_tx_multicast_packets",
600 "vadapter_tx_multicast_bytes",
601 "vadapter_tx_broadcast_packets",
602 "vadapter_tx_broadcast_bytes",
603 "vadapter_tx_bad_packets",
604 "vadapter_tx_bad_bytes",
605 "vadapter_tx_overflow",
606 "fec_uncorrected_errors",
607 "fec_corrected_errors",
608 "fec_corrected_symbols_lane0",
609 "fec_corrected_symbols_lane1",
610 "fec_corrected_symbols_lane2",
611 "fec_corrected_symbols_lane3",
612 "ctpio_vi_busy_fallback",
613 "ctpio_long_write_success",
614 "ctpio_missing_dbell_fail",
615 "ctpio_overflow_fail",
616 "ctpio_underflow_fail",
617 "ctpio_timeout_fail",
618 "ctpio_noncontig_wr_fail",
619 "ctpio_frm_clobber_fail",
620 "ctpio_invalid_wr_fail",
621 "ctpio_vi_clobber_fallback",
622 "ctpio_unqualified_fallback",
623 "ctpio_runt_fallback",
624 "ctpio_success",
625 "ctpio_fallback",
626 "ctpio_poison",
627 "ctpio_erase",
628 "rxdp_scatter_disabled_trunc",
629 "rxdp_hlb_idle",
630 "rxdp_hlb_timeout",
631};
632/* END MKCONFIG GENERATED EfxMacStatNamesBlock */
633
500};
501/* END MKCONFIG GENERATED EfxMacStatNamesBlock */
502
634 __checkReturn const char *
503 __checkReturn const char __cs *
635efx_mac_stat_name(
636 __in efx_nic_t *enp,
637 __in unsigned int id)
638{
639 _NOTE(ARGUNUSED(enp))
640 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
641
642 EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
643 return (__efx_mac_stat_name[id]);
644}
645
504efx_mac_stat_name(
505 __in efx_nic_t *enp,
506 __in unsigned int id)
507{
508 _NOTE(ARGUNUSED(enp))
509 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
510
511 EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
512 return (__efx_mac_stat_name[id]);
513}
514
646#endif /* EFSYS_OPT_NAMES */
515#endif /* EFSYS_OPT_STAT_NAME */
647
516
648static efx_rc_t
649efx_mac_stats_mask_add_range(
650 __inout_bcount(mask_size) uint32_t *maskp,
651 __in size_t mask_size,
652 __in const struct efx_mac_stats_range *rngp)
653{
654 unsigned int mask_npages = mask_size / sizeof (*maskp);
655 unsigned int el;
656 unsigned int el_min;
657 unsigned int el_max;
658 unsigned int low;
659 unsigned int high;
660 unsigned int width;
661 efx_rc_t rc;
662
663 if ((mask_npages * EFX_MAC_STATS_MASK_BITS_PER_PAGE) <=
664 (unsigned int)rngp->last) {
665 rc = EINVAL;
666 goto fail1;
667 }
668
669 EFSYS_ASSERT3U(rngp->first, <=, rngp->last);
670 EFSYS_ASSERT3U(rngp->last, <, EFX_MAC_NSTATS);
671
672 for (el = 0; el < mask_npages; ++el) {
673 el_min = el * EFX_MAC_STATS_MASK_BITS_PER_PAGE;
674 el_max =
675 el_min + (EFX_MAC_STATS_MASK_BITS_PER_PAGE - 1);
676 if ((unsigned int)rngp->first > el_max ||
677 (unsigned int)rngp->last < el_min)
678 continue;
679 low = MAX((unsigned int)rngp->first, el_min);
680 high = MIN((unsigned int)rngp->last, el_max);
681 width = high - low + 1;
682 maskp[el] |=
683 (width == EFX_MAC_STATS_MASK_BITS_PER_PAGE) ?
684 (~0ULL) : (((1ULL << width) - 1) << (low - el_min));
685 }
686
687 return (0);
688
689fail1:
690 EFSYS_PROBE1(fail1, efx_rc_t, rc);
691
692 return (rc);
693}
694
695 efx_rc_t
696efx_mac_stats_mask_add_ranges(
697 __inout_bcount(mask_size) uint32_t *maskp,
698 __in size_t mask_size,
699 __in_ecount(rng_count) const struct efx_mac_stats_range *rngp,
700 __in unsigned int rng_count)
701{
702 unsigned int i;
703 efx_rc_t rc;
704
705 for (i = 0; i < rng_count; ++i) {
706 if ((rc = efx_mac_stats_mask_add_range(maskp, mask_size,
707 &rngp[i])) != 0)
708 goto fail1;
709 }
710
711 return (0);
712
713fail1:
714 EFSYS_PROBE1(fail1, efx_rc_t, rc);
715
716 return (rc);
717}
718
719 __checkReturn efx_rc_t
720efx_mac_stats_get_mask(
721 __in efx_nic_t *enp,
722 __out_bcount(mask_size) uint32_t *maskp,
723 __in size_t mask_size)
724{
725 efx_port_t *epp = &(enp->en_port);
726 const efx_mac_ops_t *emop = epp->ep_emop;
727 efx_rc_t rc;
728
729 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
730 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
731 EFSYS_ASSERT(maskp != NULL);
732 EFSYS_ASSERT(mask_size % sizeof (maskp[0]) == 0);
733
734 (void) memset(maskp, 0, mask_size);
735
736 if ((rc = emop->emo_stats_get_mask(enp, maskp, mask_size)) != 0)
737 goto fail1;
738
739 return (0);
740
741fail1:
742 EFSYS_PROBE1(fail1, efx_rc_t, rc);
743
744 return (rc);
745}
746
747 __checkReturn efx_rc_t
748efx_mac_stats_clear(
749 __in efx_nic_t *enp)
750{
751 efx_port_t *epp = &(enp->en_port);
752 const efx_mac_ops_t *emop = epp->ep_emop;
753 efx_rc_t rc;
754
755 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
756 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
757 EFSYS_ASSERT(emop != NULL);
758
759 if ((rc = emop->emo_stats_clear(enp)) != 0)
760 goto fail1;
761
762 return (0);
763
764fail1:
765 EFSYS_PROBE1(fail1, efx_rc_t, rc);
766
767 return (rc);
768}
769
770 __checkReturn efx_rc_t
517 __checkReturn int
771efx_mac_stats_upload(
772 __in efx_nic_t *enp,
773 __in efsys_mem_t *esmp)
774{
775 efx_port_t *epp = &(enp->en_port);
518efx_mac_stats_upload(
519 __in efx_nic_t *enp,
520 __in efsys_mem_t *esmp)
521{
522 efx_port_t *epp = &(enp->en_port);
776 const efx_mac_ops_t *emop = epp->ep_emop;
777 efx_rc_t rc;
523 efx_mac_ops_t *emop = epp->ep_emop;
524 int rc;
778
779 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
780 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
781 EFSYS_ASSERT(emop != NULL);
782
525
526 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
527 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
528 EFSYS_ASSERT(emop != NULL);
529
530 /*
531 * Don't assert !ep_mac_stats_pending, because the client might
532 * have failed to finalise statistics when previously stopping
533 * the port.
534 */
783 if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
784 goto fail1;
785
535 if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
536 goto fail1;
537
538 epp->ep_mac_stats_pending = B_TRUE;
539
786 return (0);
787
788fail1:
540 return (0);
541
542fail1:
789 EFSYS_PROBE1(fail1, efx_rc_t, rc);
543 EFSYS_PROBE1(fail1, int, rc);
790
791 return (rc);
792}
793
544
545 return (rc);
546}
547
794 __checkReturn efx_rc_t
548 __checkReturn int
795efx_mac_stats_periodic(
796 __in efx_nic_t *enp,
797 __in efsys_mem_t *esmp,
798 __in uint16_t period_ms,
799 __in boolean_t events)
800{
801 efx_port_t *epp = &(enp->en_port);
549efx_mac_stats_periodic(
550 __in efx_nic_t *enp,
551 __in efsys_mem_t *esmp,
552 __in uint16_t period_ms,
553 __in boolean_t events)
554{
555 efx_port_t *epp = &(enp->en_port);
802 const efx_mac_ops_t *emop = epp->ep_emop;
803 efx_rc_t rc;
556 efx_mac_ops_t *emop = epp->ep_emop;
557 int rc;
804
805 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
806 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
807
808 EFSYS_ASSERT(emop != NULL);
809
810 if (emop->emo_stats_periodic == NULL) {
811 rc = EINVAL;
812 goto fail1;
813 }
814
815 if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
816 goto fail2;
817
818 return (0);
819
820fail2:
821 EFSYS_PROBE(fail2);
822fail1:
558
559 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
560 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
561
562 EFSYS_ASSERT(emop != NULL);
563
564 if (emop->emo_stats_periodic == NULL) {
565 rc = EINVAL;
566 goto fail1;
567 }
568
569 if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
570 goto fail2;
571
572 return (0);
573
574fail2:
575 EFSYS_PROBE(fail2);
576fail1:
823 EFSYS_PROBE1(fail1, efx_rc_t, rc);
577 EFSYS_PROBE1(fail1, int, rc);
824
825 return (rc);
826}
827
578
579 return (rc);
580}
581
828 __checkReturn efx_rc_t
582
583 __checkReturn int
829efx_mac_stats_update(
830 __in efx_nic_t *enp,
831 __in efsys_mem_t *esmp,
832 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp,
584efx_mac_stats_update(
585 __in efx_nic_t *enp,
586 __in efsys_mem_t *esmp,
587 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp,
833 __inout_opt uint32_t *generationp)
588 __in uint32_t *generationp)
834{
835 efx_port_t *epp = &(enp->en_port);
589{
590 efx_port_t *epp = &(enp->en_port);
836 const efx_mac_ops_t *emop = epp->ep_emop;
837 efx_rc_t rc;
591 efx_mac_ops_t *emop = epp->ep_emop;
592 int rc;
838
839 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
840 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
841 EFSYS_ASSERT(emop != NULL);
842
843 rc = emop->emo_stats_update(enp, esmp, essp, generationp);
593
594 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
595 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
596 EFSYS_ASSERT(emop != NULL);
597
598 rc = emop->emo_stats_update(enp, esmp, essp, generationp);
599 if (rc == 0)
600 epp->ep_mac_stats_pending = B_FALSE;
844
845 return (rc);
846}
847
848#endif /* EFSYS_OPT_MAC_STATS */
849
601
602 return (rc);
603}
604
605#endif /* EFSYS_OPT_MAC_STATS */
606
850 __checkReturn efx_rc_t
607 __checkReturn int
851efx_mac_select(
852 __in efx_nic_t *enp)
853{
854 efx_port_t *epp = &(enp->en_port);
855 efx_mac_type_t type = EFX_MAC_INVALID;
608efx_mac_select(
609 __in efx_nic_t *enp)
610{
611 efx_port_t *epp = &(enp->en_port);
612 efx_mac_type_t type = EFX_MAC_INVALID;
856 const efx_mac_ops_t *emop;
613 efx_mac_ops_t *emop;
857 int rc = EINVAL;
858
614 int rc = EINVAL;
615
859 switch (enp->en_family) {
860#if EFSYS_OPT_SIENA
616#if EFSYS_OPT_SIENA
861 case EFX_FAMILY_SIENA:
862 emop = &__efx_mac_siena_ops;
617 if (enp->en_family == EFX_FAMILY_SIENA) {
863 type = EFX_MAC_SIENA;
618 type = EFX_MAC_SIENA;
864 break;
865#endif /* EFSYS_OPT_SIENA */
619 goto chosen;
620 }
621#endif
866
622
867#if EFSYS_OPT_HUNTINGTON
868 case EFX_FAMILY_HUNTINGTON:
869 emop = &__efx_mac_ef10_ops;
870 type = EFX_MAC_HUNTINGTON;
871 break;
872#endif /* EFSYS_OPT_HUNTINGTON */
623#if EFSYS_OPT_FALCON
624 switch (epp->ep_link_mode) {
625#if EFSYS_OPT_MAC_FALCON_GMAC
626 case EFX_LINK_100HDX:
627 case EFX_LINK_100FDX:
628 case EFX_LINK_1000HDX:
629 case EFX_LINK_1000FDX:
630 type = EFX_MAC_FALCON_GMAC;
631 goto chosen;
632#endif /* EFSYS_OPT_FALCON_GMAC */
873
633
874#if EFSYS_OPT_MEDFORD
875 case EFX_FAMILY_MEDFORD:
876 emop = &__efx_mac_ef10_ops;
877 type = EFX_MAC_MEDFORD;
878 break;
879#endif /* EFSYS_OPT_MEDFORD */
634#if EFSYS_OPT_MAC_FALCON_XMAC
635 case EFX_LINK_10000FDX:
636 type = EFX_MAC_FALCON_XMAC;
637 goto chosen;
638#endif /* EFSYS_OPT_FALCON_XMAC */
880
639
881#if EFSYS_OPT_MEDFORD2
882 case EFX_FAMILY_MEDFORD2:
883 emop = &__efx_mac_ef10_ops;
884 type = EFX_MAC_MEDFORD2;
885 break;
886#endif /* EFSYS_OPT_MEDFORD2 */
887
888 default:
640 default:
889 rc = EINVAL;
890 goto fail1;
641#if EFSYS_OPT_MAC_FALCON_GMAC && EFSYS_OPT_MAC_FALCON_XMAC
642 /* Only initialise a MAC supported by the PHY */
643 if (epp->ep_phy_cap_mask &
644 ((1 << EFX_PHY_CAP_1000FDX) |
645 (1 << EFX_PHY_CAP_1000HDX) |
646 (1 << EFX_PHY_CAP_100FDX) |
647 (1 << EFX_PHY_CAP_100HDX) |
648 (1 << EFX_PHY_CAP_10FDX) |
649 (1 << EFX_PHY_CAP_10FDX)))
650 type = EFX_MAC_FALCON_GMAC;
651 else
652 type = EFX_MAC_FALCON_XMAC;
653#elif EFSYS_OPT_MAC_FALCON_GMAC
654 type = EFX_MAC_FALCON_GMAC;
655#else
656 type = EFX_MAC_FALCON_XMAC;
657#endif
658 goto chosen;
891 }
659 }
660#endif /* EFSYS_OPT_FALCON */
892
661
662chosen:
893 EFSYS_ASSERT(type != EFX_MAC_INVALID);
894 EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
663 EFSYS_ASSERT(type != EFX_MAC_INVALID);
664 EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
665 emop = epp->ep_emop = (efx_mac_ops_t *)__efx_mac_ops[type];
895 EFSYS_ASSERT(emop != NULL);
896
666 EFSYS_ASSERT(emop != NULL);
667
897 epp->ep_emop = emop;
898 epp->ep_mac_type = type;
668 epp->ep_mac_type = type;
899
900 return (0);
901
902fail1:
903 EFSYS_PROBE1(fail1, efx_rc_t, rc);
904
905 return (rc);
906}
907
908#if EFSYS_OPT_SIENA
909
910#define EFX_MAC_HASH_BITS (1 << 8)
911
912/* Compute the multicast hash as used on Falcon and Siena. */
913static void
914siena_mac_multicast_hash_compute(
915 __in_ecount(6*count) uint8_t const *addrs,
916 __in int count,
917 __out efx_oword_t *hash_low,
918 __out efx_oword_t *hash_high)
919{
920 uint32_t crc, index;
921 int i;
922
923 EFSYS_ASSERT(hash_low != NULL);
924 EFSYS_ASSERT(hash_high != NULL);
925
926 EFX_ZERO_OWORD(*hash_low);
927 EFX_ZERO_OWORD(*hash_high);
928
929 for (i = 0; i < count; i++) {
930 /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
931 crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
932 index = crc % EFX_MAC_HASH_BITS;
933 if (index < 128) {
934 EFX_SET_OWORD_BIT(*hash_low, index);
935 } else {
936 EFX_SET_OWORD_BIT(*hash_high, index - 128);
937 }
938
939 addrs += EFX_MAC_ADDR_LEN;
669
670 if (emop->emo_reset != NULL) {
671 if ((rc = emop->emo_reset(enp)) != 0)
672 goto fail1;
673
674 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
675 enp->en_reset_flags &= ~EFX_RESET_MAC;
940 }
676 }
941}
942
677
943static __checkReturn efx_rc_t
944siena_mac_multicast_list_set(
945 __in efx_nic_t *enp)
946{
947 efx_port_t *epp = &(enp->en_port);
948 const efx_mac_ops_t *emop = epp->ep_emop;
949 efx_oword_t old_hash[2];
950 efx_rc_t rc;
951
952 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
953 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
954
955 memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
956
957 siena_mac_multicast_hash_compute(
958 epp->ep_mulcst_addr_list,
959 epp->ep_mulcst_addr_count,
960 &epp->ep_multicst_hash[0],
961 &epp->ep_multicst_hash[1]);
962
963 if ((rc = emop->emo_reconfigure(enp)) != 0)
964 goto fail1;
965
966 return (0);
967
968fail1:
678 return (0);
679
680fail1:
969 EFSYS_PROBE1(fail1, efx_rc_t, rc);
681 EFSYS_PROBE1(fail1, int, rc);
970
682
971 memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
972
973 return (rc);
974}
683 return (rc);
684}
975
976#endif /* EFSYS_OPT_SIENA */