Commit c5e62a24 authored by David S. Miller's avatar David S. Miller

Merge branch 'sfc-support-25G-configuration-with-ethtool'

Edward Cree says:

====================
sfc: support 25G configuration with ethtool

Adds support for advertise bits beyond the 32-bit legacy masks, and plumbs in
 translation of the new 25/50/100G bits to/from MCDI.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c92342b0 5abb5e7f
...@@ -953,31 +953,42 @@ void efx_link_status_changed(struct efx_nic *efx) ...@@ -953,31 +953,42 @@ void efx_link_status_changed(struct efx_nic *efx)
netif_info(efx, link, efx->net_dev, "link down\n"); netif_info(efx, link, efx->net_dev, "link down\n");
} }
void efx_link_set_advertising(struct efx_nic *efx, u32 advertising) void efx_link_set_advertising(struct efx_nic *efx,
const unsigned long *advertising)
{ {
efx->link_advertising = advertising; memcpy(efx->link_advertising, advertising,
if (advertising) { sizeof(__ETHTOOL_DECLARE_LINK_MODE_MASK()));
if (advertising & ADVERTISED_Pause)
efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX); efx->link_advertising[0] |= ADVERTISED_Autoneg;
else if (advertising[0] & ADVERTISED_Pause)
efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX); efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX);
if (advertising & ADVERTISED_Asym_Pause) else
efx->wanted_fc ^= EFX_FC_TX; efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
} if (advertising[0] & ADVERTISED_Asym_Pause)
efx->wanted_fc ^= EFX_FC_TX;
}
/* Equivalent to efx_link_set_advertising with all-zeroes, except does not
* force the Autoneg bit on.
*/
void efx_link_clear_advertising(struct efx_nic *efx)
{
bitmap_zero(efx->link_advertising, __ETHTOOL_LINK_MODE_MASK_NBITS);
efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
} }
void efx_link_set_wanted_fc(struct efx_nic *efx, u8 wanted_fc) void efx_link_set_wanted_fc(struct efx_nic *efx, u8 wanted_fc)
{ {
efx->wanted_fc = wanted_fc; efx->wanted_fc = wanted_fc;
if (efx->link_advertising) { if (efx->link_advertising[0]) {
if (wanted_fc & EFX_FC_RX) if (wanted_fc & EFX_FC_RX)
efx->link_advertising |= (ADVERTISED_Pause | efx->link_advertising[0] |= (ADVERTISED_Pause |
ADVERTISED_Asym_Pause); ADVERTISED_Asym_Pause);
else else
efx->link_advertising &= ~(ADVERTISED_Pause | efx->link_advertising[0] &= ~(ADVERTISED_Pause |
ADVERTISED_Asym_Pause); ADVERTISED_Asym_Pause);
if (wanted_fc & EFX_FC_TX) if (wanted_fc & EFX_FC_TX)
efx->link_advertising ^= ADVERTISED_Asym_Pause; efx->link_advertising[0] ^= ADVERTISED_Asym_Pause;
} }
} }
......
...@@ -258,7 +258,9 @@ static inline void efx_schedule_channel_irq(struct efx_channel *channel) ...@@ -258,7 +258,9 @@ static inline void efx_schedule_channel_irq(struct efx_channel *channel)
} }
void efx_link_status_changed(struct efx_nic *efx); void efx_link_status_changed(struct efx_nic *efx);
void efx_link_set_advertising(struct efx_nic *efx, u32); void efx_link_set_advertising(struct efx_nic *efx,
const unsigned long *advertising);
void efx_link_clear_advertising(struct efx_nic *efx);
void efx_link_set_wanted_fc(struct efx_nic *efx, u8); void efx_link_set_wanted_fc(struct efx_nic *efx, u8);
static inline void efx_device_detach_sync(struct efx_nic *efx) static inline void efx_device_detach_sync(struct efx_nic *efx)
......
...@@ -720,7 +720,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, ...@@ -720,7 +720,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
goto out; goto out;
} }
if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising) { if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising[0]) {
netif_dbg(efx, drv, efx->net_dev, netif_dbg(efx, drv, efx->net_dev,
"Autonegotiation is disabled\n"); "Autonegotiation is disabled\n");
rc = -EINVAL; rc = -EINVAL;
...@@ -732,10 +732,10 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, ...@@ -732,10 +732,10 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
(wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX)) (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX))
efx->type->prepare_enable_fc_tx(efx); efx->type->prepare_enable_fc_tx(efx);
old_adv = efx->link_advertising; old_adv = efx->link_advertising[0];
old_fc = efx->wanted_fc; old_fc = efx->wanted_fc;
efx_link_set_wanted_fc(efx, wanted_fc); efx_link_set_wanted_fc(efx, wanted_fc);
if (efx->link_advertising != old_adv || if (efx->link_advertising[0] != old_adv ||
(efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) { (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) {
rc = efx->phy_op->reconfigure(efx); rc = efx->phy_op->reconfigure(efx);
if (rc) { if (rc) {
......
This diff is collapsed.
...@@ -937,7 +937,7 @@ struct efx_nic { ...@@ -937,7 +937,7 @@ struct efx_nic {
unsigned int mdio_bus; unsigned int mdio_bus;
enum efx_phy_mode phy_mode; enum efx_phy_mode phy_mode;
u32 link_advertising; __ETHTOOL_DECLARE_LINK_MODE_MASK(link_advertising);
struct efx_link_state link_state; struct efx_link_state link_state;
unsigned int n_link_state_changes; unsigned int n_link_state_changes;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment