summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2016-06-04 15:24:11 +0000
committerarybchik <arybchik@FreeBSD.org>2016-06-04 15:24:11 +0000
commit45da1f7e9b0430d2c1b95adb91935570bb94eda2 (patch)
tree113ca5dd6410c94da9f409d1e61777982256ff7e /sys/dev
parent3ddc776297ba8bf326cffe45b938dac77506a5a9 (diff)
downloadFreeBSD-src-45da1f7e9b0430d2c1b95adb91935570bb94eda2.zip
FreeBSD-src-45da1f7e9b0430d2c1b95adb91935570bb94eda2.tar.gz
MFC r299596-r299606, r299681, r299726, r299738
sfxge(4): move ef10_*() functions to ef10_*.c files Submitted by: Andy Moreton <amoreton at solarflare.com> Sponsored by: Solarflare Communications, Inc.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/sfxge/common/ef10_ev.c (renamed from sys/dev/sfxge/common/hunt_ev.c)4
-rw-r--r--sys/dev/sfxge/common/ef10_filter.c (renamed from sys/dev/sfxge/common/hunt_filter.c)4
-rw-r--r--sys/dev/sfxge/common/ef10_intr.c (renamed from sys/dev/sfxge/common/hunt_intr.c)4
-rw-r--r--sys/dev/sfxge/common/ef10_mac.c (renamed from sys/dev/sfxge/common/hunt_mac.c)4
-rw-r--r--sys/dev/sfxge/common/ef10_mcdi.c (renamed from sys/dev/sfxge/common/hunt_mcdi.c)0
-rw-r--r--sys/dev/sfxge/common/ef10_nic.c1616
-rw-r--r--sys/dev/sfxge/common/ef10_nvram.c (renamed from sys/dev/sfxge/common/hunt_nvram.c)6
-rw-r--r--sys/dev/sfxge/common/ef10_phy.c518
-rw-r--r--sys/dev/sfxge/common/ef10_rx.c (renamed from sys/dev/sfxge/common/hunt_rx.c)4
-rwxr-xr-xsys/dev/sfxge/common/ef10_tx.c (renamed from sys/dev/sfxge/common/hunt_tx.c)6
-rw-r--r--sys/dev/sfxge/common/ef10_vpd.c (renamed from sys/dev/sfxge/common/hunt_vpd.c)4
-rw-r--r--sys/dev/sfxge/common/efx_tx.c2
-rw-r--r--sys/dev/sfxge/common/hunt_impl.h2
-rw-r--r--sys/dev/sfxge/common/hunt_nic.c1573
-rw-r--r--sys/dev/sfxge/common/hunt_phy.c479
15 files changed, 2154 insertions, 2072 deletions
diff --git a/sys/dev/sfxge/common/hunt_ev.c b/sys/dev/sfxge/common/ef10_ev.c
index 1a41b49..0110c86 100644
--- a/sys/dev/sfxge/common/hunt_ev.c
+++ b/sys/dev/sfxge/common/ef10_ev.c
@@ -37,7 +37,7 @@ __FBSDID("$FreeBSD$");
#include "mcdi_mon.h"
#endif
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
#if EFSYS_OPT_QSTATS
#define EFX_EV_QSTAT_INCR(_eep, _stat) \
@@ -985,4 +985,4 @@ ef10_ev_rxlabel_fini(
eersp->eers_rx_mask = 0;
}
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/hunt_filter.c b/sys/dev/sfxge/common/ef10_filter.c
index 57c9630..3795142 100644
--- a/sys/dev/sfxge/common/hunt_filter.c
+++ b/sys/dev/sfxge/common/ef10_filter.c
@@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$");
#include "efx.h"
#include "efx_impl.h"
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
#if EFSYS_OPT_FILTER
@@ -1479,4 +1479,4 @@ ef10_filter_default_rxq_clear(
#endif /* EFSYS_OPT_FILTER */
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/hunt_intr.c b/sys/dev/sfxge/common/ef10_intr.c
index 7a4293c..5a91fe1 100644
--- a/sys/dev/sfxge/common/hunt_intr.c
+++ b/sys/dev/sfxge/common/ef10_intr.c
@@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$");
#include "efx_impl.h"
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
__checkReturn efx_rc_t
ef10_intr_init(
@@ -197,4 +197,4 @@ ef10_intr_fini(
_NOTE(ARGUNUSED(enp))
}
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/hunt_mac.c b/sys/dev/sfxge/common/ef10_mac.c
index 267be0c..6546ef1 100644
--- a/sys/dev/sfxge/common/hunt_mac.c
+++ b/sys/dev/sfxge/common/ef10_mac.c
@@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$");
#include "efx_impl.h"
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
__checkReturn efx_rc_t
ef10_mac_poll(
@@ -749,4 +749,4 @@ ef10_mac_stats_update(
#endif /* EFSYS_OPT_MAC_STATS */
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/hunt_mcdi.c b/sys/dev/sfxge/common/ef10_mcdi.c
index f39e977..f39e977 100644
--- a/sys/dev/sfxge/common/hunt_mcdi.c
+++ b/sys/dev/sfxge/common/ef10_mcdi.c
diff --git a/sys/dev/sfxge/common/ef10_nic.c b/sys/dev/sfxge/common/ef10_nic.c
new file mode 100644
index 0000000..493f4a0
--- /dev/null
+++ b/sys/dev/sfxge/common/ef10_nic.c
@@ -0,0 +1,1616 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efx.h"
+#include "efx_impl.h"
+#if EFSYS_OPT_MON_MCDI
+#include "mcdi_mon.h"
+#endif
+
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
+
+#include "ef10_tlv_layout.h"
+
+ __checkReturn efx_rc_t
+efx_mcdi_get_port_assignment(
+ __in efx_nic_t *enp,
+ __out uint32_t *portp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
+ MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN)];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *portp = MCDI_OUT_DWORD(req, GET_PORT_ASSIGNMENT_OUT_PORT);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_mcdi_get_port_modes(
+ __in efx_nic_t *enp,
+ __out uint32_t *modesp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
+ MC_CMD_GET_PORT_MODES_OUT_LEN)];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PORT_MODES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ /*
+ * Require only Modes and DefaultMode fields.
+ * (CurrentMode field was added for Medford)
+ */
+ if (req.emr_out_length_used <
+ MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn efx_rc_t
+efx_mcdi_vadaptor_alloc(
+ __in efx_nic_t *enp,
+ __in uint32_t port_id)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN,
+ MC_CMD_VADAPTOR_ALLOC_OUT_LEN)];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VADAPTOR_ALLOC;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id);
+ MCDI_IN_POPULATE_DWORD_1(req, VADAPTOR_ALLOC_IN_FLAGS,
+ VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED,
+ enp->en_nic_cfg.enc_allow_set_mac_with_installed_filters ? 1 : 0);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_vadaptor_free(
+ __in efx_nic_t *enp,
+ __in uint32_t port_id)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN,
+ MC_CMD_VADAPTOR_FREE_OUT_LEN)];
+ efx_rc_t rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VADAPTOR_FREE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_mcdi_get_mac_address_pf(
+ __in efx_nic_t *enp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6])
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ if (mac_addrp != NULL) {
+ uint8_t *addrp;
+
+ addrp = MCDI_OUT2(req, uint8_t,
+ GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE);
+
+ EFX_MAC_ADDR_COPY(mac_addrp, addrp);
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_mcdi_get_mac_address_vf(
+ __in efx_nic_t *enp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6])
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID,
+ EVB_PORT_ID_ASSIGNED);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used <
+ MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (MCDI_OUT_DWORD(req,
+ VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ if (mac_addrp != NULL) {
+ uint8_t *addrp;
+
+ addrp = MCDI_OUT2(req, uint8_t,
+ VPORT_GET_MAC_ADDRESSES_OUT_MACADDR);
+
+ EFX_MAC_ADDR_COPY(mac_addrp, addrp);
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_mcdi_get_clock(
+ __in efx_nic_t *enp,
+ __out uint32_t *sys_freqp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
+ MC_CMD_GET_CLOCK_OUT_LEN)];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_CLOCK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ);
+ if (*sys_freqp == 0) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_mcdi_get_vector_cfg(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *vec_basep,
+ __out_opt uint32_t *pf_nvecp,
+ __out_opt uint32_t *vf_nvecp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN,
+ MC_CMD_GET_VECTOR_CFG_OUT_LEN)];
+ efx_rc_t rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_VECTOR_CFG;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (vec_basep != NULL)
+ *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE);
+ if (pf_nvecp != NULL)
+ *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF);
+ if (vf_nvecp != NULL)
+ *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_get_capabilities(
+ __in efx_nic_t *enp,
+ __out uint32_t *flagsp,
+ __out uint32_t *flags2p)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
+ MC_CMD_GET_CAPABILITIES_V2_OUT_LEN)];
+ efx_rc_t rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_CAPABILITIES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_CAPABILITIES_V2_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *flagsp = MCDI_OUT_DWORD(req, GET_CAPABILITIES_OUT_FLAGS1);
+
+ if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_V2_OUT_LEN)
+ *flags2p = 0;
+ else
+ *flags2p = MCDI_OUT_DWORD(req, GET_CAPABILITIES_V2_OUT_FLAGS2);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn efx_rc_t
+efx_mcdi_alloc_vis(
+ __in efx_nic_t *enp,
+ __in uint32_t min_vi_count,
+ __in uint32_t max_vi_count,
+ __out uint32_t *vi_basep,
+ __out uint32_t *vi_countp,
+ __out uint32_t *vi_shiftp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
+ MC_CMD_ALLOC_VIS_OUT_LEN)];
+ efx_rc_t rc;
+
+ if (vi_countp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_ALLOC_VIS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ALLOC_VIS_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count);
+ MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE);
+ *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT);
+
+ /* Report VI_SHIFT if available (always zero for Huntington) */
+ if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_EXT_OUT_LEN)
+ *vi_shiftp = 0;
+ else
+ *vi_shiftp = MCDI_OUT_DWORD(req, ALLOC_VIS_EXT_OUT_VI_SHIFT);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn efx_rc_t
+efx_mcdi_free_vis(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ efx_rc_t rc;
+
+ EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0);
+ EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0);
+
+ req.emr_cmd = MC_CMD_FREE_VIS;
+ req.emr_in_buf = NULL;
+ req.emr_in_length = 0;
+ req.emr_out_buf = NULL;
+ req.emr_out_length = 0;
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ /* Ignore ELREADY (no allocated VIs, so nothing to free) */
+ if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn efx_rc_t
+efx_mcdi_alloc_piobuf(
+ __in efx_nic_t *enp,
+ __out efx_piobuf_handle_t *handlep)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN,
+ MC_CMD_ALLOC_PIOBUF_OUT_LEN)];
+ efx_rc_t rc;
+
+ if (handlep == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_ALLOC_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN;
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_free_piobuf(
+ __in efx_nic_t *enp,
+ __in efx_piobuf_handle_t handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN,
+ MC_CMD_FREE_PIOBUF_OUT_LEN)];
+ efx_rc_t rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FREE_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_link_piobuf(
+ __in efx_nic_t *enp,
+ __in uint32_t vi_index,
+ __in efx_piobuf_handle_t handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN,
+ MC_CMD_LINK_PIOBUF_OUT_LEN)];
+ efx_rc_t rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_LINK_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle);
+ MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_unlink_piobuf(
+ __in efx_nic_t *enp,
+ __in uint32_t vi_index)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN,
+ MC_CMD_UNLINK_PIOBUF_OUT_LEN)];
+ efx_rc_t rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_UNLINK_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static void
+ef10_nic_alloc_piobufs(
+ __in efx_nic_t *enp,
+ __in uint32_t max_piobuf_count)
+{
+ efx_piobuf_handle_t *handlep;
+ unsigned int i;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT3U(max_piobuf_count, <=,
+ EFX_ARRAY_SIZE(enp->en_arch.ef10.ena_piobuf_handle));
+
+ enp->en_arch.ef10.ena_piobuf_count = 0;
+
+ for (i = 0; i < max_piobuf_count; i++) {
+ handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
+
+ if ((rc = efx_mcdi_alloc_piobuf(enp, handlep)) != 0)
+ goto fail1;
+
+ enp->en_arch.ef10.ena_pio_alloc_map[i] = 0;
+ enp->en_arch.ef10.ena_piobuf_count++;
+ }
+
+ return;
+
+fail1:
+ for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
+ handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
+
+ efx_mcdi_free_piobuf(enp, *handlep);
+ *handlep = EFX_PIOBUF_HANDLE_INVALID;
+ }
+ enp->en_arch.ef10.ena_piobuf_count = 0;
+}
+
+
+static void
+ef10_nic_free_piobufs(
+ __in efx_nic_t *enp)
+{
+ efx_piobuf_handle_t *handlep;
+ unsigned int i;
+
+ for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
+ handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
+
+ efx_mcdi_free_piobuf(enp, *handlep);
+ *handlep = EFX_PIOBUF_HANDLE_INVALID;
+ }
+ enp->en_arch.ef10.ena_piobuf_count = 0;
+}
+
+/* Sub-allocate a block from a piobuf */
+ __checkReturn efx_rc_t
+ef10_nic_pio_alloc(
+ __inout efx_nic_t *enp,
+ __out uint32_t *bufnump,
+ __out efx_piobuf_handle_t *handlep,
+ __out uint32_t *blknump,
+ __out uint32_t *offsetp,
+ __out size_t *sizep)
+{
+ efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+ efx_drv_cfg_t *edcp = &enp->en_drv_cfg;
+ uint32_t blk_per_buf;
+ uint32_t buf, blk;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+ EFSYS_ASSERT(bufnump);
+ EFSYS_ASSERT(handlep);
+ EFSYS_ASSERT(blknump);
+ EFSYS_ASSERT(offsetp);
+ EFSYS_ASSERT(sizep);
+
+ if ((edcp->edc_pio_alloc_size == 0) ||
+ (enp->en_arch.ef10.ena_piobuf_count == 0)) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+ blk_per_buf = encp->enc_piobuf_size / edcp->edc_pio_alloc_size;
+
+ for (buf = 0; buf < enp->en_arch.ef10.ena_piobuf_count; buf++) {
+ uint32_t *map = &enp->en_arch.ef10.ena_pio_alloc_map[buf];
+
+ if (~(*map) == 0)
+ continue;
+
+ EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map)));
+ for (blk = 0; blk < blk_per_buf; blk++) {
+ if ((*map & (1u << blk)) == 0) {
+ *map |= (1u << blk);
+ goto done;
+ }
+ }
+ }
+ rc = ENOMEM;
+ goto fail2;
+
+done:
+ *handlep = enp->en_arch.ef10.ena_piobuf_handle[buf];
+ *bufnump = buf;
+ *blknump = blk;
+ *sizep = edcp->edc_pio_alloc_size;
+ *offsetp = blk * (*sizep);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+/* Free a piobuf sub-allocated block */
+ __checkReturn efx_rc_t
+ef10_nic_pio_free(
+ __inout efx_nic_t *enp,
+ __in uint32_t bufnum,
+ __in uint32_t blknum)
+{
+ uint32_t *map;
+ efx_rc_t rc;
+
+ if ((bufnum >= enp->en_arch.ef10.ena_piobuf_count) ||
+ (blknum >= (8 * sizeof (*map)))) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ map = &enp->en_arch.ef10.ena_pio_alloc_map[bufnum];
+ if ((*map & (1u << blknum)) == 0) {
+ rc = ENOENT;
+ goto fail2;
+ }
+ *map &= ~(1u << blknum);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_nic_pio_link(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index,
+ __in efx_piobuf_handle_t handle)
+{
+ return (efx_mcdi_link_piobuf(enp, vi_index, handle));
+}
+
+ __checkReturn efx_rc_t
+ef10_nic_pio_unlink(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index)
+{
+ return (efx_mcdi_unlink_piobuf(enp, vi_index));
+}
+
+ __checkReturn efx_rc_t
+ef10_get_datapath_caps(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t flags;
+ uint32_t flags2;
+ efx_rc_t rc;
+
+ if ((rc = efx_mcdi_get_capabilities(enp, &flags, &flags2)) != 0)
+ goto fail1;
+
+#define CAP_FLAG(flags1, field) \
+ ((flags1) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN)))
+
+#define CAP_FLAG2(flags2, field) \
+ ((flags2) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN)))
+
+ /*
+ * Huntington RXDP firmware inserts a 0 or 14 byte prefix.
+ * We only support the 14 byte prefix here.
+ */
+ if (CAP_FLAG(flags, RX_PREFIX_LEN_14) == 0) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+ encp->enc_rx_prefix_size = 14;
+
+ /* Check if the firmware supports TSO */
+ encp->enc_fw_assisted_tso_enabled =
+ CAP_FLAG(flags, TX_TSO) ? B_TRUE : B_FALSE;
+
+ /* Check if the firmware supports FATSOv2 */
+ encp->enc_fw_assisted_tso_v2_enabled =
+ CAP_FLAG2(flags2, TX_TSO_V2) ? B_TRUE : B_FALSE;
+
+ /* Check if the firmware has vadapter/vport/vswitch support */
+ encp->enc_datapath_cap_evb =
+ CAP_FLAG(flags, EVB) ? B_TRUE : B_FALSE;
+
+ /* Check if the firmware supports VLAN insertion */
+ encp->enc_hw_tx_insert_vlan_enabled =
+ CAP_FLAG(flags, TX_VLAN_INSERTION) ? B_TRUE : B_FALSE;
+
+ /* Check if the firmware supports RX event batching */
+ encp->enc_rx_batching_enabled =
+ CAP_FLAG(flags, RX_BATCHING) ? B_TRUE : B_FALSE;
+
+ if (encp->enc_rx_batching_enabled)
+ encp->enc_rx_batch_max = 16;
+
+ /* Check if the firmware supports disabling scatter on RXQs */
+ encp->enc_rx_disable_scatter_supported =
+ CAP_FLAG(flags, RX_DISABLE_SCATTER) ? B_TRUE : B_FALSE;
+
+ /* Check if the firmware supports set mac with running filters */
+ encp->enc_allow_set_mac_with_installed_filters =
+ CAP_FLAG(flags, VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED) ?
+ B_TRUE : B_FALSE;
+
+ /*
+ * Check if firmware supports the extended MC_CMD_SET_MAC, which allows
+ * specifying which parameters to configure.
+ */
+ encp->enc_enhanced_set_mac_supported =
+ CAP_FLAG(flags, SET_MAC_ENHANCED) ? B_TRUE : B_FALSE;
+
+#undef CAP_FLAG
+#undef CAP_FLAG2
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn efx_rc_t
+ef10_get_privilege_mask(
+ __in efx_nic_t *enp,
+ __out uint32_t *maskp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t mask;
+ efx_rc_t rc;
+
+ if ((rc = efx_mcdi_privilege_mask(enp, encp->enc_pf, encp->enc_vf,
+ &mask)) != 0) {
+ if (rc != ENOTSUP)
+ goto fail1;
+
+ /* Fallback for old firmware without privilege mask support */
+ if (EFX_PCI_FUNCTION_IS_PF(encp)) {
+ /* Assume PF has admin privilege */
+ mask = EF10_LEGACY_PF_PRIVILEGE_MASK;
+ } else {
+ /* VF is always unprivileged by default */
+ mask = EF10_LEGACY_VF_PRIVILEGE_MASK;
+ }
+ }
+
+ *maskp = mask;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+/*
+ * The external port mapping is a one-based numbering of the external
+ * connectors on the board. It does not distinguish off-board separated
+ * outputs such as multi-headed cables.
+ * The number of ports that map to each external port connector
+ * on the board is determined by the chip family and the port modes to
+ * which the NIC can be configured. The mapping table lists modes with
+ * port numbering requirements in increasing order.
+ */
+static struct {
+ efx_family_t family;
+ uint32_t modes_mask;
+ uint32_t stride;
+} __ef10_external_port_mappings[] = {
+ /* Supported modes requiring 1 output per port */
+ {
+ EFX_FAMILY_HUNTINGTON,
+ (1 << TLV_PORT_MODE_10G) |
+ (1 << TLV_PORT_MODE_10G_10G) |
+ (1 << TLV_PORT_MODE_10G_10G_10G_10G),
+ 1
+ },
+ {
+ EFX_FAMILY_MEDFORD,
+ (1 << TLV_PORT_MODE_10G) |
+ (1 << TLV_PORT_MODE_10G_10G) |
+ (1 << TLV_PORT_MODE_10G_10G_10G_10G),
+ 1
+ },
+ /* Supported modes requiring 2 outputs per port */
+ {
+ EFX_FAMILY_HUNTINGTON,
+ (1 << TLV_PORT_MODE_40G) |
+ (1 << TLV_PORT_MODE_40G_40G) |
+ (1 << TLV_PORT_MODE_40G_10G_10G) |
+ (1 << TLV_PORT_MODE_10G_10G_40G),
+ 2
+ },
+ {
+ EFX_FAMILY_MEDFORD,
+ (1 << TLV_PORT_MODE_40G) |
+ (1 << TLV_PORT_MODE_40G_40G) |
+ (1 << TLV_PORT_MODE_40G_10G_10G) |
+ (1 << TLV_PORT_MODE_10G_10G_40G),
+ 2
+ },
+ /* Supported modes requiring 4 outputs per port */
+ {
+ EFX_FAMILY_MEDFORD,
+ (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q) |
+ (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q2),
+ 4
+ },
+};
+
+ __checkReturn efx_rc_t
+ef10_external_port_mapping(
+ __in efx_nic_t *enp,
+ __in uint32_t port,
+ __out uint8_t *external_portp)
+{
+ efx_rc_t rc;
+ int i;
+ uint32_t port_modes;
+ uint32_t matches;
+ uint32_t stride = 1; /* default 1-1 mapping */
+
+ if ((rc = efx_mcdi_get_port_modes(enp, &port_modes)) != 0) {
+ /* No port mode information available - use default mapping */
+ goto out;
+ }
+
+ /*
+ * Infer the internal port -> external port mapping from
+ * the possible port modes for this NIC.
+ */
+ for (i = 0; i < EFX_ARRAY_SIZE(__ef10_external_port_mappings); ++i) {
+ if (__ef10_external_port_mappings[i].family !=
+ enp->en_family)
+ continue;
+ matches = (__ef10_external_port_mappings[i].modes_mask &
+ port_modes);
+ if (matches != 0) {
+ stride = __ef10_external_port_mappings[i].stride;
+ port_modes &= ~matches;
+ }
+ }
+
+ if (port_modes != 0) {
+ /* Some advertised modes are not supported */
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+out:
+ /*
+ * Scale as required by last matched mode and then convert to
+ * one-based numbering
+ */
+ *external_portp = (uint8_t)(port / stride) + 1;
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn efx_rc_t
+ef10_nic_probe(
+ __in efx_nic_t *enp)
+{
+ const efx_nic_ops_t *enop = enp->en_enop;
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ /* Read and clear any assertion state */
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
+ goto fail1;
+
+ /* Exit the assertion handler */
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
+ if (rc != EACCES)
+ goto fail2;
+
+ if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
+ goto fail3;
+
+ if ((rc = enop->eno_board_cfg(enp)) != 0)
+ if (rc != EACCES)
+ goto fail4;
+
+ /*
+ * Set default driver config limits (based on board config).
+ *
+ * FIXME: For now allocate a fixed number of VIs which is likely to be
+ * sufficient and small enough to allow multiple functions on the same
+ * port.
+ */
+ edcp->edc_min_vi_count = edcp->edc_max_vi_count =
+ MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
+
+ /* The client driver must configure and enable PIO buffer support */
+ edcp->edc_max_piobuf_count = 0;
+ edcp->edc_pio_alloc_size = 0;
+
+#if EFSYS_OPT_MAC_STATS
+ /* Wipe the MAC statistics */
+ if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
+ goto fail5;
+#endif
+
+#if EFSYS_OPT_LOOPBACK
+ if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
+ goto fail6;
+#endif
+
+#if EFSYS_OPT_MON_STATS
+ if ((rc = mcdi_mon_cfg_build(enp)) != 0) {
+ /* Unprivileged functions do not have access to sensors */
+ if (rc != EACCES)
+ goto fail7;
+ }
+#endif
+
+ encp->enc_features = enp->en_features;
+
+ return (0);
+
+#if EFSYS_OPT_MON_STATS
+fail7:
+ EFSYS_PROBE(fail7);
+#endif
+#if EFSYS_OPT_LOOPBACK
+fail6:
+ EFSYS_PROBE(fail6);
+#endif
+#if EFSYS_OPT_MAC_STATS
+fail5:
+ EFSYS_PROBE(fail5);
+#endif
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_nic_set_drv_limits(
+ __inout efx_nic_t *enp,
+ __in efx_drv_limits_t *edlp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
+ uint32_t min_evq_count, max_evq_count;
+ uint32_t min_rxq_count, max_rxq_count;
+ uint32_t min_txq_count, max_txq_count;
+ efx_rc_t rc;
+
+ if (edlp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Get minimum required and maximum usable VI limits */
+ min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
+ min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
+ min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
+
+ edcp->edc_min_vi_count =
+ MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
+
+ max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
+ max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
+ max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
+
+ edcp->edc_max_vi_count =
+ MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
+
+ /*
+ * Check limits for sub-allocated piobuf blocks.
+ * PIO is optional, so don't fail if the limits are incorrect.
+ */
+ if ((encp->enc_piobuf_size == 0) ||
+ (encp->enc_piobuf_limit == 0) ||
+ (edlp->edl_min_pio_alloc_size == 0) ||
+ (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) {
+ /* Disable PIO */
+ edcp->edc_max_piobuf_count = 0;
+ edcp->edc_pio_alloc_size = 0;
+ } else {
+ uint32_t blk_size, blk_count, blks_per_piobuf;
+
+ blk_size =
+ MAX(edlp->edl_min_pio_alloc_size,
+ encp->enc_piobuf_min_alloc_size);
+
+ blks_per_piobuf = encp->enc_piobuf_size / blk_size;
+ EFSYS_ASSERT3U(blks_per_piobuf, <=, 32);
+
+ blk_count = (encp->enc_piobuf_limit * blks_per_piobuf);
+
+ /* A zero max pio alloc count means unlimited */
+ if ((edlp->edl_max_pio_alloc_count > 0) &&
+ (edlp->edl_max_pio_alloc_count < blk_count)) {
+ blk_count = edlp->edl_max_pio_alloc_count;
+ }
+
+ edcp->edc_pio_alloc_size = blk_size;
+ edcp->edc_max_piobuf_count =
+ (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn efx_rc_t
+ef10_nic_reset(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN,
+ MC_CMD_ENTITY_RESET_OUT_LEN)];
+ efx_rc_t rc;
+
+ /* ef10_nic_reset() is called to recover from BADASSERT failures. */
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
+ goto fail1;
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
+ goto fail2;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_ENTITY_RESET;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN;
+
+ MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG,
+ ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail3;
+ }
+
+ /* Clear RX/TX DMA queue errors */
+ enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_nic_init(
+ __in efx_nic_t *enp)
+{
+ efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
+ uint32_t min_vi_count, max_vi_count;
+ uint32_t vi_count, vi_base, vi_shift;
+ uint32_t i;
+ uint32_t retry;
+ uint32_t delay_us;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ /* Enable reporting of some events (e.g. link change) */
+ if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
+ goto fail1;
+
+ /* Allocate (optional) on-chip PIO buffers */
+ ef10_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count);
+
+ /*
+ * For best performance, PIO writes should use a write-combined
+ * (WC) memory mapping. Using a separate WC mapping for the PIO
+ * aperture of each VI would be a burden to drivers (and not
+ * possible if the host page size is >4Kbyte).
+ *
+ * To avoid this we use a single uncached (UC) mapping for VI
+ * register access, and a single WC mapping for extra VIs used
+ * for PIO writes.
+ *
+ * Each piobuf must be linked to a VI in the WC mapping, and to
+ * each VI that is using a sub-allocated block from the piobuf.
+ */
+ min_vi_count = edcp->edc_min_vi_count;
+ max_vi_count =
+ edcp->edc_max_vi_count + enp->en_arch.ef10.ena_piobuf_count;
+
+ /* Ensure that the previously attached driver's VIs are freed */
+ if ((rc = efx_mcdi_free_vis(enp)) != 0)
+ goto fail2;
+
+ /*
+ * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
+ * fails then retrying the request for fewer VI resources may succeed.
+ */
+ vi_count = 0;
+ if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
+ &vi_base, &vi_count, &vi_shift)) != 0)
+ goto fail3;
+
+ EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
+
+ if (vi_count < min_vi_count) {
+ rc = ENOMEM;
+ goto fail4;
+ }
+
+ enp->en_arch.ef10.ena_vi_base = vi_base;
+ enp->en_arch.ef10.ena_vi_count = vi_count;
+ enp->en_arch.ef10.ena_vi_shift = vi_shift;
+
+ if (vi_count < min_vi_count + enp->en_arch.ef10.ena_piobuf_count) {
+ /* Not enough extra VIs to map piobufs */
+ ef10_nic_free_piobufs(enp);
+ }
+
+ enp->en_arch.ef10.ena_pio_write_vi_base =
+ vi_count - enp->en_arch.ef10.ena_piobuf_count;
+
+ /* Save UC memory mapping details */
+ enp->en_arch.ef10.ena_uc_mem_map_offset = 0;
+ if (enp->en_arch.ef10.ena_piobuf_count > 0) {
+ enp->en_arch.ef10.ena_uc_mem_map_size =
+ (ER_DZ_TX_PIOBUF_STEP *
+ enp->en_arch.ef10.ena_pio_write_vi_base);
+ } else {
+ enp->en_arch.ef10.ena_uc_mem_map_size =
+ (ER_DZ_TX_PIOBUF_STEP *
+ enp->en_arch.ef10.ena_vi_count);
+ }
+
+ /* Save WC memory mapping details */
+ enp->en_arch.ef10.ena_wc_mem_map_offset =
+ enp->en_arch.ef10.ena_uc_mem_map_offset +
+ enp->en_arch.ef10.ena_uc_mem_map_size;
+
+ enp->en_arch.ef10.ena_wc_mem_map_size =
+ (ER_DZ_TX_PIOBUF_STEP *
+ enp->en_arch.ef10.ena_piobuf_count);
+
+ /* Link piobufs to extra VIs in WC mapping */
+ if (enp->en_arch.ef10.ena_piobuf_count > 0) {
+ for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
+ rc = efx_mcdi_link_piobuf(enp,
+ enp->en_arch.ef10.ena_pio_write_vi_base + i,
+ enp->en_arch.ef10.ena_piobuf_handle[i]);
+ if (rc != 0)
+ break;
+ }
+ }
+
+ /*
+ * Allocate a vAdaptor attached to our upstream vPort/pPort.
+ *
+ * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF
+ * driver has yet to bring up the EVB port. See bug 56147. In this case,
+ * retry the request several times after waiting a while. The wait time
+ * between retries starts small (10ms) and exponentially increases.
+ * Total wait time is a little over two seconds. Retry logic in the
+ * client driver may mean this whole loop is repeated if it continues to
+ * fail.
+ */
+ retry = 0;
+ delay_us = 10000;
+ while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) {
+ if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) ||
+ (rc != ENOENT)) {
+ /*
+ * Do not retry alloc for PF, or for other errors on
+ * a VF.
+ */
+ goto fail5;
+ }
+
+ /* VF startup before PF is ready. Retry allocation. */
+ if (retry > 5) {
+ /* Too many attempts */
+ rc = EINVAL;
+ goto fail6;
+ }
+ EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry);
+ EFSYS_SLEEP(delay_us);
+ retry++;
+ if (delay_us < 500000)
+ delay_us <<= 2;
+ }
+
+ enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
+ enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2;
+
+ return (0);
+
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+
+ ef10_nic_free_piobufs(enp);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_nic_get_vi_pool(
+ __in efx_nic_t *enp,
+ __out uint32_t *vi_countp)
+{
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ /*
+ * Report VIs that the client driver can use.
+ * Do not include VIs used for PIO buffer writes.
+ */
+ *vi_countp = enp->en_arch.ef10.ena_pio_write_vi_base;
+
+ return (0);
+}
+
+ __checkReturn efx_rc_t
+ef10_nic_get_bar_region(
+ __in efx_nic_t *enp,
+ __in efx_nic_region_t region,
+ __out uint32_t *offsetp,
+ __out size_t *sizep)
+{
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
+
+ /*
+ * TODO: Specify host memory mapping alignment and granularity
+ * in efx_drv_limits_t so that they can be taken into account
+ * when allocating extra VIs for PIO writes.
+ */
+ switch (region) {
+ case EFX_REGION_VI:
+ /* UC mapped memory BAR region for VI registers */
+ *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset;
+ *sizep = enp->en_arch.ef10.ena_uc_mem_map_size;
+ break;
+
+ case EFX_REGION_PIO_WRITE_VI:
+ /* WC mapped memory BAR region for piobuf writes */
+ *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset;
+ *sizep = enp->en_arch.ef10.ena_wc_mem_map_size;
+ break;
+
+ default:
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ void
+ef10_nic_fini(
+ __in efx_nic_t *enp)
+{
+ uint32_t i;
+ efx_rc_t rc;
+
+ (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
+ enp->en_vport_id = 0;
+
+ /* Unlink piobufs from extra VIs in WC mapping */
+ if (enp->en_arch.ef10.ena_piobuf_count > 0) {
+ for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
+ rc = efx_mcdi_unlink_piobuf(enp,
+ enp->en_arch.ef10.ena_pio_write_vi_base + i);
+ if (rc != 0)
+ break;
+ }
+ }
+
+ ef10_nic_free_piobufs(enp);
+
+ (void) efx_mcdi_free_vis(enp);
+ enp->en_arch.ef10.ena_vi_count = 0;
+}
+
+ void
+ef10_nic_unprobe(
+ __in efx_nic_t *enp)
+{
+#if EFSYS_OPT_MON_STATS
+ mcdi_mon_cfg_free(enp);
+#endif /* EFSYS_OPT_MON_STATS */
+ (void) efx_mcdi_drv_attach(enp, B_FALSE);
+}
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn efx_rc_t
+ef10_nic_register_test(
+ __in efx_nic_t *enp)
+{
+ efx_rc_t rc;
+
+ /* FIXME */
+ _NOTE(ARGUNUSED(enp))
+ if (B_FALSE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ /* FIXME */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_DIAG */
+
+
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/hunt_nvram.c b/sys/dev/sfxge/common/ef10_nvram.c
index 0e19e7b..e63ba87 100644
--- a/sys/dev/sfxge/common/hunt_nvram.c
+++ b/sys/dev/sfxge/common/ef10_nvram.c
@@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$");
#include "efx.h"
#include "efx_impl.h"
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
@@ -1654,7 +1654,7 @@ ef10_nvram_segment_write_tlv(
* Read the segment from NVRAM into the segment_data buffer and validate
* it, returning if it does not validate. This is not a failure unless
* this is the first segment in a partition. In this case the caller
- * must propogate the error.
+ * must propagate the error.
*/
status = ef10_nvram_read_tlv_segment(enp, partn, *partn_offsetp,
*seg_datap, *src_remain_lenp);
@@ -2330,4 +2330,4 @@ ef10_nvram_partn_rw_finish(
#endif /* EFSYS_OPT_NVRAM */
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/ef10_phy.c b/sys/dev/sfxge/common/ef10_phy.c
new file mode 100644
index 0000000..9241297
--- /dev/null
+++ b/sys/dev/sfxge/common/ef10_phy.c
@@ -0,0 +1,518 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
+
+static void
+mcdi_phy_decode_cap(
+ __in uint32_t mcdi_cap,
+ __out uint32_t *maskp)
+{
+ uint32_t mask;
+
+ mask = 0;
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_10HDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_10FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_100HDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_100FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_1000HDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_1000FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_10000FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_40000FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
+ mask |= (1 << EFX_PHY_CAP_PAUSE);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
+ mask |= (1 << EFX_PHY_CAP_ASYM);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
+ mask |= (1 << EFX_PHY_CAP_AN);
+
+ *maskp = mask;
+}
+
+static void
+mcdi_phy_decode_link_mode(
+ __in efx_nic_t *enp,
+ __in uint32_t link_flags,
+ __in unsigned int speed,
+ __in unsigned int fcntl,
+ __out efx_link_mode_t *link_modep,
+ __out unsigned int *fcntlp)
+{
+ boolean_t fd = !!(link_flags &
+ (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
+ boolean_t up = !!(link_flags &
+ (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
+
+ _NOTE(ARGUNUSED(enp))
+
+ if (!up)
+ *link_modep = EFX_LINK_DOWN;
+ else if (speed == 40000 && fd)
+ *link_modep = EFX_LINK_40000FDX;
+ else if (speed == 10000 && fd)
+ *link_modep = EFX_LINK_10000FDX;
+ else if (speed == 1000)
+ *link_modep = fd ? EFX_LINK_1000FDX : EFX_LINK_1000HDX;
+ else if (speed == 100)
+ *link_modep = fd ? EFX_LINK_100FDX : EFX_LINK_100HDX;
+ else if (speed == 10)
+ *link_modep = fd ? EFX_LINK_10FDX : EFX_LINK_10HDX;
+ else
+ *link_modep = EFX_LINK_UNKNOWN;
+
+ if (fcntl == MC_CMD_FCNTL_OFF)
+ *fcntlp = 0;
+ else if (fcntl == MC_CMD_FCNTL_RESPOND)
+ *fcntlp = EFX_FCNTL_RESPOND;
+ else if (fcntl == MC_CMD_FCNTL_GENERATE)
+ *fcntlp = EFX_FCNTL_GENERATE;
+ else if (fcntl == MC_CMD_FCNTL_BIDIR)
+ *fcntlp = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
+ else {
+ EFSYS_PROBE1(mc_pcol_error, int, fcntl);
+ *fcntlp = 0;
+ }
+}
+
+
+ void
+ef10_phy_link_ev(
+ __in efx_nic_t *enp,
+ __in efx_qword_t *eqp,
+ __out efx_link_mode_t *link_modep)
+{
+ efx_port_t *epp = &(enp->en_port);
+ unsigned int link_flags;
+ unsigned int speed;
+ unsigned int fcntl;
+ efx_link_mode_t link_mode;
+ uint32_t lp_cap_mask;
+
+ /*
+ * Convert the LINKCHANGE speed enumeration into mbit/s, in the
+ * same way as GET_LINK encodes the speed
+ */
+ switch (MCDI_EV_FIELD(eqp, LINKCHANGE_SPEED)) {
+ case MCDI_EVENT_LINKCHANGE_SPEED_100M:
+ speed = 100;
+ break;
+ case MCDI_EVENT_LINKCHANGE_SPEED_1G:
+ speed = 1000;
+ break;
+ case MCDI_EVENT_LINKCHANGE_SPEED_10G:
+ speed = 10000;
+ break;
+ case MCDI_EVENT_LINKCHANGE_SPEED_40G:
+ speed = 40000;
+ break;
+ default:
+ speed = 0;
+ break;
+ }
+
+ link_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS);
+ mcdi_phy_decode_link_mode(enp, link_flags, speed,
+ MCDI_EV_FIELD(eqp, LINKCHANGE_FCNTL),
+ &link_mode, &fcntl);
+ mcdi_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP),
+ &lp_cap_mask);
+
+ /*
+ * It's safe to update ep_lp_cap_mask without the driver's port lock
+ * because presumably any concurrently running efx_port_poll() is
+ * only going to arrive at the same value.
+ *
+ * ep_fcntl has two meanings. It's either the link common fcntl
+ * (if the PHY supports AN), or it's the forced link state. If
+ * the former, it's safe to update the value for the same reason as
+ * for ep_lp_cap_mask. If the latter, then just ignore the value,
+ * because we can race with efx_mac_fcntl_set().
+ */
+ epp->ep_lp_cap_mask = lp_cap_mask;
+ epp->ep_fcntl = fcntl;
+
+ *link_modep = link_mode;
+}
+
+ __checkReturn efx_rc_t
+ef10_phy_power(
+ __in efx_nic_t *enp,
+ __in boolean_t power)
+{
+ efx_rc_t rc;
+
+ if (!power)
+ return (0);
+
+ /* Check if the PHY is a zombie */
+ if ((rc = ef10_phy_verify(enp)) != 0)
+ goto fail1;
+
+ enp->en_reset_flags |= EFX_RESET_PHY;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_phy_get_link(
+ __in efx_nic_t *enp,
+ __out ef10_link_state_t *elsp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
+ MC_CMD_GET_LINK_OUT_LEN)];
+ efx_rc_t rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_LINK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP),
+ &elsp->els_adv_cap_mask);
+ mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP),
+ &elsp->els_lp_cap_mask);
+
+ mcdi_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS),
+ MCDI_OUT_DWORD(req, GET_LINK_OUT_LINK_SPEED),
+ MCDI_OUT_DWORD(req, GET_LINK_OUT_FCNTL),
+ &elsp->els_link_mode, &elsp->els_fcntl);
+
+#if EFSYS_OPT_LOOPBACK
+ /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
+
+ elsp->els_loopback = MCDI_OUT_DWORD(req, GET_LINK_OUT_LOOPBACK_MODE);
+#endif /* EFSYS_OPT_LOOPBACK */
+
+ elsp->els_mac_up = MCDI_OUT_DWORD(req, GET_LINK_OUT_MAC_FAULT) == 0;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_phy_reconfigure(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_port_t *epp = &(enp->en_port);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SET_LINK_IN_LEN,
+ MC_CMD_SET_LINK_OUT_LEN)];
+ uint32_t cap_mask;
+ unsigned int led_mode;
+ unsigned int speed;
+ efx_rc_t rc;
+
+ if (~encp->enc_func_flags & EFX_NIC_FUNC_LINKCTRL)
+ goto out;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SET_LINK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_LINK_OUT_LEN;
+
+ cap_mask = epp->ep_adv_cap_mask;
+ MCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP,
+ PHY_CAP_10HDX, (cap_mask >> EFX_PHY_CAP_10HDX) & 0x1,
+ PHY_CAP_10FDX, (cap_mask >> EFX_PHY_CAP_10FDX) & 0x1,
+ PHY_CAP_100HDX, (cap_mask >> EFX_PHY_CAP_100HDX) & 0x1,
+ PHY_CAP_100FDX, (cap_mask >> EFX_PHY_CAP_100FDX) & 0x1,
+ PHY_CAP_1000HDX, (cap_mask >> EFX_PHY_CAP_1000HDX) & 0x1,
+ PHY_CAP_1000FDX, (cap_mask >> EFX_PHY_CAP_1000FDX) & 0x1,
+ PHY_CAP_10000FDX, (cap_mask >> EFX_PHY_CAP_10000FDX) & 0x1,
+ PHY_CAP_PAUSE, (cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1,
+ PHY_CAP_ASYM, (cap_mask >> EFX_PHY_CAP_ASYM) & 0x1,
+ PHY_CAP_AN, (cap_mask >> EFX_PHY_CAP_AN) & 0x1);
+ /* Too many fields for for POPULATE macros, so insert this afterwards */
+ MCDI_IN_SET_DWORD_FIELD(req, SET_LINK_IN_CAP,
+ PHY_CAP_40000FDX, (cap_mask >> EFX_PHY_CAP_40000FDX) & 0x1);
+
+#if EFSYS_OPT_LOOPBACK
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE,
+ epp->ep_loopback_type);
+ switch (epp->ep_loopback_link_mode) {
+ case EFX_LINK_100FDX:
+ speed = 100;
+ break;
+ case EFX_LINK_1000FDX:
+ speed = 1000;
+ break;
+ case EFX_LINK_10000FDX:
+ speed = 10000;
+ break;
+ case EFX_LINK_40000FDX:
+ speed = 40000;
+ break;
+ default:
+ speed = 0;
+ }
+#else
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, MC_CMD_LOOPBACK_NONE);
+ speed = 0;
+#endif /* EFSYS_OPT_LOOPBACK */
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed);
+
+#if EFSYS_OPT_PHY_FLAGS
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, epp->ep_phy_flags);
+#else
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0);
+#endif /* EFSYS_OPT_PHY_FLAGS */
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ /* And set the blink mode */
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SET_ID_LED;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN;
+
+#if EFSYS_OPT_PHY_LED_CONTROL
+ switch (epp->ep_phy_led_mode) {
+ case EFX_PHY_LED_DEFAULT:
+ led_mode = MC_CMD_LED_DEFAULT;
+ break;
+ case EFX_PHY_LED_OFF:
+ led_mode = MC_CMD_LED_OFF;
+ break;
+ case EFX_PHY_LED_ON:
+ led_mode = MC_CMD_LED_ON;
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ led_mode = MC_CMD_LED_DEFAULT;
+ }
+
+ MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, led_mode);
+#else
+ MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT);
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+out:
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_phy_verify(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
+ MC_CMD_GET_PHY_STATE_OUT_LEN)];
+ uint32_t state;
+ efx_rc_t rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PHY_STATE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PHY_STATE_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_PHY_STATE_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ state = MCDI_OUT_DWORD(req, GET_PHY_STATE_OUT_STATE);
+ if (state != MC_CMD_PHY_STATE_OK) {
+ if (state != MC_CMD_PHY_STATE_ZOMBIE)
+ EFSYS_PROBE1(mc_pcol_error, int, state);
+ rc = ENOTACTIVE;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_phy_oui_get(
+ __in efx_nic_t *enp,
+ __out uint32_t *ouip)
+{
+ _NOTE(ARGUNUSED(enp, ouip))
+
+ return (ENOTSUP);
+}
+
+#if EFSYS_OPT_PHY_STATS
+
+ __checkReturn efx_rc_t
+ef10_phy_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
+{
+ /* TBD: no stats support in firmware yet */
+ _NOTE(ARGUNUSED(enp, esmp))
+ memset(stat, 0, EFX_PHY_NSTATS * sizeof (*stat));
+
+ return (0);
+}
+
+#endif /* EFSYS_OPT_PHY_STATS */
+
+#if EFSYS_OPT_PHY_PROPS
+
+#if EFSYS_OPT_NAMES
+
+ const char *
+ef10_phy_prop_name(
+ __in efx_nic_t *enp,
+ __in unsigned int id)
+{
+ _NOTE(ARGUNUSED(enp, id))
+
+ return (NULL);
+}
+
+#endif /* EFSYS_OPT_NAMES */
+
+ __checkReturn efx_rc_t
+ef10_phy_prop_get(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t flags,
+ __out uint32_t *valp)
+{
+ _NOTE(ARGUNUSED(enp, id, flags, valp))
+
+ return (ENOTSUP);
+}
+
+ __checkReturn efx_rc_t
+ef10_phy_prop_set(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t val)
+{
+ _NOTE(ARGUNUSED(enp, id, val))
+
+ return (ENOTSUP);
+}
+
+#endif /* EFSYS_OPT_PHY_PROPS */
+
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/hunt_rx.c b/sys/dev/sfxge/common/ef10_rx.c
index 984d48d..278a0a1 100644
--- a/sys/dev/sfxge/common/hunt_rx.c
+++ b/sys/dev/sfxge/common/ef10_rx.c
@@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$");
#include "efx_impl.h"
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
static __checkReturn efx_rc_t
@@ -823,4 +823,4 @@ ef10_rx_fini(
#endif /* EFSYS_OPT_RX_SCALE */
}
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/hunt_tx.c b/sys/dev/sfxge/common/ef10_tx.c
index baa7444..2922371 100755
--- a/sys/dev/sfxge/common/hunt_tx.c
+++ b/sys/dev/sfxge/common/ef10_tx.c
@@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$");
#include "efx_impl.h"
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
#if EFSYS_OPT_QSTATS
#define EFX_TX_QSTAT_INCR(_etp, _stat) \
@@ -569,7 +569,7 @@ ef10_tx_qdesc_dma_create(
}
void
-hunt_tx_qdesc_tso_create(
+ef10_tx_qdesc_tso_create(
__in efx_txq_t *etp,
__in uint16_t ipv4_id,
__in uint32_t tcp_seq,
@@ -707,4 +707,4 @@ ef10_tx_qstats_update(
#endif /* EFSYS_OPT_QSTATS */
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/hunt_vpd.c b/sys/dev/sfxge/common/ef10_vpd.c
index b4c6d26..8eef3ad 100644
--- a/sys/dev/sfxge/common/hunt_vpd.c
+++ b/sys/dev/sfxge/common/ef10_vpd.c
@@ -37,7 +37,7 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_VPD
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
#include "ef10_tlv_layout.h"
@@ -458,6 +458,6 @@ ef10_vpd_fini(
}
}
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
#endif /* EFSYS_OPT_VPD */
diff --git a/sys/dev/sfxge/common/efx_tx.c b/sys/dev/sfxge/common/efx_tx.c
index 811530d..ceace71 100644
--- a/sys/dev/sfxge/common/efx_tx.c
+++ b/sys/dev/sfxge/common/efx_tx.c
@@ -167,7 +167,7 @@ static const efx_tx_ops_t __efx_tx_hunt_ops = {
ef10_tx_qpio_post, /* etxo_qpio_post */
ef10_tx_qdesc_post, /* etxo_qdesc_post */
ef10_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
- hunt_tx_qdesc_tso_create, /* etxo_qdesc_tso_create */
+ ef10_tx_qdesc_tso_create, /* etxo_qdesc_tso_create */
ef10_tx_qdesc_tso2_create, /* etxo_qdesc_tso2_create */
ef10_tx_qdesc_vlantci_create, /* etxo_qdesc_vlantci_create */
#if EFSYS_OPT_QSTATS
diff --git a/sys/dev/sfxge/common/hunt_impl.h b/sys/dev/sfxge/common/hunt_impl.h
index ece1e6a..2653fe2 100644
--- a/sys/dev/sfxge/common/hunt_impl.h
+++ b/sys/dev/sfxge/common/hunt_impl.h
@@ -746,7 +746,7 @@ ef10_tx_qdesc_dma_create(
__out efx_desc_t *edp);
extern void
-hunt_tx_qdesc_tso_create(
+ef10_tx_qdesc_tso_create(
__in efx_txq_t *etp,
__in uint16_t ipv4_id,
__in uint32_t tcp_seq,
diff --git a/sys/dev/sfxge/common/hunt_nic.c b/sys/dev/sfxge/common/hunt_nic.c
index d268e7b..44ddab7 100644
--- a/sys/dev/sfxge/common/hunt_nic.c
+++ b/sys/dev/sfxge/common/hunt_nic.c
@@ -39,1081 +39,6 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_HUNTINGTON
-#include "ef10_tlv_layout.h"
-
- __checkReturn efx_rc_t
-efx_mcdi_get_port_assignment(
- __in efx_nic_t *enp,
- __out uint32_t *portp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
- MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN)];
- efx_rc_t rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN;
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- *portp = MCDI_OUT_DWORD(req, GET_PORT_ASSIGNMENT_OUT_PORT);
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-efx_mcdi_get_port_modes(
- __in efx_nic_t *enp,
- __out uint32_t *modesp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
- MC_CMD_GET_PORT_MODES_OUT_LEN)];
- efx_rc_t rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_GET_PORT_MODES;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN;
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- /*
- * Require only Modes and DefaultMode fields.
- * (CurrentMode field was added for Medford)
- */
- if (req.emr_out_length_used <
- MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES);
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-
-static __checkReturn efx_rc_t
-efx_mcdi_vadaptor_alloc(
- __in efx_nic_t *enp,
- __in uint32_t port_id)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN,
- MC_CMD_VADAPTOR_ALLOC_OUT_LEN)];
- efx_rc_t rc;
-
- EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL);
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_VADAPTOR_ALLOC;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id);
- MCDI_IN_POPULATE_DWORD_1(req, VADAPTOR_ALLOC_IN_FLAGS,
- VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED,
- enp->en_nic_cfg.enc_allow_set_mac_with_installed_filters ? 1 : 0);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-static __checkReturn efx_rc_t
-efx_mcdi_vadaptor_free(
- __in efx_nic_t *enp,
- __in uint32_t port_id)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN,
- MC_CMD_VADAPTOR_FREE_OUT_LEN)];
- efx_rc_t rc;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_VADAPTOR_FREE;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-efx_mcdi_get_mac_address_pf(
- __in efx_nic_t *enp,
- __out_ecount_opt(6) uint8_t mac_addrp[6])
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
- MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)];
- efx_rc_t rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN;
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) {
- rc = ENOENT;
- goto fail3;
- }
-
- if (mac_addrp != NULL) {
- uint8_t *addrp;
-
- addrp = MCDI_OUT2(req, uint8_t,
- GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE);
-
- EFX_MAC_ADDR_COPY(mac_addrp, addrp);
- }
-
- return (0);
-
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-efx_mcdi_get_mac_address_vf(
- __in efx_nic_t *enp,
- __out_ecount_opt(6) uint8_t mac_addrp[6])
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
- MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)];
- efx_rc_t rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX;
-
- MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID,
- EVB_PORT_ID_ASSIGNED);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used <
- MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- if (MCDI_OUT_DWORD(req,
- VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) {
- rc = ENOENT;
- goto fail3;
- }
-
- if (mac_addrp != NULL) {
- uint8_t *addrp;
-
- addrp = MCDI_OUT2(req, uint8_t,
- VPORT_GET_MAC_ADDRESSES_OUT_MACADDR);
-
- EFX_MAC_ADDR_COPY(mac_addrp, addrp);
- }
-
- return (0);
-
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-efx_mcdi_get_clock(
- __in efx_nic_t *enp,
- __out uint32_t *sys_freqp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
- MC_CMD_GET_CLOCK_OUT_LEN)];
- efx_rc_t rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_GET_CLOCK;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN;
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ);
- if (*sys_freqp == 0) {
- rc = EINVAL;
- goto fail3;
- }
-
- return (0);
-
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-efx_mcdi_get_vector_cfg(
- __in efx_nic_t *enp,
- __out_opt uint32_t *vec_basep,
- __out_opt uint32_t *pf_nvecp,
- __out_opt uint32_t *vf_nvecp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN,
- MC_CMD_GET_VECTOR_CFG_OUT_LEN)];
- efx_rc_t rc;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_GET_VECTOR_CFG;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN;
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- if (vec_basep != NULL)
- *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE);
- if (pf_nvecp != NULL)
- *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF);
- if (vf_nvecp != NULL)
- *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF);
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-static __checkReturn efx_rc_t
-efx_mcdi_get_capabilities(
- __in efx_nic_t *enp,
- __out uint32_t *flagsp,
- __out uint32_t *flags2p)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
- MC_CMD_GET_CAPABILITIES_V2_OUT_LEN)];
- efx_rc_t rc;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_GET_CAPABILITIES;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_CAPABILITIES_V2_OUT_LEN;
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- *flagsp = MCDI_OUT_DWORD(req, GET_CAPABILITIES_OUT_FLAGS1);
-
- if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_V2_OUT_LEN)
- *flags2p = 0;
- else
- *flags2p = MCDI_OUT_DWORD(req, GET_CAPABILITIES_V2_OUT_FLAGS2);
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-
-static __checkReturn efx_rc_t
-efx_mcdi_alloc_vis(
- __in efx_nic_t *enp,
- __in uint32_t min_vi_count,
- __in uint32_t max_vi_count,
- __out uint32_t *vi_basep,
- __out uint32_t *vi_countp,
- __out uint32_t *vi_shiftp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
- MC_CMD_ALLOC_VIS_OUT_LEN)];
- efx_rc_t rc;
-
- if (vi_countp == NULL) {
- rc = EINVAL;
- goto fail1;
- }
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_ALLOC_VIS;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_ALLOC_VIS_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count);
- MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail2;
- }
-
- if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail3;
- }
-
- *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE);
- *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT);
-
- /* Report VI_SHIFT if available (always zero for Huntington) */
- if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_EXT_OUT_LEN)
- *vi_shiftp = 0;
- else
- *vi_shiftp = MCDI_OUT_DWORD(req, ALLOC_VIS_EXT_OUT_VI_SHIFT);
-
- return (0);
-
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-
-static __checkReturn efx_rc_t
-efx_mcdi_free_vis(
- __in efx_nic_t *enp)
-{
- efx_mcdi_req_t req;
- efx_rc_t rc;
-
- EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0);
- EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0);
-
- req.emr_cmd = MC_CMD_FREE_VIS;
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- efx_mcdi_execute_quiet(enp, &req);
-
- /* Ignore ELREADY (no allocated VIs, so nothing to free) */
- if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-
-static __checkReturn efx_rc_t
-efx_mcdi_alloc_piobuf(
- __in efx_nic_t *enp,
- __out efx_piobuf_handle_t *handlep)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN,
- MC_CMD_ALLOC_PIOBUF_OUT_LEN)];
- efx_rc_t rc;
-
- if (handlep == NULL) {
- rc = EINVAL;
- goto fail1;
- }
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_ALLOC_PIOBUF;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN;
-
- efx_mcdi_execute_quiet(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail2;
- }
-
- if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail3;
- }
-
- *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE);
-
- return (0);
-
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-static __checkReturn efx_rc_t
-efx_mcdi_free_piobuf(
- __in efx_nic_t *enp,
- __in efx_piobuf_handle_t handle)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN,
- MC_CMD_FREE_PIOBUF_OUT_LEN)];
- efx_rc_t rc;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_FREE_PIOBUF;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle);
-
- efx_mcdi_execute_quiet(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-static __checkReturn efx_rc_t
-efx_mcdi_link_piobuf(
- __in efx_nic_t *enp,
- __in uint32_t vi_index,
- __in efx_piobuf_handle_t handle)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN,
- MC_CMD_LINK_PIOBUF_OUT_LEN)];
- efx_rc_t rc;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_LINK_PIOBUF;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle);
- MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-static __checkReturn efx_rc_t
-efx_mcdi_unlink_piobuf(
- __in efx_nic_t *enp,
- __in uint32_t vi_index)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN,
- MC_CMD_UNLINK_PIOBUF_OUT_LEN)];
- efx_rc_t rc;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_UNLINK_PIOBUF;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-static void
-ef10_nic_alloc_piobufs(
- __in efx_nic_t *enp,
- __in uint32_t max_piobuf_count)
-{
- efx_piobuf_handle_t *handlep;
- unsigned int i;
- efx_rc_t rc;
-
- EFSYS_ASSERT3U(max_piobuf_count, <=,
- EFX_ARRAY_SIZE(enp->en_arch.ef10.ena_piobuf_handle));
-
- enp->en_arch.ef10.ena_piobuf_count = 0;
-
- for (i = 0; i < max_piobuf_count; i++) {
- handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
-
- if ((rc = efx_mcdi_alloc_piobuf(enp, handlep)) != 0)
- goto fail1;
-
- enp->en_arch.ef10.ena_pio_alloc_map[i] = 0;
- enp->en_arch.ef10.ena_piobuf_count++;
- }
-
- return;
-
-fail1:
- for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
- handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
-
- efx_mcdi_free_piobuf(enp, *handlep);
- *handlep = EFX_PIOBUF_HANDLE_INVALID;
- }
- enp->en_arch.ef10.ena_piobuf_count = 0;
-}
-
-
-static void
-ef10_nic_free_piobufs(
- __in efx_nic_t *enp)
-{
- efx_piobuf_handle_t *handlep;
- unsigned int i;
-
- for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
- handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
-
- efx_mcdi_free_piobuf(enp, *handlep);
- *handlep = EFX_PIOBUF_HANDLE_INVALID;
- }
- enp->en_arch.ef10.ena_piobuf_count = 0;
-}
-
-/* Sub-allocate a block from a piobuf */
- __checkReturn efx_rc_t
-ef10_nic_pio_alloc(
- __inout efx_nic_t *enp,
- __out uint32_t *bufnump,
- __out efx_piobuf_handle_t *handlep,
- __out uint32_t *blknump,
- __out uint32_t *offsetp,
- __out size_t *sizep)
-{
- efx_nic_cfg_t *encp = &enp->en_nic_cfg;
- efx_drv_cfg_t *edcp = &enp->en_drv_cfg;
- uint32_t blk_per_buf;
- uint32_t buf, blk;
- efx_rc_t rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
- EFSYS_ASSERT(bufnump);
- EFSYS_ASSERT(handlep);
- EFSYS_ASSERT(blknump);
- EFSYS_ASSERT(offsetp);
- EFSYS_ASSERT(sizep);
-
- if ((edcp->edc_pio_alloc_size == 0) ||
- (enp->en_arch.ef10.ena_piobuf_count == 0)) {
- rc = ENOMEM;
- goto fail1;
- }
- blk_per_buf = encp->enc_piobuf_size / edcp->edc_pio_alloc_size;
-
- for (buf = 0; buf < enp->en_arch.ef10.ena_piobuf_count; buf++) {
- uint32_t *map = &enp->en_arch.ef10.ena_pio_alloc_map[buf];
-
- if (~(*map) == 0)
- continue;
-
- EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map)));
- for (blk = 0; blk < blk_per_buf; blk++) {
- if ((*map & (1u << blk)) == 0) {
- *map |= (1u << blk);
- goto done;
- }
- }
- }
- rc = ENOMEM;
- goto fail2;
-
-done:
- *handlep = enp->en_arch.ef10.ena_piobuf_handle[buf];
- *bufnump = buf;
- *blknump = blk;
- *sizep = edcp->edc_pio_alloc_size;
- *offsetp = blk * (*sizep);
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-/* Free a piobuf sub-allocated block */
- __checkReturn efx_rc_t
-ef10_nic_pio_free(
- __inout efx_nic_t *enp,
- __in uint32_t bufnum,
- __in uint32_t blknum)
-{
- uint32_t *map;
- efx_rc_t rc;
-
- if ((bufnum >= enp->en_arch.ef10.ena_piobuf_count) ||
- (blknum >= (8 * sizeof (*map)))) {
- rc = EINVAL;
- goto fail1;
- }
-
- map = &enp->en_arch.ef10.ena_pio_alloc_map[bufnum];
- if ((*map & (1u << blknum)) == 0) {
- rc = ENOENT;
- goto fail2;
- }
- *map &= ~(1u << blknum);
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_nic_pio_link(
- __inout efx_nic_t *enp,
- __in uint32_t vi_index,
- __in efx_piobuf_handle_t handle)
-{
- return (efx_mcdi_link_piobuf(enp, vi_index, handle));
-}
-
- __checkReturn efx_rc_t
-ef10_nic_pio_unlink(
- __inout efx_nic_t *enp,
- __in uint32_t vi_index)
-{
- return (efx_mcdi_unlink_piobuf(enp, vi_index));
-}
-
- __checkReturn efx_rc_t
-ef10_get_datapath_caps(
- __in efx_nic_t *enp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint32_t flags;
- uint32_t flags2;
- efx_rc_t rc;
-
- if ((rc = efx_mcdi_get_capabilities(enp, &flags, &flags2)) != 0)
- goto fail1;
-
-#define CAP_FLAG(flags1, field) \
- ((flags1) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN)))
-
-#define CAP_FLAG2(flags2, field) \
- ((flags2) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN)))
-
- /*
- * Huntington RXDP firmware inserts a 0 or 14 byte prefix.
- * We only support the 14 byte prefix here.
- */
- if (CAP_FLAG(flags, RX_PREFIX_LEN_14) == 0) {
- rc = ENOTSUP;
- goto fail2;
- }
- encp->enc_rx_prefix_size = 14;
-
- /* Check if the firmware supports TSO */
- encp->enc_fw_assisted_tso_enabled =
- CAP_FLAG(flags, TX_TSO) ? B_TRUE : B_FALSE;
-
- /* Check if the firmware supports FATSOv2 */
- encp->enc_fw_assisted_tso_v2_enabled =
- CAP_FLAG2(flags2, TX_TSO_V2) ? B_TRUE : B_FALSE;
-
- /* Check if the firmware has vadapter/vport/vswitch support */
- encp->enc_datapath_cap_evb =
- CAP_FLAG(flags, EVB) ? B_TRUE : B_FALSE;
-
- /* Check if the firmware supports VLAN insertion */
- encp->enc_hw_tx_insert_vlan_enabled =
- CAP_FLAG(flags, TX_VLAN_INSERTION) ? B_TRUE : B_FALSE;
-
- /* Check if the firmware supports RX event batching */
- encp->enc_rx_batching_enabled =
- CAP_FLAG(flags, RX_BATCHING) ? B_TRUE : B_FALSE;
-
- if (encp->enc_rx_batching_enabled)
- encp->enc_rx_batch_max = 16;
-
- /* Check if the firmware supports disabling scatter on RXQs */
- encp->enc_rx_disable_scatter_supported =
- CAP_FLAG(flags, RX_DISABLE_SCATTER) ? B_TRUE : B_FALSE;
-
- /* Check if the firmware supports set mac with running filters */
- encp->enc_allow_set_mac_with_installed_filters =
- CAP_FLAG(flags, VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED) ?
- B_TRUE : B_FALSE;
-
- /*
- * Check if firmware supports the extended MC_CMD_SET_MAC, which allows
- * specifying which parameters to configure.
- */
- encp->enc_enhanced_set_mac_supported =
- CAP_FLAG(flags, SET_MAC_ENHANCED) ? B_TRUE : B_FALSE;
-
-#undef CAP_FLAG
-#undef CAP_FLAG2
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-
- __checkReturn efx_rc_t
-ef10_get_privilege_mask(
- __in efx_nic_t *enp,
- __out uint32_t *maskp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint32_t mask;
- efx_rc_t rc;
-
- if ((rc = efx_mcdi_privilege_mask(enp, encp->enc_pf, encp->enc_vf,
- &mask)) != 0) {
- if (rc != ENOTSUP)
- goto fail1;
-
- /* Fallback for old firmware without privilege mask support */
- if (EFX_PCI_FUNCTION_IS_PF(encp)) {
- /* Assume PF has admin privilege */
- mask = EF10_LEGACY_PF_PRIVILEGE_MASK;
- } else {
- /* VF is always unprivileged by default */
- mask = EF10_LEGACY_VF_PRIVILEGE_MASK;
- }
- }
-
- *maskp = mask;
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-
-/*
- * The external port mapping is a one-based numbering of the external
- * connectors on the board. It does not distinguish off-board separated
- * outputs such as multi-headed cables.
- * The number of ports that map to each external port connector
- * on the board is determined by the chip family and the port modes to
- * which the NIC can be configured. The mapping table lists modes with
- * port numbering requirements in increasing order.
- */
-static struct {
- efx_family_t family;
- uint32_t modes_mask;
- uint32_t stride;
-} __ef10_external_port_mappings[] = {
- /* Supported modes requiring 1 output per port */
- {
- EFX_FAMILY_HUNTINGTON,
- (1 << TLV_PORT_MODE_10G) |
- (1 << TLV_PORT_MODE_10G_10G) |
- (1 << TLV_PORT_MODE_10G_10G_10G_10G),
- 1
- },
- {
- EFX_FAMILY_MEDFORD,
- (1 << TLV_PORT_MODE_10G) |
- (1 << TLV_PORT_MODE_10G_10G) |
- (1 << TLV_PORT_MODE_10G_10G_10G_10G),
- 1
- },
- /* Supported modes requiring 2 outputs per port */
- {
- EFX_FAMILY_HUNTINGTON,
- (1 << TLV_PORT_MODE_40G) |
- (1 << TLV_PORT_MODE_40G_40G) |
- (1 << TLV_PORT_MODE_40G_10G_10G) |
- (1 << TLV_PORT_MODE_10G_10G_40G),
- 2
- },
- {
- EFX_FAMILY_MEDFORD,
- (1 << TLV_PORT_MODE_40G) |
- (1 << TLV_PORT_MODE_40G_40G) |
- (1 << TLV_PORT_MODE_40G_10G_10G) |
- (1 << TLV_PORT_MODE_10G_10G_40G),
- 2
- },
- /* Supported modes requiring 4 outputs per port */
- {
- EFX_FAMILY_MEDFORD,
- (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q) |
- (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q2),
- 4
- },
-};
-
- __checkReturn efx_rc_t
-ef10_external_port_mapping(
- __in efx_nic_t *enp,
- __in uint32_t port,
- __out uint8_t *external_portp)
-{
- efx_rc_t rc;
- int i;
- uint32_t port_modes;
- uint32_t matches;
- uint32_t stride = 1; /* default 1-1 mapping */
-
- if ((rc = efx_mcdi_get_port_modes(enp, &port_modes)) != 0) {
- /* No port mode information available - use default mapping */
- goto out;
- }
-
- /*
- * Infer the internal port -> external port mapping from
- * the possible port modes for this NIC.
- */
- for (i = 0; i < EFX_ARRAY_SIZE(__ef10_external_port_mappings); ++i) {
- if (__ef10_external_port_mappings[i].family !=
- enp->en_family)
- continue;
- matches = (__ef10_external_port_mappings[i].modes_mask &
- port_modes);
- if (matches != 0) {
- stride = __ef10_external_port_mappings[i].stride;
- port_modes &= ~matches;
- }
- }
-
- if (port_modes != 0) {
- /* Some advertised modes are not supported */
- rc = ENOTSUP;
- goto fail1;
- }
-
-out:
- /*
- * Scale as required by last matched mode and then convert to
- * one-based numbering
- */
- *external_portp = (uint8_t)(port / stride) + 1;
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
__checkReturn efx_rc_t
hunt_board_cfg(
@@ -1396,502 +321,4 @@ fail1:
}
- __checkReturn efx_rc_t
-ef10_nic_probe(
- __in efx_nic_t *enp)
-{
- const efx_nic_ops_t *enop = enp->en_enop;
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
- efx_rc_t rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- /* Read and clear any assertion state */
- if ((rc = efx_mcdi_read_assertion(enp)) != 0)
- goto fail1;
-
- /* Exit the assertion handler */
- if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
- if (rc != EACCES)
- goto fail2;
-
- if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
- goto fail3;
-
- if ((rc = enop->eno_board_cfg(enp)) != 0)
- if (rc != EACCES)
- goto fail4;
-
- /*
- * Set default driver config limits (based on board config).
- *
- * FIXME: For now allocate a fixed number of VIs which is likely to be
- * sufficient and small enough to allow multiple functions on the same
- * port.
- */
- edcp->edc_min_vi_count = edcp->edc_max_vi_count =
- MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
-
- /* The client driver must configure and enable PIO buffer support */
- edcp->edc_max_piobuf_count = 0;
- edcp->edc_pio_alloc_size = 0;
-
-#if EFSYS_OPT_MAC_STATS
- /* Wipe the MAC statistics */
- if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
- goto fail5;
-#endif
-
-#if EFSYS_OPT_LOOPBACK
- if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
- goto fail6;
-#endif
-
-#if EFSYS_OPT_MON_STATS
- if ((rc = mcdi_mon_cfg_build(enp)) != 0) {
- /* Unprivileged functions do not have access to sensors */
- if (rc != EACCES)
- goto fail7;
- }
-#endif
-
- encp->enc_features = enp->en_features;
-
- return (0);
-
-#if EFSYS_OPT_MON_STATS
-fail7:
- EFSYS_PROBE(fail7);
-#endif
-#if EFSYS_OPT_LOOPBACK
-fail6:
- EFSYS_PROBE(fail6);
-#endif
-#if EFSYS_OPT_MAC_STATS
-fail5:
- EFSYS_PROBE(fail5);
-#endif
-fail4:
- EFSYS_PROBE(fail4);
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_nic_set_drv_limits(
- __inout efx_nic_t *enp,
- __in efx_drv_limits_t *edlp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
- uint32_t min_evq_count, max_evq_count;
- uint32_t min_rxq_count, max_rxq_count;
- uint32_t min_txq_count, max_txq_count;
- efx_rc_t rc;
-
- if (edlp == NULL) {
- rc = EINVAL;
- goto fail1;
- }
-
- /* Get minimum required and maximum usable VI limits */
- min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
- min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
- min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
-
- edcp->edc_min_vi_count =
- MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
-
- max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
- max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
- max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
-
- edcp->edc_max_vi_count =
- MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
-
- /*
- * Check limits for sub-allocated piobuf blocks.
- * PIO is optional, so don't fail if the limits are incorrect.
- */
- if ((encp->enc_piobuf_size == 0) ||
- (encp->enc_piobuf_limit == 0) ||
- (edlp->edl_min_pio_alloc_size == 0) ||
- (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) {
- /* Disable PIO */
- edcp->edc_max_piobuf_count = 0;
- edcp->edc_pio_alloc_size = 0;
- } else {
- uint32_t blk_size, blk_count, blks_per_piobuf;
-
- blk_size =
- MAX(edlp->edl_min_pio_alloc_size,
- encp->enc_piobuf_min_alloc_size);
-
- blks_per_piobuf = encp->enc_piobuf_size / blk_size;
- EFSYS_ASSERT3U(blks_per_piobuf, <=, 32);
-
- blk_count = (encp->enc_piobuf_limit * blks_per_piobuf);
-
- /* A zero max pio alloc count means unlimited */
- if ((edlp->edl_max_pio_alloc_count > 0) &&
- (edlp->edl_max_pio_alloc_count < blk_count)) {
- blk_count = edlp->edl_max_pio_alloc_count;
- }
-
- edcp->edc_pio_alloc_size = blk_size;
- edcp->edc_max_piobuf_count =
- (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-
- __checkReturn efx_rc_t
-ef10_nic_reset(
- __in efx_nic_t *enp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN,
- MC_CMD_ENTITY_RESET_OUT_LEN)];
- efx_rc_t rc;
-
- /* ef10_nic_reset() is called to recover from BADASSERT failures. */
- if ((rc = efx_mcdi_read_assertion(enp)) != 0)
- goto fail1;
- if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
- goto fail2;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_ENTITY_RESET;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN;
-
- MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG,
- ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail3;
- }
-
- /* Clear RX/TX DMA queue errors */
- enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
-
- return (0);
-
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_nic_init(
- __in efx_nic_t *enp)
-{
- efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
- uint32_t min_vi_count, max_vi_count;
- uint32_t vi_count, vi_base, vi_shift;
- uint32_t i;
- uint32_t retry;
- uint32_t delay_us;
- efx_rc_t rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- /* Enable reporting of some events (e.g. link change) */
- if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
- goto fail1;
-
- /* Allocate (optional) on-chip PIO buffers */
- ef10_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count);
-
- /*
- * For best performance, PIO writes should use a write-combined
- * (WC) memory mapping. Using a separate WC mapping for the PIO
- * aperture of each VI would be a burden to drivers (and not
- * possible if the host page size is >4Kbyte).
- *
- * To avoid this we use a single uncached (UC) mapping for VI
- * register access, and a single WC mapping for extra VIs used
- * for PIO writes.
- *
- * Each piobuf must be linked to a VI in the WC mapping, and to
- * each VI that is using a sub-allocated block from the piobuf.
- */
- min_vi_count = edcp->edc_min_vi_count;
- max_vi_count =
- edcp->edc_max_vi_count + enp->en_arch.ef10.ena_piobuf_count;
-
- /* Ensure that the previously attached driver's VIs are freed */
- if ((rc = efx_mcdi_free_vis(enp)) != 0)
- goto fail2;
-
- /*
- * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
- * fails then retrying the request for fewer VI resources may succeed.
- */
- vi_count = 0;
- if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
- &vi_base, &vi_count, &vi_shift)) != 0)
- goto fail3;
-
- EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
-
- if (vi_count < min_vi_count) {
- rc = ENOMEM;
- goto fail4;
- }
-
- enp->en_arch.ef10.ena_vi_base = vi_base;
- enp->en_arch.ef10.ena_vi_count = vi_count;
- enp->en_arch.ef10.ena_vi_shift = vi_shift;
-
- if (vi_count < min_vi_count + enp->en_arch.ef10.ena_piobuf_count) {
- /* Not enough extra VIs to map piobufs */
- ef10_nic_free_piobufs(enp);
- }
-
- enp->en_arch.ef10.ena_pio_write_vi_base =
- vi_count - enp->en_arch.ef10.ena_piobuf_count;
-
- /* Save UC memory mapping details */
- enp->en_arch.ef10.ena_uc_mem_map_offset = 0;
- if (enp->en_arch.ef10.ena_piobuf_count > 0) {
- enp->en_arch.ef10.ena_uc_mem_map_size =
- (ER_DZ_TX_PIOBUF_STEP *
- enp->en_arch.ef10.ena_pio_write_vi_base);
- } else {
- enp->en_arch.ef10.ena_uc_mem_map_size =
- (ER_DZ_TX_PIOBUF_STEP *
- enp->en_arch.ef10.ena_vi_count);
- }
-
- /* Save WC memory mapping details */
- enp->en_arch.ef10.ena_wc_mem_map_offset =
- enp->en_arch.ef10.ena_uc_mem_map_offset +
- enp->en_arch.ef10.ena_uc_mem_map_size;
-
- enp->en_arch.ef10.ena_wc_mem_map_size =
- (ER_DZ_TX_PIOBUF_STEP *
- enp->en_arch.ef10.ena_piobuf_count);
-
- /* Link piobufs to extra VIs in WC mapping */
- if (enp->en_arch.ef10.ena_piobuf_count > 0) {
- for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
- rc = efx_mcdi_link_piobuf(enp,
- enp->en_arch.ef10.ena_pio_write_vi_base + i,
- enp->en_arch.ef10.ena_piobuf_handle[i]);
- if (rc != 0)
- break;
- }
- }
-
- /*
- * Allocate a vAdaptor attached to our upstream vPort/pPort.
- *
- * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF
- * driver has yet to bring up the EVB port. See bug 56147. In this case,
- * retry the request several times after waiting a while. The wait time
- * between retries starts small (10ms) and exponentially increases.
- * Total wait time is a little over two seconds. Retry logic in the
- * client driver may mean this whole loop is repeated if it continues to
- * fail.
- */
- retry = 0;
- delay_us = 10000;
- while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) {
- if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) ||
- (rc != ENOENT)) {
- /*
- * Do not retry alloc for PF, or for other errors on
- * a VF.
- */
- goto fail5;
- }
-
- /* VF startup before PF is ready. Retry allocation. */
- if (retry > 5) {
- /* Too many attempts */
- rc = EINVAL;
- goto fail6;
- }
- EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry);
- EFSYS_SLEEP(delay_us);
- retry++;
- if (delay_us < 500000)
- delay_us <<= 2;
- }
-
- enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
- enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2;
-
- return (0);
-
-fail6:
- EFSYS_PROBE(fail6);
-fail5:
- EFSYS_PROBE(fail5);
-fail4:
- EFSYS_PROBE(fail4);
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-
- ef10_nic_free_piobufs(enp);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_nic_get_vi_pool(
- __in efx_nic_t *enp,
- __out uint32_t *vi_countp)
-{
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- /*
- * Report VIs that the client driver can use.
- * Do not include VIs used for PIO buffer writes.
- */
- *vi_countp = enp->en_arch.ef10.ena_pio_write_vi_base;
-
- return (0);
-}
-
- __checkReturn efx_rc_t
-ef10_nic_get_bar_region(
- __in efx_nic_t *enp,
- __in efx_nic_region_t region,
- __out uint32_t *offsetp,
- __out size_t *sizep)
-{
- efx_rc_t rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- /*
- * TODO: Specify host memory mapping alignment and granularity
- * in efx_drv_limits_t so that they can be taken into account
- * when allocating extra VIs for PIO writes.
- */
- switch (region) {
- case EFX_REGION_VI:
- /* UC mapped memory BAR region for VI registers */
- *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset;
- *sizep = enp->en_arch.ef10.ena_uc_mem_map_size;
- break;
-
- case EFX_REGION_PIO_WRITE_VI:
- /* WC mapped memory BAR region for piobuf writes */
- *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset;
- *sizep = enp->en_arch.ef10.ena_wc_mem_map_size;
- break;
-
- default:
- rc = EINVAL;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- void
-ef10_nic_fini(
- __in efx_nic_t *enp)
-{
- uint32_t i;
- efx_rc_t rc;
-
- (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
- enp->en_vport_id = 0;
-
- /* Unlink piobufs from extra VIs in WC mapping */
- if (enp->en_arch.ef10.ena_piobuf_count > 0) {
- for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
- rc = efx_mcdi_unlink_piobuf(enp,
- enp->en_arch.ef10.ena_pio_write_vi_base + i);
- if (rc != 0)
- break;
- }
- }
-
- ef10_nic_free_piobufs(enp);
-
- (void) efx_mcdi_free_vis(enp);
- enp->en_arch.ef10.ena_vi_count = 0;
-}
-
- void
-ef10_nic_unprobe(
- __in efx_nic_t *enp)
-{
-#if EFSYS_OPT_MON_STATS
- mcdi_mon_cfg_free(enp);
-#endif /* EFSYS_OPT_MON_STATS */
- (void) efx_mcdi_drv_attach(enp, B_FALSE);
-}
-
-#if EFSYS_OPT_DIAG
-
- __checkReturn efx_rc_t
-ef10_nic_register_test(
- __in efx_nic_t *enp)
-{
- efx_rc_t rc;
-
- /* FIXME */
- _NOTE(ARGUNUSED(enp))
- if (B_FALSE) {
- rc = ENOTSUP;
- goto fail1;
- }
- /* FIXME */
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-#endif /* EFSYS_OPT_DIAG */
-
-
-
#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_phy.c b/sys/dev/sfxge/common/hunt_phy.c
index a6b7faa..0f54b57 100644
--- a/sys/dev/sfxge/common/hunt_phy.c
+++ b/sys/dev/sfxge/common/hunt_phy.c
@@ -36,485 +36,6 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_HUNTINGTON
-static void
-mcdi_phy_decode_cap(
- __in uint32_t mcdi_cap,
- __out uint32_t *maskp)
-{
- uint32_t mask;
-
- mask = 0;
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
- mask |= (1 << EFX_PHY_CAP_10HDX);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
- mask |= (1 << EFX_PHY_CAP_10FDX);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
- mask |= (1 << EFX_PHY_CAP_100HDX);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
- mask |= (1 << EFX_PHY_CAP_100FDX);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
- mask |= (1 << EFX_PHY_CAP_1000HDX);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
- mask |= (1 << EFX_PHY_CAP_1000FDX);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
- mask |= (1 << EFX_PHY_CAP_10000FDX);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
- mask |= (1 << EFX_PHY_CAP_40000FDX);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
- mask |= (1 << EFX_PHY_CAP_PAUSE);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
- mask |= (1 << EFX_PHY_CAP_ASYM);
- if (mcdi_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
- mask |= (1 << EFX_PHY_CAP_AN);
-
- *maskp = mask;
-}
-
-static void
-mcdi_phy_decode_link_mode(
- __in efx_nic_t *enp,
- __in uint32_t link_flags,
- __in unsigned int speed,
- __in unsigned int fcntl,
- __out efx_link_mode_t *link_modep,
- __out unsigned int *fcntlp)
-{
- boolean_t fd = !!(link_flags &
- (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
- boolean_t up = !!(link_flags &
- (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
-
- _NOTE(ARGUNUSED(enp))
-
- if (!up)
- *link_modep = EFX_LINK_DOWN;
- else if (speed == 40000 && fd)
- *link_modep = EFX_LINK_40000FDX;
- else if (speed == 10000 && fd)
- *link_modep = EFX_LINK_10000FDX;
- else if (speed == 1000)
- *link_modep = fd ? EFX_LINK_1000FDX : EFX_LINK_1000HDX;
- else if (speed == 100)
- *link_modep = fd ? EFX_LINK_100FDX : EFX_LINK_100HDX;
- else if (speed == 10)
- *link_modep = fd ? EFX_LINK_10FDX : EFX_LINK_10HDX;
- else
- *link_modep = EFX_LINK_UNKNOWN;
-
- if (fcntl == MC_CMD_FCNTL_OFF)
- *fcntlp = 0;
- else if (fcntl == MC_CMD_FCNTL_RESPOND)
- *fcntlp = EFX_FCNTL_RESPOND;
- else if (fcntl == MC_CMD_FCNTL_GENERATE)
- *fcntlp = EFX_FCNTL_GENERATE;
- else if (fcntl == MC_CMD_FCNTL_BIDIR)
- *fcntlp = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
- else {
- EFSYS_PROBE1(mc_pcol_error, int, fcntl);
- *fcntlp = 0;
- }
-}
-
-
- void
-ef10_phy_link_ev(
- __in efx_nic_t *enp,
- __in efx_qword_t *eqp,
- __out efx_link_mode_t *link_modep)
-{
- efx_port_t *epp = &(enp->en_port);
- unsigned int link_flags;
- unsigned int speed;
- unsigned int fcntl;
- efx_link_mode_t link_mode;
- uint32_t lp_cap_mask;
-
- /*
- * Convert the LINKCHANGE speed enumeration into mbit/s, in the
- * same way as GET_LINK encodes the speed
- */
- switch (MCDI_EV_FIELD(eqp, LINKCHANGE_SPEED)) {
- case MCDI_EVENT_LINKCHANGE_SPEED_100M:
- speed = 100;
- break;
- case MCDI_EVENT_LINKCHANGE_SPEED_1G:
- speed = 1000;
- break;
- case MCDI_EVENT_LINKCHANGE_SPEED_10G:
- speed = 10000;
- break;
- case MCDI_EVENT_LINKCHANGE_SPEED_40G:
- speed = 40000;
- break;
- default:
- speed = 0;
- break;
- }
-
- link_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS);
- mcdi_phy_decode_link_mode(enp, link_flags, speed,
- MCDI_EV_FIELD(eqp, LINKCHANGE_FCNTL),
- &link_mode, &fcntl);
- mcdi_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP),
- &lp_cap_mask);
-
- /*
- * It's safe to update ep_lp_cap_mask without the driver's port lock
- * because presumably any concurrently running efx_port_poll() is
- * only going to arrive at the same value.
- *
- * ep_fcntl has two meanings. It's either the link common fcntl
- * (if the PHY supports AN), or it's the forced link state. If
- * the former, it's safe to update the value for the same reason as
- * for ep_lp_cap_mask. If the latter, then just ignore the value,
- * because we can race with efx_mac_fcntl_set().
- */
- epp->ep_lp_cap_mask = lp_cap_mask;
- epp->ep_fcntl = fcntl;
-
- *link_modep = link_mode;
-}
-
- __checkReturn efx_rc_t
-ef10_phy_power(
- __in efx_nic_t *enp,
- __in boolean_t power)
-{
- efx_rc_t rc;
-
- if (!power)
- return (0);
-
- /* Check if the PHY is a zombie */
- if ((rc = ef10_phy_verify(enp)) != 0)
- goto fail1;
-
- enp->en_reset_flags |= EFX_RESET_PHY;
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_phy_get_link(
- __in efx_nic_t *enp,
- __out ef10_link_state_t *elsp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
- MC_CMD_GET_LINK_OUT_LEN)];
- efx_rc_t rc;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_GET_LINK;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN;
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP),
- &elsp->els_adv_cap_mask);
- mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP),
- &elsp->els_lp_cap_mask);
-
- mcdi_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS),
- MCDI_OUT_DWORD(req, GET_LINK_OUT_LINK_SPEED),
- MCDI_OUT_DWORD(req, GET_LINK_OUT_FCNTL),
- &elsp->els_link_mode, &elsp->els_fcntl);
-
-#if EFSYS_OPT_LOOPBACK
- /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
- EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
-
- elsp->els_loopback = MCDI_OUT_DWORD(req, GET_LINK_OUT_LOOPBACK_MODE);
-#endif /* EFSYS_OPT_LOOPBACK */
-
- elsp->els_mac_up = MCDI_OUT_DWORD(req, GET_LINK_OUT_MAC_FAULT) == 0;
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_phy_reconfigure(
- __in efx_nic_t *enp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_port_t *epp = &(enp->en_port);
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SET_LINK_IN_LEN,
- MC_CMD_SET_LINK_OUT_LEN)];
- uint32_t cap_mask;
- unsigned int led_mode;
- unsigned int speed;
- efx_rc_t rc;
-
- if (~encp->enc_func_flags & EFX_NIC_FUNC_LINKCTRL)
- goto out;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_SET_LINK;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_SET_LINK_OUT_LEN;
-
- cap_mask = epp->ep_adv_cap_mask;
- MCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP,
- PHY_CAP_10HDX, (cap_mask >> EFX_PHY_CAP_10HDX) & 0x1,
- PHY_CAP_10FDX, (cap_mask >> EFX_PHY_CAP_10FDX) & 0x1,
- PHY_CAP_100HDX, (cap_mask >> EFX_PHY_CAP_100HDX) & 0x1,
- PHY_CAP_100FDX, (cap_mask >> EFX_PHY_CAP_100FDX) & 0x1,
- PHY_CAP_1000HDX, (cap_mask >> EFX_PHY_CAP_1000HDX) & 0x1,
- PHY_CAP_1000FDX, (cap_mask >> EFX_PHY_CAP_1000FDX) & 0x1,
- PHY_CAP_10000FDX, (cap_mask >> EFX_PHY_CAP_10000FDX) & 0x1,
- PHY_CAP_PAUSE, (cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1,
- PHY_CAP_ASYM, (cap_mask >> EFX_PHY_CAP_ASYM) & 0x1,
- PHY_CAP_AN, (cap_mask >> EFX_PHY_CAP_AN) & 0x1);
- /* Too many fields for for POPULATE macros, so insert this afterwards */
- MCDI_IN_SET_DWORD_FIELD(req, SET_LINK_IN_CAP,
- PHY_CAP_40000FDX, (cap_mask >> EFX_PHY_CAP_40000FDX) & 0x1);
-
-#if EFSYS_OPT_LOOPBACK
- MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE,
- epp->ep_loopback_type);
- switch (epp->ep_loopback_link_mode) {
- case EFX_LINK_100FDX:
- speed = 100;
- break;
- case EFX_LINK_1000FDX:
- speed = 1000;
- break;
- case EFX_LINK_10000FDX:
- speed = 10000;
- break;
- case EFX_LINK_40000FDX:
- speed = 40000;
- break;
- default:
- speed = 0;
- }
-#else
- MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, MC_CMD_LOOPBACK_NONE);
- speed = 0;
-#endif /* EFSYS_OPT_LOOPBACK */
- MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed);
-
-#if EFSYS_OPT_PHY_FLAGS
- MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, epp->ep_phy_flags);
-#else
- MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0);
-#endif /* EFSYS_OPT_PHY_FLAGS */
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- /* And set the blink mode */
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_SET_ID_LED;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN;
-
-#if EFSYS_OPT_PHY_LED_CONTROL
- switch (epp->ep_phy_led_mode) {
- case EFX_PHY_LED_DEFAULT:
- led_mode = MC_CMD_LED_DEFAULT;
- break;
- case EFX_PHY_LED_OFF:
- led_mode = MC_CMD_LED_OFF;
- break;
- case EFX_PHY_LED_ON:
- led_mode = MC_CMD_LED_ON;
- break;
- default:
- EFSYS_ASSERT(0);
- led_mode = MC_CMD_LED_DEFAULT;
- }
-
- MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, led_mode);
-#else
- MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT);
-#endif /* EFSYS_OPT_PHY_LED_CONTROL */
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail2;
- }
-out:
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_phy_verify(
- __in efx_nic_t *enp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
- MC_CMD_GET_PHY_STATE_OUT_LEN)];
- uint32_t state;
- efx_rc_t rc;
-
- (void) memset(payload, 0, sizeof (payload));
- req.emr_cmd = MC_CMD_GET_PHY_STATE;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_PHY_STATE_OUT_LEN;
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_PHY_STATE_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- state = MCDI_OUT_DWORD(req, GET_PHY_STATE_OUT_STATE);
- if (state != MC_CMD_PHY_STATE_OK) {
- if (state != MC_CMD_PHY_STATE_ZOMBIE)
- EFSYS_PROBE1(mc_pcol_error, int, state);
- rc = ENOTACTIVE;
- goto fail3;
- }
-
- return (0);
-
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_phy_oui_get(
- __in efx_nic_t *enp,
- __out uint32_t *ouip)
-{
- _NOTE(ARGUNUSED(enp, ouip))
-
- return (ENOTSUP);
-}
-
-#if EFSYS_OPT_PHY_STATS
-
- __checkReturn efx_rc_t
-ef10_phy_stats_update(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp,
- __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
-{
- /* TBD: no stats support in firmware yet */
- _NOTE(ARGUNUSED(enp, esmp))
- memset(stat, 0, EFX_PHY_NSTATS * sizeof (*stat));
-
- return (0);
-}
-
-#endif /* EFSYS_OPT_PHY_STATS */
-
-#if EFSYS_OPT_PHY_PROPS
-
-#if EFSYS_OPT_NAMES
-
- const char *
-ef10_phy_prop_name(
- __in efx_nic_t *enp,
- __in unsigned int id)
-{
- _NOTE(ARGUNUSED(enp, id))
-
- return (NULL);
-}
-
-#endif /* EFSYS_OPT_NAMES */
-
- __checkReturn efx_rc_t
-ef10_phy_prop_get(
- __in efx_nic_t *enp,
- __in unsigned int id,
- __in uint32_t flags,
- __out uint32_t *valp)
-{
- _NOTE(ARGUNUSED(enp, id, flags, valp))
-
- return (ENOTSUP);
-}
-
- __checkReturn efx_rc_t
-ef10_phy_prop_set(
- __in efx_nic_t *enp,
- __in unsigned int id,
- __in uint32_t val)
-{
- _NOTE(ARGUNUSED(enp, id, val))
-
- return (ENOTSUP);
-}
-
-#endif /* EFSYS_OPT_PHY_PROPS */
-
#if EFSYS_OPT_BIST
__checkReturn efx_rc_t
OpenPOWER on IntegriCloud