cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mcdi_port_common.c (37948B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/****************************************************************************
      3 * Driver for Solarflare network controllers and boards
      4 * Copyright 2018 Solarflare Communications Inc.
      5 *
      6 * This program is free software; you can redistribute it and/or modify it
      7 * under the terms of the GNU General Public License version 2 as published
      8 * by the Free Software Foundation, incorporated herein by reference.
      9 */
     10
     11#include "mcdi_port_common.h"
     12#include "efx_common.h"
     13#include "nic.h"
     14
     15int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg)
     16{
     17	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN);
     18	size_t outlen;
     19	int rc;
     20
     21	BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_IN_LEN != 0);
     22	BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_OUT_NAME_LEN != sizeof(cfg->name));
     23
     24	rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0,
     25			  outbuf, sizeof(outbuf), &outlen);
     26	if (rc)
     27		goto fail;
     28
     29	if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) {
     30		rc = -EIO;
     31		goto fail;
     32	}
     33
     34	cfg->flags = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_FLAGS);
     35	cfg->type = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_TYPE);
     36	cfg->supported_cap =
     37		MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_SUPPORTED_CAP);
     38	cfg->channel = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_CHANNEL);
     39	cfg->port = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_PRT);
     40	cfg->stats_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_STATS_MASK);
     41	memcpy(cfg->name, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_NAME),
     42	       sizeof(cfg->name));
     43	cfg->media = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MEDIA_TYPE);
     44	cfg->mmd_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MMD_MASK);
     45	memcpy(cfg->revision, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_REVISION),
     46	       sizeof(cfg->revision));
     47
     48	return 0;
     49
     50fail:
     51	netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
     52	return rc;
     53}
     54
     55void efx_link_set_advertising(struct efx_nic *efx,
     56			      const unsigned long *advertising)
     57{
     58	memcpy(efx->link_advertising, advertising,
     59	       sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
     60
     61	efx->link_advertising[0] |= ADVERTISED_Autoneg;
     62	if (advertising[0] & ADVERTISED_Pause)
     63		efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX);
     64	else
     65		efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
     66	if (advertising[0] & ADVERTISED_Asym_Pause)
     67		efx->wanted_fc ^= EFX_FC_TX;
     68}
     69
     70int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
     71		      u32 flags, u32 loopback_mode, u32 loopback_speed)
     72{
     73	MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_LINK_IN_LEN);
     74
     75	BUILD_BUG_ON(MC_CMD_SET_LINK_OUT_LEN != 0);
     76
     77	MCDI_SET_DWORD(inbuf, SET_LINK_IN_CAP, capabilities);
     78	MCDI_SET_DWORD(inbuf, SET_LINK_IN_FLAGS, flags);
     79	MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_MODE, loopback_mode);
     80	MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_SPEED, loopback_speed);
     81
     82	return efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
     83			  NULL, 0, NULL);
     84}
     85
     86int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
     87{
     88	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LOOPBACK_MODES_OUT_LEN);
     89	size_t outlen;
     90	int rc;
     91
     92	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0,
     93			  outbuf, sizeof(outbuf), &outlen);
     94	if (rc)
     95		goto fail;
     96
     97	if (outlen < (MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
     98		      MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN)) {
     99		rc = -EIO;
    100		goto fail;
    101	}
    102
    103	*loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED);
    104
    105	return 0;
    106
    107fail:
    108	netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
    109	return rc;
    110}
    111
    112void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset)
    113{
    114	#define SET_BIT(name)	__set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
    115					  linkset)
    116
    117	bitmap_zero(linkset, __ETHTOOL_LINK_MODE_MASK_NBITS);
    118	switch (media) {
    119	case MC_CMD_MEDIA_KX4:
    120		SET_BIT(Backplane);
    121		if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
    122			SET_BIT(1000baseKX_Full);
    123		if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
    124			SET_BIT(10000baseKX4_Full);
    125		if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
    126			SET_BIT(40000baseKR4_Full);
    127		break;
    128
    129	case MC_CMD_MEDIA_XFP:
    130	case MC_CMD_MEDIA_SFP_PLUS:
    131	case MC_CMD_MEDIA_QSFP_PLUS:
    132		SET_BIT(FIBRE);
    133		if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) {
    134			SET_BIT(1000baseT_Full);
    135			SET_BIT(1000baseX_Full);
    136		}
    137		if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) {
    138			SET_BIT(10000baseCR_Full);
    139			SET_BIT(10000baseLR_Full);
    140			SET_BIT(10000baseSR_Full);
    141		}
    142		if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) {
    143			SET_BIT(40000baseCR4_Full);
    144			SET_BIT(40000baseSR4_Full);
    145		}
    146		if (cap & (1 << MC_CMD_PHY_CAP_100000FDX_LBN)) {
    147			SET_BIT(100000baseCR4_Full);
    148			SET_BIT(100000baseSR4_Full);
    149		}
    150		if (cap & (1 << MC_CMD_PHY_CAP_25000FDX_LBN)) {
    151			SET_BIT(25000baseCR_Full);
    152			SET_BIT(25000baseSR_Full);
    153		}
    154		if (cap & (1 << MC_CMD_PHY_CAP_50000FDX_LBN))
    155			SET_BIT(50000baseCR2_Full);
    156		break;
    157
    158	case MC_CMD_MEDIA_BASE_T:
    159		SET_BIT(TP);
    160		if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
    161			SET_BIT(10baseT_Half);
    162		if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
    163			SET_BIT(10baseT_Full);
    164		if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
    165			SET_BIT(100baseT_Half);
    166		if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
    167			SET_BIT(100baseT_Full);
    168		if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
    169			SET_BIT(1000baseT_Half);
    170		if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
    171			SET_BIT(1000baseT_Full);
    172		if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
    173			SET_BIT(10000baseT_Full);
    174		break;
    175	}
    176
    177	if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
    178		SET_BIT(Pause);
    179	if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
    180		SET_BIT(Asym_Pause);
    181	if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
    182		SET_BIT(Autoneg);
    183
    184	#undef SET_BIT
    185}
    186
    187u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset)
    188{
    189	u32 result = 0;
    190
    191	#define TEST_BIT(name)	test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
    192					 linkset)
    193
    194	if (TEST_BIT(10baseT_Half))
    195		result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN);
    196	if (TEST_BIT(10baseT_Full))
    197		result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN);
    198	if (TEST_BIT(100baseT_Half))
    199		result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN);
    200	if (TEST_BIT(100baseT_Full))
    201		result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN);
    202	if (TEST_BIT(1000baseT_Half))
    203		result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN);
    204	if (TEST_BIT(1000baseT_Full) || TEST_BIT(1000baseKX_Full) ||
    205			TEST_BIT(1000baseX_Full))
    206		result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN);
    207	if (TEST_BIT(10000baseT_Full) || TEST_BIT(10000baseKX4_Full) ||
    208			TEST_BIT(10000baseCR_Full) || TEST_BIT(10000baseLR_Full) ||
    209			TEST_BIT(10000baseSR_Full))
    210		result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN);
    211	if (TEST_BIT(40000baseCR4_Full) || TEST_BIT(40000baseKR4_Full) ||
    212			TEST_BIT(40000baseSR4_Full))
    213		result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN);
    214	if (TEST_BIT(100000baseCR4_Full) || TEST_BIT(100000baseSR4_Full))
    215		result |= (1 << MC_CMD_PHY_CAP_100000FDX_LBN);
    216	if (TEST_BIT(25000baseCR_Full) || TEST_BIT(25000baseSR_Full))
    217		result |= (1 << MC_CMD_PHY_CAP_25000FDX_LBN);
    218	if (TEST_BIT(50000baseCR2_Full))
    219		result |= (1 << MC_CMD_PHY_CAP_50000FDX_LBN);
    220	if (TEST_BIT(Pause))
    221		result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN);
    222	if (TEST_BIT(Asym_Pause))
    223		result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN);
    224	if (TEST_BIT(Autoneg))
    225		result |= (1 << MC_CMD_PHY_CAP_AN_LBN);
    226
    227	#undef TEST_BIT
    228
    229	return result;
    230}
    231
    232u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
    233{
    234	struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
    235	enum efx_phy_mode mode, supported;
    236	u32 flags;
    237
    238	/* TODO: Advertise the capabilities supported by this PHY */
    239	supported = 0;
    240	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN))
    241		supported |= PHY_MODE_TX_DISABLED;
    242	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN))
    243		supported |= PHY_MODE_LOW_POWER;
    244	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN))
    245		supported |= PHY_MODE_OFF;
    246
    247	mode = efx->phy_mode & supported;
    248
    249	flags = 0;
    250	if (mode & PHY_MODE_TX_DISABLED)
    251		flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN);
    252	if (mode & PHY_MODE_LOW_POWER)
    253		flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN);
    254	if (mode & PHY_MODE_OFF)
    255		flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN);
    256
    257	return flags;
    258}
    259
    260u8 mcdi_to_ethtool_media(u32 media)
    261{
    262	switch (media) {
    263	case MC_CMD_MEDIA_XAUI:
    264	case MC_CMD_MEDIA_CX4:
    265	case MC_CMD_MEDIA_KX4:
    266		return PORT_OTHER;
    267
    268	case MC_CMD_MEDIA_XFP:
    269	case MC_CMD_MEDIA_SFP_PLUS:
    270	case MC_CMD_MEDIA_QSFP_PLUS:
    271		return PORT_FIBRE;
    272
    273	case MC_CMD_MEDIA_BASE_T:
    274		return PORT_TP;
    275
    276	default:
    277		return PORT_OTHER;
    278	}
    279}
    280
    281void efx_mcdi_phy_decode_link(struct efx_nic *efx,
    282			      struct efx_link_state *link_state,
    283			      u32 speed, u32 flags, u32 fcntl)
    284{
    285	switch (fcntl) {
    286	case MC_CMD_FCNTL_AUTO:
    287		WARN_ON(1);	/* This is not a link mode */
    288		link_state->fc = EFX_FC_AUTO | EFX_FC_TX | EFX_FC_RX;
    289		break;
    290	case MC_CMD_FCNTL_BIDIR:
    291		link_state->fc = EFX_FC_TX | EFX_FC_RX;
    292		break;
    293	case MC_CMD_FCNTL_RESPOND:
    294		link_state->fc = EFX_FC_RX;
    295		break;
    296	default:
    297		WARN_ON(1);
    298		fallthrough;
    299	case MC_CMD_FCNTL_OFF:
    300		link_state->fc = 0;
    301		break;
    302	}
    303
    304	link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
    305	link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
    306	link_state->speed = speed;
    307}
    308
    309/* The semantics of the ethtool FEC mode bitmask are not well defined,
    310 * particularly the meaning of combinations of bits.  Which means we get to
    311 * define our own semantics, as follows:
    312 * OFF overrides any other bits, and means "disable all FEC" (with the
    313 * exception of 25G KR4/CR4, where it is not possible to reject it if AN
    314 * partner requests it).
    315 * AUTO on its own means use cable requirements and link partner autoneg with
    316 * fw-default preferences for the cable type.
    317 * AUTO and either RS or BASER means use the specified FEC type if cable and
    318 * link partner support it, otherwise autoneg/fw-default.
    319 * RS or BASER alone means use the specified FEC type if cable and link partner
    320 * support it and either requests it, otherwise no FEC.
    321 * Both RS and BASER (whether AUTO or not) means use FEC if cable and link
    322 * partner support it, preferring RS to BASER.
    323 */
    324u32 ethtool_fec_caps_to_mcdi(u32 supported_cap, u32 ethtool_cap)
    325{
    326	u32 ret = 0;
    327
    328	if (ethtool_cap & ETHTOOL_FEC_OFF)
    329		return 0;
    330
    331	if (ethtool_cap & ETHTOOL_FEC_AUTO)
    332		ret |= ((1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
    333			(1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
    334			(1 << MC_CMD_PHY_CAP_RS_FEC_LBN)) & supported_cap;
    335	if (ethtool_cap & ETHTOOL_FEC_RS &&
    336	    supported_cap & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN))
    337		ret |= (1 << MC_CMD_PHY_CAP_RS_FEC_LBN) |
    338		       (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN);
    339	if (ethtool_cap & ETHTOOL_FEC_BASER) {
    340		if (supported_cap & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN))
    341			ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
    342			       (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
    343		if (supported_cap & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN))
    344			ret |= (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
    345			       (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN);
    346	}
    347	return ret;
    348}
    349
    350/* Invert ethtool_fec_caps_to_mcdi.  There are two combinations that function
    351 * can never produce, (baser xor rs) and neither req; the implementation below
    352 * maps both of those to AUTO.  This should never matter, and it's not clear
    353 * what a better mapping would be anyway.
    354 */
    355u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g)
    356{
    357	bool rs = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN),
    358	     rs_req = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN),
    359	     baser = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN)
    360			    : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN),
    361	     baser_req = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN)
    362				: caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
    363
    364	if (!baser && !rs)
    365		return ETHTOOL_FEC_OFF;
    366	return (rs_req ? ETHTOOL_FEC_RS : 0) |
    367	       (baser_req ? ETHTOOL_FEC_BASER : 0) |
    368	       (baser == baser_req && rs == rs_req ? 0 : ETHTOOL_FEC_AUTO);
    369}
    370
    371/* Verify that the forced flow control settings (!EFX_FC_AUTO) are
    372 * supported by the link partner. Warn the user if this isn't the case
    373 */
    374void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa)
    375{
    376	struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
    377	u32 rmtadv;
    378
    379	/* The link partner capabilities are only relevant if the
    380	 * link supports flow control autonegotiation
    381	 */
    382	if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
    383		return;
    384
    385	/* If flow control autoneg is supported and enabled, then fine */
    386	if (efx->wanted_fc & EFX_FC_AUTO)
    387		return;
    388
    389	rmtadv = 0;
    390	if (lpa & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
    391		rmtadv |= ADVERTISED_Pause;
    392	if (lpa & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
    393		rmtadv |=  ADVERTISED_Asym_Pause;
    394
    395	if ((efx->wanted_fc & EFX_FC_TX) && rmtadv == ADVERTISED_Asym_Pause)
    396		netif_err(efx, link, efx->net_dev,
    397			  "warning: link partner doesn't support pause frames");
    398}
    399
    400bool efx_mcdi_phy_poll(struct efx_nic *efx)
    401{
    402	struct efx_link_state old_state = efx->link_state;
    403	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
    404	int rc;
    405
    406	WARN_ON(!mutex_is_locked(&efx->mac_lock));
    407
    408	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
    409
    410	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
    411			  outbuf, sizeof(outbuf), NULL);
    412	if (rc)
    413		efx->link_state.up = false;
    414	else
    415		efx_mcdi_phy_decode_link(
    416			efx, &efx->link_state,
    417			MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
    418			MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
    419			MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
    420
    421	return !efx_link_state_equal(&efx->link_state, &old_state);
    422}
    423
    424int efx_mcdi_phy_probe(struct efx_nic *efx)
    425{
    426	struct efx_mcdi_phy_data *phy_data;
    427	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
    428	u32 caps;
    429	int rc;
    430
    431	/* Initialise and populate phy_data */
    432	phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
    433	if (phy_data == NULL)
    434		return -ENOMEM;
    435
    436	rc = efx_mcdi_get_phy_cfg(efx, phy_data);
    437	if (rc != 0)
    438		goto fail;
    439
    440	/* Read initial link advertisement */
    441	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
    442	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
    443			  outbuf, sizeof(outbuf), NULL);
    444	if (rc)
    445		goto fail;
    446
    447	/* Fill out nic state */
    448	efx->phy_data = phy_data;
    449	efx->phy_type = phy_data->type;
    450
    451	efx->mdio_bus = phy_data->channel;
    452	efx->mdio.prtad = phy_data->port;
    453	efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
    454	efx->mdio.mode_support = 0;
    455	if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
    456		efx->mdio.mode_support |= MDIO_SUPPORTS_C22;
    457	if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
    458		efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
    459
    460	caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
    461	if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
    462		mcdi_to_ethtool_linkset(phy_data->media, caps,
    463					efx->link_advertising);
    464	else
    465		phy_data->forced_cap = caps;
    466
    467	/* Assert that we can map efx -> mcdi loopback modes */
    468	BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE);
    469	BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA);
    470	BUILD_BUG_ON(LOOPBACK_GMAC != MC_CMD_LOOPBACK_GMAC);
    471	BUILD_BUG_ON(LOOPBACK_XGMII != MC_CMD_LOOPBACK_XGMII);
    472	BUILD_BUG_ON(LOOPBACK_XGXS != MC_CMD_LOOPBACK_XGXS);
    473	BUILD_BUG_ON(LOOPBACK_XAUI != MC_CMD_LOOPBACK_XAUI);
    474	BUILD_BUG_ON(LOOPBACK_GMII != MC_CMD_LOOPBACK_GMII);
    475	BUILD_BUG_ON(LOOPBACK_SGMII != MC_CMD_LOOPBACK_SGMII);
    476	BUILD_BUG_ON(LOOPBACK_XGBR != MC_CMD_LOOPBACK_XGBR);
    477	BUILD_BUG_ON(LOOPBACK_XFI != MC_CMD_LOOPBACK_XFI);
    478	BUILD_BUG_ON(LOOPBACK_XAUI_FAR != MC_CMD_LOOPBACK_XAUI_FAR);
    479	BUILD_BUG_ON(LOOPBACK_GMII_FAR != MC_CMD_LOOPBACK_GMII_FAR);
    480	BUILD_BUG_ON(LOOPBACK_SGMII_FAR != MC_CMD_LOOPBACK_SGMII_FAR);
    481	BUILD_BUG_ON(LOOPBACK_XFI_FAR != MC_CMD_LOOPBACK_XFI_FAR);
    482	BUILD_BUG_ON(LOOPBACK_GPHY != MC_CMD_LOOPBACK_GPHY);
    483	BUILD_BUG_ON(LOOPBACK_PHYXS != MC_CMD_LOOPBACK_PHYXS);
    484	BUILD_BUG_ON(LOOPBACK_PCS != MC_CMD_LOOPBACK_PCS);
    485	BUILD_BUG_ON(LOOPBACK_PMAPMD != MC_CMD_LOOPBACK_PMAPMD);
    486	BUILD_BUG_ON(LOOPBACK_XPORT != MC_CMD_LOOPBACK_XPORT);
    487	BUILD_BUG_ON(LOOPBACK_XGMII_WS != MC_CMD_LOOPBACK_XGMII_WS);
    488	BUILD_BUG_ON(LOOPBACK_XAUI_WS != MC_CMD_LOOPBACK_XAUI_WS);
    489	BUILD_BUG_ON(LOOPBACK_XAUI_WS_FAR != MC_CMD_LOOPBACK_XAUI_WS_FAR);
    490	BUILD_BUG_ON(LOOPBACK_XAUI_WS_NEAR != MC_CMD_LOOPBACK_XAUI_WS_NEAR);
    491	BUILD_BUG_ON(LOOPBACK_GMII_WS != MC_CMD_LOOPBACK_GMII_WS);
    492	BUILD_BUG_ON(LOOPBACK_XFI_WS != MC_CMD_LOOPBACK_XFI_WS);
    493	BUILD_BUG_ON(LOOPBACK_XFI_WS_FAR != MC_CMD_LOOPBACK_XFI_WS_FAR);
    494	BUILD_BUG_ON(LOOPBACK_PHYXS_WS != MC_CMD_LOOPBACK_PHYXS_WS);
    495
    496	rc = efx_mcdi_loopback_modes(efx, &efx->loopback_modes);
    497	if (rc != 0)
    498		goto fail;
    499	/* The MC indicates that LOOPBACK_NONE is a valid loopback mode,
    500	 * but by convention we don't
    501	 */
    502	efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
    503
    504	/* Set the initial link mode */
    505	efx_mcdi_phy_decode_link(efx, &efx->link_state,
    506				 MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
    507				 MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
    508				 MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
    509
    510	/* Record the initial FEC configuration (or nearest approximation
    511	 * representable in the ethtool configuration space)
    512	 */
    513	efx->fec_config = mcdi_fec_caps_to_ethtool(caps,
    514						   efx->link_state.speed == 25000 ||
    515						   efx->link_state.speed == 50000);
    516
    517	/* Default to Autonegotiated flow control if the PHY supports it */
    518	efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
    519	if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
    520		efx->wanted_fc |= EFX_FC_AUTO;
    521	efx_link_set_wanted_fc(efx, efx->wanted_fc);
    522
    523	return 0;
    524
    525fail:
    526	kfree(phy_data);
    527	return rc;
    528}
    529
    530void efx_mcdi_phy_remove(struct efx_nic *efx)
    531{
    532	struct efx_mcdi_phy_data *phy_data = efx->phy_data;
    533
    534	efx->phy_data = NULL;
    535	kfree(phy_data);
    536}
    537
    538void efx_mcdi_phy_get_link_ksettings(struct efx_nic *efx, struct ethtool_link_ksettings *cmd)
    539{
    540	struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
    541	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
    542	int rc;
    543
    544	cmd->base.speed = efx->link_state.speed;
    545	cmd->base.duplex = efx->link_state.fd;
    546	cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media);
    547	cmd->base.phy_address = phy_cfg->port;
    548	cmd->base.autoneg = !!(efx->link_advertising[0] & ADVERTISED_Autoneg);
    549	cmd->base.mdio_support = (efx->mdio.mode_support &
    550			      (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
    551
    552	mcdi_to_ethtool_linkset(phy_cfg->media, phy_cfg->supported_cap,
    553				cmd->link_modes.supported);
    554	memcpy(cmd->link_modes.advertising, efx->link_advertising,
    555	       sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
    556
    557	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
    558	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
    559			  outbuf, sizeof(outbuf), NULL);
    560	if (rc)
    561		return;
    562	mcdi_to_ethtool_linkset(phy_cfg->media,
    563				MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP),
    564				cmd->link_modes.lp_advertising);
    565}
    566
    567int efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx, const struct ethtool_link_ksettings *cmd)
    568{
    569	struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
    570	u32 caps;
    571	int rc;
    572
    573	if (cmd->base.autoneg) {
    574		caps = (ethtool_linkset_to_mcdi_cap(cmd->link_modes.advertising) |
    575			1 << MC_CMD_PHY_CAP_AN_LBN);
    576	} else if (cmd->base.duplex) {
    577		switch (cmd->base.speed) {
    578		case 10:     caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN;     break;
    579		case 100:    caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN;    break;
    580		case 1000:   caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN;   break;
    581		case 10000:  caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN;  break;
    582		case 40000:  caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN;  break;
    583		case 100000: caps = 1 << MC_CMD_PHY_CAP_100000FDX_LBN; break;
    584		case 25000:  caps = 1 << MC_CMD_PHY_CAP_25000FDX_LBN;  break;
    585		case 50000:  caps = 1 << MC_CMD_PHY_CAP_50000FDX_LBN;  break;
    586		default:     return -EINVAL;
    587		}
    588	} else {
    589		switch (cmd->base.speed) {
    590		case 10:     caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN;     break;
    591		case 100:    caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN;    break;
    592		case 1000:   caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN;   break;
    593		default:     return -EINVAL;
    594		}
    595	}
    596
    597	caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, efx->fec_config);
    598
    599	rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
    600			       efx->loopback_mode, 0);
    601	if (rc)
    602		return rc;
    603
    604	if (cmd->base.autoneg) {
    605		efx_link_set_advertising(efx, cmd->link_modes.advertising);
    606		phy_cfg->forced_cap = 0;
    607	} else {
    608		efx_link_clear_advertising(efx);
    609		phy_cfg->forced_cap = caps;
    610	}
    611	return 0;
    612}
    613
    614int efx_mcdi_phy_get_fecparam(struct efx_nic *efx, struct ethtool_fecparam *fec)
    615{
    616	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN);
    617	u32 caps, active, speed; /* MCDI format */
    618	bool is_25g = false;
    619	size_t outlen;
    620	int rc;
    621
    622	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
    623	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
    624			  outbuf, sizeof(outbuf), &outlen);
    625	if (rc)
    626		return rc;
    627	if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN)
    628		return -EOPNOTSUPP;
    629
    630	/* behaviour for 25G/50G links depends on 25G BASER bit */
    631	speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED);
    632	is_25g = speed == 25000 || speed == 50000;
    633
    634	caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP);
    635	fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g);
    636	/* BASER is never supported on 100G */
    637	if (speed == 100000)
    638		fec->fec &= ~ETHTOOL_FEC_BASER;
    639
    640	active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE);
    641	switch (active) {
    642	case MC_CMD_FEC_NONE:
    643		fec->active_fec = ETHTOOL_FEC_OFF;
    644		break;
    645	case MC_CMD_FEC_BASER:
    646		fec->active_fec = ETHTOOL_FEC_BASER;
    647		break;
    648	case MC_CMD_FEC_RS:
    649		fec->active_fec = ETHTOOL_FEC_RS;
    650		break;
    651	default:
    652		netif_warn(efx, hw, efx->net_dev,
    653			   "Firmware reports unrecognised FEC_TYPE %u\n",
    654			   active);
    655		/* We don't know what firmware has picked.  AUTO is as good a
    656		 * "can't happen" value as any other.
    657		 */
    658		fec->active_fec = ETHTOOL_FEC_AUTO;
    659		break;
    660	}
    661
    662	return 0;
    663}
    664
    665/* Basic validation to ensure that the caps we are going to attempt to set are
    666 * in fact supported by the adapter.  Note that 'no FEC' is always supported.
    667 */
    668static int ethtool_fec_supported(u32 supported_cap, u32 ethtool_cap)
    669{
    670	if (ethtool_cap & ETHTOOL_FEC_OFF)
    671		return 0;
    672
    673	if (ethtool_cap &&
    674	    !ethtool_fec_caps_to_mcdi(supported_cap, ethtool_cap))
    675		return -EINVAL;
    676	return 0;
    677}
    678
    679int efx_mcdi_phy_set_fecparam(struct efx_nic *efx, const struct ethtool_fecparam *fec)
    680{
    681	struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
    682	u32 caps;
    683	int rc;
    684
    685	rc = ethtool_fec_supported(phy_cfg->supported_cap, fec->fec);
    686	if (rc)
    687		return rc;
    688
    689	/* Work out what efx_mcdi_phy_set_link_ksettings() would produce from
    690	 * saved advertising bits
    691	 */
    692	if (test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, efx->link_advertising))
    693		caps = (ethtool_linkset_to_mcdi_cap(efx->link_advertising) |
    694			1 << MC_CMD_PHY_CAP_AN_LBN);
    695	else
    696		caps = phy_cfg->forced_cap;
    697
    698	caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, fec->fec);
    699	rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
    700			       efx->loopback_mode, 0);
    701	if (rc)
    702		return rc;
    703
    704	/* Record the new FEC setting for subsequent set_link calls */
    705	efx->fec_config = fec->fec;
    706	return 0;
    707}
    708
    709int efx_mcdi_phy_test_alive(struct efx_nic *efx)
    710{
    711	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN);
    712	size_t outlen;
    713	int rc;
    714
    715	BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
    716
    717	rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
    718			  outbuf, sizeof(outbuf), &outlen);
    719	if (rc)
    720		return rc;
    721
    722	if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
    723		return -EIO;
    724	if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK)
    725		return -EINVAL;
    726
    727	return 0;
    728}
    729
    730int efx_mcdi_port_reconfigure(struct efx_nic *efx)
    731{
    732	struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
    733	u32 caps = (efx->link_advertising[0] ?
    734		    ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
    735		    phy_cfg->forced_cap);
    736
    737	caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, efx->fec_config);
    738
    739	return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
    740				 efx->loopback_mode, 0);
    741}
    742
    743static const char *const mcdi_sft9001_cable_diag_names[] = {
    744	"cable.pairA.length",
    745	"cable.pairB.length",
    746	"cable.pairC.length",
    747	"cable.pairD.length",
    748	"cable.pairA.status",
    749	"cable.pairB.status",
    750	"cable.pairC.status",
    751	"cable.pairD.status",
    752};
    753
    754static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
    755			 int *results)
    756{
    757	unsigned int retry, i, count = 0;
    758	size_t outlen;
    759	u32 status;
    760	MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
    761	MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_SFT9001_LEN);
    762	u8 *ptr;
    763	int rc;
    764
    765	BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0);
    766	MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_mode);
    767	rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST,
    768			  inbuf, MC_CMD_START_BIST_IN_LEN, NULL, 0, NULL);
    769	if (rc)
    770		goto out;
    771
    772	/* Wait up to 10s for BIST to finish */
    773	for (retry = 0; retry < 100; ++retry) {
    774		BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0);
    775		rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
    776				  outbuf, sizeof(outbuf), &outlen);
    777		if (rc)
    778			goto out;
    779
    780		status = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
    781		if (status != MC_CMD_POLL_BIST_RUNNING)
    782			goto finished;
    783
    784		msleep(100);
    785	}
    786
    787	rc = -ETIMEDOUT;
    788	goto out;
    789
    790finished:
    791	results[count++] = (status == MC_CMD_POLL_BIST_PASSED) ? 1 : -1;
    792
    793	/* SFT9001 specific cable diagnostics output */
    794	if (efx->phy_type == PHY_TYPE_SFT9001B &&
    795	    (bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT ||
    796	     bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) {
    797		ptr = MCDI_PTR(outbuf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
    798		if (status == MC_CMD_POLL_BIST_PASSED &&
    799		    outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) {
    800			for (i = 0; i < 8; i++) {
    801				results[count + i] =
    802					EFX_DWORD_FIELD(((efx_dword_t *)ptr)[i],
    803							EFX_DWORD_0);
    804			}
    805		}
    806		count += 8;
    807	}
    808	rc = count;
    809
    810out:
    811	return rc;
    812}
    813
    814int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, unsigned int flags)
    815{
    816	struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
    817	u32 mode;
    818	int rc;
    819
    820	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
    821		rc = efx_mcdi_bist(efx, MC_CMD_PHY_BIST, results);
    822		if (rc < 0)
    823			return rc;
    824
    825		results += rc;
    826	}
    827
    828	/* If we support both LONG and SHORT, then run each in response to
    829	 * break or not. Otherwise, run the one we support
    830	 */
    831	mode = 0;
    832	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN)) {
    833		if ((flags & ETH_TEST_FL_OFFLINE) &&
    834		    (phy_cfg->flags &
    835		     (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN)))
    836			mode = MC_CMD_PHY_BIST_CABLE_LONG;
    837		else
    838			mode = MC_CMD_PHY_BIST_CABLE_SHORT;
    839	} else if (phy_cfg->flags &
    840		   (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))
    841		mode = MC_CMD_PHY_BIST_CABLE_LONG;
    842
    843	if (mode != 0) {
    844		rc = efx_mcdi_bist(efx, mode, results);
    845		if (rc < 0)
    846			return rc;
    847		results += rc;
    848	}
    849
    850	return 0;
    851}
    852
    853const char *efx_mcdi_phy_test_name(struct efx_nic *efx, unsigned int index)
    854{
    855	struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
    856
    857	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
    858		if (index == 0)
    859			return "bist";
    860		--index;
    861	}
    862
    863	if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN) |
    864			      (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) {
    865		if (index == 0)
    866			return "cable";
    867		--index;
    868
    869		if (efx->phy_type == PHY_TYPE_SFT9001B) {
    870			if (index < ARRAY_SIZE(mcdi_sft9001_cable_diag_names))
    871				return mcdi_sft9001_cable_diag_names[index];
    872			index -= ARRAY_SIZE(mcdi_sft9001_cable_diag_names);
    873		}
    874	}
    875
    876	return NULL;
    877}
    878
    879#define SFP_PAGE_SIZE		128
    880#define SFF_DIAG_TYPE_OFFSET	92
    881#define SFF_DIAG_ADDR_CHANGE	BIT(2)
    882#define SFF_8079_NUM_PAGES	2
    883#define SFF_8472_NUM_PAGES	4
    884#define SFF_8436_NUM_PAGES	5
    885#define SFF_DMT_LEVEL_OFFSET	94
    886
    887/** efx_mcdi_phy_get_module_eeprom_page() - Get a single page of module eeprom
    888 * @efx:	NIC context
    889 * @page:	EEPROM page number
    890 * @data:	Destination data pointer
    891 * @offset:	Offset in page to copy from in to data
    892 * @space:	Space available in data
    893 *
    894 * Return:
    895 *   >=0 - amount of data copied
    896 *   <0  - error
    897 */
    898static int efx_mcdi_phy_get_module_eeprom_page(struct efx_nic *efx,
    899					       unsigned int page,
    900					       u8 *data, ssize_t offset,
    901					       ssize_t space)
    902{
    903	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX);
    904	MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN);
    905	unsigned int payload_len;
    906	unsigned int to_copy;
    907	size_t outlen;
    908	int rc;
    909
    910	if (offset > SFP_PAGE_SIZE)
    911		return -EINVAL;
    912
    913	to_copy = min(space, SFP_PAGE_SIZE - offset);
    914
    915	MCDI_SET_DWORD(inbuf, GET_PHY_MEDIA_INFO_IN_PAGE, page);
    916	rc = efx_mcdi_rpc_quiet(efx, MC_CMD_GET_PHY_MEDIA_INFO,
    917				inbuf, sizeof(inbuf),
    918				outbuf, sizeof(outbuf),
    919				&outlen);
    920
    921	if (rc)
    922		return rc;
    923
    924	if (outlen < (MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST +
    925			SFP_PAGE_SIZE))
    926		return -EIO;
    927
    928	payload_len = MCDI_DWORD(outbuf, GET_PHY_MEDIA_INFO_OUT_DATALEN);
    929	if (payload_len != SFP_PAGE_SIZE)
    930		return -EIO;
    931
    932	memcpy(data, MCDI_PTR(outbuf, GET_PHY_MEDIA_INFO_OUT_DATA) + offset,
    933	       to_copy);
    934
    935	return to_copy;
    936}
    937
    938static int efx_mcdi_phy_get_module_eeprom_byte(struct efx_nic *efx,
    939					       unsigned int page,
    940					       u8 byte)
    941{
    942	u8 data;
    943	int rc;
    944
    945	rc = efx_mcdi_phy_get_module_eeprom_page(efx, page, &data, byte, 1);
    946	if (rc == 1)
    947		return data;
    948
    949	return rc;
    950}
    951
    952static int efx_mcdi_phy_diag_type(struct efx_nic *efx)
    953{
    954	/* Page zero of the EEPROM includes the diagnostic type at byte 92. */
    955	return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
    956						   SFF_DIAG_TYPE_OFFSET);
    957}
    958
    959static int efx_mcdi_phy_sff_8472_level(struct efx_nic *efx)
    960{
    961	/* Page zero of the EEPROM includes the DMT level at byte 94. */
    962	return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
    963						   SFF_DMT_LEVEL_OFFSET);
    964}
    965
    966static u32 efx_mcdi_phy_module_type(struct efx_nic *efx)
    967{
    968	struct efx_mcdi_phy_data *phy_data = efx->phy_data;
    969
    970	if (phy_data->media != MC_CMD_MEDIA_QSFP_PLUS)
    971		return phy_data->media;
    972
    973	/* A QSFP+ NIC may actually have an SFP+ module attached.
    974	 * The ID is page 0, byte 0.
    975	 */
    976	switch (efx_mcdi_phy_get_module_eeprom_byte(efx, 0, 0)) {
    977	case 0x3:
    978		return MC_CMD_MEDIA_SFP_PLUS;
    979	case 0xc:
    980	case 0xd:
    981		return MC_CMD_MEDIA_QSFP_PLUS;
    982	default:
    983		return 0;
    984	}
    985}
    986
    987int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx, struct ethtool_eeprom *ee, u8 *data)
    988{
    989	int rc;
    990	ssize_t space_remaining = ee->len;
    991	unsigned int page_off;
    992	bool ignore_missing;
    993	int num_pages;
    994	int page;
    995
    996	switch (efx_mcdi_phy_module_type(efx)) {
    997	case MC_CMD_MEDIA_SFP_PLUS:
    998		num_pages = efx_mcdi_phy_sff_8472_level(efx) > 0 ?
    999				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
   1048int 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
   1088static unsigned int efx_calc_mac_mtu(struct efx_nic *efx)
   1089{
   1090	return EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
   1091}
   1092
   1093int 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
   1137int 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
   1152enum efx_stats_action {
   1153	EFX_STATS_ENABLE,
   1154	EFX_STATS_DISABLE,
   1155	EFX_STATS_PULL,
   1156};
   1157
   1158static 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
   1195void 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
   1204void 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
   1212void 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
   1226int 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
   1251void 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) */
   1257int 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
   1270static 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
   1280void 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}