extern void e1000_down(struct e1000_adapter *adapter);
extern void e1000_reset(struct e1000_adapter *adapter);
extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
-extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_update_stats(struct e1000_adapter *adapter);
struct e1000_stats {
{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
{ "rx_long_byte_count", E1000_STAT(stats.gorcl) },
{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
- { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }
+ { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
+ { "rx_header_split", E1000_STAT(rx_hdr_split) },
};
#define E1000_STATS_LEN \
sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
static int
e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
if(hw->media_type == e1000_media_type_copper) {
SUPPORTED_FIBRE |
SUPPORTED_Autoneg);
- ecmd->advertising = (SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg);
+ ecmd->advertising = (ADVERTISED_1000baseT_Full |
+ ADVERTISED_FIBRE |
+ ADVERTISED_Autoneg);
ecmd->port = PORT_FIBRE;
static int
e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
if(ecmd->autoneg == AUTONEG_ENABLE) {
hw->autoneg = 1;
- hw->autoneg_advertised = 0x002F;
- ecmd->advertising = 0x002F;
+ if(hw->media_type == e1000_media_type_fiber)
+ hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
+ ADVERTISED_FIBRE |
+ ADVERTISED_Autoneg;
+ else
+ hw->autoneg_advertised = ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_1000baseT_Full|
+ ADVERTISED_Autoneg |
+ ADVERTISED_TP;
+ ecmd->advertising = hw->autoneg_advertised;
} else
if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
return -EINVAL;
e1000_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
pause->autoneg =
e1000_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
adapter->fc_autoneg = pause->autoneg;
static uint32_t
e1000_get_rx_csum(struct net_device *netdev)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
return adapter->rx_csum;
}
static int
e1000_set_rx_csum(struct net_device *netdev, uint32_t data)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
adapter->rx_csum = data;
if(netif_running(netdev)) {
static int
e1000_set_tx_csum(struct net_device *netdev, uint32_t data)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
if(adapter->hw.mac_type < e1000_82543) {
if (!data)
static int
e1000_set_tso(struct net_device *netdev, uint32_t data)
{
- struct e1000_adapter *adapter = netdev->priv;
- if ((adapter->hw.mac_type < e1000_82544) ||
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ if((adapter->hw.mac_type < e1000_82544) ||
(adapter->hw.mac_type == e1000_82547))
return data ? -EINVAL : 0;
static uint32_t
e1000_get_msglevel(struct net_device *netdev)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
return adapter->msg_enable;
}
static void
e1000_set_msglevel(struct net_device *netdev, uint32_t data)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
adapter->msg_enable = data;
}
e1000_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *p)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
uint32_t *regs_buff = p;
uint16_t phy_data;
static int
e1000_get_eeprom_len(struct net_device *netdev)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
return adapter->hw.eeprom.word_size * 2;
}
e1000_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, uint8_t *bytes)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff;
int first_word, last_word;
e1000_set_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, uint8_t *bytes)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff;
void *ptr;
ret_val = e1000_write_eeprom(hw, first_word,
last_word - first_word + 1, eeprom_buff);
- /* Update the checksum over the first part of the EEPROM if needed */
- if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
+ /* Update the checksum over the first part of the EEPROM if needed
+ * and flush shadow RAM for 82573 conrollers */
+ if((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) ||
+ (hw->mac_type == e1000_82573)))
e1000_update_eeprom_checksum(hw);
kfree(eeprom_buff);
e1000_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
strncpy(drvinfo->driver, e1000_driver_name, 32);
strncpy(drvinfo->version, e1000_driver_version, 32);
e1000_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
+ struct e1000_tx_ring *txdr = adapter->tx_ring;
+ struct e1000_rx_ring *rxdr = adapter->rx_ring;
ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
E1000_MAX_82544_RXD;
e1000_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
- struct e1000_desc_ring *txdr = &adapter->tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
- struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new;
- int err;
+ struct e1000_tx_ring *txdr, *tx_old, *tx_new;
+ struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
+ int i, err, tx_ring_size, rx_ring_size;
+
+ tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
+ rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+
+ if (netif_running(adapter->netdev))
+ e1000_down(adapter);
tx_old = adapter->tx_ring;
rx_old = adapter->rx_ring;
+ adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
+ if (!adapter->tx_ring) {
+ err = -ENOMEM;
+ goto err_setup_rx;
+ }
+ memset(adapter->tx_ring, 0, tx_ring_size);
+
+ adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
+ if (!adapter->rx_ring) {
+ kfree(adapter->tx_ring);
+ err = -ENOMEM;
+ goto err_setup_rx;
+ }
+ memset(adapter->rx_ring, 0, rx_ring_size);
+
+ txdr = adapter->tx_ring;
+ rxdr = adapter->rx_ring;
+
if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
- if(netif_running(adapter->netdev))
- e1000_down(adapter);
-
rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
E1000_MAX_RXD : E1000_MAX_82544_RXD));
E1000_MAX_TXD : E1000_MAX_82544_TXD));
E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
+ for (i = 0; i < adapter->num_queues; i++) {
+ txdr[i].count = txdr->count;
+ rxdr[i].count = rxdr->count;
+ }
+
if(netif_running(adapter->netdev)) {
/* Try to get new resources before deleting old */
- if((err = e1000_setup_rx_resources(adapter)))
+ if ((err = e1000_setup_all_rx_resources(adapter)))
goto err_setup_rx;
- if((err = e1000_setup_tx_resources(adapter)))
+ if ((err = e1000_setup_all_tx_resources(adapter)))
goto err_setup_tx;
/* save the new, restore the old in order to free it,
tx_new = adapter->tx_ring;
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
- e1000_free_rx_resources(adapter);
- e1000_free_tx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
+ e1000_free_all_tx_resources(adapter);
+ kfree(tx_old);
+ kfree(rx_old);
adapter->rx_ring = rx_new;
adapter->tx_ring = tx_new;
if((err = e1000_up(adapter)))
return 0;
err_setup_tx:
- e1000_free_rx_resources(adapter);
+ e1000_free_all_rx_resources(adapter);
err_setup_rx:
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \
value = E1000_READ_REG(&adapter->hw, R); \
if(value != (test[pat] & W & M)) { \
+ DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
+ "0x%08X expected 0x%08X\n", \
+ E1000_##R, value, (test[pat] & W & M)); \
*data = (adapter->hw.mac_type < e1000_82543) ? \
E1000_82542_##R : E1000_##R; \
return 1; \
uint32_t value; \
E1000_WRITE_REG(&adapter->hw, R, W & M); \
value = E1000_READ_REG(&adapter->hw, R); \
- if ((W & M) != (value & M)) { \
+ if((W & M) != (value & M)) { \
+ DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
+ "expected 0x%08X\n", E1000_##R, (value & M), (W & M)); \
*data = (adapter->hw.mac_type < e1000_82543) ? \
E1000_82542_##R : E1000_##R; \
return 1; \
static int
e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
{
- uint32_t value;
- uint32_t i;
+ uint32_t value, before, after;
+ uint32_t i, toggle;
/* The status register is Read Only, so a write should fail.
* Some bits that get toggled are ignored.
*/
- value = (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833));
- E1000_WRITE_REG(&adapter->hw, STATUS, (0xFFFFFFFF));
- if(value != (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833))) {
+ switch (adapter->hw.mac_type) {
+ /* there are several bits on newer hardware that are r/w */
+ case e1000_82571:
+ case e1000_82572:
+ toggle = 0x7FFFF3FF;
+ break;
+ case e1000_82573:
+ toggle = 0x7FFFF033;
+ break;
+ default:
+ toggle = 0xFFFFF833;
+ break;
+ }
+
+ before = E1000_READ_REG(&adapter->hw, STATUS);
+ value = (E1000_READ_REG(&adapter->hw, STATUS) & toggle);
+ E1000_WRITE_REG(&adapter->hw, STATUS, toggle);
+ after = E1000_READ_REG(&adapter->hw, STATUS) & toggle;
+ if(value != after) {
+ DPRINTK(DRV, ERR, "failed STATUS register test got: "
+ "0x%08X expected: 0x%08X\n", after, value);
*data = 1;
return 1;
}
+ /* restore previous status */
+ E1000_WRITE_REG(&adapter->hw, STATUS, before);
REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
struct pt_regs *regs)
{
struct net_device *netdev = (struct net_device *) data;
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR);
static void
e1000_free_desc_rings(struct e1000_adapter *adapter)
{
- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
int i;
static int
e1000_setup_desc_rings(struct e1000_adapter *adapter)
{
- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
uint32_t rctl;
int size, i, ret_val;
case e1000_82541_rev_2:
case e1000_82547:
case e1000_82547_rev_2:
+ case e1000_82571:
+ case e1000_82572:
+ case e1000_82573:
return e1000_integrated_phy_loopback(adapter);
break;
static int
e1000_run_loopback_test(struct e1000_adapter *adapter)
{
- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
int i, j, k, l, lc, good_cnt, ret_val=0;
unsigned long time;
e1000_diag_test(struct net_device *netdev,
struct ethtool_test *eth_test, uint64_t *data)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
boolean_t if_running = netif_running(netdev);
if(eth_test->flags == ETH_TEST_FL_OFFLINE) {
data[2] = 0;
data[3] = 0;
}
+ msleep_interruptible(4 * 1000);
}
static void
e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
switch(adapter->hw.device_id) {
static int
e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
switch(adapter->hw.device_id) {
static int
e1000_phys_id(struct net_device *netdev, uint32_t data)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
- if(!adapter->blink_timer.function) {
- init_timer(&adapter->blink_timer);
- adapter->blink_timer.function = e1000_led_blink_callback;
- adapter->blink_timer.data = (unsigned long) adapter;
+ if(adapter->hw.mac_type < e1000_82571) {
+ if(!adapter->blink_timer.function) {
+ init_timer(&adapter->blink_timer);
+ adapter->blink_timer.function = e1000_led_blink_callback;
+ adapter->blink_timer.data = (unsigned long) adapter;
+ }
+ e1000_setup_led(&adapter->hw);
+ mod_timer(&adapter->blink_timer, jiffies);
+ msleep_interruptible(data * 1000);
+ del_timer_sync(&adapter->blink_timer);
+ }
+ else {
+ E1000_WRITE_REG(&adapter->hw, LEDCTL, (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);
}
- e1000_setup_led(&adapter->hw);
- mod_timer(&adapter->blink_timer, jiffies);
-
- msleep_interruptible(data * 1000);
- del_timer_sync(&adapter->blink_timer);
e1000_led_off(&adapter->hw);
clear_bit(E1000_LED_ON, &adapter->led_status);
e1000_cleanup_led(&adapter->hw);
static int
e1000_nway_reset(struct net_device *netdev)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
if(netif_running(netdev)) {
e1000_down(adapter);
e1000_up(adapter);
e1000_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, uint64_t *data)
{
- struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
int i;
e1000_update_stats(adapter);
.phys_id = e1000_phys_id,
.get_stats_count = e1000_get_stats_count,
.get_ethtool_stats = e1000_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
};
void e1000_set_ethtool_ops(struct net_device *netdev)