Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /****************************************************************************
0003  * Driver for Solarflare network controllers and boards
0004  * Copyright 2018 Solarflare Communications Inc.
0005  *
0006  * This program is free software; you can redistribute it and/or modify it
0007  * under the terms of the GNU General Public License version 2 as published
0008  * by the Free Software Foundation, incorporated herein by reference.
0009  */
0010 
0011 #include "mcdi_port_common.h"
0012 #include "efx_common.h"
0013 #include "nic.h"
0014 
0015 int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg)
0016 {
0017     MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN);
0018     size_t outlen;
0019     int rc;
0020 
0021     BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_IN_LEN != 0);
0022     BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_OUT_NAME_LEN != sizeof(cfg->name));
0023 
0024     rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0,
0025               outbuf, sizeof(outbuf), &outlen);
0026     if (rc)
0027         goto fail;
0028 
0029     if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) {
0030         rc = -EIO;
0031         goto fail;
0032     }
0033 
0034     cfg->flags = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_FLAGS);
0035     cfg->type = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_TYPE);
0036     cfg->supported_cap =
0037         MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_SUPPORTED_CAP);
0038     cfg->channel = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_CHANNEL);
0039     cfg->port = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_PRT);
0040     cfg->stats_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_STATS_MASK);
0041     memcpy(cfg->name, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_NAME),
0042            sizeof(cfg->name));
0043     cfg->media = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MEDIA_TYPE);
0044     cfg->mmd_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MMD_MASK);
0045     memcpy(cfg->revision, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_REVISION),
0046            sizeof(cfg->revision));
0047 
0048     return 0;
0049 
0050 fail:
0051     netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
0052     return rc;
0053 }
0054 
0055 void efx_link_set_advertising(struct efx_nic *efx,
0056                   const unsigned long *advertising)
0057 {
0058     memcpy(efx->link_advertising, advertising,
0059            sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
0060 
0061     efx->link_advertising[0] |= ADVERTISED_Autoneg;
0062     if (advertising[0] & ADVERTISED_Pause)
0063         efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX);
0064     else
0065         efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
0066     if (advertising[0] & ADVERTISED_Asym_Pause)
0067         efx->wanted_fc ^= EFX_FC_TX;
0068 }
0069 
0070 int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
0071               u32 flags, u32 loopback_mode, u32 loopback_speed)
0072 {
0073     MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_LINK_IN_LEN);
0074 
0075     BUILD_BUG_ON(MC_CMD_SET_LINK_OUT_LEN != 0);
0076 
0077     MCDI_SET_DWORD(inbuf, SET_LINK_IN_CAP, capabilities);
0078     MCDI_SET_DWORD(inbuf, SET_LINK_IN_FLAGS, flags);
0079     MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_MODE, loopback_mode);
0080     MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_SPEED, loopback_speed);
0081 
0082     return efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
0083               NULL, 0, NULL);
0084 }
0085 
0086 int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
0087 {
0088     MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LOOPBACK_MODES_OUT_LEN);
0089     size_t outlen;
0090     int rc;
0091 
0092     rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0,
0093               outbuf, sizeof(outbuf), &outlen);
0094     if (rc)
0095         goto fail;
0096 
0097     if (outlen < (MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
0098               MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN)) {
0099         rc = -EIO;
0100         goto fail;
0101     }
0102 
0103     *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED);
0104 
0105     return 0;
0106 
0107 fail:
0108     netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
0109     return rc;
0110 }
0111 
0112 void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset)
0113 {
0114     #define SET_BIT(name)   __set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
0115                       linkset)
0116 
0117     bitmap_zero(linkset, __ETHTOOL_LINK_MODE_MASK_NBITS);
0118     switch (media) {
0119     case MC_CMD_MEDIA_KX4:
0120         SET_BIT(Backplane);
0121         if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
0122             SET_BIT(1000baseKX_Full);
0123         if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
0124             SET_BIT(10000baseKX4_Full);
0125         if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
0126             SET_BIT(40000baseKR4_Full);
0127         break;
0128 
0129     case MC_CMD_MEDIA_XFP:
0130     case MC_CMD_MEDIA_SFP_PLUS:
0131     case MC_CMD_MEDIA_QSFP_PLUS:
0132         SET_BIT(FIBRE);
0133         if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) {
0134             SET_BIT(1000baseT_Full);
0135             SET_BIT(1000baseX_Full);
0136         }
0137         if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) {
0138             SET_BIT(10000baseCR_Full);
0139             SET_BIT(10000baseLR_Full);
0140             SET_BIT(10000baseSR_Full);
0141         }
0142         if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) {
0143             SET_BIT(40000baseCR4_Full);
0144             SET_BIT(40000baseSR4_Full);
0145         }
0146         if (cap & (1 << MC_CMD_PHY_CAP_100000FDX_LBN)) {
0147             SET_BIT(100000baseCR4_Full);
0148             SET_BIT(100000baseSR4_Full);
0149         }
0150         if (cap & (1 << MC_CMD_PHY_CAP_25000FDX_LBN)) {
0151             SET_BIT(25000baseCR_Full);
0152             SET_BIT(25000baseSR_Full);
0153         }
0154         if (cap & (1 << MC_CMD_PHY_CAP_50000FDX_LBN))
0155             SET_BIT(50000baseCR2_Full);
0156         break;
0157 
0158     case MC_CMD_MEDIA_BASE_T:
0159         SET_BIT(TP);
0160         if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
0161             SET_BIT(10baseT_Half);
0162         if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
0163             SET_BIT(10baseT_Full);
0164         if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
0165             SET_BIT(100baseT_Half);
0166         if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
0167             SET_BIT(100baseT_Full);
0168         if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
0169             SET_BIT(1000baseT_Half);
0170         if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
0171             SET_BIT(1000baseT_Full);
0172         if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
0173             SET_BIT(10000baseT_Full);
0174         break;
0175     }
0176 
0177     if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
0178         SET_BIT(Pause);
0179     if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
0180         SET_BIT(Asym_Pause);
0181     if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
0182         SET_BIT(Autoneg);
0183 
0184     #undef SET_BIT
0185 }
0186 
0187 u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset)
0188 {
0189     u32 result = 0;
0190 
0191     #define TEST_BIT(name)  test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
0192                      linkset)
0193 
0194     if (TEST_BIT(10baseT_Half))
0195         result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN);
0196     if (TEST_BIT(10baseT_Full))
0197         result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN);
0198     if (TEST_BIT(100baseT_Half))
0199         result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN);
0200     if (TEST_BIT(100baseT_Full))
0201         result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN);
0202     if (TEST_BIT(1000baseT_Half))
0203         result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN);
0204     if (TEST_BIT(1000baseT_Full) || TEST_BIT(1000baseKX_Full) ||
0205             TEST_BIT(1000baseX_Full))
0206         result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN);
0207     if (TEST_BIT(10000baseT_Full) || TEST_BIT(10000baseKX4_Full) ||
0208             TEST_BIT(10000baseCR_Full) || TEST_BIT(10000baseLR_Full) ||
0209             TEST_BIT(10000baseSR_Full))
0210         result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN);
0211     if (TEST_BIT(40000baseCR4_Full) || TEST_BIT(40000baseKR4_Full) ||
0212             TEST_BIT(40000baseSR4_Full))
0213         result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN);
0214     if (TEST_BIT(100000baseCR4_Full) || TEST_BIT(100000baseSR4_Full))
0215         result |= (1 << MC_CMD_PHY_CAP_100000FDX_LBN);
0216     if (TEST_BIT(25000baseCR_Full) || TEST_BIT(25000baseSR_Full))
0217         result |= (1 << MC_CMD_PHY_CAP_25000FDX_LBN);
0218     if (TEST_BIT(50000baseCR2_Full))
0219         result |= (1 << MC_CMD_PHY_CAP_50000FDX_LBN);
0220     if (TEST_BIT(Pause))
0221         result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN);
0222     if (TEST_BIT(Asym_Pause))
0223         result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN);
0224     if (TEST_BIT(Autoneg))
0225         result |= (1 << MC_CMD_PHY_CAP_AN_LBN);
0226 
0227     #undef TEST_BIT
0228 
0229     return result;
0230 }
0231 
0232 u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
0233 {
0234     struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
0235     enum efx_phy_mode mode, supported;
0236     u32 flags;
0237 
0238     /* TODO: Advertise the capabilities supported by this PHY */
0239     supported = 0;
0240     if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN))
0241         supported |= PHY_MODE_TX_DISABLED;
0242     if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN))
0243         supported |= PHY_MODE_LOW_POWER;
0244     if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN))
0245         supported |= PHY_MODE_OFF;
0246 
0247     mode = efx->phy_mode & supported;
0248 
0249     flags = 0;
0250     if (mode & PHY_MODE_TX_DISABLED)
0251         flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN);
0252     if (mode & PHY_MODE_LOW_POWER)
0253         flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN);
0254     if (mode & PHY_MODE_OFF)
0255         flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN);
0256 
0257     return flags;
0258 }
0259 
0260 u8 mcdi_to_ethtool_media(u32 media)
0261 {
0262     switch (media) {
0263     case MC_CMD_MEDIA_XAUI:
0264     case MC_CMD_MEDIA_CX4:
0265     case MC_CMD_MEDIA_KX4:
0266         return PORT_OTHER;
0267 
0268     case MC_CMD_MEDIA_XFP:
0269     case MC_CMD_MEDIA_SFP_PLUS:
0270     case MC_CMD_MEDIA_QSFP_PLUS:
0271         return PORT_FIBRE;
0272 
0273     case MC_CMD_MEDIA_BASE_T:
0274         return PORT_TP;
0275 
0276     default:
0277         return PORT_OTHER;
0278     }
0279 }
0280 
0281 void efx_mcdi_phy_decode_link(struct efx_nic *efx,
0282                   struct efx_link_state *link_state,
0283                   u32 speed, u32 flags, u32 fcntl)
0284 {
0285     switch (fcntl) {
0286     case MC_CMD_FCNTL_AUTO:
0287         WARN_ON(1); /* This is not a link mode */
0288         link_state->fc = EFX_FC_AUTO | EFX_FC_TX | EFX_FC_RX;
0289         break;
0290     case MC_CMD_FCNTL_BIDIR:
0291         link_state->fc = EFX_FC_TX | EFX_FC_RX;
0292         break;
0293     case MC_CMD_FCNTL_RESPOND:
0294         link_state->fc = EFX_FC_RX;
0295         break;
0296     default:
0297         WARN_ON(1);
0298         fallthrough;
0299     case MC_CMD_FCNTL_OFF:
0300         link_state->fc = 0;
0301         break;
0302     }
0303 
0304     link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
0305     link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
0306     link_state->speed = speed;
0307 }
0308 
0309 /* The semantics of the ethtool FEC mode bitmask are not well defined,
0310  * particularly the meaning of combinations of bits.  Which means we get to
0311  * define our own semantics, as follows:
0312  * OFF overrides any other bits, and means "disable all FEC" (with the
0313  * exception of 25G KR4/CR4, where it is not possible to reject it if AN
0314  * partner requests it).
0315  * AUTO on its own means use cable requirements and link partner autoneg with
0316  * fw-default preferences for the cable type.
0317  * AUTO and either RS or BASER means use the specified FEC type if cable and
0318  * link partner support it, otherwise autoneg/fw-default.
0319  * RS or BASER alone means use the specified FEC type if cable and link partner
0320  * support it and either requests it, otherwise no FEC.
0321  * Both RS and BASER (whether AUTO or not) means use FEC if cable and link
0322  * partner support it, preferring RS to BASER.
0323  */
0324 u32 ethtool_fec_caps_to_mcdi(u32 supported_cap, u32 ethtool_cap)
0325 {
0326     u32 ret = 0;
0327 
0328     if (ethtool_cap & ETHTOOL_FEC_OFF)
0329         return 0;
0330 
0331     if (ethtool_cap & ETHTOOL_FEC_AUTO)
0332         ret |= ((1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
0333             (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
0334             (1 << MC_CMD_PHY_CAP_RS_FEC_LBN)) & supported_cap;
0335     if (ethtool_cap & ETHTOOL_FEC_RS &&
0336         supported_cap & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN))
0337         ret |= (1 << MC_CMD_PHY_CAP_RS_FEC_LBN) |
0338                (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN);
0339     if (ethtool_cap & ETHTOOL_FEC_BASER) {
0340         if (supported_cap & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN))
0341             ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
0342                    (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
0343         if (supported_cap & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN))
0344             ret |= (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
0345                    (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN);
0346     }
0347     return ret;
0348 }
0349 
0350 /* Invert ethtool_fec_caps_to_mcdi.  There are two combinations that function
0351  * can never produce, (baser xor rs) and neither req; the implementation below
0352  * maps both of those to AUTO.  This should never matter, and it's not clear
0353  * what a better mapping would be anyway.
0354  */
0355 u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g)
0356 {
0357     bool rs = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN),
0358          rs_req = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN),
0359          baser = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN)
0360                 : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN),
0361          baser_req = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN)
0362                 : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
0363 
0364     if (!baser && !rs)
0365         return ETHTOOL_FEC_OFF;
0366     return (rs_req ? ETHTOOL_FEC_RS : 0) |
0367            (baser_req ? ETHTOOL_FEC_BASER : 0) |
0368            (baser == baser_req && rs == rs_req ? 0 : ETHTOOL_FEC_AUTO);
0369 }
0370 
0371 /* Verify that the forced flow control settings (!EFX_FC_AUTO) are
0372  * supported by the link partner. Warn the user if this isn't the case
0373  */
0374 void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa)
0375 {
0376     struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
0377     u32 rmtadv;
0378 
0379     /* The link partner capabilities are only relevant if the
0380      * link supports flow control autonegotiation
0381      */
0382     if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
0383         return;
0384 
0385     /* If flow control autoneg is supported and enabled, then fine */
0386     if (efx->wanted_fc & EFX_FC_AUTO)
0387         return;
0388 
0389     rmtadv = 0;
0390     if (lpa & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
0391         rmtadv |= ADVERTISED_Pause;
0392     if (lpa & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
0393         rmtadv |=  ADVERTISED_Asym_Pause;
0394 
0395     if ((efx->wanted_fc & EFX_FC_TX) && rmtadv == ADVERTISED_Asym_Pause)
0396         netif_err(efx, link, efx->net_dev,
0397               "warning: link partner doesn't support pause frames");
0398 }
0399 
0400 bool efx_mcdi_phy_poll(struct efx_nic *efx)
0401 {
0402     struct efx_link_state old_state = efx->link_state;
0403     MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
0404     int rc;
0405 
0406     WARN_ON(!mutex_is_locked(&efx->mac_lock));
0407 
0408     BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
0409 
0410     rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
0411               outbuf, sizeof(outbuf), NULL);
0412     if (rc)
0413         efx->link_state.up = false;
0414     else
0415         efx_mcdi_phy_decode_link(
0416             efx, &efx->link_state,
0417             MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
0418             MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
0419             MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
0420 
0421     return !efx_link_state_equal(&efx->link_state, &old_state);
0422 }
0423 
0424 int efx_mcdi_phy_probe(struct efx_nic *efx)
0425 {
0426     struct efx_mcdi_phy_data *phy_data;
0427     MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
0428     u32 caps;
0429     int rc;
0430 
0431     /* Initialise and populate phy_data */
0432     phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
0433     if (phy_data == NULL)
0434         return -ENOMEM;
0435 
0436     rc = efx_mcdi_get_phy_cfg(efx, phy_data);
0437     if (rc != 0)
0438         goto fail;
0439 
0440     /* Read initial link advertisement */
0441     BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
0442     rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
0443               outbuf, sizeof(outbuf), NULL);
0444     if (rc)
0445         goto fail;
0446 
0447     /* Fill out nic state */
0448     efx->phy_data = phy_data;
0449     efx->phy_type = phy_data->type;
0450 
0451     efx->mdio_bus = phy_data->channel;
0452     efx->mdio.prtad = phy_data->port;
0453     efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
0454     efx->mdio.mode_support = 0;
0455     if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
0456         efx->mdio.mode_support |= MDIO_SUPPORTS_C22;
0457     if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
0458         efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
0459 
0460     caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
0461     if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
0462         mcdi_to_ethtool_linkset(phy_data->media, caps,
0463                     efx->link_advertising);
0464     else
0465         phy_data->forced_cap = caps;
0466 
0467     /* Assert that we can map efx -> mcdi loopback modes */
0468     BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE);
0469     BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA);
0470     BUILD_BUG_ON(LOOPBACK_GMAC != MC_CMD_LOOPBACK_GMAC);
0471     BUILD_BUG_ON(LOOPBACK_XGMII != MC_CMD_LOOPBACK_XGMII);
0472     BUILD_BUG_ON(LOOPBACK_XGXS != MC_CMD_LOOPBACK_XGXS);
0473     BUILD_BUG_ON(LOOPBACK_XAUI != MC_CMD_LOOPBACK_XAUI);
0474     BUILD_BUG_ON(LOOPBACK_GMII != MC_CMD_LOOPBACK_GMII);
0475     BUILD_BUG_ON(LOOPBACK_SGMII != MC_CMD_LOOPBACK_SGMII);
0476     BUILD_BUG_ON(LOOPBACK_XGBR != MC_CMD_LOOPBACK_XGBR);
0477     BUILD_BUG_ON(LOOPBACK_XFI != MC_CMD_LOOPBACK_XFI);
0478     BUILD_BUG_ON(LOOPBACK_XAUI_FAR != MC_CMD_LOOPBACK_XAUI_FAR);
0479     BUILD_BUG_ON(LOOPBACK_GMII_FAR != MC_CMD_LOOPBACK_GMII_FAR);
0480     BUILD_BUG_ON(LOOPBACK_SGMII_FAR != MC_CMD_LOOPBACK_SGMII_FAR);
0481     BUILD_BUG_ON(LOOPBACK_XFI_FAR != MC_CMD_LOOPBACK_XFI_FAR);
0482     BUILD_BUG_ON(LOOPBACK_GPHY != MC_CMD_LOOPBACK_GPHY);
0483     BUILD_BUG_ON(LOOPBACK_PHYXS != MC_CMD_LOOPBACK_PHYXS);
0484     BUILD_BUG_ON(LOOPBACK_PCS != MC_CMD_LOOPBACK_PCS);
0485     BUILD_BUG_ON(LOOPBACK_PMAPMD != MC_CMD_LOOPBACK_PMAPMD);
0486     BUILD_BUG_ON(LOOPBACK_XPORT != MC_CMD_LOOPBACK_XPORT);
0487     BUILD_BUG_ON(LOOPBACK_XGMII_WS != MC_CMD_LOOPBACK_XGMII_WS);
0488     BUILD_BUG_ON(LOOPBACK_XAUI_WS != MC_CMD_LOOPBACK_XAUI_WS);
0489     BUILD_BUG_ON(LOOPBACK_XAUI_WS_FAR != MC_CMD_LOOPBACK_XAUI_WS_FAR);
0490     BUILD_BUG_ON(LOOPBACK_XAUI_WS_NEAR != MC_CMD_LOOPBACK_XAUI_WS_NEAR);
0491     BUILD_BUG_ON(LOOPBACK_GMII_WS != MC_CMD_LOOPBACK_GMII_WS);
0492     BUILD_BUG_ON(LOOPBACK_XFI_WS != MC_CMD_LOOPBACK_XFI_WS);
0493     BUILD_BUG_ON(LOOPBACK_XFI_WS_FAR != MC_CMD_LOOPBACK_XFI_WS_FAR);
0494     BUILD_BUG_ON(LOOPBACK_PHYXS_WS != MC_CMD_LOOPBACK_PHYXS_WS);
0495 
0496     rc = efx_mcdi_loopback_modes(efx, &efx->loopback_modes);
0497     if (rc != 0)
0498         goto fail;
0499     /* The MC indicates that LOOPBACK_NONE is a valid loopback mode,
0500      * but by convention we don't
0501      */
0502     efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
0503 
0504     /* Set the initial link mode */
0505     efx_mcdi_phy_decode_link(efx, &efx->link_state,
0506                  MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
0507                  MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
0508                  MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
0509 
0510     /* Record the initial FEC configuration (or nearest approximation
0511      * representable in the ethtool configuration space)
0512      */
0513     efx->fec_config = mcdi_fec_caps_to_ethtool(caps,
0514                            efx->link_state.speed == 25000 ||
0515                            efx->link_state.speed == 50000);
0516 
0517     /* Default to Autonegotiated flow control if the PHY supports it */
0518     efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
0519     if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
0520         efx->wanted_fc |= EFX_FC_AUTO;
0521     efx_link_set_wanted_fc(efx, efx->wanted_fc);
0522 
0523     return 0;
0524 
0525 fail:
0526     kfree(phy_data);
0527     return rc;
0528 }
0529 
0530 void efx_mcdi_phy_remove(struct efx_nic *efx)
0531 {
0532     struct efx_mcdi_phy_data *phy_data = efx->phy_data;
0533 
0534     efx->phy_data = NULL;
0535     kfree(phy_data);
0536 }
0537 
0538 void efx_mcdi_phy_get_link_ksettings(struct efx_nic *efx, struct ethtool_link_ksettings *cmd)
0539 {
0540     struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
0541     MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
0542     int rc;
0543 
0544     cmd->base.speed = efx->link_state.speed;
0545     cmd->base.duplex = efx->link_state.fd;
0546     cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media);
0547     cmd->base.phy_address = phy_cfg->port;
0548     cmd->base.autoneg = !!(efx->link_advertising[0] & ADVERTISED_Autoneg);
0549     cmd->base.mdio_support = (efx->mdio.mode_support &
0550                   (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
0551 
0552     mcdi_to_ethtool_linkset(phy_cfg->media, phy_cfg->supported_cap,
0553                 cmd->link_modes.supported);
0554     memcpy(cmd->link_modes.advertising, efx->link_advertising,
0555            sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
0556 
0557     BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
0558     rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
0559               outbuf, sizeof(outbuf), NULL);
0560     if (rc)
0561         return;
0562     mcdi_to_ethtool_linkset(phy_cfg->media,
0563                 MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP),
0564                 cmd->link_modes.lp_advertising);
0565 }
0566 
0567 int efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx, const struct ethtool_link_ksettings *cmd)
0568 {
0569     struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
0570     u32 caps;
0571     int rc;
0572 
0573     if (cmd->base.autoneg) {
0574         caps = (ethtool_linkset_to_mcdi_cap(cmd->link_modes.advertising) |
0575             1 << MC_CMD_PHY_CAP_AN_LBN);
0576     } else if (cmd->base.duplex) {
0577         switch (cmd->base.speed) {
0578         case 10:     caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN;     break;
0579         case 100:    caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN;    break;
0580         case 1000:   caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN;   break;
0581         case 10000:  caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN;  break;
0582         case 40000:  caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN;  break;
0583         case 100000: caps = 1 << MC_CMD_PHY_CAP_100000FDX_LBN; break;
0584         case 25000:  caps = 1 << MC_CMD_PHY_CAP_25000FDX_LBN;  break;
0585         case 50000:  caps = 1 << MC_CMD_PHY_CAP_50000FDX_LBN;  break;
0586         default:     return -EINVAL;
0587         }
0588     } else {
0589         switch (cmd->base.speed) {
0590         case 10:     caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN;     break;
0591         case 100:    caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN;    break;
0592         case 1000:   caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN;   break;
0593         default:     return -EINVAL;
0594         }
0595     }
0596 
0597     caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, efx->fec_config);
0598 
0599     rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
0600                    efx->loopback_mode, 0);
0601     if (rc)
0602         return rc;
0603 
0604     if (cmd->base.autoneg) {
0605         efx_link_set_advertising(efx, cmd->link_modes.advertising);
0606         phy_cfg->forced_cap = 0;
0607     } else {
0608         efx_link_clear_advertising(efx);
0609         phy_cfg->forced_cap = caps;
0610     }
0611     return 0;
0612 }
0613 
0614 int efx_mcdi_phy_get_fecparam(struct efx_nic *efx, struct ethtool_fecparam *fec)
0615 {
0616     MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN);
0617     u32 caps, active, speed; /* MCDI format */
0618     bool is_25g = false;
0619     size_t outlen;
0620     int rc;
0621 
0622     BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
0623     rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
0624               outbuf, sizeof(outbuf), &outlen);
0625     if (rc)
0626         return rc;
0627     if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN)
0628         return -EOPNOTSUPP;
0629 
0630     /* behaviour for 25G/50G links depends on 25G BASER bit */
0631     speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED);
0632     is_25g = speed == 25000 || speed == 50000;
0633 
0634     caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP);
0635     fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g);
0636     /* BASER is never supported on 100G */
0637     if (speed == 100000)
0638         fec->fec &= ~ETHTOOL_FEC_BASER;
0639 
0640     active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE);
0641     switch (active) {
0642     case MC_CMD_FEC_NONE:
0643         fec->active_fec = ETHTOOL_FEC_OFF;
0644         break;
0645     case MC_CMD_FEC_BASER:
0646         fec->active_fec = ETHTOOL_FEC_BASER;
0647         break;
0648     case MC_CMD_FEC_RS:
0649         fec->active_fec = ETHTOOL_FEC_RS;
0650         break;
0651     default:
0652         netif_warn(efx, hw, efx->net_dev,
0653                "Firmware reports unrecognised FEC_TYPE %u\n",
0654                active);
0655         /* We don't know what firmware has picked.  AUTO is as good a
0656          * "can't happen" value as any other.
0657          */
0658         fec->active_fec = ETHTOOL_FEC_AUTO;
0659         break;
0660     }
0661 
0662     return 0;
0663 }
0664 
0665 /* Basic validation to ensure that the caps we are going to attempt to set are
0666  * in fact supported by the adapter.  Note that 'no FEC' is always supported.
0667  */
0668 static int ethtool_fec_supported(u32 supported_cap, u32 ethtool_cap)
0669 {
0670     if (ethtool_cap & ETHTOOL_FEC_OFF)
0671         return 0;
0672 
0673     if (ethtool_cap &&
0674         !ethtool_fec_caps_to_mcdi(supported_cap, ethtool_cap))
0675         return -EINVAL;
0676     return 0;
0677 }
0678 
0679 int efx_mcdi_phy_set_fecparam(struct efx_nic *efx, const struct ethtool_fecparam *fec)
0680 {
0681     struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
0682     u32 caps;
0683     int rc;
0684 
0685     rc = ethtool_fec_supported(phy_cfg->supported_cap, fec->fec);
0686     if (rc)
0687         return rc;
0688 
0689     /* Work out what efx_mcdi_phy_set_link_ksettings() would produce from
0690      * saved advertising bits
0691      */
0692     if (test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, efx->link_advertising))
0693         caps = (ethtool_linkset_to_mcdi_cap(efx->link_advertising) |
0694             1 << MC_CMD_PHY_CAP_AN_LBN);
0695     else
0696         caps = phy_cfg->forced_cap;
0697 
0698     caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, fec->fec);
0699     rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
0700                    efx->loopback_mode, 0);
0701     if (rc)
0702         return rc;
0703 
0704     /* Record the new FEC setting for subsequent set_link calls */
0705     efx->fec_config = fec->fec;
0706     return 0;
0707 }
0708 
0709 int efx_mcdi_phy_test_alive(struct efx_nic *efx)
0710 {
0711     MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN);
0712     size_t outlen;
0713     int rc;
0714 
0715     BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
0716 
0717     rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
0718               outbuf, sizeof(outbuf), &outlen);
0719     if (rc)
0720         return rc;
0721 
0722     if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
0723         return -EIO;
0724     if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK)
0725         return -EINVAL;
0726 
0727     return 0;
0728 }
0729 
0730 int efx_mcdi_port_reconfigure(struct efx_nic *efx)
0731 {
0732     struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
0733     u32 caps = (efx->link_advertising[0] ?
0734             ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
0735             phy_cfg->forced_cap);
0736 
0737     caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, efx->fec_config);
0738 
0739     return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
0740                  efx->loopback_mode, 0);
0741 }
0742 
0743 static const char *const mcdi_sft9001_cable_diag_names[] = {
0744     "cable.pairA.length",
0745     "cable.pairB.length",
0746     "cable.pairC.length",
0747     "cable.pairD.length",
0748     "cable.pairA.status",
0749     "cable.pairB.status",
0750     "cable.pairC.status",
0751     "cable.pairD.status",
0752 };
0753 
0754 static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
0755              int *results)
0756 {
0757     unsigned int retry, i, count = 0;
0758     size_t outlen;
0759     u32 status;
0760     MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
0761     MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_SFT9001_LEN);
0762     u8 *ptr;
0763     int rc;
0764 
0765     BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0);
0766     MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_mode);
0767     rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST,
0768               inbuf, MC_CMD_START_BIST_IN_LEN, NULL, 0, NULL);
0769     if (rc)
0770         goto out;
0771 
0772     /* Wait up to 10s for BIST to finish */
0773     for (retry = 0; retry < 100; ++retry) {
0774         BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0);
0775         rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
0776                   outbuf, sizeof(outbuf), &outlen);
0777         if (rc)
0778             goto out;
0779 
0780         status = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
0781         if (status != MC_CMD_POLL_BIST_RUNNING)
0782             goto finished;
0783 
0784         msleep(100);
0785     }
0786 
0787     rc = -ETIMEDOUT;
0788     goto out;
0789 
0790 finished:
0791     results[count++] = (status == MC_CMD_POLL_BIST_PASSED) ? 1 : -1;
0792 
0793     /* SFT9001 specific cable diagnostics output */
0794     if (efx->phy_type == PHY_TYPE_SFT9001B &&
0795         (bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT ||
0796          bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) {
0797         ptr = MCDI_PTR(outbuf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
0798         if (status == MC_CMD_POLL_BIST_PASSED &&
0799             outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) {
0800             for (i = 0; i < 8; i++) {
0801                 results[count + i] =
0802                     EFX_DWORD_FIELD(((efx_dword_t *)ptr)[i],
0803                             EFX_DWORD_0);
0804             }
0805         }
0806         count += 8;
0807     }
0808     rc = count;
0809 
0810 out:
0811     return rc;
0812 }
0813 
0814 int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, unsigned int flags)
0815 {
0816     struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
0817     u32 mode;
0818     int rc;
0819 
0820     if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
0821         rc = efx_mcdi_bist(efx, MC_CMD_PHY_BIST, results);
0822         if (rc < 0)
0823             return rc;
0824 
0825         results += rc;
0826     }
0827 
0828     /* If we support both LONG and SHORT, then run each in response to
0829      * break or not. Otherwise, run the one we support
0830      */
0831     mode = 0;
0832     if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN)) {
0833         if ((flags & ETH_TEST_FL_OFFLINE) &&
0834             (phy_cfg->flags &
0835              (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN)))
0836             mode = MC_CMD_PHY_BIST_CABLE_LONG;
0837         else
0838             mode = MC_CMD_PHY_BIST_CABLE_SHORT;
0839     } else if (phy_cfg->flags &
0840            (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))
0841         mode = MC_CMD_PHY_BIST_CABLE_LONG;
0842 
0843     if (mode != 0) {
0844         rc = efx_mcdi_bist(efx, mode, results);
0845         if (rc < 0)
0846             return rc;
0847         results += rc;
0848     }
0849 
0850     return 0;
0851 }
0852 
0853 const char *efx_mcdi_phy_test_name(struct efx_nic *efx, unsigned int index)
0854 {
0855     struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
0856 
0857     if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
0858         if (index == 0)
0859             return "bist";
0860         --index;
0861     }
0862 
0863     if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN) |
0864                   (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) {
0865         if (index == 0)
0866             return "cable";
0867         --index;
0868 
0869         if (efx->phy_type == PHY_TYPE_SFT9001B) {
0870             if (index < ARRAY_SIZE(mcdi_sft9001_cable_diag_names))
0871                 return mcdi_sft9001_cable_diag_names[index];
0872             index -= ARRAY_SIZE(mcdi_sft9001_cable_diag_names);
0873         }
0874     }
0875 
0876     return NULL;
0877 }
0878 
0879 #define SFP_PAGE_SIZE       128
0880 #define SFF_DIAG_TYPE_OFFSET    92
0881 #define SFF_DIAG_ADDR_CHANGE    BIT(2)
0882 #define SFF_8079_NUM_PAGES  2
0883 #define SFF_8472_NUM_PAGES  4
0884 #define SFF_8436_NUM_PAGES  5
0885 #define SFF_DMT_LEVEL_OFFSET    94
0886 
0887 /** efx_mcdi_phy_get_module_eeprom_page() - Get a single page of module eeprom
0888  * @efx:    NIC context
0889  * @page:   EEPROM page number
0890  * @data:   Destination data pointer
0891  * @offset: Offset in page to copy from in to data
0892  * @space:  Space available in data
0893  *
0894  * Return:
0895  *   >=0 - amount of data copied
0896  *   <0  - error
0897  */
0898 static int efx_mcdi_phy_get_module_eeprom_page(struct efx_nic *efx,
0899                            unsigned int page,
0900                            u8 *data, ssize_t offset,
0901                            ssize_t space)
0902 {
0903     MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX);
0904     MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN);
0905     unsigned int payload_len;
0906     unsigned int to_copy;
0907     size_t outlen;
0908     int rc;
0909 
0910     if (offset > SFP_PAGE_SIZE)
0911         return -EINVAL;
0912 
0913     to_copy = min(space, SFP_PAGE_SIZE - offset);
0914 
0915     MCDI_SET_DWORD(inbuf, GET_PHY_MEDIA_INFO_IN_PAGE, page);
0916     rc = efx_mcdi_rpc_quiet(efx, MC_CMD_GET_PHY_MEDIA_INFO,
0917                 inbuf, sizeof(inbuf),
0918                 outbuf, sizeof(outbuf),
0919                 &outlen);
0920 
0921     if (rc)
0922         return rc;
0923 
0924     if (outlen < (MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST +
0925             SFP_PAGE_SIZE))
0926         return -EIO;
0927 
0928     payload_len = MCDI_DWORD(outbuf, GET_PHY_MEDIA_INFO_OUT_DATALEN);
0929     if (payload_len != SFP_PAGE_SIZE)
0930         return -EIO;
0931 
0932     memcpy(data, MCDI_PTR(outbuf, GET_PHY_MEDIA_INFO_OUT_DATA) + offset,
0933            to_copy);
0934 
0935     return to_copy;
0936 }
0937 
0938 static int efx_mcdi_phy_get_module_eeprom_byte(struct efx_nic *efx,
0939                            unsigned int page,
0940                            u8 byte)
0941 {
0942     u8 data;
0943     int rc;
0944 
0945     rc = efx_mcdi_phy_get_module_eeprom_page(efx, page, &data, byte, 1);
0946     if (rc == 1)
0947         return data;
0948 
0949     return rc;
0950 }
0951 
0952 static int efx_mcdi_phy_diag_type(struct efx_nic *efx)
0953 {
0954     /* Page zero of the EEPROM includes the diagnostic type at byte 92. */
0955     return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
0956                            SFF_DIAG_TYPE_OFFSET);
0957 }
0958 
0959 static int efx_mcdi_phy_sff_8472_level(struct efx_nic *efx)
0960 {
0961     /* Page zero of the EEPROM includes the DMT level at byte 94. */
0962     return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
0963                            SFF_DMT_LEVEL_OFFSET);
0964 }
0965 
0966 static u32 efx_mcdi_phy_module_type(struct efx_nic *efx)
0967 {
0968     struct efx_mcdi_phy_data *phy_data = efx->phy_data;
0969 
0970     if (phy_data->media != MC_CMD_MEDIA_QSFP_PLUS)
0971         return phy_data->media;
0972 
0973     /* A QSFP+ NIC may actually have an SFP+ module attached.
0974      * The ID is page 0, byte 0.
0975      */
0976     switch (efx_mcdi_phy_get_module_eeprom_byte(efx, 0, 0)) {
0977     case 0x3:
0978         return MC_CMD_MEDIA_SFP_PLUS;
0979     case 0xc:
0980     case 0xd:
0981         return MC_CMD_MEDIA_QSFP_PLUS;
0982     default:
0983         return 0;
0984     }
0985 }
0986 
0987 int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx, struct ethtool_eeprom *ee, u8 *data)
0988 {
0989     int rc;
0990     ssize_t space_remaining = ee->len;
0991     unsigned int page_off;
0992     bool ignore_missing;
0993     int num_pages;
0994     int page;
0995 
0996     switch (efx_mcdi_phy_module_type(efx)) {
0997     case MC_CMD_MEDIA_SFP_PLUS:
0998         num_pages = efx_mcdi_phy_sff_8472_level(efx) > 0 ?
0999                 SFF_8472_NUM_PAGES : SFF_8079_NUM_PAGES;
1000         page = 0;
1001         ignore_missing = false;
1002         break;
1003     case MC_CMD_MEDIA_QSFP_PLUS:
1004         num_pages = SFF_8436_NUM_PAGES;
1005         page = -1; /* We obtain the lower page by asking for -1. */
1006         ignore_missing = true; /* Ignore missing pages after page 0. */
1007         break;
1008     default:
1009         return -EOPNOTSUPP;
1010     }
1011 
1012     page_off = ee->offset % SFP_PAGE_SIZE;
1013     page += ee->offset / SFP_PAGE_SIZE;
1014 
1015     while (space_remaining && (page < num_pages)) {
1016         rc = efx_mcdi_phy_get_module_eeprom_page(efx, page,
1017                              data, page_off,
1018                              space_remaining);
1019 
1020         if (rc > 0) {
1021             space_remaining -= rc;
1022             data += rc;
1023             page_off = 0;
1024             page++;
1025         } else if (rc == 0) {
1026             space_remaining = 0;
1027         } else if (ignore_missing && (page > 0)) {
1028             int intended_size = SFP_PAGE_SIZE - page_off;
1029 
1030             space_remaining -= intended_size;
1031             if (space_remaining < 0) {
1032                 space_remaining = 0;
1033             } else {
1034                 memset(data, 0, intended_size);
1035                 data += intended_size;
1036                 page_off = 0;
1037                 page++;
1038                 rc = 0;
1039             }
1040         } else {
1041             return rc;
1042         }
1043     }
1044 
1045     return 0;
1046 }
1047 
1048 int efx_mcdi_phy_get_module_info(struct efx_nic *efx, struct ethtool_modinfo *modinfo)
1049 {
1050     int sff_8472_level;
1051     int diag_type;
1052 
1053     switch (efx_mcdi_phy_module_type(efx)) {
1054     case MC_CMD_MEDIA_SFP_PLUS:
1055         sff_8472_level = efx_mcdi_phy_sff_8472_level(efx);
1056 
1057         /* If we can't read the diagnostics level we have none. */
1058         if (sff_8472_level < 0)
1059             return -EOPNOTSUPP;
1060 
1061         /* Check if this module requires the (unsupported) address
1062          * change operation.
1063          */
1064         diag_type = efx_mcdi_phy_diag_type(efx);
1065 
1066         if (sff_8472_level == 0 ||
1067             (diag_type & SFF_DIAG_ADDR_CHANGE)) {
1068             modinfo->type = ETH_MODULE_SFF_8079;
1069             modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
1070         } else {
1071             modinfo->type = ETH_MODULE_SFF_8472;
1072             modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1073         }
1074         break;
1075 
1076     case MC_CMD_MEDIA_QSFP_PLUS:
1077         modinfo->type = ETH_MODULE_SFF_8436;
1078         modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
1079         break;
1080 
1081     default:
1082         return -EOPNOTSUPP;
1083     }
1084 
1085     return 0;
1086 }
1087 
1088 static unsigned int efx_calc_mac_mtu(struct efx_nic *efx)
1089 {
1090     return EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
1091 }
1092 
1093 int efx_mcdi_set_mac(struct efx_nic *efx)
1094 {
1095     u32 fcntl;
1096     MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN);
1097 
1098     BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
1099 
1100     /* This has no effect on EF10 */
1101     ether_addr_copy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
1102             efx->net_dev->dev_addr);
1103 
1104     MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU, efx_calc_mac_mtu(efx));
1105     MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0);
1106 
1107     /* Set simple MAC filter for Siena */
1108     MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_REJECT,
1109                   SET_MAC_IN_REJECT_UNCST, efx->unicast_filter);
1110 
1111     MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_FLAGS,
1112                   SET_MAC_IN_FLAG_INCLUDE_FCS,
1113                   !!(efx->net_dev->features & NETIF_F_RXFCS));
1114 
1115     switch (efx->wanted_fc) {
1116     case EFX_FC_RX | EFX_FC_TX:
1117         fcntl = MC_CMD_FCNTL_BIDIR;
1118         break;
1119     case EFX_FC_RX:
1120         fcntl = MC_CMD_FCNTL_RESPOND;
1121         break;
1122     default:
1123         fcntl = MC_CMD_FCNTL_OFF;
1124         break;
1125     }
1126     if (efx->wanted_fc & EFX_FC_AUTO)
1127         fcntl = MC_CMD_FCNTL_AUTO;
1128     if (efx->fc_disable)
1129         fcntl = MC_CMD_FCNTL_OFF;
1130 
1131     MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
1132 
1133     return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes),
1134                 NULL, 0, NULL);
1135 }
1136 
1137 int efx_mcdi_set_mtu(struct efx_nic *efx)
1138 {
1139     MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_MAC_EXT_IN_LEN);
1140 
1141     BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
1142 
1143     MCDI_SET_DWORD(inbuf, SET_MAC_EXT_IN_MTU, efx_calc_mac_mtu(efx));
1144 
1145     MCDI_POPULATE_DWORD_1(inbuf, SET_MAC_EXT_IN_CONTROL,
1146                   SET_MAC_EXT_IN_CFG_MTU, 1);
1147 
1148     return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, inbuf, sizeof(inbuf),
1149                 NULL, 0, NULL);
1150 }
1151 
1152 enum efx_stats_action {
1153     EFX_STATS_ENABLE,
1154     EFX_STATS_DISABLE,
1155     EFX_STATS_PULL,
1156 };
1157 
1158 static int efx_mcdi_mac_stats(struct efx_nic *efx,
1159                   enum efx_stats_action action, int clear)
1160 {
1161     MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
1162     int rc;
1163     int change = action == EFX_STATS_PULL ? 0 : 1;
1164     int enable = action == EFX_STATS_ENABLE ? 1 : 0;
1165     int period = action == EFX_STATS_ENABLE ? 1000 : 0;
1166     dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
1167     u32 dma_len = action != EFX_STATS_DISABLE ?
1168         efx->num_mac_stats * sizeof(u64) : 0;
1169 
1170     BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
1171 
1172     MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, dma_addr);
1173     MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
1174                   MAC_STATS_IN_DMA, !!enable,
1175                   MAC_STATS_IN_CLEAR, clear,
1176                   MAC_STATS_IN_PERIODIC_CHANGE, change,
1177                   MAC_STATS_IN_PERIODIC_ENABLE, enable,
1178                   MAC_STATS_IN_PERIODIC_CLEAR, 0,
1179                   MAC_STATS_IN_PERIODIC_NOEVENT, 1,
1180                   MAC_STATS_IN_PERIOD_MS, period);
1181     MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
1182 
1183     if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0)
1184         MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, efx->vport_id);
1185 
1186     rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
1187                 NULL, 0, NULL);
1188     /* Expect ENOENT if DMA queues have not been set up */
1189     if (rc && (rc != -ENOENT || atomic_read(&efx->active_queues)))
1190         efx_mcdi_display_error(efx, MC_CMD_MAC_STATS, sizeof(inbuf),
1191                        NULL, 0, rc);
1192     return rc;
1193 }
1194 
1195 void efx_mcdi_mac_start_stats(struct efx_nic *efx)
1196 {
1197     __le64 *dma_stats = efx->stats_buffer.addr;
1198 
1199     dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
1200 
1201     efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
1202 }
1203 
1204 void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
1205 {
1206     efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
1207 }
1208 
1209 #define EFX_MAC_STATS_WAIT_US 100
1210 #define EFX_MAC_STATS_WAIT_ATTEMPTS 10
1211 
1212 void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
1213 {
1214     __le64 *dma_stats = efx->stats_buffer.addr;
1215     int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
1216 
1217     dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
1218     efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
1219 
1220     while (dma_stats[efx->num_mac_stats - 1] ==
1221                 EFX_MC_STATS_GENERATION_INVALID &&
1222             attempts-- != 0)
1223         udelay(EFX_MAC_STATS_WAIT_US);
1224 }
1225 
1226 int efx_mcdi_mac_init_stats(struct efx_nic *efx)
1227 {
1228     int rc;
1229 
1230     if (!efx->num_mac_stats)
1231         return 0;
1232 
1233     /* Allocate buffer for stats */
1234     rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
1235                   efx->num_mac_stats * sizeof(u64), GFP_KERNEL);
1236     if (rc) {
1237         netif_warn(efx, probe, efx->net_dev,
1238                "failed to allocate DMA buffer: %d\n", rc);
1239         return rc;
1240     }
1241 
1242     netif_dbg(efx, probe, efx->net_dev,
1243           "stats buffer at %llx (virt %p phys %llx)\n",
1244           (u64) efx->stats_buffer.dma_addr,
1245           efx->stats_buffer.addr,
1246           (u64) virt_to_phys(efx->stats_buffer.addr));
1247 
1248     return 0;
1249 }
1250 
1251 void efx_mcdi_mac_fini_stats(struct efx_nic *efx)
1252 {
1253     efx_nic_free_buffer(efx, &efx->stats_buffer);
1254 }
1255 
1256 /* Get physical port number (EF10 only; on Siena it is same as PF number) */
1257 int efx_mcdi_port_get_number(struct efx_nic *efx)
1258 {
1259     MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
1260     int rc;
1261 
1262     rc = efx_mcdi_rpc(efx, MC_CMD_GET_PORT_ASSIGNMENT, NULL, 0,
1263               outbuf, sizeof(outbuf), NULL);
1264     if (rc)
1265         return rc;
1266 
1267     return MCDI_DWORD(outbuf, GET_PORT_ASSIGNMENT_OUT_PORT);
1268 }
1269 
1270 static unsigned int efx_mcdi_event_link_speed[] = {
1271     [MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
1272     [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
1273     [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
1274     [MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000,
1275     [MCDI_EVENT_LINKCHANGE_SPEED_25G] = 25000,
1276     [MCDI_EVENT_LINKCHANGE_SPEED_50G] = 50000,
1277     [MCDI_EVENT_LINKCHANGE_SPEED_100G] = 100000,
1278 };
1279 
1280 void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
1281 {
1282     u32 flags, fcntl, speed, lpa;
1283 
1284     speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED);
1285     EFX_WARN_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed));
1286     speed = efx_mcdi_event_link_speed[speed];
1287 
1288     flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS);
1289     fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL);
1290     lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP);
1291 
1292     /* efx->link_state is only modified by efx_mcdi_phy_get_link(),
1293      * which is only run after flushing the event queues. Therefore, it
1294      * is safe to modify the link state outside of the mac_lock here.
1295      */
1296     efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);
1297 
1298     efx_mcdi_phy_check_fcntl(efx, lpa);
1299 
1300     efx_link_status_changed(efx);
1301 }