|
@@ -183,7 +183,15 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
- if(ecmd->autoneg == AUTONEG_ENABLE) {
|
|
|
+ /* When SoL/IDER sessions are active, autoneg/speed/duplex
|
|
|
+ * cannot be changed */
|
|
|
+ if (e1000_check_phy_reset_block(hw)) {
|
|
|
+ DPRINTK(DRV, ERR, "Cannot change link characteristics "
|
|
|
+ "when SoL/IDER is active.\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ecmd->autoneg == AUTONEG_ENABLE) {
|
|
|
hw->autoneg = 1;
|
|
|
if(hw->media_type == e1000_media_type_fiber)
|
|
|
hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
|
|
@@ -562,29 +570,10 @@ e1000_get_drvinfo(struct net_device *netdev,
|
|
|
struct ethtool_drvinfo *drvinfo)
|
|
|
{
|
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
- char firmware_version[32];
|
|
|
- uint16_t eeprom_data;
|
|
|
|
|
|
strncpy(drvinfo->driver, e1000_driver_name, 32);
|
|
|
strncpy(drvinfo->version, e1000_driver_version, 32);
|
|
|
-
|
|
|
- /* EEPROM image version # is reported as firware version # for
|
|
|
- * 8257{1|2|3} controllers */
|
|
|
- e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data);
|
|
|
- switch (adapter->hw.mac_type) {
|
|
|
- case e1000_82571:
|
|
|
- case e1000_82572:
|
|
|
- case e1000_82573:
|
|
|
- sprintf(firmware_version, "%d.%d-%d",
|
|
|
- (eeprom_data & 0xF000) >> 12,
|
|
|
- (eeprom_data & 0x0FF0) >> 4,
|
|
|
- eeprom_data & 0x000F);
|
|
|
- break;
|
|
|
- default:
|
|
|
- sprintf(firmware_version, "n/a");
|
|
|
- }
|
|
|
-
|
|
|
- strncpy(drvinfo->fw_version, firmware_version, 32);
|
|
|
+ strncpy(drvinfo->fw_version, "N/A", 32);
|
|
|
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
|
|
|
drvinfo->n_stats = E1000_STATS_LEN;
|
|
|
drvinfo->testinfo_len = E1000_TEST_LEN;
|
|
@@ -990,10 +979,8 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
|
|
|
|
|
|
kfree(txdr->buffer_info);
|
|
|
txdr->buffer_info = NULL;
|
|
|
-
|
|
|
kfree(rxdr->buffer_info);
|
|
|
rxdr->buffer_info = NULL;
|
|
|
-
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -1328,32 +1315,21 @@ static int
|
|
|
e1000_setup_loopback_test(struct e1000_adapter *adapter)
|
|
|
{
|
|
|
uint32_t rctl;
|
|
|
- struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
- if (hw->media_type == e1000_media_type_fiber ||
|
|
|
- hw->media_type == e1000_media_type_internal_serdes) {
|
|
|
- switch (hw->mac_type) {
|
|
|
- case e1000_82545:
|
|
|
- case e1000_82546:
|
|
|
- case e1000_82545_rev_3:
|
|
|
- case e1000_82546_rev_3:
|
|
|
+ if(adapter->hw.media_type == e1000_media_type_fiber ||
|
|
|
+ adapter->hw.media_type == e1000_media_type_internal_serdes) {
|
|
|
+ if(adapter->hw.mac_type == e1000_82545 ||
|
|
|
+ adapter->hw.mac_type == e1000_82546 ||
|
|
|
+ adapter->hw.mac_type == e1000_82545_rev_3 ||
|
|
|
+ adapter->hw.mac_type == e1000_82546_rev_3)
|
|
|
return e1000_set_phy_loopback(adapter);
|
|
|
- break;
|
|
|
- case e1000_82571:
|
|
|
- case e1000_82572:
|
|
|
-#define E1000_SERDES_LB_ON 0x410
|
|
|
- e1000_set_phy_loopback(adapter);
|
|
|
- E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_ON);
|
|
|
- msec_delay(10);
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- default:
|
|
|
- rctl = E1000_READ_REG(hw, RCTL);
|
|
|
+ else {
|
|
|
+ rctl = E1000_READ_REG(&adapter->hw, RCTL);
|
|
|
rctl |= E1000_RCTL_LBM_TCVR;
|
|
|
- E1000_WRITE_REG(hw, RCTL, rctl);
|
|
|
+ E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
|
|
|
return 0;
|
|
|
}
|
|
|
- } else if (hw->media_type == e1000_media_type_copper)
|
|
|
+ } else if(adapter->hw.media_type == e1000_media_type_copper)
|
|
|
return e1000_set_phy_loopback(adapter);
|
|
|
|
|
|
return 7;
|
|
@@ -1364,36 +1340,25 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter)
|
|
|
{
|
|
|
uint32_t rctl;
|
|
|
uint16_t phy_reg;
|
|
|
- struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
rctl = E1000_READ_REG(&adapter->hw, RCTL);
|
|
|
rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
|
|
|
E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
|
|
|
|
|
|
- switch (hw->mac_type) {
|
|
|
- case e1000_82571:
|
|
|
- case e1000_82572:
|
|
|
- if (hw->media_type == e1000_media_type_fiber ||
|
|
|
- hw->media_type == e1000_media_type_internal_serdes){
|
|
|
-#define E1000_SERDES_LB_OFF 0x400
|
|
|
- E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF);
|
|
|
- msec_delay(10);
|
|
|
- break;
|
|
|
- }
|
|
|
- /* fall thru for Cu adapters */
|
|
|
- case e1000_82545:
|
|
|
- case e1000_82546:
|
|
|
- case e1000_82545_rev_3:
|
|
|
- case e1000_82546_rev_3:
|
|
|
- default:
|
|
|
- hw->autoneg = TRUE;
|
|
|
- e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
|
|
|
- if (phy_reg & MII_CR_LOOPBACK) {
|
|
|
+ if(adapter->hw.media_type == e1000_media_type_copper ||
|
|
|
+ ((adapter->hw.media_type == e1000_media_type_fiber ||
|
|
|
+ adapter->hw.media_type == e1000_media_type_internal_serdes) &&
|
|
|
+ (adapter->hw.mac_type == e1000_82545 ||
|
|
|
+ adapter->hw.mac_type == e1000_82546 ||
|
|
|
+ adapter->hw.mac_type == e1000_82545_rev_3 ||
|
|
|
+ adapter->hw.mac_type == e1000_82546_rev_3))) {
|
|
|
+ adapter->hw.autoneg = TRUE;
|
|
|
+ e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
|
|
|
+ if(phy_reg & MII_CR_LOOPBACK) {
|
|
|
phy_reg &= ~MII_CR_LOOPBACK;
|
|
|
- e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
|
|
|
- e1000_phy_reset(hw);
|
|
|
+ e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);
|
|
|
+ e1000_phy_reset(&adapter->hw);
|
|
|
}
|
|
|
- break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1488,14 +1453,25 @@ e1000_run_loopback_test(struct e1000_adapter *adapter)
|
|
|
static int
|
|
|
e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data)
|
|
|
{
|
|
|
- if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback;
|
|
|
- if((*data = e1000_setup_loopback_test(adapter)))
|
|
|
- goto err_loopback_setup;
|
|
|
+ /* PHY loopback cannot be performed if SoL/IDER
|
|
|
+ * sessions are active */
|
|
|
+ if (e1000_check_phy_reset_block(&adapter->hw)) {
|
|
|
+ DPRINTK(DRV, ERR, "Cannot do PHY loopback test "
|
|
|
+ "when SoL/IDER is active.\n");
|
|
|
+ *data = 0;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((*data = e1000_setup_desc_rings(adapter)))
|
|
|
+ goto out;
|
|
|
+ if ((*data = e1000_setup_loopback_test(adapter)))
|
|
|
+ goto err_loopback;
|
|
|
*data = e1000_run_loopback_test(adapter);
|
|
|
e1000_loopback_cleanup(adapter);
|
|
|
-err_loopback_setup:
|
|
|
- e1000_free_desc_rings(adapter);
|
|
|
+
|
|
|
err_loopback:
|
|
|
+ e1000_free_desc_rings(adapter);
|
|
|
+out:
|
|
|
return *data;
|
|
|
}
|
|
|
|
|
@@ -1722,14 +1698,6 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
|
|
|
msleep_interruptible(data * 1000);
|
|
|
del_timer_sync(&adapter->blink_timer);
|
|
|
}
|
|
|
- else if(adapter->hw.mac_type < e1000_82573) {
|
|
|
- E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
|
|
|
- E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK |
|
|
|
- (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
|
|
|
- (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) |
|
|
|
- (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT)));
|
|
|
- msleep_interruptible(data * 1000);
|
|
|
- }
|
|
|
else {
|
|
|
E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
|
|
|
E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK |
|