hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/ethernet/sfc/mcdi_port.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /****************************************************************************
23 * Driver for Solarflare network controllers and boards
34 * Copyright 2009-2013 Solarflare Communications Inc.
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms of the GNU General Public License version 2 as published
7
- * by the Free Software Foundation, incorporated herein by reference.
85 */
96
107 /*
....@@ -13,110 +10,12 @@
1310
1411 #include <linux/slab.h>
1512 #include "efx.h"
13
+#include "mcdi_port.h"
1614 #include "mcdi.h"
1715 #include "mcdi_pcol.h"
1816 #include "nic.h"
1917 #include "selftest.h"
20
-
21
-struct efx_mcdi_phy_data {
22
- u32 flags;
23
- u32 type;
24
- u32 supported_cap;
25
- u32 channel;
26
- u32 port;
27
- u32 stats_mask;
28
- u8 name[20];
29
- u32 media;
30
- u32 mmd_mask;
31
- u8 revision[20];
32
- u32 forced_cap;
33
-};
34
-
35
-static int
36
-efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg)
37
-{
38
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_CFG_OUT_LEN);
39
- size_t outlen;
40
- int rc;
41
-
42
- BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_IN_LEN != 0);
43
- BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_OUT_NAME_LEN != sizeof(cfg->name));
44
-
45
- rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0,
46
- outbuf, sizeof(outbuf), &outlen);
47
- if (rc)
48
- goto fail;
49
-
50
- if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) {
51
- rc = -EIO;
52
- goto fail;
53
- }
54
-
55
- cfg->flags = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_FLAGS);
56
- cfg->type = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_TYPE);
57
- cfg->supported_cap =
58
- MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_SUPPORTED_CAP);
59
- cfg->channel = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_CHANNEL);
60
- cfg->port = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_PRT);
61
- cfg->stats_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_STATS_MASK);
62
- memcpy(cfg->name, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_NAME),
63
- sizeof(cfg->name));
64
- cfg->media = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MEDIA_TYPE);
65
- cfg->mmd_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MMD_MASK);
66
- memcpy(cfg->revision, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_REVISION),
67
- sizeof(cfg->revision));
68
-
69
- return 0;
70
-
71
-fail:
72
- netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
73
- return rc;
74
-}
75
-
76
-static int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
77
- u32 flags, u32 loopback_mode,
78
- u32 loopback_speed)
79
-{
80
- MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_LINK_IN_LEN);
81
- int rc;
82
-
83
- BUILD_BUG_ON(MC_CMD_SET_LINK_OUT_LEN != 0);
84
-
85
- MCDI_SET_DWORD(inbuf, SET_LINK_IN_CAP, capabilities);
86
- MCDI_SET_DWORD(inbuf, SET_LINK_IN_FLAGS, flags);
87
- MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_MODE, loopback_mode);
88
- MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_SPEED, loopback_speed);
89
-
90
- rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
91
- NULL, 0, NULL);
92
- return rc;
93
-}
94
-
95
-static int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
96
-{
97
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LOOPBACK_MODES_OUT_LEN);
98
- size_t outlen;
99
- int rc;
100
-
101
- rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0,
102
- outbuf, sizeof(outbuf), &outlen);
103
- if (rc)
104
- goto fail;
105
-
106
- if (outlen < (MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
107
- MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN)) {
108
- rc = -EIO;
109
- goto fail;
110
- }
111
-
112
- *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED);
113
-
114
- return 0;
115
-
116
-fail:
117
- netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
118
- return rc;
119
-}
18
+#include "mcdi_port_common.h"
12019
12120 static int efx_mcdi_mdio_read(struct net_device *net_dev,
12221 int prtad, int devad, u16 addr)
....@@ -171,1052 +70,11 @@
17170 return 0;
17271 }
17372
174
-static void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset)
175
-{
176
- #define SET_BIT(name) __set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
177
- linkset)
178
-
179
- bitmap_zero(linkset, __ETHTOOL_LINK_MODE_MASK_NBITS);
180
- switch (media) {
181
- case MC_CMD_MEDIA_KX4:
182
- SET_BIT(Backplane);
183
- if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
184
- SET_BIT(1000baseKX_Full);
185
- if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
186
- SET_BIT(10000baseKX4_Full);
187
- if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
188
- SET_BIT(40000baseKR4_Full);
189
- break;
190
-
191
- case MC_CMD_MEDIA_XFP:
192
- case MC_CMD_MEDIA_SFP_PLUS:
193
- case MC_CMD_MEDIA_QSFP_PLUS:
194
- SET_BIT(FIBRE);
195
- if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
196
- SET_BIT(1000baseT_Full);
197
- if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
198
- SET_BIT(10000baseT_Full);
199
- if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
200
- SET_BIT(40000baseCR4_Full);
201
- if (cap & (1 << MC_CMD_PHY_CAP_100000FDX_LBN))
202
- SET_BIT(100000baseCR4_Full);
203
- if (cap & (1 << MC_CMD_PHY_CAP_25000FDX_LBN))
204
- SET_BIT(25000baseCR_Full);
205
- if (cap & (1 << MC_CMD_PHY_CAP_50000FDX_LBN))
206
- SET_BIT(50000baseCR2_Full);
207
- break;
208
-
209
- case MC_CMD_MEDIA_BASE_T:
210
- SET_BIT(TP);
211
- if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
212
- SET_BIT(10baseT_Half);
213
- if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
214
- SET_BIT(10baseT_Full);
215
- if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
216
- SET_BIT(100baseT_Half);
217
- if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
218
- SET_BIT(100baseT_Full);
219
- if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
220
- SET_BIT(1000baseT_Half);
221
- if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
222
- SET_BIT(1000baseT_Full);
223
- if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
224
- SET_BIT(10000baseT_Full);
225
- break;
226
- }
227
-
228
- if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
229
- SET_BIT(Pause);
230
- if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
231
- SET_BIT(Asym_Pause);
232
- if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
233
- SET_BIT(Autoneg);
234
-
235
- #undef SET_BIT
236
-}
237
-
238
-static u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset)
239
-{
240
- u32 result = 0;
241
-
242
- #define TEST_BIT(name) test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
243
- linkset)
244
-
245
- if (TEST_BIT(10baseT_Half))
246
- result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN);
247
- if (TEST_BIT(10baseT_Full))
248
- result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN);
249
- if (TEST_BIT(100baseT_Half))
250
- result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN);
251
- if (TEST_BIT(100baseT_Full))
252
- result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN);
253
- if (TEST_BIT(1000baseT_Half))
254
- result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN);
255
- if (TEST_BIT(1000baseT_Full) || TEST_BIT(1000baseKX_Full))
256
- result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN);
257
- if (TEST_BIT(10000baseT_Full) || TEST_BIT(10000baseKX4_Full))
258
- result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN);
259
- if (TEST_BIT(40000baseCR4_Full) || TEST_BIT(40000baseKR4_Full))
260
- result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN);
261
- if (TEST_BIT(100000baseCR4_Full))
262
- result |= (1 << MC_CMD_PHY_CAP_100000FDX_LBN);
263
- if (TEST_BIT(25000baseCR_Full))
264
- result |= (1 << MC_CMD_PHY_CAP_25000FDX_LBN);
265
- if (TEST_BIT(50000baseCR2_Full))
266
- result |= (1 << MC_CMD_PHY_CAP_50000FDX_LBN);
267
- if (TEST_BIT(Pause))
268
- result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN);
269
- if (TEST_BIT(Asym_Pause))
270
- result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN);
271
- if (TEST_BIT(Autoneg))
272
- result |= (1 << MC_CMD_PHY_CAP_AN_LBN);
273
-
274
- #undef TEST_BIT
275
-
276
- return result;
277
-}
278
-
279
-static u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
280
-{
281
- struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
282
- enum efx_phy_mode mode, supported;
283
- u32 flags;
284
-
285
- /* TODO: Advertise the capabilities supported by this PHY */
286
- supported = 0;
287
- if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN))
288
- supported |= PHY_MODE_TX_DISABLED;
289
- if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN))
290
- supported |= PHY_MODE_LOW_POWER;
291
- if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN))
292
- supported |= PHY_MODE_OFF;
293
-
294
- mode = efx->phy_mode & supported;
295
-
296
- flags = 0;
297
- if (mode & PHY_MODE_TX_DISABLED)
298
- flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN);
299
- if (mode & PHY_MODE_LOW_POWER)
300
- flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN);
301
- if (mode & PHY_MODE_OFF)
302
- flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN);
303
-
304
- return flags;
305
-}
306
-
307
-static u8 mcdi_to_ethtool_media(u32 media)
308
-{
309
- switch (media) {
310
- case MC_CMD_MEDIA_XAUI:
311
- case MC_CMD_MEDIA_CX4:
312
- case MC_CMD_MEDIA_KX4:
313
- return PORT_OTHER;
314
-
315
- case MC_CMD_MEDIA_XFP:
316
- case MC_CMD_MEDIA_SFP_PLUS:
317
- case MC_CMD_MEDIA_QSFP_PLUS:
318
- return PORT_FIBRE;
319
-
320
- case MC_CMD_MEDIA_BASE_T:
321
- return PORT_TP;
322
-
323
- default:
324
- return PORT_OTHER;
325
- }
326
-}
327
-
328
-static void efx_mcdi_phy_decode_link(struct efx_nic *efx,
329
- struct efx_link_state *link_state,
330
- u32 speed, u32 flags, u32 fcntl)
331
-{
332
- switch (fcntl) {
333
- case MC_CMD_FCNTL_AUTO:
334
- WARN_ON(1); /* This is not a link mode */
335
- link_state->fc = EFX_FC_AUTO | EFX_FC_TX | EFX_FC_RX;
336
- break;
337
- case MC_CMD_FCNTL_BIDIR:
338
- link_state->fc = EFX_FC_TX | EFX_FC_RX;
339
- break;
340
- case MC_CMD_FCNTL_RESPOND:
341
- link_state->fc = EFX_FC_RX;
342
- break;
343
- default:
344
- WARN_ON(1);
345
- case MC_CMD_FCNTL_OFF:
346
- link_state->fc = 0;
347
- break;
348
- }
349
-
350
- link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
351
- link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
352
- link_state->speed = speed;
353
-}
354
-
355
-/* The semantics of the ethtool FEC mode bitmask are not well defined,
356
- * particularly the meaning of combinations of bits. Which means we get to
357
- * define our own semantics, as follows:
358
- * OFF overrides any other bits, and means "disable all FEC" (with the
359
- * exception of 25G KR4/CR4, where it is not possible to reject it if AN
360
- * partner requests it).
361
- * AUTO on its own means use cable requirements and link partner autoneg with
362
- * fw-default preferences for the cable type.
363
- * AUTO and either RS or BASER means use the specified FEC type if cable and
364
- * link partner support it, otherwise autoneg/fw-default.
365
- * RS or BASER alone means use the specified FEC type if cable and link partner
366
- * support it and either requests it, otherwise no FEC.
367
- * Both RS and BASER (whether AUTO or not) means use FEC if cable and link
368
- * partner support it, preferring RS to BASER.
369
- */
370
-static u32 ethtool_fec_caps_to_mcdi(u32 ethtool_cap)
371
-{
372
- u32 ret = 0;
373
-
374
- if (ethtool_cap & ETHTOOL_FEC_OFF)
375
- return 0;
376
-
377
- if (ethtool_cap & ETHTOOL_FEC_AUTO)
378
- ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
379
- (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
380
- (1 << MC_CMD_PHY_CAP_RS_FEC_LBN);
381
- if (ethtool_cap & ETHTOOL_FEC_RS)
382
- ret |= (1 << MC_CMD_PHY_CAP_RS_FEC_LBN) |
383
- (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN);
384
- if (ethtool_cap & ETHTOOL_FEC_BASER)
385
- ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
386
- (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
387
- (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN) |
388
- (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN);
389
- return ret;
390
-}
391
-
392
-/* Invert ethtool_fec_caps_to_mcdi. There are two combinations that function
393
- * can never produce, (baser xor rs) and neither req; the implementation below
394
- * maps both of those to AUTO. This should never matter, and it's not clear
395
- * what a better mapping would be anyway.
396
- */
397
-static u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g)
398
-{
399
- bool rs = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN),
400
- rs_req = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN),
401
- baser = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN)
402
- : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN),
403
- baser_req = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN)
404
- : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
405
-
406
- if (!baser && !rs)
407
- return ETHTOOL_FEC_OFF;
408
- return (rs_req ? ETHTOOL_FEC_RS : 0) |
409
- (baser_req ? ETHTOOL_FEC_BASER : 0) |
410
- (baser == baser_req && rs == rs_req ? 0 : ETHTOOL_FEC_AUTO);
411
-}
412
-
413
-static int efx_mcdi_phy_probe(struct efx_nic *efx)
414
-{
415
- struct efx_mcdi_phy_data *phy_data;
416
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
417
- u32 caps;
418
- int rc;
419
-
420
- /* Initialise and populate phy_data */
421
- phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
422
- if (phy_data == NULL)
423
- return -ENOMEM;
424
-
425
- rc = efx_mcdi_get_phy_cfg(efx, phy_data);
426
- if (rc != 0)
427
- goto fail;
428
-
429
- /* Read initial link advertisement */
430
- BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
431
- rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
432
- outbuf, sizeof(outbuf), NULL);
433
- if (rc)
434
- goto fail;
435
-
436
- /* Fill out nic state */
437
- efx->phy_data = phy_data;
438
- efx->phy_type = phy_data->type;
439
-
440
- efx->mdio_bus = phy_data->channel;
441
- efx->mdio.prtad = phy_data->port;
442
- efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
443
- efx->mdio.mode_support = 0;
444
- if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
445
- efx->mdio.mode_support |= MDIO_SUPPORTS_C22;
446
- if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
447
- efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
448
-
449
- caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
450
- if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
451
- mcdi_to_ethtool_linkset(phy_data->media, caps,
452
- efx->link_advertising);
453
- else
454
- phy_data->forced_cap = caps;
455
-
456
- /* Assert that we can map efx -> mcdi loopback modes */
457
- BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE);
458
- BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA);
459
- BUILD_BUG_ON(LOOPBACK_GMAC != MC_CMD_LOOPBACK_GMAC);
460
- BUILD_BUG_ON(LOOPBACK_XGMII != MC_CMD_LOOPBACK_XGMII);
461
- BUILD_BUG_ON(LOOPBACK_XGXS != MC_CMD_LOOPBACK_XGXS);
462
- BUILD_BUG_ON(LOOPBACK_XAUI != MC_CMD_LOOPBACK_XAUI);
463
- BUILD_BUG_ON(LOOPBACK_GMII != MC_CMD_LOOPBACK_GMII);
464
- BUILD_BUG_ON(LOOPBACK_SGMII != MC_CMD_LOOPBACK_SGMII);
465
- BUILD_BUG_ON(LOOPBACK_XGBR != MC_CMD_LOOPBACK_XGBR);
466
- BUILD_BUG_ON(LOOPBACK_XFI != MC_CMD_LOOPBACK_XFI);
467
- BUILD_BUG_ON(LOOPBACK_XAUI_FAR != MC_CMD_LOOPBACK_XAUI_FAR);
468
- BUILD_BUG_ON(LOOPBACK_GMII_FAR != MC_CMD_LOOPBACK_GMII_FAR);
469
- BUILD_BUG_ON(LOOPBACK_SGMII_FAR != MC_CMD_LOOPBACK_SGMII_FAR);
470
- BUILD_BUG_ON(LOOPBACK_XFI_FAR != MC_CMD_LOOPBACK_XFI_FAR);
471
- BUILD_BUG_ON(LOOPBACK_GPHY != MC_CMD_LOOPBACK_GPHY);
472
- BUILD_BUG_ON(LOOPBACK_PHYXS != MC_CMD_LOOPBACK_PHYXS);
473
- BUILD_BUG_ON(LOOPBACK_PCS != MC_CMD_LOOPBACK_PCS);
474
- BUILD_BUG_ON(LOOPBACK_PMAPMD != MC_CMD_LOOPBACK_PMAPMD);
475
- BUILD_BUG_ON(LOOPBACK_XPORT != MC_CMD_LOOPBACK_XPORT);
476
- BUILD_BUG_ON(LOOPBACK_XGMII_WS != MC_CMD_LOOPBACK_XGMII_WS);
477
- BUILD_BUG_ON(LOOPBACK_XAUI_WS != MC_CMD_LOOPBACK_XAUI_WS);
478
- BUILD_BUG_ON(LOOPBACK_XAUI_WS_FAR != MC_CMD_LOOPBACK_XAUI_WS_FAR);
479
- BUILD_BUG_ON(LOOPBACK_XAUI_WS_NEAR != MC_CMD_LOOPBACK_XAUI_WS_NEAR);
480
- BUILD_BUG_ON(LOOPBACK_GMII_WS != MC_CMD_LOOPBACK_GMII_WS);
481
- BUILD_BUG_ON(LOOPBACK_XFI_WS != MC_CMD_LOOPBACK_XFI_WS);
482
- BUILD_BUG_ON(LOOPBACK_XFI_WS_FAR != MC_CMD_LOOPBACK_XFI_WS_FAR);
483
- BUILD_BUG_ON(LOOPBACK_PHYXS_WS != MC_CMD_LOOPBACK_PHYXS_WS);
484
-
485
- rc = efx_mcdi_loopback_modes(efx, &efx->loopback_modes);
486
- if (rc != 0)
487
- goto fail;
488
- /* The MC indicates that LOOPBACK_NONE is a valid loopback mode,
489
- * but by convention we don't */
490
- efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
491
-
492
- /* Set the initial link mode */
493
- efx_mcdi_phy_decode_link(
494
- efx, &efx->link_state,
495
- MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
496
- MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
497
- MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
498
-
499
- /* Record the initial FEC configuration (or nearest approximation
500
- * representable in the ethtool configuration space)
501
- */
502
- efx->fec_config = mcdi_fec_caps_to_ethtool(caps,
503
- efx->link_state.speed == 25000 ||
504
- efx->link_state.speed == 50000);
505
-
506
- /* Default to Autonegotiated flow control if the PHY supports it */
507
- efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
508
- if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
509
- efx->wanted_fc |= EFX_FC_AUTO;
510
- efx_link_set_wanted_fc(efx, efx->wanted_fc);
511
-
512
- return 0;
513
-
514
-fail:
515
- kfree(phy_data);
516
- return rc;
517
-}
518
-
519
-int efx_mcdi_port_reconfigure(struct efx_nic *efx)
520
-{
521
- struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
522
- u32 caps = (efx->link_advertising[0] ?
523
- ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
524
- phy_cfg->forced_cap);
525
-
526
- caps |= ethtool_fec_caps_to_mcdi(efx->fec_config);
527
-
528
- return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
529
- efx->loopback_mode, 0);
530
-}
531
-
532
-/* Verify that the forced flow control settings (!EFX_FC_AUTO) are
533
- * supported by the link partner. Warn the user if this isn't the case
534
- */
535
-static void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa)
536
-{
537
- struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
538
- u32 rmtadv;
539
-
540
- /* The link partner capabilities are only relevant if the
541
- * link supports flow control autonegotiation */
542
- if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
543
- return;
544
-
545
- /* If flow control autoneg is supported and enabled, then fine */
546
- if (efx->wanted_fc & EFX_FC_AUTO)
547
- return;
548
-
549
- rmtadv = 0;
550
- if (lpa & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
551
- rmtadv |= ADVERTISED_Pause;
552
- if (lpa & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
553
- rmtadv |= ADVERTISED_Asym_Pause;
554
-
555
- if ((efx->wanted_fc & EFX_FC_TX) && rmtadv == ADVERTISED_Asym_Pause)
556
- netif_err(efx, link, efx->net_dev,
557
- "warning: link partner doesn't support pause frames");
558
-}
559
-
560
-static bool efx_mcdi_phy_poll(struct efx_nic *efx)
561
-{
562
- struct efx_link_state old_state = efx->link_state;
563
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
564
- int rc;
565
-
566
- WARN_ON(!mutex_is_locked(&efx->mac_lock));
567
-
568
- BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
569
-
570
- rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
571
- outbuf, sizeof(outbuf), NULL);
572
- if (rc)
573
- efx->link_state.up = false;
574
- else
575
- efx_mcdi_phy_decode_link(
576
- efx, &efx->link_state,
577
- MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
578
- MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
579
- MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
580
-
581
- return !efx_link_state_equal(&efx->link_state, &old_state);
582
-}
583
-
584
-static void efx_mcdi_phy_remove(struct efx_nic *efx)
585
-{
586
- struct efx_mcdi_phy_data *phy_data = efx->phy_data;
587
-
588
- efx->phy_data = NULL;
589
- kfree(phy_data);
590
-}
591
-
592
-static void efx_mcdi_phy_get_link_ksettings(struct efx_nic *efx,
593
- struct ethtool_link_ksettings *cmd)
594
-{
595
- struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
596
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
597
- int rc;
598
-
599
- cmd->base.speed = efx->link_state.speed;
600
- cmd->base.duplex = efx->link_state.fd;
601
- cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media);
602
- cmd->base.phy_address = phy_cfg->port;
603
- cmd->base.autoneg = !!(efx->link_advertising[0] & ADVERTISED_Autoneg);
604
- cmd->base.mdio_support = (efx->mdio.mode_support &
605
- (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
606
-
607
- mcdi_to_ethtool_linkset(phy_cfg->media, phy_cfg->supported_cap,
608
- cmd->link_modes.supported);
609
- memcpy(cmd->link_modes.advertising, efx->link_advertising,
610
- sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
611
-
612
- BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
613
- rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
614
- outbuf, sizeof(outbuf), NULL);
615
- if (rc)
616
- return;
617
- mcdi_to_ethtool_linkset(phy_cfg->media,
618
- MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP),
619
- cmd->link_modes.lp_advertising);
620
-}
621
-
622
-static int
623
-efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx,
624
- const struct ethtool_link_ksettings *cmd)
625
-{
626
- struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
627
- u32 caps;
628
- int rc;
629
-
630
- if (cmd->base.autoneg) {
631
- caps = (ethtool_linkset_to_mcdi_cap(cmd->link_modes.advertising) |
632
- 1 << MC_CMD_PHY_CAP_AN_LBN);
633
- } else if (cmd->base.duplex) {
634
- switch (cmd->base.speed) {
635
- case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break;
636
- case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break;
637
- case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break;
638
- case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break;
639
- case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break;
640
- case 100000: caps = 1 << MC_CMD_PHY_CAP_100000FDX_LBN; break;
641
- case 25000: caps = 1 << MC_CMD_PHY_CAP_25000FDX_LBN; break;
642
- case 50000: caps = 1 << MC_CMD_PHY_CAP_50000FDX_LBN; break;
643
- default: return -EINVAL;
644
- }
645
- } else {
646
- switch (cmd->base.speed) {
647
- case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break;
648
- case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break;
649
- case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break;
650
- default: return -EINVAL;
651
- }
652
- }
653
-
654
- caps |= ethtool_fec_caps_to_mcdi(efx->fec_config);
655
-
656
- rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
657
- efx->loopback_mode, 0);
658
- if (rc)
659
- return rc;
660
-
661
- if (cmd->base.autoneg) {
662
- efx_link_set_advertising(efx, cmd->link_modes.advertising);
663
- phy_cfg->forced_cap = 0;
664
- } else {
665
- efx_link_clear_advertising(efx);
666
- phy_cfg->forced_cap = caps;
667
- }
668
- return 0;
669
-}
670
-
671
-static int efx_mcdi_phy_get_fecparam(struct efx_nic *efx,
672
- struct ethtool_fecparam *fec)
673
-{
674
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN);
675
- u32 caps, active, speed; /* MCDI format */
676
- bool is_25g = false;
677
- size_t outlen;
678
- int rc;
679
-
680
- BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
681
- rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
682
- outbuf, sizeof(outbuf), &outlen);
683
- if (rc)
684
- return rc;
685
- if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN)
686
- return -EOPNOTSUPP;
687
-
688
- /* behaviour for 25G/50G links depends on 25G BASER bit */
689
- speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED);
690
- is_25g = speed == 25000 || speed == 50000;
691
-
692
- caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP);
693
- fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g);
694
- /* BASER is never supported on 100G */
695
- if (speed == 100000)
696
- fec->fec &= ~ETHTOOL_FEC_BASER;
697
-
698
- active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE);
699
- switch (active) {
700
- case MC_CMD_FEC_NONE:
701
- fec->active_fec = ETHTOOL_FEC_OFF;
702
- break;
703
- case MC_CMD_FEC_BASER:
704
- fec->active_fec = ETHTOOL_FEC_BASER;
705
- break;
706
- case MC_CMD_FEC_RS:
707
- fec->active_fec = ETHTOOL_FEC_RS;
708
- break;
709
- default:
710
- netif_warn(efx, hw, efx->net_dev,
711
- "Firmware reports unrecognised FEC_TYPE %u\n",
712
- active);
713
- /* We don't know what firmware has picked. AUTO is as good a
714
- * "can't happen" value as any other.
715
- */
716
- fec->active_fec = ETHTOOL_FEC_AUTO;
717
- break;
718
- }
719
-
720
- return 0;
721
-}
722
-
723
-static int efx_mcdi_phy_set_fecparam(struct efx_nic *efx,
724
- const struct ethtool_fecparam *fec)
725
-{
726
- struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
727
- u32 caps;
728
- int rc;
729
-
730
- /* Work out what efx_mcdi_phy_set_link_ksettings() would produce from
731
- * saved advertising bits
732
- */
733
- if (test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, efx->link_advertising))
734
- caps = (ethtool_linkset_to_mcdi_cap(efx->link_advertising) |
735
- 1 << MC_CMD_PHY_CAP_AN_LBN);
736
- else
737
- caps = phy_cfg->forced_cap;
738
-
739
- caps |= ethtool_fec_caps_to_mcdi(fec->fec);
740
- rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
741
- efx->loopback_mode, 0);
742
- if (rc)
743
- return rc;
744
-
745
- /* Record the new FEC setting for subsequent set_link calls */
746
- efx->fec_config = fec->fec;
747
- return 0;
748
-}
749
-
750
-static int efx_mcdi_phy_test_alive(struct efx_nic *efx)
751
-{
752
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN);
753
- size_t outlen;
754
- int rc;
755
-
756
- BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
757
-
758
- rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
759
- outbuf, sizeof(outbuf), &outlen);
760
- if (rc)
761
- return rc;
762
-
763
- if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
764
- return -EIO;
765
- if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK)
766
- return -EINVAL;
767
-
768
- return 0;
769
-}
770
-
771
-static const char *const mcdi_sft9001_cable_diag_names[] = {
772
- "cable.pairA.length",
773
- "cable.pairB.length",
774
- "cable.pairC.length",
775
- "cable.pairD.length",
776
- "cable.pairA.status",
777
- "cable.pairB.status",
778
- "cable.pairC.status",
779
- "cable.pairD.status",
780
-};
781
-
782
-static int efx_mcdi_bist(struct efx_nic *efx, unsigned int bist_mode,
783
- int *results)
784
-{
785
- unsigned int retry, i, count = 0;
786
- size_t outlen;
787
- u32 status;
788
- MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
789
- MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_SFT9001_LEN);
790
- u8 *ptr;
791
- int rc;
792
-
793
- BUILD_BUG_ON(MC_CMD_START_BIST_OUT_LEN != 0);
794
- MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_mode);
795
- rc = efx_mcdi_rpc(efx, MC_CMD_START_BIST,
796
- inbuf, MC_CMD_START_BIST_IN_LEN, NULL, 0, NULL);
797
- if (rc)
798
- goto out;
799
-
800
- /* Wait up to 10s for BIST to finish */
801
- for (retry = 0; retry < 100; ++retry) {
802
- BUILD_BUG_ON(MC_CMD_POLL_BIST_IN_LEN != 0);
803
- rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
804
- outbuf, sizeof(outbuf), &outlen);
805
- if (rc)
806
- goto out;
807
-
808
- status = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
809
- if (status != MC_CMD_POLL_BIST_RUNNING)
810
- goto finished;
811
-
812
- msleep(100);
813
- }
814
-
815
- rc = -ETIMEDOUT;
816
- goto out;
817
-
818
-finished:
819
- results[count++] = (status == MC_CMD_POLL_BIST_PASSED) ? 1 : -1;
820
-
821
- /* SFT9001 specific cable diagnostics output */
822
- if (efx->phy_type == PHY_TYPE_SFT9001B &&
823
- (bist_mode == MC_CMD_PHY_BIST_CABLE_SHORT ||
824
- bist_mode == MC_CMD_PHY_BIST_CABLE_LONG)) {
825
- ptr = MCDI_PTR(outbuf, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
826
- if (status == MC_CMD_POLL_BIST_PASSED &&
827
- outlen >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN) {
828
- for (i = 0; i < 8; i++) {
829
- results[count + i] =
830
- EFX_DWORD_FIELD(((efx_dword_t *)ptr)[i],
831
- EFX_DWORD_0);
832
- }
833
- }
834
- count += 8;
835
- }
836
- rc = count;
837
-
838
-out:
839
- return rc;
840
-}
841
-
842
-static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results,
843
- unsigned flags)
844
-{
845
- struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
846
- u32 mode;
847
- int rc;
848
-
849
- if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
850
- rc = efx_mcdi_bist(efx, MC_CMD_PHY_BIST, results);
851
- if (rc < 0)
852
- return rc;
853
-
854
- results += rc;
855
- }
856
-
857
- /* If we support both LONG and SHORT, then run each in response to
858
- * break or not. Otherwise, run the one we support */
859
- mode = 0;
860
- if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN)) {
861
- if ((flags & ETH_TEST_FL_OFFLINE) &&
862
- (phy_cfg->flags &
863
- (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN)))
864
- mode = MC_CMD_PHY_BIST_CABLE_LONG;
865
- else
866
- mode = MC_CMD_PHY_BIST_CABLE_SHORT;
867
- } else if (phy_cfg->flags &
868
- (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))
869
- mode = MC_CMD_PHY_BIST_CABLE_LONG;
870
-
871
- if (mode != 0) {
872
- rc = efx_mcdi_bist(efx, mode, results);
873
- if (rc < 0)
874
- return rc;
875
- results += rc;
876
- }
877
-
878
- return 0;
879
-}
880
-
881
-static const char *efx_mcdi_phy_test_name(struct efx_nic *efx,
882
- unsigned int index)
883
-{
884
- struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
885
-
886
- if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
887
- if (index == 0)
888
- return "bist";
889
- --index;
890
- }
891
-
892
- if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN) |
893
- (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) {
894
- if (index == 0)
895
- return "cable";
896
- --index;
897
-
898
- if (efx->phy_type == PHY_TYPE_SFT9001B) {
899
- if (index < ARRAY_SIZE(mcdi_sft9001_cable_diag_names))
900
- return mcdi_sft9001_cable_diag_names[index];
901
- index -= ARRAY_SIZE(mcdi_sft9001_cable_diag_names);
902
- }
903
- }
904
-
905
- return NULL;
906
-}
907
-
908
-#define SFP_PAGE_SIZE 128
909
-#define SFF_DIAG_TYPE_OFFSET 92
910
-#define SFF_DIAG_ADDR_CHANGE BIT(2)
911
-#define SFF_8079_NUM_PAGES 2
912
-#define SFF_8472_NUM_PAGES 4
913
-#define SFF_8436_NUM_PAGES 5
914
-#define SFF_DMT_LEVEL_OFFSET 94
915
-
916
-/** efx_mcdi_phy_get_module_eeprom_page() - Get a single page of module eeprom
917
- * @efx: NIC context
918
- * @page: EEPROM page number
919
- * @data: Destination data pointer
920
- * @offset: Offset in page to copy from in to data
921
- * @space: Space available in data
922
- *
923
- * Return:
924
- * >=0 - amount of data copied
925
- * <0 - error
926
- */
927
-static int efx_mcdi_phy_get_module_eeprom_page(struct efx_nic *efx,
928
- unsigned int page,
929
- u8 *data, ssize_t offset,
930
- ssize_t space)
931
-{
932
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX);
933
- MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN);
934
- size_t outlen;
935
- unsigned int payload_len;
936
- unsigned int to_copy;
937
- int rc;
938
-
939
- if (offset > SFP_PAGE_SIZE)
940
- return -EINVAL;
941
-
942
- to_copy = min(space, SFP_PAGE_SIZE - offset);
943
-
944
- MCDI_SET_DWORD(inbuf, GET_PHY_MEDIA_INFO_IN_PAGE, page);
945
- rc = efx_mcdi_rpc_quiet(efx, MC_CMD_GET_PHY_MEDIA_INFO,
946
- inbuf, sizeof(inbuf),
947
- outbuf, sizeof(outbuf),
948
- &outlen);
949
-
950
- if (rc)
951
- return rc;
952
-
953
- if (outlen < (MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST +
954
- SFP_PAGE_SIZE))
955
- return -EIO;
956
-
957
- payload_len = MCDI_DWORD(outbuf, GET_PHY_MEDIA_INFO_OUT_DATALEN);
958
- if (payload_len != SFP_PAGE_SIZE)
959
- return -EIO;
960
-
961
- memcpy(data, MCDI_PTR(outbuf, GET_PHY_MEDIA_INFO_OUT_DATA) + offset,
962
- to_copy);
963
-
964
- return to_copy;
965
-}
966
-
967
-static int efx_mcdi_phy_get_module_eeprom_byte(struct efx_nic *efx,
968
- unsigned int page,
969
- u8 byte)
970
-{
971
- int rc;
972
- u8 data;
973
-
974
- rc = efx_mcdi_phy_get_module_eeprom_page(efx, page, &data, byte, 1);
975
- if (rc == 1)
976
- return data;
977
-
978
- return rc;
979
-}
980
-
981
-static int efx_mcdi_phy_diag_type(struct efx_nic *efx)
982
-{
983
- /* Page zero of the EEPROM includes the diagnostic type at byte 92. */
984
- return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
985
- SFF_DIAG_TYPE_OFFSET);
986
-}
987
-
988
-static int efx_mcdi_phy_sff_8472_level(struct efx_nic *efx)
989
-{
990
- /* Page zero of the EEPROM includes the DMT level at byte 94. */
991
- return efx_mcdi_phy_get_module_eeprom_byte(efx, 0,
992
- SFF_DMT_LEVEL_OFFSET);
993
-}
994
-
995
-static u32 efx_mcdi_phy_module_type(struct efx_nic *efx)
996
-{
997
- struct efx_mcdi_phy_data *phy_data = efx->phy_data;
998
-
999
- if (phy_data->media != MC_CMD_MEDIA_QSFP_PLUS)
1000
- return phy_data->media;
1001
-
1002
- /* A QSFP+ NIC may actually have an SFP+ module attached.
1003
- * The ID is page 0, byte 0.
1004
- */
1005
- switch (efx_mcdi_phy_get_module_eeprom_byte(efx, 0, 0)) {
1006
- case 0x3:
1007
- return MC_CMD_MEDIA_SFP_PLUS;
1008
- case 0xc:
1009
- case 0xd:
1010
- return MC_CMD_MEDIA_QSFP_PLUS;
1011
- default:
1012
- return 0;
1013
- }
1014
-}
1015
-
1016
-static int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx,
1017
- struct ethtool_eeprom *ee, u8 *data)
1018
-{
1019
- int rc;
1020
- ssize_t space_remaining = ee->len;
1021
- unsigned int page_off;
1022
- bool ignore_missing;
1023
- int num_pages;
1024
- int page;
1025
-
1026
- switch (efx_mcdi_phy_module_type(efx)) {
1027
- case MC_CMD_MEDIA_SFP_PLUS:
1028
- num_pages = efx_mcdi_phy_sff_8472_level(efx) > 0 ?
1029
- SFF_8472_NUM_PAGES : SFF_8079_NUM_PAGES;
1030
- page = 0;
1031
- ignore_missing = false;
1032
- break;
1033
- case MC_CMD_MEDIA_QSFP_PLUS:
1034
- num_pages = SFF_8436_NUM_PAGES;
1035
- page = -1; /* We obtain the lower page by asking for -1. */
1036
- ignore_missing = true; /* Ignore missing pages after page 0. */
1037
- break;
1038
- default:
1039
- return -EOPNOTSUPP;
1040
- }
1041
-
1042
- page_off = ee->offset % SFP_PAGE_SIZE;
1043
- page += ee->offset / SFP_PAGE_SIZE;
1044
-
1045
- while (space_remaining && (page < num_pages)) {
1046
- rc = efx_mcdi_phy_get_module_eeprom_page(efx, page,
1047
- data, page_off,
1048
- space_remaining);
1049
-
1050
- if (rc > 0) {
1051
- space_remaining -= rc;
1052
- data += rc;
1053
- page_off = 0;
1054
- page++;
1055
- } else if (rc == 0) {
1056
- space_remaining = 0;
1057
- } else if (ignore_missing && (page > 0)) {
1058
- int intended_size = SFP_PAGE_SIZE - page_off;
1059
-
1060
- space_remaining -= intended_size;
1061
- if (space_remaining < 0) {
1062
- space_remaining = 0;
1063
- } else {
1064
- memset(data, 0, intended_size);
1065
- data += intended_size;
1066
- page_off = 0;
1067
- page++;
1068
- rc = 0;
1069
- }
1070
- } else {
1071
- return rc;
1072
- }
1073
- }
1074
-
1075
- return 0;
1076
-}
1077
-
1078
-static int efx_mcdi_phy_get_module_info(struct efx_nic *efx,
1079
- struct ethtool_modinfo *modinfo)
1080
-{
1081
- int sff_8472_level;
1082
- int diag_type;
1083
-
1084
- switch (efx_mcdi_phy_module_type(efx)) {
1085
- case MC_CMD_MEDIA_SFP_PLUS:
1086
- sff_8472_level = efx_mcdi_phy_sff_8472_level(efx);
1087
-
1088
- /* If we can't read the diagnostics level we have none. */
1089
- if (sff_8472_level < 0)
1090
- return -EOPNOTSUPP;
1091
-
1092
- /* Check if this module requires the (unsupported) address
1093
- * change operation.
1094
- */
1095
- diag_type = efx_mcdi_phy_diag_type(efx);
1096
-
1097
- if ((sff_8472_level == 0) ||
1098
- (diag_type & SFF_DIAG_ADDR_CHANGE)) {
1099
- modinfo->type = ETH_MODULE_SFF_8079;
1100
- modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
1101
- } else {
1102
- modinfo->type = ETH_MODULE_SFF_8472;
1103
- modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1104
- }
1105
- break;
1106
-
1107
- case MC_CMD_MEDIA_QSFP_PLUS:
1108
- modinfo->type = ETH_MODULE_SFF_8436;
1109
- modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
1110
- break;
1111
-
1112
- default:
1113
- return -EOPNOTSUPP;
1114
- }
1115
-
1116
- return 0;
1117
-}
1118
-
1119
-static const struct efx_phy_operations efx_mcdi_phy_ops = {
1120
- .probe = efx_mcdi_phy_probe,
1121
- .init = efx_port_dummy_op_int,
1122
- .reconfigure = efx_mcdi_port_reconfigure,
1123
- .poll = efx_mcdi_phy_poll,
1124
- .fini = efx_port_dummy_op_void,
1125
- .remove = efx_mcdi_phy_remove,
1126
- .get_link_ksettings = efx_mcdi_phy_get_link_ksettings,
1127
- .set_link_ksettings = efx_mcdi_phy_set_link_ksettings,
1128
- .get_fecparam = efx_mcdi_phy_get_fecparam,
1129
- .set_fecparam = efx_mcdi_phy_set_fecparam,
1130
- .test_alive = efx_mcdi_phy_test_alive,
1131
- .run_tests = efx_mcdi_phy_run_tests,
1132
- .test_name = efx_mcdi_phy_test_name,
1133
- .get_module_eeprom = efx_mcdi_phy_get_module_eeprom,
1134
- .get_module_info = efx_mcdi_phy_get_module_info,
1135
-};
1136
-
113773 u32 efx_mcdi_phy_get_caps(struct efx_nic *efx)
113874 {
113975 struct efx_mcdi_phy_data *phy_data = efx->phy_data;
114076
114177 return phy_data->supported_cap;
1142
-}
1143
-
1144
-static unsigned int efx_mcdi_event_link_speed[] = {
1145
- [MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
1146
- [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
1147
- [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
1148
- [MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000,
1149
- [MCDI_EVENT_LINKCHANGE_SPEED_25G] = 25000,
1150
- [MCDI_EVENT_LINKCHANGE_SPEED_50G] = 50000,
1151
- [MCDI_EVENT_LINKCHANGE_SPEED_100G] = 100000,
1152
-};
1153
-
1154
-void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
1155
-{
1156
- u32 flags, fcntl, speed, lpa;
1157
-
1158
- speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED);
1159
- EFX_WARN_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed));
1160
- speed = efx_mcdi_event_link_speed[speed];
1161
-
1162
- flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS);
1163
- fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL);
1164
- lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP);
1165
-
1166
- /* efx->link_state is only modified by efx_mcdi_phy_get_link(),
1167
- * which is only run after flushing the event queues. Therefore, it
1168
- * is safe to modify the link state outside of the mac_lock here.
1169
- */
1170
- efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);
1171
-
1172
- efx_mcdi_phy_check_fcntl(efx, lpa);
1173
-
1174
- efx_link_status_changed(efx);
1175
-}
1176
-
1177
-int efx_mcdi_set_mac(struct efx_nic *efx)
1178
-{
1179
- u32 fcntl;
1180
- MCDI_DECLARE_BUF(cmdbytes, MC_CMD_SET_MAC_IN_LEN);
1181
-
1182
- BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
1183
-
1184
- /* This has no effect on EF10 */
1185
- ether_addr_copy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
1186
- efx->net_dev->dev_addr);
1187
-
1188
- MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU,
1189
- EFX_MAX_FRAME_LEN(efx->net_dev->mtu));
1190
- MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0);
1191
-
1192
- /* Set simple MAC filter for Siena */
1193
- MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_REJECT,
1194
- SET_MAC_IN_REJECT_UNCST, efx->unicast_filter);
1195
-
1196
- MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_FLAGS,
1197
- SET_MAC_IN_FLAG_INCLUDE_FCS,
1198
- !!(efx->net_dev->features & NETIF_F_RXFCS));
1199
-
1200
- switch (efx->wanted_fc) {
1201
- case EFX_FC_RX | EFX_FC_TX:
1202
- fcntl = MC_CMD_FCNTL_BIDIR;
1203
- break;
1204
- case EFX_FC_RX:
1205
- fcntl = MC_CMD_FCNTL_RESPOND;
1206
- break;
1207
- default:
1208
- fcntl = MC_CMD_FCNTL_OFF;
1209
- break;
1210
- }
1211
- if (efx->wanted_fc & EFX_FC_AUTO)
1212
- fcntl = MC_CMD_FCNTL_AUTO;
1213
- if (efx->fc_disable)
1214
- fcntl = MC_CMD_FCNTL_OFF;
1215
-
1216
- MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
1217
-
1218
- return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes),
1219
- NULL, 0, NULL);
122078 }
122179
122280 bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
....@@ -1235,89 +93,9 @@
123593 return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
123694 }
123795
1238
-enum efx_stats_action {
1239
- EFX_STATS_ENABLE,
1240
- EFX_STATS_DISABLE,
1241
- EFX_STATS_PULL,
1242
-};
1243
-
1244
-static int efx_mcdi_mac_stats(struct efx_nic *efx,
1245
- enum efx_stats_action action, int clear)
1246
-{
1247
- MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
1248
- int rc;
1249
- int change = action == EFX_STATS_PULL ? 0 : 1;
1250
- int enable = action == EFX_STATS_ENABLE ? 1 : 0;
1251
- int period = action == EFX_STATS_ENABLE ? 1000 : 0;
1252
- dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
1253
- u32 dma_len = action != EFX_STATS_DISABLE ?
1254
- efx->num_mac_stats * sizeof(u64) : 0;
1255
-
1256
- BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
1257
-
1258
- MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, dma_addr);
1259
- MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
1260
- MAC_STATS_IN_DMA, !!enable,
1261
- MAC_STATS_IN_CLEAR, clear,
1262
- MAC_STATS_IN_PERIODIC_CHANGE, change,
1263
- MAC_STATS_IN_PERIODIC_ENABLE, enable,
1264
- MAC_STATS_IN_PERIODIC_CLEAR, 0,
1265
- MAC_STATS_IN_PERIODIC_NOEVENT, 1,
1266
- MAC_STATS_IN_PERIOD_MS, period);
1267
- MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
1268
-
1269
- if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) {
1270
- struct efx_ef10_nic_data *nic_data = efx->nic_data;
1271
-
1272
- MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, nic_data->vport_id);
1273
- }
1274
-
1275
- rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
1276
- NULL, 0, NULL);
1277
- /* Expect ENOENT if DMA queues have not been set up */
1278
- if (rc && (rc != -ENOENT || atomic_read(&efx->active_queues)))
1279
- efx_mcdi_display_error(efx, MC_CMD_MAC_STATS, sizeof(inbuf),
1280
- NULL, 0, rc);
1281
- return rc;
1282
-}
1283
-
1284
-void efx_mcdi_mac_start_stats(struct efx_nic *efx)
1285
-{
1286
- __le64 *dma_stats = efx->stats_buffer.addr;
1287
-
1288
- dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
1289
-
1290
- efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
1291
-}
1292
-
1293
-void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
1294
-{
1295
- efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
1296
-}
1297
-
1298
-#define EFX_MAC_STATS_WAIT_US 100
1299
-#define EFX_MAC_STATS_WAIT_ATTEMPTS 10
1300
-
1301
-void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
1302
-{
1303
- __le64 *dma_stats = efx->stats_buffer.addr;
1304
- int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
1305
-
1306
- dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
1307
- efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
1308
-
1309
- while (dma_stats[efx->num_mac_stats - 1] ==
1310
- EFX_MC_STATS_GENERATION_INVALID &&
1311
- attempts-- != 0)
1312
- udelay(EFX_MAC_STATS_WAIT_US);
1313
-}
1314
-
131596 int efx_mcdi_port_probe(struct efx_nic *efx)
131697 {
131798 int rc;
1318
-
1319
- /* Hook in PHY operations table */
1320
- efx->phy_op = &efx_mcdi_phy_ops;
132199
1322100 /* Set up MDIO structure for PHY */
1323101 efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
....@@ -1325,42 +103,15 @@
1325103 efx->mdio.mdio_write = efx_mcdi_mdio_write;
1326104
1327105 /* Fill out MDIO structure, loopback modes, and initial link state */
1328
- rc = efx->phy_op->probe(efx);
106
+ rc = efx_mcdi_phy_probe(efx);
1329107 if (rc != 0)
1330108 return rc;
1331109
1332
- /* Allocate buffer for stats */
1333
- rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
1334
- efx->num_mac_stats * sizeof(u64), GFP_KERNEL);
1335
- if (rc)
1336
- return rc;
1337
- netif_dbg(efx, probe, efx->net_dev,
1338
- "stats buffer at %llx (virt %p phys %llx)\n",
1339
- (u64)efx->stats_buffer.dma_addr,
1340
- efx->stats_buffer.addr,
1341
- (u64)virt_to_phys(efx->stats_buffer.addr));
1342
-
1343
- efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 1);
1344
-
1345
- return 0;
110
+ return efx_mcdi_mac_init_stats(efx);
1346111 }
1347112
1348113 void efx_mcdi_port_remove(struct efx_nic *efx)
1349114 {
1350
- efx->phy_op->remove(efx);
1351
- efx_nic_free_buffer(efx, &efx->stats_buffer);
1352
-}
1353
-
1354
-/* Get physical port number (EF10 only; on Siena it is same as PF number) */
1355
-int efx_mcdi_port_get_number(struct efx_nic *efx)
1356
-{
1357
- MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
1358
- int rc;
1359
-
1360
- rc = efx_mcdi_rpc(efx, MC_CMD_GET_PORT_ASSIGNMENT, NULL, 0,
1361
- outbuf, sizeof(outbuf), NULL);
1362
- if (rc)
1363
- return rc;
1364
-
1365
- return MCDI_DWORD(outbuf, GET_PORT_ASSIGNMENT_OUT_PORT);
115
+ efx_mcdi_phy_remove(efx);
116
+ efx_mcdi_mac_fini_stats(efx);
1366117 }