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 */ | |