diff options
author | Ajit Khaparde <ajitkhaparde@gmail.com> | 2012-04-21 18:53:22 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-04-23 17:23:29 -0400 |
commit | 42f11cf20cc5b76766fd1f0e591eda26283a38ec (patch) | |
tree | a5520b1b1fd26a30be075dd0da7f8eb476231ee1 /drivers/net/ethernet/emulex/benet/be_ethtool.c | |
parent | ac807fa8e625aff58060876d70298c93a59c4252 (diff) | |
download | blackbird-op-linux-42f11cf20cc5b76766fd1f0e591eda26283a38ec.tar.gz blackbird-op-linux-42f11cf20cc5b76766fd1f0e591eda26283a38ec.zip |
be2net: fix ethtool get settings
ethtool get settings was not displaying all the settings correctly.
use the get_phy_info to get more information about the PHY to fix this.
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_ethtool.c | 245 |
1 files changed, 168 insertions, 77 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index c1ff73cb0e62..dc9f74c69c40 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -433,102 +433,193 @@ static int be_get_sset_count(struct net_device *netdev, int stringset) } } +static u32 be_get_port_type(u32 phy_type, u32 dac_cable_len) +{ + u32 port; + + switch (phy_type) { + case PHY_TYPE_BASET_1GB: + case PHY_TYPE_BASEX_1GB: + case PHY_TYPE_SGMII: + port = PORT_TP; + break; + case PHY_TYPE_SFP_PLUS_10GB: + port = dac_cable_len ? PORT_DA : PORT_FIBRE; + break; + case PHY_TYPE_XFP_10GB: + case PHY_TYPE_SFP_1GB: + port = PORT_FIBRE; + break; + case PHY_TYPE_BASET_10GB: + port = PORT_TP; + break; + default: + port = PORT_OTHER; + } + + return port; +} + +static u32 convert_to_et_setting(u32 if_type, u32 if_speeds) +{ + u32 val = 0; + + switch (if_type) { + case PHY_TYPE_BASET_1GB: + case PHY_TYPE_BASEX_1GB: + case PHY_TYPE_SGMII: + val |= SUPPORTED_TP; + if (if_speeds & BE_SUPPORTED_SPEED_1GBPS) + val |= SUPPORTED_1000baseT_Full; + if (if_speeds & BE_SUPPORTED_SPEED_100MBPS) + val |= SUPPORTED_100baseT_Full; + if (if_speeds & BE_SUPPORTED_SPEED_10MBPS) + val |= SUPPORTED_10baseT_Full; + break; + case PHY_TYPE_KX4_10GB: + val |= SUPPORTED_Backplane; + if (if_speeds & BE_SUPPORTED_SPEED_1GBPS) + val |= SUPPORTED_1000baseKX_Full; + if (if_speeds & BE_SUPPORTED_SPEED_10GBPS) + val |= SUPPORTED_10000baseKX4_Full; + break; + case PHY_TYPE_KR_10GB: + val |= SUPPORTED_Backplane | + SUPPORTED_10000baseKR_Full; + break; + case PHY_TYPE_SFP_PLUS_10GB: + case PHY_TYPE_XFP_10GB: + case PHY_TYPE_SFP_1GB: + val |= SUPPORTED_FIBRE; + if (if_speeds & BE_SUPPORTED_SPEED_10GBPS) + val |= SUPPORTED_10000baseT_Full; + if (if_speeds & BE_SUPPORTED_SPEED_1GBPS) + val |= SUPPORTED_1000baseT_Full; + break; + case PHY_TYPE_BASET_10GB: + val |= SUPPORTED_TP; + if (if_speeds & BE_SUPPORTED_SPEED_10GBPS) + val |= SUPPORTED_10000baseT_Full; + if (if_speeds & BE_SUPPORTED_SPEED_1GBPS) + val |= SUPPORTED_1000baseT_Full; + if (if_speeds & BE_SUPPORTED_SPEED_100MBPS) + val |= SUPPORTED_100baseT_Full; + break; + default: + val |= SUPPORTED_TP; + } + + return val; +} + +static int convert_to_et_speed(u32 be_speed) +{ + int et_speed = SPEED_10000; + + switch (be_speed) { + case PHY_LINK_SPEED_10MBPS: + et_speed = SPEED_10; + break; + case PHY_LINK_SPEED_100MBPS: + et_speed = SPEED_100; + break; + case PHY_LINK_SPEED_1GBPS: + et_speed = SPEED_1000; + break; + case PHY_LINK_SPEED_10GBPS: + et_speed = SPEED_10000; + break; + } + + return et_speed; +} + +bool be_pause_supported(struct be_adapter *adapter) +{ + return (adapter->phy.interface_type == PHY_TYPE_SFP_PLUS_10GB || + adapter->phy.interface_type == PHY_TYPE_XFP_10GB) ? + false : true; +} + static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_phy_info phy_info; - u8 mac_speed = 0; + u8 port_speed = 0; u16 link_speed = 0; u8 link_status; + u32 et_speed = 0; int status; - if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) { - status = be_cmd_link_status_query(adapter, &mac_speed, - &link_speed, &link_status, 0); - if (!status) - be_link_status_update(adapter, link_status); - - /* link_speed is in units of 10 Mbps */ - if (link_speed) { - ethtool_cmd_speed_set(ecmd, link_speed*10); + if (adapter->phy.link_speed < 0 || !(netdev->flags & IFF_UP)) { + if (adapter->phy.forced_port_speed < 0) { + status = be_cmd_link_status_query(adapter, &port_speed, + &link_speed, &link_status, 0); + if (!status) + be_link_status_update(adapter, link_status); + if (link_speed) + et_speed = link_speed; + else + et_speed = convert_to_et_speed(port_speed); } else { - switch (mac_speed) { - case PHY_LINK_SPEED_10MBPS: - ethtool_cmd_speed_set(ecmd, SPEED_10); - break; - case PHY_LINK_SPEED_100MBPS: - ethtool_cmd_speed_set(ecmd, SPEED_100); - break; - case PHY_LINK_SPEED_1GBPS: - ethtool_cmd_speed_set(ecmd, SPEED_1000); - break; - case PHY_LINK_SPEED_10GBPS: - ethtool_cmd_speed_set(ecmd, SPEED_10000); - break; - case PHY_LINK_SPEED_ZERO: - ethtool_cmd_speed_set(ecmd, 0); - break; - } + et_speed = adapter->phy.forced_port_speed; } - status = be_cmd_get_phy_info(adapter, &phy_info); - if (!status) { - switch (phy_info.interface_type) { - case PHY_TYPE_XFP_10GB: - case PHY_TYPE_SFP_1GB: - case PHY_TYPE_SFP_PLUS_10GB: - ecmd->port = PORT_FIBRE; - break; - default: - ecmd->port = PORT_TP; - break; - } + ethtool_cmd_speed_set(ecmd, et_speed); + + status = be_cmd_get_phy_info(adapter); + if (status) + return status; + + ecmd->supported = + convert_to_et_setting(adapter->phy.interface_type, + adapter->phy.auto_speeds_supported | + adapter->phy.fixed_speeds_supported); + ecmd->advertising = + convert_to_et_setting(adapter->phy.interface_type, + adapter->phy.auto_speeds_supported); - switch (phy_info.interface_type) { - case PHY_TYPE_KR_10GB: - case PHY_TYPE_KX4_10GB: - ecmd->autoneg = AUTONEG_ENABLE; + ecmd->port = be_get_port_type(adapter->phy.interface_type, + adapter->phy.dac_cable_len); + + if (adapter->phy.auto_speeds_supported) { + ecmd->supported |= SUPPORTED_Autoneg; + ecmd->autoneg = AUTONEG_ENABLE; + ecmd->advertising |= ADVERTISED_Autoneg; + } + + if (be_pause_supported(adapter)) { + ecmd->supported |= SUPPORTED_Pause; + ecmd->advertising |= ADVERTISED_Pause; + } + + switch (adapter->phy.interface_type) { + case PHY_TYPE_KR_10GB: + case PHY_TYPE_KX4_10GB: ecmd->transceiver = XCVR_INTERNAL; - break; - default: - ecmd->autoneg = AUTONEG_DISABLE; - ecmd->transceiver = XCVR_EXTERNAL; - break; - } + break; + default: + ecmd->transceiver = XCVR_EXTERNAL; + break; } /* Save for future use */ - adapter->link_speed = ethtool_cmd_speed(ecmd); - adapter->port_type = ecmd->port; - adapter->transceiver = ecmd->transceiver; - adapter->autoneg = ecmd->autoneg; + adapter->phy.link_speed = ethtool_cmd_speed(ecmd); + adapter->phy.port_type = ecmd->port; + adapter->phy.transceiver = ecmd->transceiver; + adapter->phy.autoneg = ecmd->autoneg; + adapter->phy.advertising = ecmd->advertising; + adapter->phy.supported = ecmd->supported; } else { - ethtool_cmd_speed_set(ecmd, adapter->link_speed); - ecmd->port = adapter->port_type; - ecmd->transceiver = adapter->transceiver; - ecmd->autoneg = adapter->autoneg; + ethtool_cmd_speed_set(ecmd, adapter->phy.link_speed); + ecmd->port = adapter->phy.port_type; + ecmd->transceiver = adapter->phy.transceiver; + ecmd->autoneg = adapter->phy.autoneg; + ecmd->advertising = adapter->phy.advertising; + ecmd->supported = adapter->phy.supported; } ecmd->duplex = DUPLEX_FULL; ecmd->phy_address = adapter->port_num; - switch (ecmd->port) { - case PORT_FIBRE: - ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); - break; - case PORT_TP: - ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP); - break; - case PORT_AUI: - ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI); - break; - } - - if (ecmd->autoneg) { - ecmd->supported |= SUPPORTED_1000baseT_Full; - ecmd->supported |= SUPPORTED_Autoneg; - ecmd->advertising |= (ADVERTISED_10000baseT_Full | - ADVERTISED_1000baseT_Full); - } return 0; } @@ -548,7 +639,7 @@ be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) struct be_adapter *adapter = netdev_priv(netdev); be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause); - ecmd->autoneg = 0; + ecmd->autoneg = adapter->phy.fc_autoneg; } static int |