]> Git Repo - linux.git/blob - drivers/net/ethernet/sfc/mcdi_port_common.c
efi/x86: add headroom to decompressor BSS to account for setup block
[linux.git] / drivers / net / ethernet / sfc / mcdi_port_common.c
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
14 int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg)
15 {
16         MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN);
17         size_t outlen;
18         int rc;
19
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));
22
23         rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0,
24                           outbuf, sizeof(outbuf), &outlen);
25         if (rc)
26                 goto fail;
27
28         if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) {
29                 rc = -EIO;
30                 goto fail;
31         }
32
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));
46
47         return 0;
48
49 fail:
50         netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
51         return rc;
52 }
53
54 void efx_link_set_advertising(struct efx_nic *efx,
55                               const unsigned long *advertising)
56 {
57         memcpy(efx->link_advertising, advertising,
58                sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
59
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;
67 }
68
69 int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
70                       u32 flags, u32 loopback_mode, u32 loopback_speed)
71 {
72         MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_LINK_IN_LEN);
73         int rc;
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         rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
83                           NULL, 0, NULL);
84         return rc;
85 }
86
87 int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
88 {
89         MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LOOPBACK_MODES_OUT_LEN);
90         size_t outlen;
91         int rc;
92
93         rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0,
94                           outbuf, sizeof(outbuf), &outlen);
95         if (rc)
96                 goto fail;
97
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;
102         }
103
104         *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED);
105
106         return 0;
107
108 fail:
109         netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
110         return rc;
111 }
112
113 void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset)
114 {
115         #define SET_BIT(name)   __set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
116                                           linkset)
117
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;
129
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;
147
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;
165         }
166
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);
173
174         #undef SET_BIT
175 }
176
177 u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset)
178 {
179         u32 result = 0;
180
181         #define TEST_BIT(name)  test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
182                                          linkset)
183
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);
212
213         #undef TEST_BIT
214
215         return result;
216 }
217
218 u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
219 {
220         struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
221         enum efx_phy_mode mode, supported;
222         u32 flags;
223
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;
232
233         mode = efx->phy_mode & supported;
234
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);
242
243         return flags;
244 }
245
246 u8 mcdi_to_ethtool_media(u32 media)
247 {
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;
253
254         case MC_CMD_MEDIA_XFP:
255         case MC_CMD_MEDIA_SFP_PLUS:
256         case MC_CMD_MEDIA_QSFP_PLUS:
257                 return PORT_FIBRE;
258
259         case MC_CMD_MEDIA_BASE_T:
260                 return PORT_TP;
261
262         default:
263                 return PORT_OTHER;
264         }
265 }
266
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)
270 {
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;
288         }
289
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;
293 }
294
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.
309  */
310 u32 ethtool_fec_caps_to_mcdi(u32 ethtool_cap)
311 {
312         u32 ret = 0;
313
314         if (ethtool_cap & ETHTOOL_FEC_OFF)
315                 return 0;
316
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;
330 }
331
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.
336  */
337 u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g)
338 {
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);
345
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);
351 }
352
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
355  */
356 void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa)
357 {
358         struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
359         u32 rmtadv;
360
361         /* The link partner capabilities are only relevant if the
362          * link supports flow control autonegotiation
363          */
364         if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
365                 return;
366
367         /* If flow control autoneg is supported and enabled, then fine */
368         if (efx->wanted_fc & EFX_FC_AUTO)
369                 return;
370
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;
376
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");
380 }
381
382 bool efx_mcdi_phy_poll(struct efx_nic *efx)
383 {
384         struct efx_link_state old_state = efx->link_state;
385         MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
386         int rc;
387
388         WARN_ON(!mutex_is_locked(&efx->mac_lock));
389
390         BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
391
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));
402
403         return !efx_link_state_equal(&efx->link_state, &old_state);
404 }
405
406 int efx_mcdi_phy_get_fecparam(struct efx_nic *efx, struct ethtool_fecparam *fec)
407 {
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;
413
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;
421
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;
425
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;
431
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.
449                  */
450                 fec->active_fec = ETHTOOL_FEC_AUTO;
451                 break;
452         }
453
454         return 0;
455 }
456
457 int efx_mcdi_phy_test_alive(struct efx_nic *efx)
458 {
459         MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN);
460         size_t outlen;
461         int rc;
462
463         BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
464
465         rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
466                           outbuf, sizeof(outbuf), &outlen);
467         if (rc)
468                 return rc;
469
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;
474
475         return 0;
476 }
477
478 int efx_mcdi_set_mac(struct efx_nic *efx)
479 {
480         u32 fcntl;
481         MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN);
482
483         BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
484
485         /* This has no effect on EF10 */
486         ether_addr_copy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
487                         efx->net_dev->dev_addr);
488
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);
492
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);
496
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));
500
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;
511         }
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;
516
517         MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
518
519         return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes),
520                             NULL, 0, NULL);
521 }
522
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)
525 {
526         MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
527         int rc;
528
529         rc = efx_mcdi_rpc(efx, MC_CMD_GET_PORT_ASSIGNMENT, NULL, 0,
530                           outbuf, sizeof(outbuf), NULL);
531         if (rc)
532                 return rc;
533
534         return MCDI_DWORD(outbuf, GET_PORT_ASSIGNMENT_OUT_PORT);
535 }
536
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,
545 };
546
547 void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
548 {
549         u32 flags, fcntl, speed, lpa;
550
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];
554
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);
558
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.
562          */
563         efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);
564
565         efx_mcdi_phy_check_fcntl(efx, lpa);
566
567         efx_link_status_changed(efx);
568 }
This page took 0.065076 seconds and 4 git commands to generate.