提交 c0bc8721 编写于 作者: J Jeff Garzik

Merge branch 'upstream' of git://lost.foo-projects.org/~ahkok/git/netdev-2.6 into upstream

Conflicts:

	drivers/net/e1000/e1000_main.c
...@@ -68,7 +68,6 @@ ...@@ -68,7 +68,6 @@
#ifdef NETIF_F_TSO #ifdef NETIF_F_TSO
#include <net/checksum.h> #include <net/checksum.h>
#endif #endif
#include <linux/workqueue.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
...@@ -143,6 +142,7 @@ struct e1000_adapter; ...@@ -143,6 +142,7 @@ struct e1000_adapter;
#define AUTO_ALL_MODES 0 #define AUTO_ALL_MODES 0
#define E1000_EEPROM_82544_APM 0x0004 #define E1000_EEPROM_82544_APM 0x0004
#define E1000_EEPROM_ICH8_APME 0x0004
#define E1000_EEPROM_APME 0x0400 #define E1000_EEPROM_APME 0x0400
#ifndef E1000_MASTER_SLAVE #ifndef E1000_MASTER_SLAVE
...@@ -254,7 +254,6 @@ struct e1000_adapter { ...@@ -254,7 +254,6 @@ struct e1000_adapter {
spinlock_t tx_queue_lock; spinlock_t tx_queue_lock;
#endif #endif
atomic_t irq_sem; atomic_t irq_sem;
struct work_struct watchdog_task;
struct work_struct reset_task; struct work_struct reset_task;
uint8_t fc_autoneg; uint8_t fc_autoneg;
...@@ -339,8 +338,14 @@ struct e1000_adapter { ...@@ -339,8 +338,14 @@ struct e1000_adapter {
#ifdef NETIF_F_TSO #ifdef NETIF_F_TSO
boolean_t tso_force; boolean_t tso_force;
#endif #endif
boolean_t smart_power_down; /* phy smart power down */
unsigned long flags;
}; };
enum e1000_state_t {
__E1000_DRIVER_TESTING,
__E1000_RESETTING,
};
/* e1000_main.c */ /* e1000_main.c */
extern char e1000_driver_name[]; extern char e1000_driver_name[];
...@@ -348,6 +353,7 @@ extern char e1000_driver_version[]; ...@@ -348,6 +353,7 @@ extern char e1000_driver_version[];
int e1000_up(struct e1000_adapter *adapter); int e1000_up(struct e1000_adapter *adapter);
void e1000_down(struct e1000_adapter *adapter); void e1000_down(struct e1000_adapter *adapter);
void e1000_reset(struct e1000_adapter *adapter); void e1000_reset(struct e1000_adapter *adapter);
void e1000_reinit_locked(struct e1000_adapter *adapter);
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter); int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
void e1000_free_all_tx_resources(struct e1000_adapter *adapter); void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
......
...@@ -109,7 +109,8 @@ e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -109,7 +109,8 @@ e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
SUPPORTED_1000baseT_Full| SUPPORTED_1000baseT_Full|
SUPPORTED_Autoneg | SUPPORTED_Autoneg |
SUPPORTED_TP); SUPPORTED_TP);
if (hw->phy_type == e1000_phy_ife)
ecmd->supported &= ~SUPPORTED_1000baseT_Full;
ecmd->advertising = ADVERTISED_TP; ecmd->advertising = ADVERTISED_TP;
if (hw->autoneg == 1) { if (hw->autoneg == 1) {
...@@ -203,11 +204,9 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -203,11 +204,9 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
/* reset the link */ /* reset the link */
if (netif_running(adapter->netdev)) { if (netif_running(adapter->netdev))
e1000_down(adapter); e1000_reinit_locked(adapter);
e1000_reset(adapter); else
e1000_up(adapter);
} else
e1000_reset(adapter); e1000_reset(adapter);
return 0; return 0;
...@@ -254,10 +253,9 @@ e1000_set_pauseparam(struct net_device *netdev, ...@@ -254,10 +253,9 @@ e1000_set_pauseparam(struct net_device *netdev,
hw->original_fc = hw->fc; hw->original_fc = hw->fc;
if (adapter->fc_autoneg == AUTONEG_ENABLE) { if (adapter->fc_autoneg == AUTONEG_ENABLE) {
if (netif_running(adapter->netdev)) { if (netif_running(adapter->netdev))
e1000_down(adapter); e1000_reinit_locked(adapter);
e1000_up(adapter); else
} else
e1000_reset(adapter); e1000_reset(adapter);
} else } else
return ((hw->media_type == e1000_media_type_fiber) ? return ((hw->media_type == e1000_media_type_fiber) ?
...@@ -279,10 +277,9 @@ e1000_set_rx_csum(struct net_device *netdev, uint32_t data) ...@@ -279,10 +277,9 @@ e1000_set_rx_csum(struct net_device *netdev, uint32_t data)
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
adapter->rx_csum = data; adapter->rx_csum = data;
if (netif_running(netdev)) { if (netif_running(netdev))
e1000_down(adapter); e1000_reinit_locked(adapter);
e1000_up(adapter); else
} else
e1000_reset(adapter); e1000_reset(adapter);
return 0; return 0;
} }
...@@ -577,6 +574,7 @@ e1000_get_drvinfo(struct net_device *netdev, ...@@ -577,6 +574,7 @@ e1000_get_drvinfo(struct net_device *netdev,
case e1000_82572: case e1000_82572:
case e1000_82573: case e1000_82573:
case e1000_80003es2lan: case e1000_80003es2lan:
case e1000_ich8lan:
sprintf(firmware_version, "%d.%d-%d", sprintf(firmware_version, "%d.%d-%d",
(eeprom_data & 0xF000) >> 12, (eeprom_data & 0xF000) >> 12,
(eeprom_data & 0x0FF0) >> 4, (eeprom_data & 0x0FF0) >> 4,
...@@ -631,6 +629,9 @@ e1000_set_ringparam(struct net_device *netdev, ...@@ -631,6 +629,9 @@ e1000_set_ringparam(struct net_device *netdev,
tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues; tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues; rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues;
while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
msleep(1);
if (netif_running(adapter->netdev)) if (netif_running(adapter->netdev))
e1000_down(adapter); e1000_down(adapter);
...@@ -691,9 +692,11 @@ e1000_set_ringparam(struct net_device *netdev, ...@@ -691,9 +692,11 @@ e1000_set_ringparam(struct net_device *netdev,
adapter->rx_ring = rx_new; adapter->rx_ring = rx_new;
adapter->tx_ring = tx_new; adapter->tx_ring = tx_new;
if ((err = e1000_up(adapter))) if ((err = e1000_up(adapter)))
return err; goto err_setup;
} }
clear_bit(__E1000_RESETTING, &adapter->flags);
return 0; return 0;
err_setup_tx: err_setup_tx:
e1000_free_all_rx_resources(adapter); e1000_free_all_rx_resources(adapter);
...@@ -701,6 +704,8 @@ e1000_set_ringparam(struct net_device *netdev, ...@@ -701,6 +704,8 @@ e1000_set_ringparam(struct net_device *netdev,
adapter->rx_ring = rx_old; adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old; adapter->tx_ring = tx_old;
e1000_up(adapter); e1000_up(adapter);
err_setup:
clear_bit(__E1000_RESETTING, &adapter->flags);
return err; return err;
} }
...@@ -754,6 +759,7 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data) ...@@ -754,6 +759,7 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
toggle = 0x7FFFF3FF; toggle = 0x7FFFF3FF;
break; break;
case e1000_82573: case e1000_82573:
case e1000_ich8lan:
toggle = 0x7FFFF033; toggle = 0x7FFFF033;
break; break;
default: default:
...@@ -773,11 +779,12 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data) ...@@ -773,11 +779,12 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
} }
/* restore previous status */ /* restore previous status */
E1000_WRITE_REG(&adapter->hw, STATUS, before); E1000_WRITE_REG(&adapter->hw, STATUS, before);
if (adapter->hw.mac_type != e1000_ich8lan) {
REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF); REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF); REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF); REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF);
REG_PATTERN_TEST(VET, 0x0000FFFF, 0xFFFFFFFF); REG_PATTERN_TEST(VET, 0x0000FFFF, 0xFFFFFFFF);
}
REG_PATTERN_TEST(RDTR, 0x0000FFFF, 0xFFFFFFFF); REG_PATTERN_TEST(RDTR, 0x0000FFFF, 0xFFFFFFFF);
REG_PATTERN_TEST(RDBAH, 0xFFFFFFFF, 0xFFFFFFFF); REG_PATTERN_TEST(RDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
REG_PATTERN_TEST(RDLEN, 0x000FFF80, 0x000FFFFF); REG_PATTERN_TEST(RDLEN, 0x000FFF80, 0x000FFFFF);
...@@ -790,20 +797,22 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data) ...@@ -790,20 +797,22 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
REG_PATTERN_TEST(TDLEN, 0x000FFF80, 0x000FFFFF); REG_PATTERN_TEST(TDLEN, 0x000FFF80, 0x000FFFFF);
REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x00000000); REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x00000000);
REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0x003FFFFB); before = (adapter->hw.mac_type == e1000_ich8lan ?
0x06C3B33E : 0x06DFB3FE);
REG_SET_AND_CHECK(RCTL, before, 0x003FFFFB);
REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000); REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000);
if (adapter->hw.mac_type >= e1000_82543) { if (adapter->hw.mac_type >= e1000_82543) {
REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0xFFFFFFFF); REG_SET_AND_CHECK(RCTL, before, 0xFFFFFFFF);
REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF); REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF); if (adapter->hw.mac_type != e1000_ich8lan)
REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF);
REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF); REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF); REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF);
value = (adapter->hw.mac_type == e1000_ich8lan ?
for (i = 0; i < E1000_RAR_ENTRIES; i++) { E1000_RAR_ENTRIES_ICH8LAN : E1000_RAR_ENTRIES);
REG_PATTERN_TEST(RA + ((i << 1) << 2), 0xFFFFFFFF, for (i = 0; i < value; i++) {
0xFFFFFFFF);
REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF, REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF,
0xFFFFFFFF); 0xFFFFFFFF);
} }
...@@ -817,7 +826,9 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data) ...@@ -817,7 +826,9 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
} }
for (i = 0; i < E1000_MC_TBL_SIZE; i++) value = (adapter->hw.mac_type == e1000_ich8lan ?
E1000_MC_TBL_SIZE_ICH8LAN : E1000_MC_TBL_SIZE);
for (i = 0; i < value; i++)
REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF); REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF);
*data = 0; *data = 0;
...@@ -889,6 +900,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) ...@@ -889,6 +900,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
/* Test each interrupt */ /* Test each interrupt */
for (; i < 10; i++) { for (; i < 10; i++) {
if (adapter->hw.mac_type == e1000_ich8lan && i == 8)
continue;
/* Interrupt to test */ /* Interrupt to test */
mask = 1 << i; mask = 1 << i;
...@@ -1246,18 +1259,33 @@ e1000_integrated_phy_loopback(struct e1000_adapter *adapter) ...@@ -1246,18 +1259,33 @@ e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
} else if (adapter->hw.phy_type == e1000_phy_gg82563) { } else if (adapter->hw.phy_type == e1000_phy_gg82563) {
e1000_write_phy_reg(&adapter->hw, e1000_write_phy_reg(&adapter->hw,
GG82563_PHY_KMRN_MODE_CTRL, GG82563_PHY_KMRN_MODE_CTRL,
0x1CE); 0x1CC);
} }
/* force 1000, set loopback */
e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140);
/* Now set up the MAC to the same speed/duplex as the PHY. */
ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL); ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);
ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ if (adapter->hw.phy_type == e1000_phy_ife) {
E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ /* force 100, set loopback */
E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x6100);
E1000_CTRL_FD); /* Force Duplex to FULL */
/* Now set up the MAC to the same speed/duplex as the PHY. */
ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
E1000_CTRL_SPD_100 |/* Force Speed to 100 */
E1000_CTRL_FD); /* Force Duplex to FULL */
} else {
/* force 1000, set loopback */
e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140);
/* Now set up the MAC to the same speed/duplex as the PHY. */
ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);
ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
E1000_CTRL_FD); /* Force Duplex to FULL */
}
if (adapter->hw.media_type == e1000_media_type_copper && if (adapter->hw.media_type == e1000_media_type_copper &&
adapter->hw.phy_type == e1000_phy_m88) { adapter->hw.phy_type == e1000_phy_m88) {
...@@ -1317,6 +1345,7 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter) ...@@ -1317,6 +1345,7 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter)
case e1000_82572: case e1000_82572:
case e1000_82573: case e1000_82573:
case e1000_80003es2lan: case e1000_80003es2lan:
case e1000_ich8lan:
return e1000_integrated_phy_loopback(adapter); return e1000_integrated_phy_loopback(adapter);
break; break;
...@@ -1568,6 +1597,7 @@ e1000_diag_test(struct net_device *netdev, ...@@ -1568,6 +1597,7 @@ e1000_diag_test(struct net_device *netdev,
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
boolean_t if_running = netif_running(netdev); boolean_t if_running = netif_running(netdev);
set_bit(__E1000_DRIVER_TESTING, &adapter->flags);
if (eth_test->flags == ETH_TEST_FL_OFFLINE) { if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
/* Offline tests */ /* Offline tests */
...@@ -1582,7 +1612,8 @@ e1000_diag_test(struct net_device *netdev, ...@@ -1582,7 +1612,8 @@ e1000_diag_test(struct net_device *netdev,
eth_test->flags |= ETH_TEST_FL_FAILED; eth_test->flags |= ETH_TEST_FL_FAILED;
if (if_running) if (if_running)
e1000_down(adapter); /* indicate we're in test mode */
dev_close(netdev);
else else
e1000_reset(adapter); e1000_reset(adapter);
...@@ -1607,8 +1638,9 @@ e1000_diag_test(struct net_device *netdev, ...@@ -1607,8 +1638,9 @@ e1000_diag_test(struct net_device *netdev,
adapter->hw.autoneg = autoneg; adapter->hw.autoneg = autoneg;
e1000_reset(adapter); e1000_reset(adapter);
clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
if (if_running) if (if_running)
e1000_up(adapter); dev_open(netdev);
} else { } else {
/* Online tests */ /* Online tests */
if (e1000_link_test(adapter, &data[4])) if (e1000_link_test(adapter, &data[4]))
...@@ -1619,6 +1651,8 @@ e1000_diag_test(struct net_device *netdev, ...@@ -1619,6 +1651,8 @@ e1000_diag_test(struct net_device *netdev,
data[1] = 0; data[1] = 0;
data[2] = 0; data[2] = 0;
data[3] = 0; data[3] = 0;
clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
} }
msleep_interruptible(4 * 1000); msleep_interruptible(4 * 1000);
} }
...@@ -1778,21 +1812,18 @@ e1000_phys_id(struct net_device *netdev, uint32_t data) ...@@ -1778,21 +1812,18 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
mod_timer(&adapter->blink_timer, jiffies); mod_timer(&adapter->blink_timer, jiffies);
msleep_interruptible(data * 1000); msleep_interruptible(data * 1000);
del_timer_sync(&adapter->blink_timer); del_timer_sync(&adapter->blink_timer);
} else if (adapter->hw.mac_type < e1000_82573) { } else if (adapter->hw.phy_type == e1000_phy_ife) {
E1000_WRITE_REG(&adapter->hw, LEDCTL, if (!adapter->blink_timer.function) {
(E1000_LEDCTL_LED2_BLINK_RATE | init_timer(&adapter->blink_timer);
E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK | adapter->blink_timer.function = e1000_led_blink_callback;
(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) | adapter->blink_timer.data = (unsigned long) adapter;
(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) | }
(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT))); mod_timer(&adapter->blink_timer, jiffies);
msleep_interruptible(data * 1000); msleep_interruptible(data * 1000);
del_timer_sync(&adapter->blink_timer);
e1000_write_phy_reg(&(adapter->hw), IFE_PHY_SPECIAL_CONTROL_LED, 0);
} else { } else {
E1000_WRITE_REG(&adapter->hw, LEDCTL, e1000_blink_led_start(&adapter->hw);
(E1000_LEDCTL_LED2_BLINK_RATE |
E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK |
(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) |
(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT)));
msleep_interruptible(data * 1000); msleep_interruptible(data * 1000);
} }
...@@ -1807,10 +1838,8 @@ static int ...@@ -1807,10 +1838,8 @@ static int
e1000_nway_reset(struct net_device *netdev) e1000_nway_reset(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev)) { if (netif_running(netdev))
e1000_down(adapter); e1000_reinit_locked(adapter);
e1000_up(adapter);
}
return 0; return 0;
} }
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -127,4 +127,17 @@ typedef enum { ...@@ -127,4 +127,17 @@ typedef enum {
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS) #define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
#define E1000_WRITE_ICH8_REG(a, reg, value) ( \
writel((value), ((a)->flash_address + reg)))
#define E1000_READ_ICH8_REG(a, reg) ( \
readl((a)->flash_address + reg))
#define E1000_WRITE_ICH8_REG16(a, reg, value) ( \
writew((value), ((a)->flash_address + reg)))
#define E1000_READ_ICH8_REG16(a, reg) ( \
readw((a)->flash_address + reg))
#endif /* _E1000_OSDEP_H_ */ #endif /* _E1000_OSDEP_H_ */
...@@ -45,6 +45,16 @@ ...@@ -45,6 +45,16 @@
*/ */
#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET } #define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
/* Module Parameters are always initialized to -1, so that the driver
* can tell the difference between no user specified value or the
* user asking for the default value.
* The true default values are loaded in when e1000_check_options is called.
*
* This is a GCC extension to ANSI C.
* See the item "Labeled Elements in Initializers" in the section
* "Extensions to the C Language Family" of the GCC documentation.
*/
#define E1000_PARAM(X, desc) \ #define E1000_PARAM(X, desc) \
static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \ static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \
static int num_##X = 0; \ static int num_##X = 0; \
...@@ -183,6 +193,24 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); ...@@ -183,6 +193,24 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
/* Enable Smart Power Down of the PHY
*
* Valid Range: 0, 1
*
* Default Value: 0 (disabled)
*/
E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
/* Enable Kumeran Lock Loss workaround
*
* Valid Range: 0, 1
*
* Default Value: 1 (enabled)
*/
E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
#define AUTONEG_ADV_DEFAULT 0x2F #define AUTONEG_ADV_DEFAULT 0x2F
#define AUTONEG_ADV_MASK 0x2F #define AUTONEG_ADV_MASK 0x2F
#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
...@@ -296,6 +324,7 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -296,6 +324,7 @@ e1000_check_options(struct e1000_adapter *adapter)
DPRINTK(PROBE, NOTICE, DPRINTK(PROBE, NOTICE,
"Warning: no configuration for board #%i\n", bd); "Warning: no configuration for board #%i\n", bd);
DPRINTK(PROBE, NOTICE, "Using defaults for all values\n"); DPRINTK(PROBE, NOTICE, "Using defaults for all values\n");
bd = E1000_MAX_NIC;
} }
{ /* Transmit Descriptor Count */ { /* Transmit Descriptor Count */
...@@ -313,14 +342,9 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -313,14 +342,9 @@ e1000_check_options(struct e1000_adapter *adapter)
opt.arg.r.max = mac_type < e1000_82544 ? opt.arg.r.max = mac_type < e1000_82544 ?
E1000_MAX_TXD : E1000_MAX_82544_TXD; E1000_MAX_TXD : E1000_MAX_82544_TXD;
if (num_TxDescriptors > bd) { tx_ring->count = TxDescriptors[bd];
tx_ring->count = TxDescriptors[bd]; e1000_validate_option(&tx_ring->count, &opt, adapter);
e1000_validate_option(&tx_ring->count, &opt, adapter); E1000_ROUNDUP(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE);
E1000_ROUNDUP(tx_ring->count,
REQ_TX_DESCRIPTOR_MULTIPLE);
} else {
tx_ring->count = opt.def;
}
for (i = 0; i < adapter->num_tx_queues; i++) for (i = 0; i < adapter->num_tx_queues; i++)
tx_ring[i].count = tx_ring->count; tx_ring[i].count = tx_ring->count;
} }
...@@ -339,14 +363,9 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -339,14 +363,9 @@ e1000_check_options(struct e1000_adapter *adapter)
opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD : opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
E1000_MAX_82544_RXD; E1000_MAX_82544_RXD;
if (num_RxDescriptors > bd) { rx_ring->count = RxDescriptors[bd];
rx_ring->count = RxDescriptors[bd]; e1000_validate_option(&rx_ring->count, &opt, adapter);
e1000_validate_option(&rx_ring->count, &opt, adapter); E1000_ROUNDUP(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE);
E1000_ROUNDUP(rx_ring->count,
REQ_RX_DESCRIPTOR_MULTIPLE);
} else {
rx_ring->count = opt.def;
}
for (i = 0; i < adapter->num_rx_queues; i++) for (i = 0; i < adapter->num_rx_queues; i++)
rx_ring[i].count = rx_ring->count; rx_ring[i].count = rx_ring->count;
} }
...@@ -358,13 +377,9 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -358,13 +377,9 @@ e1000_check_options(struct e1000_adapter *adapter)
.def = OPTION_ENABLED .def = OPTION_ENABLED
}; };
if (num_XsumRX > bd) { int rx_csum = XsumRX[bd];
int rx_csum = XsumRX[bd]; e1000_validate_option(&rx_csum, &opt, adapter);
e1000_validate_option(&rx_csum, &opt, adapter); adapter->rx_csum = rx_csum;
adapter->rx_csum = rx_csum;
} else {
adapter->rx_csum = opt.def;
}
} }
{ /* Flow Control */ { /* Flow Control */
...@@ -384,13 +399,9 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -384,13 +399,9 @@ e1000_check_options(struct e1000_adapter *adapter)
.p = fc_list }} .p = fc_list }}
}; };
if (num_FlowControl > bd) { int fc = FlowControl[bd];
int fc = FlowControl[bd]; e1000_validate_option(&fc, &opt, adapter);
e1000_validate_option(&fc, &opt, adapter); adapter->hw.fc = adapter->hw.original_fc = fc;
adapter->hw.fc = adapter->hw.original_fc = fc;
} else {
adapter->hw.fc = adapter->hw.original_fc = opt.def;
}
} }
{ /* Transmit Interrupt Delay */ { /* Transmit Interrupt Delay */
struct e1000_option opt = { struct e1000_option opt = {
...@@ -402,13 +413,8 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -402,13 +413,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.max = MAX_TXDELAY }} .max = MAX_TXDELAY }}
}; };
if (num_TxIntDelay > bd) { adapter->tx_int_delay = TxIntDelay[bd];
adapter->tx_int_delay = TxIntDelay[bd]; e1000_validate_option(&adapter->tx_int_delay, &opt, adapter);
e1000_validate_option(&adapter->tx_int_delay, &opt,
adapter);
} else {
adapter->tx_int_delay = opt.def;
}
} }
{ /* Transmit Absolute Interrupt Delay */ { /* Transmit Absolute Interrupt Delay */
struct e1000_option opt = { struct e1000_option opt = {
...@@ -420,13 +426,9 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -420,13 +426,9 @@ e1000_check_options(struct e1000_adapter *adapter)
.max = MAX_TXABSDELAY }} .max = MAX_TXABSDELAY }}
}; };
if (num_TxAbsIntDelay > bd) { adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; e1000_validate_option(&adapter->tx_abs_int_delay, &opt,
e1000_validate_option(&adapter->tx_abs_int_delay, &opt, adapter);
adapter);
} else {
adapter->tx_abs_int_delay = opt.def;
}
} }
{ /* Receive Interrupt Delay */ { /* Receive Interrupt Delay */
struct e1000_option opt = { struct e1000_option opt = {
...@@ -438,13 +440,8 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -438,13 +440,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.max = MAX_RXDELAY }} .max = MAX_RXDELAY }}
}; };
if (num_RxIntDelay > bd) { adapter->rx_int_delay = RxIntDelay[bd];
adapter->rx_int_delay = RxIntDelay[bd]; e1000_validate_option(&adapter->rx_int_delay, &opt, adapter);
e1000_validate_option(&adapter->rx_int_delay, &opt,
adapter);
} else {
adapter->rx_int_delay = opt.def;
}
} }
{ /* Receive Absolute Interrupt Delay */ { /* Receive Absolute Interrupt Delay */
struct e1000_option opt = { struct e1000_option opt = {
...@@ -456,13 +453,9 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -456,13 +453,9 @@ e1000_check_options(struct e1000_adapter *adapter)
.max = MAX_RXABSDELAY }} .max = MAX_RXABSDELAY }}
}; };
if (num_RxAbsIntDelay > bd) { adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; e1000_validate_option(&adapter->rx_abs_int_delay, &opt,
e1000_validate_option(&adapter->rx_abs_int_delay, &opt, adapter);
adapter);
} else {
adapter->rx_abs_int_delay = opt.def;
}
} }
{ /* Interrupt Throttling Rate */ { /* Interrupt Throttling Rate */
struct e1000_option opt = { struct e1000_option opt = {
...@@ -474,26 +467,44 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -474,26 +467,44 @@ e1000_check_options(struct e1000_adapter *adapter)
.max = MAX_ITR }} .max = MAX_ITR }}
}; };
if (num_InterruptThrottleRate > bd) { adapter->itr = InterruptThrottleRate[bd];
adapter->itr = InterruptThrottleRate[bd]; switch (adapter->itr) {
switch (adapter->itr) { case 0:
case 0: DPRINTK(PROBE, INFO, "%s turned off\n", opt.name);
DPRINTK(PROBE, INFO, "%s turned off\n", break;
opt.name); case 1:
break; DPRINTK(PROBE, INFO, "%s set to dynamic mode\n",
case 1: opt.name);
DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", break;
opt.name); default:
break; e1000_validate_option(&adapter->itr, &opt, adapter);
default: break;
e1000_validate_option(&adapter->itr, &opt,
adapter);
break;
}
} else {
adapter->itr = opt.def;
} }
} }
{ /* Smart Power Down */
struct e1000_option opt = {
.type = enable_option,
.name = "PHY Smart Power Down",
.err = "defaulting to Disabled",
.def = OPTION_DISABLED
};
int spd = SmartPowerDownEnable[bd];
e1000_validate_option(&spd, &opt, adapter);
adapter->smart_power_down = spd;
}
{ /* Kumeran Lock Loss Workaround */
struct e1000_option opt = {
.type = enable_option,
.name = "Kumeran Lock Loss Workaround",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
int kmrn_lock_loss = KumeranLockLoss[bd];
e1000_validate_option(&kmrn_lock_loss, &opt, adapter);
adapter->hw.kmrn_lock_loss_workaround_disabled = !kmrn_lock_loss;
}
switch (adapter->hw.media_type) { switch (adapter->hw.media_type) {
case e1000_media_type_fiber: case e1000_media_type_fiber:
...@@ -519,17 +530,18 @@ static void __devinit ...@@ -519,17 +530,18 @@ static void __devinit
e1000_check_fiber_options(struct e1000_adapter *adapter) e1000_check_fiber_options(struct e1000_adapter *adapter)
{ {
int bd = adapter->bd_number; int bd = adapter->bd_number;
if (num_Speed > bd) { bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd;
if ((Speed[bd] != OPTION_UNSET)) {
DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, " DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, "
"parameter ignored\n"); "parameter ignored\n");
} }
if (num_Duplex > bd) { if ((Duplex[bd] != OPTION_UNSET)) {
DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, " DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, "
"parameter ignored\n"); "parameter ignored\n");
} }
if ((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) { if ((AutoNeg[bd] != OPTION_UNSET) && (AutoNeg[bd] != 0x20)) {
DPRINTK(PROBE, INFO, "AutoNeg other than 1000/Full is " DPRINTK(PROBE, INFO, "AutoNeg other than 1000/Full is "
"not valid for fiber adapters, " "not valid for fiber adapters, "
"parameter ignored\n"); "parameter ignored\n");
...@@ -548,6 +560,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -548,6 +560,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
{ {
int speed, dplx, an; int speed, dplx, an;
int bd = adapter->bd_number; int bd = adapter->bd_number;
bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd;
{ /* Speed */ { /* Speed */
struct e1000_opt_list speed_list[] = {{ 0, "" }, struct e1000_opt_list speed_list[] = {{ 0, "" },
...@@ -564,12 +577,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -564,12 +577,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
.p = speed_list }} .p = speed_list }}
}; };
if (num_Speed > bd) { speed = Speed[bd];
speed = Speed[bd]; e1000_validate_option(&speed, &opt, adapter);
e1000_validate_option(&speed, &opt, adapter);
} else {
speed = opt.def;
}
} }
{ /* Duplex */ { /* Duplex */
struct e1000_opt_list dplx_list[] = {{ 0, "" }, struct e1000_opt_list dplx_list[] = {{ 0, "" },
...@@ -591,15 +600,11 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -591,15 +600,11 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
"Speed/Duplex/AutoNeg parameter ignored.\n"); "Speed/Duplex/AutoNeg parameter ignored.\n");
return; return;
} }
if (num_Duplex > bd) { dplx = Duplex[bd];
dplx = Duplex[bd]; e1000_validate_option(&dplx, &opt, adapter);
e1000_validate_option(&dplx, &opt, adapter);
} else {
dplx = opt.def;
}
} }
if ((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) { if (AutoNeg[bd] != OPTION_UNSET && (speed != 0 || dplx != 0)) {
DPRINTK(PROBE, INFO, DPRINTK(PROBE, INFO,
"AutoNeg specified along with Speed or Duplex, " "AutoNeg specified along with Speed or Duplex, "
"parameter ignored\n"); "parameter ignored\n");
...@@ -648,19 +653,15 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -648,19 +653,15 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
.p = an_list }} .p = an_list }}
}; };
if (num_AutoNeg > bd) { an = AutoNeg[bd];
an = AutoNeg[bd]; e1000_validate_option(&an, &opt, adapter);
e1000_validate_option(&an, &opt, adapter);
} else {
an = opt.def;
}
adapter->hw.autoneg_advertised = an; adapter->hw.autoneg_advertised = an;
} }
switch (speed + dplx) { switch (speed + dplx) {
case 0: case 0:
adapter->hw.autoneg = adapter->fc_autoneg = 1; adapter->hw.autoneg = adapter->fc_autoneg = 1;
if ((num_Speed > bd) && (speed != 0 || dplx != 0)) if (Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET)
DPRINTK(PROBE, INFO, DPRINTK(PROBE, INFO,
"Speed and duplex autonegotiation enabled\n"); "Speed and duplex autonegotiation enabled\n");
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册