1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3 * Driver for Solarflare network controllers and boards
4 * Copyright 2018 Solarflare Communications Inc.
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.
11 #include "mcdi_port_common.h"
12 #include "efx_common.h"
15 int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg)
17 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN);
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));
24 rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0,
25 outbuf, sizeof(outbuf), &outlen);
29 if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) {
34 cfg->flags = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_FLAGS);
35 cfg->type = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_TYPE);
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),
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));
51 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
55 void efx_link_set_advertising(struct efx_nic *efx,
56 const unsigned long *advertising)
58 memcpy(efx->link_advertising, advertising,
59 sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
61 efx->link_advertising[0] |= ADVERTISED_Autoneg;
62 if (advertising[0] & ADVERTISED_Pause)
63 efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX);
65 efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
66 if (advertising[0] & ADVERTISED_Asym_Pause)
67 efx->wanted_fc ^= EFX_FC_TX;
70 int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
71 u32 flags, u32 loopback_mode, u32 loopback_speed)
73 MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_LINK_IN_LEN);
76 BUILD_BUG_ON(MC_CMD_SET_LINK_OUT_LEN != 0);
78 MCDI_SET_DWORD(inbuf, SET_LINK_IN_CAP, capabilities);
79 MCDI_SET_DWORD(inbuf, SET_LINK_IN_FLAGS, flags);
80 MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_MODE, loopback_mode);
81 MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_SPEED, loopback_speed);
83 rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
88 int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
90 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LOOPBACK_MODES_OUT_LEN);
94 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0,
95 outbuf, sizeof(outbuf), &outlen);
99 if (outlen < (MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
100 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN)) {
105 *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED);
110 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
114 void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset)
116 #define SET_BIT(name) __set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
119 bitmap_zero(linkset, __ETHTOOL_LINK_MODE_MASK_NBITS);
121 case MC_CMD_MEDIA_KX4:
123 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
124 SET_BIT(1000baseKX_Full);
125 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
126 SET_BIT(10000baseKX4_Full);
127 if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
128 SET_BIT(40000baseKR4_Full);
131 case MC_CMD_MEDIA_XFP:
132 case MC_CMD_MEDIA_SFP_PLUS:
133 case MC_CMD_MEDIA_QSFP_PLUS:
135 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) {
136 SET_BIT(1000baseT_Full);
137 SET_BIT(1000baseX_Full);
139 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) {
140 SET_BIT(10000baseCR_Full);
141 SET_BIT(10000baseLR_Full);
142 SET_BIT(10000baseSR_Full);
144 if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) {
145 SET_BIT(40000baseCR4_Full);
146 SET_BIT(40000baseSR4_Full);
148 if (cap & (1 << MC_CMD_PHY_CAP_100000FDX_LBN)) {
149 SET_BIT(100000baseCR4_Full);
150 SET_BIT(100000baseSR4_Full);
152 if (cap & (1 << MC_CMD_PHY_CAP_25000FDX_LBN)) {
153 SET_BIT(25000baseCR_Full);
154 SET_BIT(25000baseSR_Full);
156 if (cap & (1 << MC_CMD_PHY_CAP_50000FDX_LBN))
157 SET_BIT(50000baseCR2_Full);
160 case MC_CMD_MEDIA_BASE_T:
162 if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
163 SET_BIT(10baseT_Half);
164 if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
165 SET_BIT(10baseT_Full);
166 if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
167 SET_BIT(100baseT_Half);
168 if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
169 SET_BIT(100baseT_Full);
170 if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
171 SET_BIT(1000baseT_Half);
172 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
173 SET_BIT(1000baseT_Full);
174 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
175 SET_BIT(10000baseT_Full);
179 if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
181 if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
183 if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
189 u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset)
193 #define TEST_BIT(name) test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
196 if (TEST_BIT(10baseT_Half))
197 result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN);
198 if (TEST_BIT(10baseT_Full))
199 result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN);
200 if (TEST_BIT(100baseT_Half))
201 result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN);
202 if (TEST_BIT(100baseT_Full))
203 result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN);
204 if (TEST_BIT(1000baseT_Half))
205 result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN);
206 if (TEST_BIT(1000baseT_Full) || TEST_BIT(1000baseKX_Full) ||
207 TEST_BIT(1000baseX_Full))
208 result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN);
209 if (TEST_BIT(10000baseT_Full) || TEST_BIT(10000baseKX4_Full) ||
210 TEST_BIT(10000baseCR_Full) || TEST_BIT(10000baseLR_Full) ||
211 TEST_BIT(10000baseSR_Full))
212 result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN);
213 if (TEST_BIT(40000baseCR4_Full) || TEST_BIT(40000baseKR4_Full) ||
214 TEST_BIT(40000baseSR4_Full))
215 result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN);
216 if (TEST_BIT(100000baseCR4_Full) || TEST_BIT(100000baseSR4_Full))
217 result |= (1 << MC_CMD_PHY_CAP_100000FDX_LBN);
218 if (TEST_BIT(25000baseCR_Full) || TEST_BIT(25000baseSR_Full))
219 result |= (1 << MC_CMD_PHY_CAP_25000FDX_LBN);
220 if (TEST_BIT(50000baseCR2_Full))
221 result |= (1 << MC_CMD_PHY_CAP_50000FDX_LBN);
223 result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN);
224 if (TEST_BIT(Asym_Pause))
225 result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN);
226 if (TEST_BIT(Autoneg))
227 result |= (1 << MC_CMD_PHY_CAP_AN_LBN);
234 u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
236 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
237 enum efx_phy_mode mode, supported;
240 /* TODO: Advertise the capabilities supported by this PHY */
242 if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN))
243 supported |= PHY_MODE_TX_DISABLED;
244 if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN))
245 supported |= PHY_MODE_LOW_POWER;
246 if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN))
247 supported |= PHY_MODE_OFF;
249 mode = efx->phy_mode & supported;
252 if (mode & PHY_MODE_TX_DISABLED)
253 flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN);
254 if (mode & PHY_MODE_LOW_POWER)
255 flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN);
256 if (mode & PHY_MODE_OFF)
257 flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN);
262 u8 mcdi_to_ethtool_media(u32 media)
265 case MC_CMD_MEDIA_XAUI:
266 case MC_CMD_MEDIA_CX4:
267 case MC_CMD_MEDIA_KX4:
270 case MC_CMD_MEDIA_XFP:
271 case MC_CMD_MEDIA_SFP_PLUS:
272 case MC_CMD_MEDIA_QSFP_PLUS:
275 case MC_CMD_MEDIA_BASE_T:
283 void efx_mcdi_phy_decode_link(struct efx_nic *efx,
284 struct efx_link_state *link_state,
285 u32 speed, u32 flags, u32 fcntl)
288 case MC_CMD_FCNTL_AUTO:
289 WARN_ON(1); /* This is not a link mode */
290 link_state->fc = EFX_FC_AUTO | EFX_FC_TX | EFX_FC_RX;
292 case MC_CMD_FCNTL_BIDIR:
293 link_state->fc = EFX_FC_TX | EFX_FC_RX;
295 case MC_CMD_FCNTL_RESPOND:
296 link_state->fc = EFX_FC_RX;
301 case MC_CMD_FCNTL_OFF:
306 link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
307 link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
308 link_state->speed = speed;
311 /* The semantics of the ethtool FEC mode bitmask are not well defined,
312 * particularly the meaning of combinations of bits. Which means we get to
313 * define our own semantics, as follows:
314 * OFF overrides any other bits, and means "disable all FEC" (with the
315 * exception of 25G KR4/CR4, where it is not possible to reject it if AN
316 * partner requests it).
317 * AUTO on its own means use cable requirements and link partner autoneg with
318 * fw-default preferences for the cable type.
319 * AUTO and either RS or BASER means use the specified FEC type if cable and
320 * link partner support it, otherwise autoneg/fw-default.
321 * RS or BASER alone means use the specified FEC type if cable and link partner
322 * support it and either requests it, otherwise no FEC.
323 * Both RS and BASER (whether AUTO or not) means use FEC if cable and link
324 * partner support it, preferring RS to BASER.
326 u32 ethtool_fec_caps_to_mcdi(u32 supported_cap, u32 ethtool_cap)
330 if (ethtool_cap & ETHTOOL_FEC_OFF)
333 if (ethtool_cap & ETHTOOL_FEC_AUTO)
334 ret |= ((1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
335 (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
336 (1 << MC_CMD_PHY_CAP_RS_FEC_LBN)) & supported_cap;
337 if (ethtool_cap & ETHTOOL_FEC_RS &&
338 supported_cap & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN))
339 ret |= (1 << MC_CMD_PHY_CAP_RS_FEC_LBN) |
340 (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN);
341 if (ethtool_cap & ETHTOOL_FEC_BASER) {
342 if (supported_cap & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN))
343 ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
344 (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
345 if (supported_cap & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN))
346 ret |= (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
347 (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN);
352 /* Invert ethtool_fec_caps_to_mcdi. There are two combinations that function
353 * can never produce, (baser xor rs) and neither req; the implementation below
354 * maps both of those to AUTO. This should never matter, and it's not clear
355 * what a better mapping would be anyway.
357 u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g)
359 bool rs = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN),
360 rs_req = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN),
361 baser = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN)
362 : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN),
363 baser_req = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN)
364 : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
367 return ETHTOOL_FEC_OFF;
368 return (rs_req ? ETHTOOL_FEC_RS : 0) |
369 (baser_req ? ETHTOOL_FEC_BASER : 0) |
370 (baser == baser_req && rs == rs_req ? 0 : ETHTOOL_FEC_AUTO);
373 /* Verify that the forced flow control settings (!EFX_FC_AUTO) are
374 * supported by the link partner. Warn the user if this isn't the case
376 void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa)
378 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
381 /* The link partner capabilities are only relevant if the
382 * link supports flow control autonegotiation
384 if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
387 /* If flow control autoneg is supported and enabled, then fine */
388 if (efx->wanted_fc & EFX_FC_AUTO)
392 if (lpa & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
393 rmtadv |= ADVERTISED_Pause;
394 if (lpa & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
395 rmtadv |= ADVERTISED_Asym_Pause;
397 if ((efx->wanted_fc & EFX_FC_TX) && rmtadv == ADVERTISED_Asym_Pause)
398 netif_err(efx, link, efx->net_dev,
399 "warning: link partner doesn't support pause frames");
402 bool efx_mcdi_phy_poll(struct efx_nic *efx)
404 struct efx_link_state old_state = efx->link_state;
405 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
408 WARN_ON(!mutex_is_locked(&efx->mac_lock));
410 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
412 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
413 outbuf, sizeof(outbuf), NULL);
415 efx->link_state.up = false;
417 efx_mcdi_phy_decode_link(
418 efx, &efx->link_state,
419 MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
420 MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
421 MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
423 return !efx_link_state_equal(&efx->link_state, &old_state);
426 int efx_mcdi_phy_probe(struct efx_nic *efx)
428 struct efx_mcdi_phy_data *phy_data;
429 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
433 /* Initialise and populate phy_data */
434 phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
435 if (phy_data == NULL)
438 rc = efx_mcdi_get_phy_cfg(efx, phy_data);
442 /* Read initial link advertisement */
443 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
444 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
445 outbuf, sizeof(outbuf), NULL);
449 /* Fill out nic state */
450 efx->phy_data = phy_data;
451 efx->phy_type = phy_data->type;
453 efx->mdio_bus = phy_data->channel;
454 efx->mdio.prtad = phy_data->port;
455 efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
456 efx->mdio.mode_support = 0;
457 if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
458 efx->mdio.mode_support |= MDIO_SUPPORTS_C22;
459 if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
460 efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
462 caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
463 if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
464 mcdi_to_ethtool_linkset(phy_data->media, caps,
465 efx->link_advertising);
467 phy_data->forced_cap = caps;
469 /* Assert that we can map efx -> mcdi loopback modes */
470 BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE);
471 BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA);
472 BUILD_BUG_ON(LOOPBACK_GMAC != MC_CMD_LOOPBACK_GMAC);
473 BUILD_BUG_ON(LOOPBACK_XGMII != MC_CMD_LOOPBACK_XGMII);
474 BUILD_BUG_ON(LOOPBACK_XGXS != MC_CMD_LOOPBACK_XGXS);
475 BUILD_BUG_ON(LOOPBACK_XAUI != MC_CMD_LOOPBACK_XAUI);
476 BUILD_BUG_ON(LOOPBACK_GMII != MC_CMD_LOOPBACK_GMII);
477 BUILD_BUG_ON(LOOPBACK_SGMII != MC_CMD_LOOPBACK_SGMII);
478 BUILD_BUG_ON(LOOPBACK_XGBR != MC_CMD_LOOPBACK_XGBR);
479 BUILD_BUG_ON(LOOPBACK_XFI != MC_CMD_LOOPBACK_XFI);
480 BUILD_BUG_ON(LOOPBACK_XAUI_FAR != MC_CMD_LOOPBACK_XAUI_FAR);
481 BUILD_BUG_ON(LOOPBACK_GMII_FAR != MC_CMD_LOOPBACK_GMII_FAR);
482 BUILD_BUG_ON(LOOPBACK_SGMII_FAR != MC_CMD_LOOPBACK_SGMII_FAR);
483 BUILD_BUG_ON(LOOPBACK_XFI_FAR != MC_CMD_LOOPBACK_XFI_FAR);
484 BUILD_BUG_ON(LOOPBACK_GPHY != MC_CMD_LOOPBACK_GPHY);
485 BUILD_BUG_ON(LOOPBACK_PHYXS != MC_CMD_LOOPBACK_PHYXS);
486 BUILD_BUG_ON(LOOPBACK_PCS != MC_CMD_LOOPBACK_PCS);
487 BUILD_BUG_ON(LOOPBACK_PMAPMD != MC_CMD_LOOPBACK_PMAPMD);
488 BUILD_BUG_ON(LOOPBACK_XPORT != MC_CMD_LOOPBACK_XPORT);
489 BUILD_BUG_ON(LOOPBACK_XGMII_WS != MC_CMD_LOOPBACK_XGMII_WS);
490 BUILD_BUG_ON(LOOPBACK_XAUI_WS != MC_CMD_LOOPBACK_XAUI_WS);
491 BUILD_BUG_ON(LOOPBACK_XAUI_WS_FAR != MC_CMD_LOOPBACK_XAUI_WS_FAR);
492 BUILD_BUG_ON(LOOPBACK_XAUI_WS_NEAR != MC_CMD_LOOPBACK_XAUI_WS_NEAR);
493 BUILD_BUG_ON(LOOPBACK_GMII_WS != MC_CMD_LOOPBACK_GMII_WS);
494 BUILD_BUG_ON(LOOPBACK_XFI_WS != MC_CMD_LOOPBACK_XFI_WS);
495 BUILD_BUG_ON(LOOPBACK_XFI_WS_FAR != MC_CMD_LOOPBACK_XFI_WS_FAR);
496 BUILD_BUG_ON(LOOPBACK_PHYXS_WS != MC_CMD_LOOPBACK_PHYXS_WS);
498 rc = efx_mcdi_loopback_modes(efx, &efx->loopback_modes);
501 /* The MC indicates that LOOPBACK_NONE is a valid loopback mode,
502 * but by convention we don't
504 efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
506 /* Set the initial link mode */
507 efx_mcdi_phy_decode_link(efx, &efx->link_state,
508 MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
509 MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
510 MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
512 /* Record the initial FEC configuration (or nearest approximation
513 * representable in the ethtool configuration space)
515 efx->fec_config = mcdi_fec_caps_to_ethtool(caps,
516 efx->link_state.speed == 25000 ||
517 efx->link_state.speed == 50000);
519 /* Default to Autonegotiated flow control if the PHY supports it */
520 efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
521 if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
522 efx->wanted_fc |= EFX_FC_AUTO;
523 efx_link_set_wanted_fc(efx, efx->wanted_fc);
532 void efx_mcdi_phy_remove(struct efx_nic *efx)
534 struct efx_mcdi_phy_data *phy_data = efx->phy_data;
536 efx->phy_data = NULL;
540 void efx_mcdi_phy_get_link_ksettings(struct efx_nic *efx, struct ethtool_link_ksettings *cmd)
542 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
543 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
546 cmd->base.speed = efx->link_state.speed;
547 cmd->base.duplex = efx->link_state.fd;
548 cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media);
549 cmd->base.phy_address = phy_cfg->port;
550 cmd->base.autoneg = !!(efx->link_advertising[0] & ADVERTISED_Autoneg);
551 cmd->base.mdio_support = (efx->mdio.mode_support &
552 (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
554 mcdi_to_ethtool_linkset(phy_cfg->media, phy_cfg->supported_cap,
555 cmd->link_modes.supported);
556 memcpy(cmd->link_modes.advertising, efx->link_advertising,
557 sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
559 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
560 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
561 outbuf, sizeof(outbuf), NULL);
564 mcdi_to_ethtool_linkset(phy_cfg->media,
565 MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP),
566 cmd->link_modes.lp_advertising);
569 int efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx, const struct ethtool_link_ksettings *cmd)
571 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
575 if (cmd->base.autoneg) {
576 caps = (ethtool_linkset_to_mcdi_cap(cmd->link_modes.advertising) |
577 1 << MC_CMD_PHY_CAP_AN_LBN);
578 } else if (cmd->base.duplex) {
579 switch (cmd->base.speed) {
580 case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break;
581 case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break;
582 case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break;
583 case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break;
584 case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break;
585 case 100000: caps = 1 << MC_CMD_PHY_CAP_100000FDX_LBN; break;
586 case 25000: caps = 1 << MC_CMD_PHY_CAP_25000FDX_LBN; break;
587 case 50000: caps = 1 << MC_CMD_PHY_CAP_50000FDX_LBN; break;
588 default: return -EINVAL;
591 switch (cmd->base.speed) {
592 case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break;
593 case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break;
594 case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break;
595 default: return -EINVAL;
599 caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, efx->fec_config);
601 rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
602 efx->loopback_mode, 0);
606 if (cmd->base.autoneg) {
607 efx_link_set_advertising(efx, cmd->link_modes.advertising);
608 phy_cfg->forced_cap = 0;
610 efx_link_clear_advertising(efx);
611 phy_cfg->forced_cap = caps;
616 int efx_mcdi_phy_get_fecparam(struct efx_nic *efx, struct ethtool_fecparam *fec)
618 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN);
619 u32 caps, active, speed; /* MCDI format */
624 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
625 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
626 outbuf, sizeof(outbuf), &outlen);
629 if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN)
632 /* behaviour for 25G/50G links depends on 25G BASER bit */
633 speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED);
634 is_25g = speed == 25000 || speed == 50000;
636 caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP);
637 fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g);
638 /* BASER is never supported on 100G */
640 fec->fec &= ~ETHTOOL_FEC_BASER;
642 active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE);
644 case MC_CMD_FEC_NONE:
645 fec->active_fec = ETHTOOL_FEC_OFF;
647 case MC_CMD_FEC_BASER:
648 fec->active_fec = ETHTOOL_FEC_BASER;
651 fec->active_fec = ETHTOOL_FEC_RS;
654 netif_warn(efx, hw, efx->net_dev,
655 "Firmware reports unrecognised FEC_TYPE %u\n",
657 /* We don't know what firmware has picked. AUTO is as good a
658 * "can't happen" value as any other.
660 fec->active_fec = ETHTOOL_FEC_AUTO;
667 /* Basic validation to ensure that the caps we are going to attempt to set are
668 * in fact supported by the adapter. Note that 'no FEC' is always supported.
670 static int ethtool_fec_supported(u32 supported_cap, u32 ethtool_cap)
672 if (ethtool_cap & ETHTOOL_FEC_OFF)
676 !ethtool_fec_caps_to_mcdi(supported_cap, ethtool_cap))
681 int efx_mcdi_phy_set_fecparam(struct efx_nic *efx, const struct ethtool_fecparam *fec)
683 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
687 rc = ethtool_fec_supported(phy_cfg->supported_cap, fec->fec);
691 /* Work out what efx_mcdi_phy_set_link_ksettings() would produce from
692 * saved advertising bits
694 if (test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, efx->link_advertising))
695 caps = (ethtool_linkset_to_mcdi_cap(efx->link_advertising) |
696 1 << MC_CMD_PHY_CAP_AN_LBN);
698 caps = phy_cfg->forced_cap;
700 caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, fec->fec);
701 rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
702 efx->loopback_mode, 0);
706 /* Record the new FEC setting for subsequent set_link calls */
707 efx->fec_config = fec->fec;
711 int efx_mcdi_phy_test_alive(struct efx_nic *efx)
713 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN);
717 BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
719 rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
720 outbuf, sizeof(outbuf), &outlen);
724 if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
726 if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK)
732 int efx_mcdi_port_reconfigure(struct efx_nic *efx)
734 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
735 u32 caps = (efx->link_advertising[0] ?
736 ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
737 phy_cfg->forced_cap);
739 caps |= ethtool_fec_caps_to_mcdi(phy_cfg->supported_cap, efx->fec_config);
741 return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
742 efx->loopback_mode, 0);
745 static const char *const mcdi_sft9001_cable_diag_names[] = {
746 "cable.pairA.length",
747 "cable.pairB.length",
748 "cable.pairC.length",
749 "cable.pairD.length",
750 "cable.pairA.status",
751 "cable.pairB.status",
752 "cable.pairC.status",
753 "cable.pairD.status",
756 static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
759 unsigned int retry, i, count = 0;
762 MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
763 MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_SFT9001_LEN);
767 BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0);
768 MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_mode);
769 rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST,
770 inbuf, MC_CMD_START_BIST_IN_LEN, NULL, 0, NULL);
774 /* Wait up to 10s for BIST to finish */
775 for (retry = 0; retry < 100; ++retry) {
776 BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0);
777 rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
778 outbuf, sizeof(outbuf), &outlen);
782 status = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
783 if (status != MC_CMD_POLL_BIST_RUNNING)
793 results[count++] = (status == MC_CMD_POLL_BIST_PASSED) ? 1 : -1;
795 /* SFT9001 specific cable diagnostics output */
796 if (efx->phy_type == PHY_TYPE_SFT9001B &&
797 (bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT ||
798 bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) {
799 ptr = MCDI_PTR(outbuf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
800 if (status == MC_CMD_POLL_BIST_PASSED &&
801 outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) {
802 for (i = 0; i < 8; i++) {
804 EFX_DWORD_FIELD(((efx_dword_t *)ptr)[i],
816 int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, unsigned int flags)
818 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
822 if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
823 rc = efx_mcdi_bist(efx, MC_CMD_PHY_BIST, results);
830 /* If we support both LONG and SHORT, then run each in response to
831 * break or not. Otherwise, run the one we support
834 if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN)) {
835 if ((flags & ETH_TEST_FL_OFFLINE) &&
837 (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN)))
838 mode = MC_CMD_PHY_BIST_CABLE_LONG;
840 mode = MC_CMD_PHY_BIST_CABLE_SHORT;
841 } else if (phy_cfg->flags &
842 (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))
843 mode = MC_CMD_PHY_BIST_CABLE_LONG;
846 rc = efx_mcdi_bist(efx, mode, results);
855 const char *efx_mcdi_phy_test_name(struct efx_nic *efx, unsigned int index)
857 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
859 if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
865 if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN) |
866 (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) {
871 if (efx->phy_type == PHY_TYPE_SFT9001B) {
872 if (index < ARRAY_SIZE(mcdi_sft9001_cable_diag_names))
873 return mcdi_sft9001_cable_diag_names[index];
874 index -= ARRAY_SIZE(mcdi_sft9001_cable_diag_names);
881 #define SFP_PAGE_SIZE 128
882 #define SFF_DIAG_TYPE_OFFSET 92
883 #define SFF_DIAG_ADDR_CHANGE BIT(2)
884 #define SFF_8079_NUM_PAGES 2
885 #define SFF_8472_NUM_PAGES 4
886 #define SFF_8436_NUM_PAGES 5
887 #define SFF_DMT_LEVEL_OFFSET 94
889 /** efx_mcdi_phy_get_module_eeprom_page() - Get a single page of module eeprom
891 * @page: EEPROM page number
892 * @data: Destination data pointer
893 * @offset: Offset in page to copy from in to data
894 * @space: Space available in data
897 * >=0 - amount of data copied
900 static int efx_mcdi_phy_get_module_eeprom_page(struct efx_nic *efx,
902 u8 *data, ssize_t offset,
905 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX);
906 MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN);
907 unsigned int payload_len;
908 unsigned int to_copy;
912 if (offset > SFP_PAGE_SIZE)
915 to_copy = min(space, SFP_PAGE_SIZE - offset);
917 MCDI_SET_DWORD(inbuf, GET_PHY_MEDIA_INFO_IN_PAGE, page);
918 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_GET_PHY_MEDIA_INFO,
919 inbuf, sizeof(inbuf),
920 outbuf, sizeof(outbuf),
926 if (outlen < (MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST +
930 payload_len = MCDI_DWORD(outbuf, GET_PHY_MEDIA_INFO_OUT_DATALEN);
931 if (payload_len != SFP_PAGE_SIZE)
934 memcpy(data, MCDI_PTR(outbuf, GET_PHY_MEDIA_INFO_OUT_DATA) + offset,
940 static int efx_mcdi_phy_get_module_eeprom_byte(struct efx_nic *efx,
947 rc = efx_mcdi_phy_get_module_eeprom_page(efx, page, &data, byte, 1);
954 static int efx_mcdi_phy_diag_type(struct efx_nic *efx)
956 /* Page zero of the EEPROM includes the diagnostic type at byte 92. */
957 return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
958 SFF_DIAG_TYPE_OFFSET);
961 static int efx_mcdi_phy_sff_8472_level(struct efx_nic *efx)
963 /* Page zero of the EEPROM includes the DMT level at byte 94. */
964 return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
965 SFF_DMT_LEVEL_OFFSET);
968 static u32 efx_mcdi_phy_module_type(struct efx_nic *efx)
970 struct efx_mcdi_phy_data *phy_data = efx->phy_data;
972 if (phy_data->media != MC_CMD_MEDIA_QSFP_PLUS)
973 return phy_data->media;
975 /* A QSFP+ NIC may actually have an SFP+ module attached.
976 * The ID is page 0, byte 0.
978 switch (efx_mcdi_phy_get_module_eeprom_byte(efx, 0, 0)) {
980 return MC_CMD_MEDIA_SFP_PLUS;
983 return MC_CMD_MEDIA_QSFP_PLUS;
989 int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx, struct ethtool_eeprom *ee, u8 *data)
992 ssize_t space_remaining = ee->len;
993 unsigned int page_off;
998 switch (efx_mcdi_phy_module_type(efx)) {
999 case MC_CMD_MEDIA_SFP_PLUS:
1000 num_pages = efx_mcdi_phy_sff_8472_level(efx) > 0 ?
1001 SFF_8472_NUM_PAGES : SFF_8079_NUM_PAGES;
1003 ignore_missing = false;
1005 case MC_CMD_MEDIA_QSFP_PLUS:
1006 num_pages = SFF_8436_NUM_PAGES;
1007 page = -1; /* We obtain the lower page by asking for -1. */
1008 ignore_missing = true; /* Ignore missing pages after page 0. */
1014 page_off = ee->offset % SFP_PAGE_SIZE;
1015 page += ee->offset / SFP_PAGE_SIZE;
1017 while (space_remaining && (page < num_pages)) {
1018 rc = efx_mcdi_phy_get_module_eeprom_page(efx, page,
1023 space_remaining -= rc;
1027 } else if (rc == 0) {
1028 space_remaining = 0;
1029 } else if (ignore_missing && (page > 0)) {
1030 int intended_size = SFP_PAGE_SIZE - page_off;
1032 space_remaining -= intended_size;
1033 if (space_remaining < 0) {
1034 space_remaining = 0;
1036 memset(data, 0, intended_size);
1037 data += intended_size;
1050 int efx_mcdi_phy_get_module_info(struct efx_nic *efx, struct ethtool_modinfo *modinfo)
1055 switch (efx_mcdi_phy_module_type(efx)) {
1056 case MC_CMD_MEDIA_SFP_PLUS:
1057 sff_8472_level = efx_mcdi_phy_sff_8472_level(efx);
1059 /* If we can't read the diagnostics level we have none. */
1060 if (sff_8472_level < 0)
1063 /* Check if this module requires the (unsupported) address
1066 diag_type = efx_mcdi_phy_diag_type(efx);
1068 if (sff_8472_level == 0 ||
1069 (diag_type & SFF_DIAG_ADDR_CHANGE)) {
1070 modinfo->type = ETH_MODULE_SFF_8079;
1071 modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
1073 modinfo->type = ETH_MODULE_SFF_8472;
1074 modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1078 case MC_CMD_MEDIA_QSFP_PLUS:
1079 modinfo->type = ETH_MODULE_SFF_8436;
1080 modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
1090 static unsigned int efx_calc_mac_mtu(struct efx_nic *efx)
1092 return EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
1095 int efx_mcdi_set_mac(struct efx_nic *efx)
1098 MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN);
1100 BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
1102 /* This has no effect on EF10 */
1103 ether_addr_copy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
1104 efx->net_dev->dev_addr);
1106 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU, efx_calc_mac_mtu(efx));
1107 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0);
1109 /* Set simple MAC filter for Siena */
1110 MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_REJECT,
1111 SET_MAC_IN_REJECT_UNCST, efx->unicast_filter);
1113 MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_FLAGS,
1114 SET_MAC_IN_FLAG_INCLUDE_FCS,
1115 !!(efx->net_dev->features & NETIF_F_RXFCS));
1117 switch (efx->wanted_fc) {
1118 case EFX_FC_RX | EFX_FC_TX:
1119 fcntl = MC_CMD_FCNTL_BIDIR;
1122 fcntl = MC_CMD_FCNTL_RESPOND;
1125 fcntl = MC_CMD_FCNTL_OFF;
1128 if (efx->wanted_fc & EFX_FC_AUTO)
1129 fcntl = MC_CMD_FCNTL_AUTO;
1130 if (efx->fc_disable)
1131 fcntl = MC_CMD_FCNTL_OFF;
1133 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
1135 return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes),
1139 int efx_mcdi_set_mtu(struct efx_nic *efx)
1141 MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_MAC_EXT_IN_LEN);
1143 BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
1145 MCDI_SET_DWORD(inbuf, SET_MAC_EXT_IN_MTU, efx_calc_mac_mtu(efx));
1147 MCDI_POPULATE_DWORD_1(inbuf, SET_MAC_EXT_IN_CONTROL,
1148 SET_MAC_EXT_IN_CFG_MTU, 1);
1150 return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, inbuf, sizeof(inbuf),
1154 enum efx_stats_action {
1160 static int efx_mcdi_mac_stats(struct efx_nic *efx,
1161 enum efx_stats_action action, int clear)
1163 MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
1165 int change = action == EFX_STATS_PULL ? 0 : 1;
1166 int enable = action == EFX_STATS_ENABLE ? 1 : 0;
1167 int period = action == EFX_STATS_ENABLE ? 1000 : 0;
1168 dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
1169 u32 dma_len = action != EFX_STATS_DISABLE ?
1170 efx->num_mac_stats * sizeof(u64) : 0;
1172 BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
1174 MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, dma_addr);
1175 MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
1176 MAC_STATS_IN_DMA, !!enable,
1177 MAC_STATS_IN_CLEAR, clear,
1178 MAC_STATS_IN_PERIODIC_CHANGE, change,
1179 MAC_STATS_IN_PERIODIC_ENABLE, enable,
1180 MAC_STATS_IN_PERIODIC_CLEAR, 0,
1181 MAC_STATS_IN_PERIODIC_NOEVENT, 1,
1182 MAC_STATS_IN_PERIOD_MS, period);
1183 MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
1185 if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0)
1186 MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, efx->vport_id);
1188 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
1190 /* Expect ENOENT if DMA queues have not been set up */
1191 if (rc && (rc != -ENOENT || atomic_read(&efx->active_queues)))
1192 efx_mcdi_display_error(efx, MC_CMD_MAC_STATS, sizeof(inbuf),
1197 void efx_mcdi_mac_start_stats(struct efx_nic *efx)
1199 __le64 *dma_stats = efx->stats_buffer.addr;
1201 dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
1203 efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
1206 void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
1208 efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
1211 #define EFX_MAC_STATS_WAIT_US 100
1212 #define EFX_MAC_STATS_WAIT_ATTEMPTS 10
1214 void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
1216 __le64 *dma_stats = efx->stats_buffer.addr;
1217 int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
1219 dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
1220 efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
1222 while (dma_stats[efx->num_mac_stats - 1] ==
1223 EFX_MC_STATS_GENERATION_INVALID &&
1225 udelay(EFX_MAC_STATS_WAIT_US);
1228 int efx_mcdi_mac_init_stats(struct efx_nic *efx)
1232 if (!efx->num_mac_stats)
1235 /* Allocate buffer for stats */
1236 rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
1237 efx->num_mac_stats * sizeof(u64), GFP_KERNEL);
1239 netif_warn(efx, probe, efx->net_dev,
1240 "failed to allocate DMA buffer: %d\n", rc);
1244 netif_dbg(efx, probe, efx->net_dev,
1245 "stats buffer at %llx (virt %p phys %llx)\n",
1246 (u64) efx->stats_buffer.dma_addr,
1247 efx->stats_buffer.addr,
1248 (u64) virt_to_phys(efx->stats_buffer.addr));
1253 void efx_mcdi_mac_fini_stats(struct efx_nic *efx)
1255 efx_nic_free_buffer(efx, &efx->stats_buffer);
1258 /* Get physical port number (EF10 only; on Siena it is same as PF number) */
1259 int efx_mcdi_port_get_number(struct efx_nic *efx)
1261 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
1264 rc = efx_mcdi_rpc(efx, MC_CMD_GET_PORT_ASSIGNMENT, NULL, 0,
1265 outbuf, sizeof(outbuf), NULL);
1269 return MCDI_DWORD(outbuf, GET_PORT_ASSIGNMENT_OUT_PORT);
1272 static unsigned int efx_mcdi_event_link_speed[] = {
1273 [MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
1274 [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
1275 [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
1276 [MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000,
1277 [MCDI_EVENT_LINKCHANGE_SPEED_25G] = 25000,
1278 [MCDI_EVENT_LINKCHANGE_SPEED_50G] = 50000,
1279 [MCDI_EVENT_LINKCHANGE_SPEED_100G] = 100000,
1282 void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
1284 u32 flags, fcntl, speed, lpa;
1286 speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED);
1287 EFX_WARN_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed));
1288 speed = efx_mcdi_event_link_speed[speed];
1290 flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS);
1291 fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL);
1292 lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP);
1294 /* efx->link_state is only modified by efx_mcdi_phy_get_link(),
1295 * which is only run after flushing the event queues. Therefore, it
1296 * is safe to modify the link state outside of the mac_lock here.
1298 efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);
1300 efx_mcdi_phy_check_fcntl(efx, lpa);
1302 efx_link_status_changed(efx);