gpio: rcar: Fix runtime PM imbalance on error
[linux/fpc-iii.git] / drivers / net / ethernet / sfc / mcdi_port_common.c
bloba6a072ba46d3714342fc17008a4d190b8dd1e294
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.
9 */
11 #include "mcdi_port_common.h"
12 #include "efx_common.h"
14 int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg)
16 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN);
17 size_t outlen;
18 int rc;
20 BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_IN_LEN != 0);
21 BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_OUT_NAME_LEN != sizeof(cfg->name));
23 rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0,
24 outbuf, sizeof(outbuf), &outlen);
25 if (rc)
26 goto fail;
28 if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) {
29 rc = -EIO;
30 goto fail;
33 cfg->flags = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_FLAGS);
34 cfg->type = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_TYPE);
35 cfg->supported_cap =
36 MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_SUPPORTED_CAP);
37 cfg->channel = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_CHANNEL);
38 cfg->port = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_PRT);
39 cfg->stats_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_STATS_MASK);
40 memcpy(cfg->name, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_NAME),
41 sizeof(cfg->name));
42 cfg->media = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MEDIA_TYPE);
43 cfg->mmd_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MMD_MASK);
44 memcpy(cfg->revision, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_REVISION),
45 sizeof(cfg->revision));
47 return 0;
49 fail:
50 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
51 return rc;
54 void efx_link_set_advertising(struct efx_nic *efx,
55 const unsigned long *advertising)
57 memcpy(efx->link_advertising, advertising,
58 sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
60 efx->link_advertising[0] |= ADVERTISED_Autoneg;
61 if (advertising[0] & ADVERTISED_Pause)
62 efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX);
63 else
64 efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
65 if (advertising[0] & ADVERTISED_Asym_Pause)
66 efx->wanted_fc ^= EFX_FC_TX;
69 int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
70 u32 flags, u32 loopback_mode, u32 loopback_speed)
72 MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_LINK_IN_LEN);
73 int rc;
75 BUILD_BUG_ON(MC_CMD_SET_LINK_OUT_LEN != 0);
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);
82 rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
83 NULL, 0, NULL);
84 return rc;
87 int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
89 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LOOPBACK_MODES_OUT_LEN);
90 size_t outlen;
91 int rc;
93 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0,
94 outbuf, sizeof(outbuf), &outlen);
95 if (rc)
96 goto fail;
98 if (outlen < (MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
99 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN)) {
100 rc = -EIO;
101 goto fail;
104 *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED);
106 return 0;
108 fail:
109 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
110 return rc;
113 void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset)
115 #define SET_BIT(name) __set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
116 linkset)
118 bitmap_zero(linkset, __ETHTOOL_LINK_MODE_MASK_NBITS);
119 switch (media) {
120 case MC_CMD_MEDIA_KX4:
121 SET_BIT(Backplane);
122 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
123 SET_BIT(1000baseKX_Full);
124 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
125 SET_BIT(10000baseKX4_Full);
126 if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
127 SET_BIT(40000baseKR4_Full);
128 break;
130 case MC_CMD_MEDIA_XFP:
131 case MC_CMD_MEDIA_SFP_PLUS:
132 case MC_CMD_MEDIA_QSFP_PLUS:
133 SET_BIT(FIBRE);
134 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
135 SET_BIT(1000baseT_Full);
136 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
137 SET_BIT(10000baseT_Full);
138 if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
139 SET_BIT(40000baseCR4_Full);
140 if (cap & (1 << MC_CMD_PHY_CAP_100000FDX_LBN))
141 SET_BIT(100000baseCR4_Full);
142 if (cap & (1 << MC_CMD_PHY_CAP_25000FDX_LBN))
143 SET_BIT(25000baseCR_Full);
144 if (cap & (1 << MC_CMD_PHY_CAP_50000FDX_LBN))
145 SET_BIT(50000baseCR2_Full);
146 break;
148 case MC_CMD_MEDIA_BASE_T:
149 SET_BIT(TP);
150 if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
151 SET_BIT(10baseT_Half);
152 if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
153 SET_BIT(10baseT_Full);
154 if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
155 SET_BIT(100baseT_Half);
156 if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
157 SET_BIT(100baseT_Full);
158 if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
159 SET_BIT(1000baseT_Half);
160 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
161 SET_BIT(1000baseT_Full);
162 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
163 SET_BIT(10000baseT_Full);
164 break;
167 if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
168 SET_BIT(Pause);
169 if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
170 SET_BIT(Asym_Pause);
171 if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
172 SET_BIT(Autoneg);
174 #undef SET_BIT
177 u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset)
179 u32 result = 0;
181 #define TEST_BIT(name) test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
182 linkset)
184 if (TEST_BIT(10baseT_Half))
185 result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN);
186 if (TEST_BIT(10baseT_Full))
187 result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN);
188 if (TEST_BIT(100baseT_Half))
189 result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN);
190 if (TEST_BIT(100baseT_Full))
191 result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN);
192 if (TEST_BIT(1000baseT_Half))
193 result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN);
194 if (TEST_BIT(1000baseT_Full) || TEST_BIT(1000baseKX_Full))
195 result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN);
196 if (TEST_BIT(10000baseT_Full) || TEST_BIT(10000baseKX4_Full))
197 result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN);
198 if (TEST_BIT(40000baseCR4_Full) || TEST_BIT(40000baseKR4_Full))
199 result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN);
200 if (TEST_BIT(100000baseCR4_Full))
201 result |= (1 << MC_CMD_PHY_CAP_100000FDX_LBN);
202 if (TEST_BIT(25000baseCR_Full))
203 result |= (1 << MC_CMD_PHY_CAP_25000FDX_LBN);
204 if (TEST_BIT(50000baseCR2_Full))
205 result |= (1 << MC_CMD_PHY_CAP_50000FDX_LBN);
206 if (TEST_BIT(Pause))
207 result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN);
208 if (TEST_BIT(Asym_Pause))
209 result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN);
210 if (TEST_BIT(Autoneg))
211 result |= (1 << MC_CMD_PHY_CAP_AN_LBN);
213 #undef TEST_BIT
215 return result;
218 u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
220 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
221 enum efx_phy_mode mode, supported;
222 u32 flags;
224 /* TODO: Advertise the capabilities supported by this PHY */
225 supported = 0;
226 if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN))
227 supported |= PHY_MODE_TX_DISABLED;
228 if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN))
229 supported |= PHY_MODE_LOW_POWER;
230 if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN))
231 supported |= PHY_MODE_OFF;
233 mode = efx->phy_mode & supported;
235 flags = 0;
236 if (mode & PHY_MODE_TX_DISABLED)
237 flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN);
238 if (mode & PHY_MODE_LOW_POWER)
239 flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN);
240 if (mode & PHY_MODE_OFF)
241 flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN);
243 return flags;
246 u8 mcdi_to_ethtool_media(u32 media)
248 switch (media) {
249 case MC_CMD_MEDIA_XAUI:
250 case MC_CMD_MEDIA_CX4:
251 case MC_CMD_MEDIA_KX4:
252 return PORT_OTHER;
254 case MC_CMD_MEDIA_XFP:
255 case MC_CMD_MEDIA_SFP_PLUS:
256 case MC_CMD_MEDIA_QSFP_PLUS:
257 return PORT_FIBRE;
259 case MC_CMD_MEDIA_BASE_T:
260 return PORT_TP;
262 default:
263 return PORT_OTHER;
267 void efx_mcdi_phy_decode_link(struct efx_nic *efx,
268 struct efx_link_state *link_state,
269 u32 speed, u32 flags, u32 fcntl)
271 switch (fcntl) {
272 case MC_CMD_FCNTL_AUTO:
273 WARN_ON(1); /* This is not a link mode */
274 link_state->fc = EFX_FC_AUTO | EFX_FC_TX | EFX_FC_RX;
275 break;
276 case MC_CMD_FCNTL_BIDIR:
277 link_state->fc = EFX_FC_TX | EFX_FC_RX;
278 break;
279 case MC_CMD_FCNTL_RESPOND:
280 link_state->fc = EFX_FC_RX;
281 break;
282 default:
283 WARN_ON(1);
284 /* Fall through */
285 case MC_CMD_FCNTL_OFF:
286 link_state->fc = 0;
287 break;
290 link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
291 link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
292 link_state->speed = speed;
295 /* The semantics of the ethtool FEC mode bitmask are not well defined,
296 * particularly the meaning of combinations of bits. Which means we get to
297 * define our own semantics, as follows:
298 * OFF overrides any other bits, and means "disable all FEC" (with the
299 * exception of 25G KR4/CR4, where it is not possible to reject it if AN
300 * partner requests it).
301 * AUTO on its own means use cable requirements and link partner autoneg with
302 * fw-default preferences for the cable type.
303 * AUTO and either RS or BASER means use the specified FEC type if cable and
304 * link partner support it, otherwise autoneg/fw-default.
305 * RS or BASER alone means use the specified FEC type if cable and link partner
306 * support it and either requests it, otherwise no FEC.
307 * Both RS and BASER (whether AUTO or not) means use FEC if cable and link
308 * partner support it, preferring RS to BASER.
310 u32 ethtool_fec_caps_to_mcdi(u32 ethtool_cap)
312 u32 ret = 0;
314 if (ethtool_cap & ETHTOOL_FEC_OFF)
315 return 0;
317 if (ethtool_cap & ETHTOOL_FEC_AUTO)
318 ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
319 (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
320 (1 << MC_CMD_PHY_CAP_RS_FEC_LBN);
321 if (ethtool_cap & ETHTOOL_FEC_RS)
322 ret |= (1 << MC_CMD_PHY_CAP_RS_FEC_LBN) |
323 (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN);
324 if (ethtool_cap & ETHTOOL_FEC_BASER)
325 ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
326 (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
327 (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN) |
328 (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN);
329 return ret;
332 /* Invert ethtool_fec_caps_to_mcdi. There are two combinations that function
333 * can never produce, (baser xor rs) and neither req; the implementation below
334 * maps both of those to AUTO. This should never matter, and it's not clear
335 * what a better mapping would be anyway.
337 u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g)
339 bool rs = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN),
340 rs_req = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN),
341 baser = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN)
342 : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN),
343 baser_req = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN)
344 : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
346 if (!baser && !rs)
347 return ETHTOOL_FEC_OFF;
348 return (rs_req ? ETHTOOL_FEC_RS : 0) |
349 (baser_req ? ETHTOOL_FEC_BASER : 0) |
350 (baser == baser_req && rs == rs_req ? 0 : ETHTOOL_FEC_AUTO);
353 /* Verify that the forced flow control settings (!EFX_FC_AUTO) are
354 * supported by the link partner. Warn the user if this isn't the case
356 void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa)
358 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
359 u32 rmtadv;
361 /* The link partner capabilities are only relevant if the
362 * link supports flow control autonegotiation
364 if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
365 return;
367 /* If flow control autoneg is supported and enabled, then fine */
368 if (efx->wanted_fc & EFX_FC_AUTO)
369 return;
371 rmtadv = 0;
372 if (lpa & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
373 rmtadv |= ADVERTISED_Pause;
374 if (lpa & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
375 rmtadv |= ADVERTISED_Asym_Pause;
377 if ((efx->wanted_fc & EFX_FC_TX) && rmtadv == ADVERTISED_Asym_Pause)
378 netif_err(efx, link, efx->net_dev,
379 "warning: link partner doesn't support pause frames");
382 bool efx_mcdi_phy_poll(struct efx_nic *efx)
384 struct efx_link_state old_state = efx->link_state;
385 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
386 int rc;
388 WARN_ON(!mutex_is_locked(&efx->mac_lock));
390 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
392 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
393 outbuf, sizeof(outbuf), NULL);
394 if (rc)
395 efx->link_state.up = false;
396 else
397 efx_mcdi_phy_decode_link(
398 efx, &efx->link_state,
399 MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
400 MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
401 MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
403 return !efx_link_state_equal(&efx->link_state, &old_state);
406 int efx_mcdi_phy_get_fecparam(struct efx_nic *efx, struct ethtool_fecparam *fec)
408 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN);
409 u32 caps, active, speed; /* MCDI format */
410 bool is_25g = false;
411 size_t outlen;
412 int rc;
414 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
415 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
416 outbuf, sizeof(outbuf), &outlen);
417 if (rc)
418 return rc;
419 if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN)
420 return -EOPNOTSUPP;
422 /* behaviour for 25G/50G links depends on 25G BASER bit */
423 speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED);
424 is_25g = speed == 25000 || speed == 50000;
426 caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP);
427 fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g);
428 /* BASER is never supported on 100G */
429 if (speed == 100000)
430 fec->fec &= ~ETHTOOL_FEC_BASER;
432 active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE);
433 switch (active) {
434 case MC_CMD_FEC_NONE:
435 fec->active_fec = ETHTOOL_FEC_OFF;
436 break;
437 case MC_CMD_FEC_BASER:
438 fec->active_fec = ETHTOOL_FEC_BASER;
439 break;
440 case MC_CMD_FEC_RS:
441 fec->active_fec = ETHTOOL_FEC_RS;
442 break;
443 default:
444 netif_warn(efx, hw, efx->net_dev,
445 "Firmware reports unrecognised FEC_TYPE %u\n",
446 active);
447 /* We don't know what firmware has picked. AUTO is as good a
448 * "can't happen" value as any other.
450 fec->active_fec = ETHTOOL_FEC_AUTO;
451 break;
454 return 0;
457 int efx_mcdi_phy_test_alive(struct efx_nic *efx)
459 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN);
460 size_t outlen;
461 int rc;
463 BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
465 rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
466 outbuf, sizeof(outbuf), &outlen);
467 if (rc)
468 return rc;
470 if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
471 return -EIO;
472 if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK)
473 return -EINVAL;
475 return 0;
478 int efx_mcdi_set_mac(struct efx_nic *efx)
480 u32 fcntl;
481 MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN);
483 BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
485 /* This has no effect on EF10 */
486 ether_addr_copy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
487 efx->net_dev->dev_addr);
489 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU,
490 EFX_MAX_FRAME_LEN(efx->net_dev->mtu));
491 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0);
493 /* Set simple MAC filter for Siena */
494 MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_REJECT,
495 SET_MAC_IN_REJECT_UNCST, efx->unicast_filter);
497 MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_FLAGS,
498 SET_MAC_IN_FLAG_INCLUDE_FCS,
499 !!(efx->net_dev->features & NETIF_F_RXFCS));
501 switch (efx->wanted_fc) {
502 case EFX_FC_RX | EFX_FC_TX:
503 fcntl = MC_CMD_FCNTL_BIDIR;
504 break;
505 case EFX_FC_RX:
506 fcntl = MC_CMD_FCNTL_RESPOND;
507 break;
508 default:
509 fcntl = MC_CMD_FCNTL_OFF;
510 break;
512 if (efx->wanted_fc & EFX_FC_AUTO)
513 fcntl = MC_CMD_FCNTL_AUTO;
514 if (efx->fc_disable)
515 fcntl = MC_CMD_FCNTL_OFF;
517 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
519 return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes),
520 NULL, 0, NULL);
523 /* Get physical port number (EF10 only; on Siena it is same as PF number) */
524 int efx_mcdi_port_get_number(struct efx_nic *efx)
526 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
527 int rc;
529 rc = efx_mcdi_rpc(efx, MC_CMD_GET_PORT_ASSIGNMENT, NULL, 0,
530 outbuf, sizeof(outbuf), NULL);
531 if (rc)
532 return rc;
534 return MCDI_DWORD(outbuf, GET_PORT_ASSIGNMENT_OUT_PORT);
537 static unsigned int efx_mcdi_event_link_speed[] = {
538 [MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
539 [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
540 [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
541 [MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000,
542 [MCDI_EVENT_LINKCHANGE_SPEED_25G] = 25000,
543 [MCDI_EVENT_LINKCHANGE_SPEED_50G] = 50000,
544 [MCDI_EVENT_LINKCHANGE_SPEED_100G] = 100000,
547 void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
549 u32 flags, fcntl, speed, lpa;
551 speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED);
552 EFX_WARN_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed));
553 speed = efx_mcdi_event_link_speed[speed];
555 flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS);
556 fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL);
557 lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP);
559 /* efx->link_state is only modified by efx_mcdi_phy_get_link(),
560 * which is only run after flushing the event queues. Therefore, it
561 * is safe to modify the link state outside of the mac_lock here.
563 efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);
565 efx_mcdi_phy_check_fcntl(efx, lpa);
567 efx_link_status_changed(efx);