New upstream version 18.11-rc1
[deb_dpdk.git] / drivers / net / sfc / base / ef10_nic.c
index 7dbf843..50e23b7 100644 (file)
@@ -20,15 +20,14 @@ efx_mcdi_get_port_assignment(
        __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_MCDI_DECLARE_BUF(payload, 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 ||
            enp->en_family == EFX_FAMILY_MEDFORD2);
 
-       (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;
@@ -63,18 +62,18 @@ fail1:
 efx_mcdi_get_port_modes(
        __in            efx_nic_t *enp,
        __out           uint32_t *modesp,
-       __out_opt       uint32_t *current_modep)
+       __out_opt       uint32_t *current_modep,
+       __out_opt       uint32_t *default_modep)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
-                           MC_CMD_GET_PORT_MODES_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, 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 ||
            enp->en_family == EFX_FAMILY_MEDFORD2);
 
-       (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;
@@ -110,6 +109,11 @@ efx_mcdi_get_port_modes(
                                            GET_PORT_MODES_OUT_CURRENT_MODE);
        }
 
+       if (default_modep != NULL) {
+               *default_modep = MCDI_OUT_DWORD(req,
+                                           GET_PORT_MODES_OUT_DEFAULT_MODE);
+       }
+
        return (0);
 
 fail3:
@@ -124,44 +128,99 @@ fail1:
 
        __checkReturn   efx_rc_t
 ef10_nic_get_port_mode_bandwidth(
-       __in            uint32_t port_mode,
+       __in            efx_nic_t *enp,
        __out           uint32_t *bandwidth_mbpsp)
 {
+       uint32_t port_modes;
+       uint32_t current_mode;
+       efx_port_t *epp = &(enp->en_port);
+
+       uint32_t single_lane;
+       uint32_t dual_lane;
+       uint32_t quad_lane;
        uint32_t bandwidth;
        efx_rc_t rc;
 
-       switch (port_mode) {
-       case TLV_PORT_MODE_10G:
-               bandwidth = 10000;
+       if ((rc = efx_mcdi_get_port_modes(enp, &port_modes,
+                                   &current_mode, NULL)) != 0) {
+               /* No port mode info available. */
+               goto fail1;
+       }
+
+       if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_25000FDX))
+               single_lane = 25000;
+       else
+               single_lane = 10000;
+
+       if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_50000FDX))
+               dual_lane = 50000;
+       else
+               dual_lane = 20000;
+
+       if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_100000FDX))
+               quad_lane = 100000;
+       else
+               quad_lane = 40000;
+
+       switch (current_mode) {
+       case TLV_PORT_MODE_1x1_NA:                      /* mode 0 */
+               bandwidth = single_lane;
+               break;
+       case TLV_PORT_MODE_1x2_NA:                      /* mode 10 */
+       case TLV_PORT_MODE_NA_1x2:                      /* mode 11 */
+               bandwidth = dual_lane;
+               break;
+       case TLV_PORT_MODE_1x1_1x1:                     /* mode 2 */
+               bandwidth = single_lane + single_lane;
+               break;
+       case TLV_PORT_MODE_4x1_NA:                      /* mode 4 */
+       case TLV_PORT_MODE_NA_4x1:                      /* mode 8 */
+               bandwidth = 4 * single_lane;
+               break;
+       case TLV_PORT_MODE_2x1_2x1:                     /* mode 5 */
+               bandwidth = (2 * single_lane) + (2 * single_lane);
+               break;
+       case TLV_PORT_MODE_1x2_1x2:                     /* mode 12 */
+               bandwidth = dual_lane + dual_lane;
+               break;
+       case TLV_PORT_MODE_1x2_2x1:                     /* mode 17 */
+       case TLV_PORT_MODE_2x1_1x2:                     /* mode 18 */
+               bandwidth = dual_lane + (2 * single_lane);
                break;
-       case TLV_PORT_MODE_10G_10G:
-               bandwidth = 10000 * 2;
+       /* Legacy Medford-only mode. Do not use (see bug63270) */
+       case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2:       /* mode 9 */
+               bandwidth = 4 * single_lane;
                break;
-       case TLV_PORT_MODE_10G_10G_10G_10G:
-       case TLV_PORT_MODE_10G_10G_10G_10G_Q:
-       case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2:
-       case TLV_PORT_MODE_10G_10G_10G_10G_Q2:
-               bandwidth = 10000 * 4;
+       case TLV_PORT_MODE_1x4_NA:                      /* mode 1 */
+       case TLV_PORT_MODE_NA_1x4:                      /* mode 22 */
+               bandwidth = quad_lane;
                break;
-       case TLV_PORT_MODE_40G:
-               bandwidth = 40000;
+       case TLV_PORT_MODE_2x2_NA:                      /* mode 13 */
+       case TLV_PORT_MODE_NA_2x2:                      /* mode 14 */
+               bandwidth = 2 * dual_lane;
                break;
-       case TLV_PORT_MODE_40G_40G:
-               bandwidth = 40000 * 2;
+       case TLV_PORT_MODE_1x4_2x1:                     /* mode 6 */
+       case TLV_PORT_MODE_2x1_1x4:                     /* mode 7 */
+               bandwidth = quad_lane + (2 * single_lane);
                break;
-       case TLV_PORT_MODE_40G_10G_10G:
-       case TLV_PORT_MODE_10G_10G_40G:
-               bandwidth = 40000 + (10000 * 2);
+       case TLV_PORT_MODE_1x4_1x2:                     /* mode 15 */
+       case TLV_PORT_MODE_1x2_1x4:                     /* mode 16 */
+               bandwidth = quad_lane + dual_lane;
+               break;
+       case TLV_PORT_MODE_1x4_1x4:                     /* mode 3 */
+               bandwidth = quad_lane + quad_lane;
                break;
        default:
                rc = EINVAL;
-               goto fail1;
+               goto fail2;
        }
 
        *bandwidth_mbpsp = bandwidth;
 
        return (0);
 
