aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/sfc/efx.c43
-rw-r--r--drivers/net/ethernet/sfc/efx.h4
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c6
-rw-r--r--drivers/net/ethernet/sfc/mcdi_port.c158
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h2
5 files changed, 120 insertions, 93 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 3780161de5a1..12f0abc30cb1 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -953,31 +953,42 @@ void efx_link_status_changed(struct efx_nic *efx)
953 netif_info(efx, link, efx->net_dev, "link down\n"); 953 netif_info(efx, link, efx->net_dev, "link down\n");
954} 954}
955 955
956void efx_link_set_advertising(struct efx_nic *efx, u32 advertising) 956void efx_link_set_advertising(struct efx_nic *efx,
957 const unsigned long *advertising)
957{ 958{
958 efx->link_advertising = advertising; 959 memcpy(efx->link_advertising, advertising,
959 if (advertising) { 960 sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
960 if (advertising & ADVERTISED_Pause) 961
961 efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX); 962 efx->link_advertising[0] |= ADVERTISED_Autoneg;
962 else 963 if (advertising[0] & ADVERTISED_Pause)
963 efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX); 964 efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX);
964 if (advertising & ADVERTISED_Asym_Pause) 965 else
965 efx->wanted_fc ^= EFX_FC_TX; 966 efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
966 } 967 if (advertising[0] & ADVERTISED_Asym_Pause)
968 efx->wanted_fc ^= EFX_FC_TX;
969}
970
971/* Equivalent to efx_link_set_advertising with all-zeroes, except does not
972 * force the Autoneg bit on.
973 */
974void efx_link_clear_advertising(struct efx_nic *efx)
975{
976 bitmap_zero(efx->link_advertising, __ETHTOOL_LINK_MODE_MASK_NBITS);
977 efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
967} 978}
968 979
969void efx_link_set_wanted_fc(struct efx_nic *efx, u8 wanted_fc) 980void efx_link_set_wanted_fc(struct efx_nic *efx, u8 wanted_fc)
970{ 981{
971 efx->wanted_fc = wanted_fc; 982 efx->wanted_fc = wanted_fc;
972 if (efx->link_advertising) { 983 if (efx->link_advertising[0]) {
973 if (wanted_fc & EFX_FC_RX) 984 if (wanted_fc & EFX_FC_RX)
974 efx->link_advertising |= (ADVERTISED_Pause | 985 efx->link_advertising[0] |= (ADVERTISED_Pause |
975 ADVERTISED_Asym_Pause); 986 ADVERTISED_Asym_Pause);
976 else 987 else
977 efx->link_advertising &= ~(ADVERTISED_Pause | 988 efx->link_advertising[0] &= ~(ADVERTISED_Pause |
978 ADVERTISED_Asym_Pause); 989 ADVERTISED_Asym_Pause);
979 if (wanted_fc & EFX_FC_TX) 990 if (wanted_fc & EFX_FC_TX)
980 efx->link_advertising ^= ADVERTISED_Asym_Pause; 991 efx->link_advertising[0] ^= ADVERTISED_Asym_Pause;
981 } 992 }
982} 993}
983 994
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 16da3e9a6000..0cddc5ad77b1 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -258,7 +258,9 @@ static inline void efx_schedule_channel_irq(struct efx_channel *channel)
258} 258}
259 259
260void efx_link_status_changed(struct efx_nic *efx); 260void efx_link_status_changed(struct efx_nic *efx);
261void efx_link_set_advertising(struct efx_nic *efx, u32); 261void efx_link_set_advertising(struct efx_nic *efx,
262 const unsigned long *advertising);
263void efx_link_clear_advertising(struct efx_nic *efx);
262void efx_link_set_wanted_fc(struct efx_nic *efx, u8); 264void efx_link_set_wanted_fc(struct efx_nic *efx, u8);
263 265
264static inline void efx_device_detach_sync(struct efx_nic *efx) 266static inline void efx_device_detach_sync(struct efx_nic *efx)
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 3747b5644110..4db2dc2bf52f 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -720,7 +720,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
720 goto out; 720 goto out;
721 } 721 }
722 722
723 if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising) { 723 if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising[0]) {
724 netif_dbg(efx, drv, efx->net_dev, 724 netif_dbg(efx, drv, efx->net_dev,
725 "Autonegotiation is disabled\n"); 725 "Autonegotiation is disabled\n");
726 rc = -EINVAL; 726 rc = -EINVAL;
@@ -732,10 +732,10 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
732 (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX)) 732 (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX))
733 efx->type->prepare_enable_fc_tx(efx); 733 efx->type->prepare_enable_fc_tx(efx);
734 734
735 old_adv = efx->link_advertising; 735 old_adv = efx->link_advertising[0];
736 old_fc = efx->wanted_fc; 736 old_fc = efx->wanted_fc;
737 efx_link_set_wanted_fc(efx, wanted_fc); 737 efx_link_set_wanted_fc(efx, wanted_fc);
738 if (efx->link_advertising != old_adv || 738 if (efx->link_advertising[0] != old_adv ||
739 (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) { 739 (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) {
740 rc = efx->phy_op->reconfigure(efx); 740 rc = efx->phy_op->reconfigure(efx);
741 if (rc) { 741 if (rc) {
diff --git a/drivers/net/ethernet/sfc/mcdi_port.c b/drivers/net/ethernet/sfc/mcdi_port.c
index 65ee1a468170..ce8aabf9091e 100644
--- a/drivers/net/ethernet/sfc/mcdi_port.c
+++ b/drivers/net/ethernet/sfc/mcdi_port.c
@@ -171,89 +171,108 @@ static int efx_mcdi_mdio_write(struct net_device *net_dev,
171 return 0; 171 return 0;
172} 172}
173 173
174static u32 mcdi_to_ethtool_cap(u32 media, u32 cap) 174static void mcdi_to_ethtool_linkset(u32 media, u32 cap, unsigned long *linkset)
175{ 175{
176 u32 result = 0; 176 #define SET_BIT(name) __set_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
177 linkset)
177 178
179 bitmap_zero(linkset, __ETHTOOL_LINK_MODE_MASK_NBITS);
178 switch (media) { 180 switch (media) {
179 case MC_CMD_MEDIA_KX4: 181 case MC_CMD_MEDIA_KX4:
180 result |= SUPPORTED_Backplane; 182 SET_BIT(Backplane);
181 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) 183 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
182 result |= SUPPORTED_1000baseKX_Full; 184 SET_BIT(1000baseKX_Full);
183 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) 185 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
184 result |= SUPPORTED_10000baseKX4_Full; 186 SET_BIT(10000baseKX4_Full);
185 if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) 187 if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
186 result |= SUPPORTED_40000baseKR4_Full; 188 SET_BIT(40000baseKR4_Full);
187 break; 189 break;
188 190
189 case MC_CMD_MEDIA_XFP: 191 case MC_CMD_MEDIA_XFP:
190 case MC_CMD_MEDIA_SFP_PLUS: 192 case MC_CMD_MEDIA_SFP_PLUS:
191 case MC_CMD_MEDIA_QSFP_PLUS: 193 case MC_CMD_MEDIA_QSFP_PLUS:
192 result |= SUPPORTED_FIBRE; 194 SET_BIT(FIBRE);
193 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) 195 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
194 result |= SUPPORTED_1000baseT_Full; 196 SET_BIT(1000baseT_Full);
195 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) 197 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
196 result |= SUPPORTED_10000baseT_Full; 198 SET_BIT(10000baseT_Full);
197 if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) 199 if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
198 result |= SUPPORTED_40000baseCR4_Full; 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);
199 break; 207 break;
200 208
201 case MC_CMD_MEDIA_BASE_T: 209 case MC_CMD_MEDIA_BASE_T:
202 result |= SUPPORTED_TP; 210 SET_BIT(TP);
203 if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN)) 211 if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
204 result |= SUPPORTED_10baseT_Half; 212 SET_BIT(10baseT_Half);
205 if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN)) 213 if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
206 result |= SUPPORTED_10baseT_Full; 214 SET_BIT(10baseT_Full);
207 if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN)) 215 if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
208 result |= SUPPORTED_100baseT_Half; 216 SET_BIT(100baseT_Half);
209 if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN)) 217 if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
210 result |= SUPPORTED_100baseT_Full; 218 SET_BIT(100baseT_Full);
211 if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN)) 219 if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
212 result |= SUPPORTED_1000baseT_Half; 220 SET_BIT(1000baseT_Half);
213 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) 221 if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
214 result |= SUPPORTED_1000baseT_Full; 222 SET_BIT(1000baseT_Full);
215 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) 223 if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
216 result |= SUPPORTED_10000baseT_Full; 224 SET_BIT(10000baseT_Full);
217 break; 225 break;
218 } 226 }
219 227
220 if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN)) 228 if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
221 result |= SUPPORTED_Pause; 229 SET_BIT(Pause);
222 if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN)) 230 if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
223 result |= SUPPORTED_Asym_Pause; 231 SET_BIT(Asym_Pause);
224 if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) 232 if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
225 result |= SUPPORTED_Autoneg; 233 SET_BIT(Autoneg);
226 234
227 return result; 235 #undef SET_BIT
228} 236}
229 237
230static u32 ethtool_to_mcdi_cap(u32 cap) 238static u32 ethtool_linkset_to_mcdi_cap(const unsigned long *linkset)
231{ 239{
232 u32 result = 0; 240 u32 result = 0;
233 241
234 if (cap & SUPPORTED_10baseT_Half) 242 #define TEST_BIT(name) test_bit(ETHTOOL_LINK_MODE_ ## name ## _BIT, \
243 linkset)
244
245 if (TEST_BIT(10baseT_Half))
235 result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN); 246 result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN);
236 if (cap & SUPPORTED_10baseT_Full) 247 if (TEST_BIT(10baseT_Full))
237 result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN); 248 result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN);
238 if (cap & SUPPORTED_100baseT_Half) 249 if (TEST_BIT(100baseT_Half))
239 result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN); 250 result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN);
240 if (cap & SUPPORTED_100baseT_Full) 251 if (TEST_BIT(100baseT_Full))
241 result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN); 252 result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN);
242 if (cap & SUPPORTED_1000baseT_Half) 253 if (TEST_BIT(1000baseT_Half))
243 result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN); 254 result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN);
244 if (cap & (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseKX_Full)) 255 if (TEST_BIT(1000baseT_Full) || TEST_BIT(1000baseKX_Full))
245 result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN); 256 result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN);
246 if (cap & (SUPPORTED_10000baseT_Full | SUPPORTED_10000baseKX4_Full)) 257 if (TEST_BIT(10000baseT_Full) || TEST_BIT(10000baseKX4_Full))
247 result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN); 258 result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN);
248 if (cap & (SUPPORTED_40000baseCR4_Full | SUPPORTED_40000baseKR4_Full)) 259 if (TEST_BIT(40000baseCR4_Full) || TEST_BIT(40000baseKR4_Full))
249 result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN); 260 result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN);
250 if (cap & SUPPORTED_Pause) 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))
251 result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN); 268 result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN);
252 if (cap & SUPPORTED_Asym_Pause) 269 if (TEST_BIT(Asym_Pause))
253 result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN); 270 result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN);
254 if (cap & SUPPORTED_Autoneg) 271 if (TEST_BIT(Autoneg))
255 result |= (1 << MC_CMD_PHY_CAP_AN_LBN); 272 result |= (1 << MC_CMD_PHY_CAP_AN_LBN);
256 273
274 #undef TEST_BIT
275
257 return result; 276 return result;
258} 277}
259 278
@@ -285,7 +304,7 @@ static u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
285 return flags; 304 return flags;
286} 305}
287 306
288static u32 mcdi_to_ethtool_media(u32 media) 307static u8 mcdi_to_ethtool_media(u32 media)
289{ 308{
290 switch (media) { 309 switch (media) {
291 case MC_CMD_MEDIA_XAUI: 310 case MC_CMD_MEDIA_XAUI:
@@ -371,8 +390,8 @@ static int efx_mcdi_phy_probe(struct efx_nic *efx)
371 390
372 caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP); 391 caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
373 if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN)) 392 if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
374 efx->link_advertising = 393 mcdi_to_ethtool_linkset(phy_data->media, caps,
375 mcdi_to_ethtool_cap(phy_data->media, caps); 394 efx->link_advertising);
376 else 395 else
377 phy_data->forced_cap = caps; 396 phy_data->forced_cap = caps;
378 397
@@ -435,8 +454,8 @@ fail:
435int efx_mcdi_port_reconfigure(struct efx_nic *efx) 454int efx_mcdi_port_reconfigure(struct efx_nic *efx)
436{ 455{
437 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; 456 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
438 u32 caps = (efx->link_advertising ? 457 u32 caps = (efx->link_advertising[0] ?
439 ethtool_to_mcdi_cap(efx->link_advertising) : 458 ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
440 phy_cfg->forced_cap); 459 phy_cfg->forced_cap);
441 460
442 return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx), 461 return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
@@ -509,34 +528,28 @@ static void efx_mcdi_phy_get_link_ksettings(struct efx_nic *efx,
509 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; 528 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
510 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN); 529 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
511 int rc; 530 int rc;
512 u32 supported, advertising, lp_advertising;
513 531
514 supported = mcdi_to_ethtool_cap(phy_cfg->media, phy_cfg->supported_cap);
515 advertising = efx->link_advertising;
516 cmd->base.speed = efx->link_state.speed; 532 cmd->base.speed = efx->link_state.speed;
517 cmd->base.duplex = efx->link_state.fd; 533 cmd->base.duplex = efx->link_state.fd;
518 cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media); 534 cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media);
519 cmd->base.phy_address = phy_cfg->port; 535 cmd->base.phy_address = phy_cfg->port;
520 cmd->base.autoneg = !!(efx->link_advertising & ADVERTISED_Autoneg); 536 cmd->base.autoneg = !!(efx->link_advertising[0] & ADVERTISED_Autoneg);
521 cmd->base.mdio_support = (efx->mdio.mode_support & 537 cmd->base.mdio_support = (efx->mdio.mode_support &
522 (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22)); 538 (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
523 539
524 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, 540 mcdi_to_ethtool_linkset(phy_cfg->media, phy_cfg->supported_cap,
525 supported); 541 cmd->link_modes.supported);
526 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, 542 memcpy(cmd->link_modes.advertising, efx->link_advertising,
527 advertising); 543 sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
528 544
529 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); 545 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
530 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, 546 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
531 outbuf, sizeof(outbuf), NULL); 547 outbuf, sizeof(outbuf), NULL);
532 if (rc) 548 if (rc)
533 return; 549 return;
534 lp_advertising = 550 mcdi_to_ethtool_linkset(phy_cfg->media,
535 mcdi_to_ethtool_cap(phy_cfg->media, 551 MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP),
536 MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP)); 552 cmd->link_modes.lp_advertising);
537
538 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising,
539 lp_advertising);
540} 553}
541 554
542static int 555static int
@@ -546,29 +559,28 @@ efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx,
546 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; 559 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
547 u32 caps; 560 u32 caps;
548 int rc; 561 int rc;
549 u32 advertising;
550
551 ethtool_convert_link_mode_to_legacy_u32(&advertising,
552 cmd->link_modes.advertising);
553 562
554 if (cmd->base.autoneg) { 563 if (cmd->base.autoneg) {
555 caps = (ethtool_to_mcdi_cap(advertising) | 564 caps = (ethtool_linkset_to_mcdi_cap(cmd->link_modes.advertising) |
556 1 << MC_CMD_PHY_CAP_AN_LBN); 565 1 << MC_CMD_PHY_CAP_AN_LBN);
557 } else if (cmd->base.duplex) { 566 } else if (cmd->base.duplex) {
558 switch (cmd->base.speed) { 567 switch (cmd->base.speed) {
559 case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break; 568 case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break;
560 case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break; 569 case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break;
561 case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break; 570 case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break;
562 case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break; 571 case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break;
563 case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break; 572 case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break;
564 default: return -EINVAL; 573 case 100000: caps = 1 << MC_CMD_PHY_CAP_100000FDX_LBN; break;
574 case 25000: caps = 1 << MC_CMD_PHY_CAP_25000FDX_LBN; break;
575 case 50000: caps = 1 << MC_CMD_PHY_CAP_50000FDX_LBN; break;
576 default: return -EINVAL;
565 } 577 }
566 } else { 578 } else {
567 switch (cmd->base.speed) { 579 switch (cmd->base.speed) {
568 case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break; 580 case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break;
569 case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break; 581 case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break;
570 case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break; 582 case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break;
571 default: return -EINVAL; 583 default: return -EINVAL;
572 } 584 }
573 } 585 }
574 586
@@ -578,11 +590,10 @@ efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx,
578 return rc; 590 return rc;
579 591
580 if (cmd->base.autoneg) { 592 if (cmd->base.autoneg) {
581 efx_link_set_advertising( 593 efx_link_set_advertising(efx, cmd->link_modes.advertising);
582 efx, advertising | ADVERTISED_Autoneg);
583 phy_cfg->forced_cap = 0; 594 phy_cfg->forced_cap = 0;
584 } else { 595 } else {
585 efx_link_set_advertising(efx, 0); 596 efx_link_clear_advertising(efx);
586 phy_cfg->forced_cap = caps; 597 phy_cfg->forced_cap = caps;
587 } 598 }
588 return 0; 599 return 0;
@@ -985,6 +996,9 @@ static unsigned int efx_mcdi_event_link_speed[] = {
985 [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000, 996 [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
986 [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000, 997 [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
987 [MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000, 998 [MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000,
999 [MCDI_EVENT_LINKCHANGE_SPEED_25G] = 25000,
1000 [MCDI_EVENT_LINKCHANGE_SPEED_50G] = 50000,
1001 [MCDI_EVENT_LINKCHANGE_SPEED_100G] = 100000,
988}; 1002};
989 1003
990void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev) 1004void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 4cedc5c4c6d9..3dd42f3136fe 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -937,7 +937,7 @@ struct efx_nic {
937 unsigned int mdio_bus; 937 unsigned int mdio_bus;
938 enum efx_phy_mode phy_mode; 938 enum efx_phy_mode phy_mode;
939 939
940 u32 link_advertising; 940 __ETHTOOL_DECLARE_LINK_MODE_MASK(link_advertising);
941 struct efx_link_state link_state; 941 struct efx_link_state link_state;
942 unsigned int n_link_state_changes; 942 unsigned int n_link_state_changes;
943 943