+fail2:
+       EFSYS_PROBE(fail2);
 fail1:
        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
@@ -174,13 +233,12 @@ efx_mcdi_vadaptor_alloc(
        __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_MCDI_DECLARE_BUF(payload, 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;
@@ -213,11 +271,10 @@ efx_mcdi_vadaptor_free(
        __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_MCDI_DECLARE_BUF(payload, 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;
@@ -247,15 +304,14 @@ efx_mcdi_get_mac_address_pf(
        __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_MCDI_DECLARE_BUF(payload, 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 ||
            enp->en_family == EFX_FAMILY_MEDFORD2);
 
-       (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;
@@ -306,15 +362,14 @@ efx_mcdi_get_mac_address_vf(
        __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_MCDI_DECLARE_BUF(payload, 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 ||
            enp->en_family == EFX_FAMILY_MEDFORD2);
 
-       (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;
@@ -371,15 +426,14 @@ efx_mcdi_get_clock(
        __out           uint32_t *dpcpu_freqp)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
-                           MC_CMD_GET_CLOCK_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, 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 ||
            enp->en_family == EFX_FAMILY_MEDFORD2);
 
-       (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;
@@ -429,12 +483,11 @@ efx_mcdi_get_rxdp_config(
        __out           uint32_t *end_paddingp)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_GET_RXDP_CONFIG_IN_LEN,
-                           MC_CMD_GET_RXDP_CONFIG_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RXDP_CONFIG_IN_LEN,
+               MC_CMD_GET_RXDP_CONFIG_OUT_LEN);
        uint32_t end_padding;
        efx_rc_t rc;
 
-       memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_GET_RXDP_CONFIG;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_GET_RXDP_CONFIG_IN_LEN;
@@ -489,11 +542,10 @@ efx_mcdi_get_vector_cfg(
        __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_MCDI_DECLARE_BUF(payload, 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;
@@ -539,8 +591,8 @@ efx_mcdi_alloc_vis(
        __out           uint32_t *vi_shiftp)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
-                           MC_CMD_ALLOC_VIS_EXT_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_VIS_IN_LEN,
+               MC_CMD_ALLOC_VIS_EXT_OUT_LEN);
        efx_rc_t rc;
 
        if (vi_countp == NULL) {
@@ -548,7 +600,6 @@ efx_mcdi_alloc_vis(
                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;
@@ -631,8 +682,8 @@ efx_mcdi_alloc_piobuf(
        __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_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_PIOBUF_IN_LEN,
+               MC_CMD_ALLOC_PIOBUF_OUT_LEN);
        efx_rc_t rc;
 
        if (handlep == NULL) {
@@ -640,7 +691,6 @@ efx_mcdi_alloc_piobuf(
                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;
@@ -679,11 +729,10 @@ efx_mcdi_free_piobuf(
        __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_MCDI_DECLARE_BUF(payload, 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;
@@ -714,11 +763,10 @@ efx_mcdi_link_piobuf(
        __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_MCDI_DECLARE_BUF(payload, 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;
@@ -749,11 +797,10 @@ efx_mcdi_unlink_piobuf(
        __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_MCDI_DECLARE_BUF(payload, 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;
@@ -806,7 +853,7 @@ 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);
+               (void) efx_mcdi_free_piobuf(enp, *handlep);
                *handlep = EFX_PIOBUF_HANDLE_INVALID;
        }
        enp->en_arch.ef10.ena_piobuf_count = 0;
@@ -823,7 +870,7 @@ ef10_nic_free_piobufs(
        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);
+               (void) efx_mcdi_free_piobuf(enp, *handlep);
                *handlep = EFX_PIOBUF_HANDLE_INVALID;
        }
        enp->en_arch.ef10.ena_piobuf_count = 0;
@@ -951,11 +998,10 @@ ef10_mcdi_get_pf_count(
        __out           uint32_t *pf_countp)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_GET_PF_COUNT_IN_LEN,
-                           MC_CMD_GET_PF_COUNT_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PF_COUNT_IN_LEN,
+               MC_CMD_GET_PF_COUNT_OUT_LEN);
        efx_rc_t rc;
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_GET_PF_COUNT;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN;
@@ -995,15 +1041,14 @@ ef10_get_datapath_caps(
 {
        efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
-                           MC_CMD_GET_CAPABILITIES_V5_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN,
+               MC_CMD_GET_CAPABILITIES_V5_OUT_LEN);
        efx_rc_t rc;
 
        if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0)
                goto fail1;
 
 
-       (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;
@@ -1041,11 +1086,13 @@ ef10_get_datapath_caps(
        }
        encp->enc_rx_prefix_size = 14;
 
+#if EFSYS_OPT_RX_SCALE
        /* Check if the firmware supports additional RSS modes */
        if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES))
                encp->enc_rx_scale_additional_modes_supported = B_TRUE;
        else
                encp->enc_rx_scale_additional_modes_supported = B_FALSE;
+#endif /* EFSYS_OPT_RX_SCALE */
 
        /* Check if the firmware supports TSO */
        if (CAP_FLAGS1(req, TX_TSO))
@@ -1251,6 +1298,7 @@ ef10_get_datapath_caps(
        else
                encp->enc_hlb_counters = B_FALSE;
 
+#if EFSYS_OPT_RX_SCALE
        if (CAP_FLAGS1(req, RX_RSS_LIMITED)) {
                /* Only one exclusive RSS context is available per port. */
                encp->enc_rx_scale_max_exclusive_contexts = 1;
@@ -1300,6 +1348,8 @@ ef10_get_datapath_caps(
                 */
                encp->enc_rx_scale_l4_hash_supported = B_TRUE;
        }
+#endif /* EFSYS_OPT_RX_SCALE */
+
        /* Check if the firmware supports "FLAG" and "MARK" filter actions */
        if (CAP_FLAGS2(req, FILTER_ACTION_FLAG))
                encp->enc_filter_action_flag_supported = B_TRUE;
@@ -1323,8 +1373,10 @@ ef10_get_datapath_caps(
 
        return (0);
 
+#if EFSYS_OPT_RX_SCALE
 fail5:
        EFSYS_PROBE(fail5);
+#endif /* EFSYS_OPT_RX_SCALE */
 fail4:
        EFSYS_PROBE(fail4);
 fail3:
@@ -1478,8 +1530,8 @@ static struct ef10_external_port_map_s {
         */
        {
                EFX_FAMILY_MEDFORD,
-               (1U << TLV_PORT_MODE_10G) |                     /* mode 0 */
-               (1U << TLV_PORT_MODE_10G_10G),                  /* mode 2 */
+               (1U << TLV_PORT_MODE_1x1_NA) |                  /* mode 0 */
+               (1U << TLV_PORT_MODE_1x1_1x1),                  /* mode 2 */
                1,      /* ports per cage */
                1       /* first cage */
        },
@@ -1493,10 +1545,10 @@ static struct ef10_external_port_map_s {
         */
        {
                EFX_FAMILY_MEDFORD,
-               (1U << TLV_PORT_MODE_40G) |                     /* mode 1 */
-               (1U << TLV_PORT_MODE_40G_40G) |                 /* mode 3 */
-               (1U << TLV_PORT_MODE_40G_10G_10G) |             /* mode 6 */
-               (1U << TLV_PORT_MODE_10G_10G_40G) |             /* mode 7 */
+               (1U << TLV_PORT_MODE_1x4_NA) |                  /* mode 1 */
+               (1U << TLV_PORT_MODE_1x4_1x4) |                 /* mode 3 */
+               (1U << TLV_PORT_MODE_1x4_2x1) |                 /* mode 6 */
+               (1U << TLV_PORT_MODE_2x1_1x4) |                 /* mode 7 */
                /* Do not use 10G_10G_10G_10G_Q1_Q2 (see bug63270) */
                (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2),    /* mode 9 */
                2,      /* ports per cage */
@@ -1512,9 +1564,9 @@ static struct ef10_external_port_map_s {
         */
        {
                EFX_FAMILY_MEDFORD,
-               (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q) |       /* mode 5 */
+               (1U << TLV_PORT_MODE_2x1_2x1) |                 /* mode 5 */
                /* Do not use 10G_10G_10G_10G_Q1 (see bug63270) */
-               (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1),       /* mode 4 */
+               (1U << TLV_PORT_MODE_4x1_NA),                   /* mode 4 */
                4,      /* ports per cage */
                1       /* first cage */
        },
@@ -1528,7 +1580,7 @@ static struct ef10_external_port_map_s {
         */
        {
                EFX_FAMILY_MEDFORD,
-               (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q2),       /* mode 8 */
+               (1U << TLV_PORT_MODE_NA_4x1),                   /* mode 8 */
                4,      /* ports per cage */
                2       /* first cage */
        },
@@ -1635,13 +1687,14 @@ ef10_external_port_mapping(
        int32_t count = 1; /* Default 1-1 mapping */
        int32_t offset = 1; /* Default starting external port number */
 
-       if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, &current)) != 0) {
+       if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, &current,
+                   NULL)) != 0) {
                /*
                 * No current port mode information (i.e. Huntington)
                 * - infer mapping from available modes
                 */
                if ((rc = efx_mcdi_get_port_modes(enp,
-                           &port_modes, NULL)) != 0) {
+                           &port_modes, NULL, NULL)) != 0) {
                        /*
                         * No port mode information available
                         * - use default mapping
@@ -1781,11 +1834,26 @@ ef10_nic_board_cfg(
        if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
                goto fail6;
 
+       /*
+        * Firmware with support for *_FEC capability bits does not
+        * report that the corresponding *_FEC_REQUESTED bits are supported.
+        * Add them here so that drivers understand that they are supported.
+        */
+       if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_BASER_FEC))
+               epp->ep_phy_cap_mask |=
+                   (1u << EFX_PHY_CAP_BASER_FEC_REQUESTED);
+       if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_RS_FEC))
+               epp->ep_phy_cap_mask |=
+                   (1u << EFX_PHY_CAP_RS_FEC_REQUESTED);
+       if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_25G_BASER_FEC))
+               epp->ep_phy_cap_mask |=
+                   (1u << EFX_PHY_CAP_25G_BASER_FEC_REQUESTED);
+
        /* Obtain the default PHY advertised capabilities */
        if ((rc = ef10_phy_get_link(enp, &els)) != 0)
                goto fail7;
-       epp->ep_default_adv_cap_mask = els.els_adv_cap_mask;
-       epp->ep_adv_cap_mask = els.els_adv_cap_mask;
+       epp->ep_default_adv_cap_mask = els.epls.epls_adv_cap_mask;
+       epp->ep_adv_cap_mask = els.epls.epls_adv_cap_mask;
 
        /* Check capabilities of running datapath firmware */
        if ((rc = ef10_get_datapath_caps(enp)) != 0)
@@ -2039,8 +2107,8 @@ 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_MCDI_DECLARE_BUF(payload, 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. */
@@ -2049,7 +2117,6 @@ ef10_nic_reset(
        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;
@@ -2314,6 +2381,36 @@ fail1:
        return (rc);
 }
 
+       __checkReturn   boolean_t
+ef10_nic_hw_unavailable(
+       __in            efx_nic_t *enp)
+{
+       efx_dword_t dword;
+
+       if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL)
+               return (B_TRUE);
+
+       EFX_BAR_READD(enp, ER_DZ_BIU_MC_SFT_STATUS_REG, &dword, B_FALSE);
+       if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff)
+               goto unavail;
+
+       return (B_FALSE);
+
+unavail:
+       ef10_nic_set_hw_unavailable(enp);
+
+       return (B_TRUE);
+}
+
+                       void
+ef10_nic_set_hw_unavailable(
+       __in            efx_nic_t *enp)
+{
+       EFSYS_PROBE(hw_unavail);
+       enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
+}
+
+
                        void
 ef10_nic_fini(
        __in            efx_nic_t *enp)
@@ -2386,11 +2483,10 @@ efx_mcdi_get_nic_global(
        __out           uint32_t *valuep)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MAX(MC_CMD_GET_NIC_GLOBAL_IN_LEN,
-                           MC_CMD_GET_NIC_GLOBAL_OUT_LEN)];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_NIC_GLOBAL_IN_LEN,
+               MC_CMD_GET_NIC_GLOBAL_OUT_LEN);
        efx_rc_t rc;
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_GET_NIC_GLOBAL;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_GET_NIC_GLOBAL_IN_LEN;
@@ -2430,10 +2526,9 @@ efx_mcdi_set_nic_global(
        __in            uint32_t value)
 {
        efx_mcdi_req_t req;
-       uint8_t payload[MC_CMD_SET_NIC_GLOBAL_IN_LEN];
+       EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_NIC_GLOBAL_IN_LEN, 0);
        efx_rc_t rc;
 
-       (void) memset(payload, 0, sizeof (payload));
        req.emr_cmd = MC_CMD_SET_NIC_GLOBAL;
        req.emr_in_buf = payload;
        req.emr_in_length = MC_CMD_SET_NIC_GLOBAL_IN_LEN;