Commit 8a76ddc0 authored by Scott Feldman's avatar Scott Feldman Committed by Jeff Garzik

e1000 net driver update 1/4:

* Adds support for ETHTOOL_GREGS to dump register set to ethtool. 
* Adds support for ETHTOOL_LEDBLINK to blink LED's on adapter 
  from ethtool. 
* Bug fix: error message added for corrupted EEPROM detection. 
* Bug fix: when setting up link on copper interface, explicitly 
  turn off force speed and duplex before auto-negotiation. 
parent a82fa3a4
...@@ -107,7 +107,6 @@ ...@@ -107,7 +107,6 @@
#include <linux/udp.h> #include <linux/udp.h>
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
#include <linux/list.h> #include <linux/list.h>
#include <asm/uaccess.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#ifdef NETIF_F_HW_VLAN_TX #ifdef NETIF_F_HW_VLAN_TX
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
...@@ -204,6 +203,11 @@ struct e1000_adapter { ...@@ -204,6 +203,11 @@ struct e1000_adapter {
spinlock_t stats_lock; spinlock_t stats_lock;
atomic_t irq_sem; atomic_t irq_sem;
#ifdef ETHTOOL_PHYS_ID
struct timer_list blink_timer;
unsigned long led_status;
#endif
/* TX */ /* TX */
struct e1000_desc_ring tx_ring; struct e1000_desc_ring tx_ring;
unsigned long trans_finish; unsigned long trans_finish;
...@@ -228,6 +232,7 @@ struct e1000_adapter { ...@@ -228,6 +232,7 @@ struct e1000_adapter {
struct e1000_hw_stats stats; struct e1000_hw_stats stats;
struct e1000_phy_info phy_info; struct e1000_phy_info phy_info;
struct e1000_phy_stats phy_stats; struct e1000_phy_stats phy_stats;
};
};
#endif /* _E1000_H_ */ #endif /* _E1000_H_ */
...@@ -75,7 +75,6 @@ ...@@ -75,7 +75,6 @@
#include "e1000.h" #include "e1000.h"
#include <linux/ethtool.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
extern char e1000_driver_name[]; extern char e1000_driver_name[];
...@@ -211,9 +210,37 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter, ...@@ -211,9 +210,37 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
strncpy(drvinfo->version, e1000_driver_version, 32); strncpy(drvinfo->version, e1000_driver_version, 32);
strncpy(drvinfo->fw_version, "", 32); strncpy(drvinfo->fw_version, "", 32);
strncpy(drvinfo->bus_info, adapter->pdev->slot_name, 32); strncpy(drvinfo->bus_info, adapter->pdev->slot_name, 32);
#define E1000_REGS_LEN 32
drvinfo->regdump_len = E1000_REGS_LEN * sizeof(uint32_t);
drvinfo->eedump_len = e1000_eeprom_size(&adapter->hw); drvinfo->eedump_len = e1000_eeprom_size(&adapter->hw);
} }
static void
e1000_ethtool_gregs(struct e1000_adapter *adapter,
struct ethtool_regs *regs, uint32_t *regs_buff)
{
struct e1000_hw *hw = &adapter->hw;
regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
regs_buff[0] = E1000_READ_REG(hw, CTRL);
regs_buff[1] = E1000_READ_REG(hw, STATUS);
regs_buff[2] = E1000_READ_REG(hw, RCTL);
regs_buff[3] = E1000_READ_REG(hw, RDLEN);
regs_buff[4] = E1000_READ_REG(hw, RDH);
regs_buff[5] = E1000_READ_REG(hw, RDT);
regs_buff[6] = E1000_READ_REG(hw, RDTR);
regs_buff[7] = E1000_READ_REG(hw, TCTL);
regs_buff[8] = E1000_READ_REG(hw, TDLEN);
regs_buff[9] = E1000_READ_REG(hw, TDH);
regs_buff[10] = E1000_READ_REG(hw, TDT);
regs_buff[11] = E1000_READ_REG(hw, TIDV);
return;
}
static void static void
e1000_ethtool_geeprom(struct e1000_adapter *adapter, e1000_ethtool_geeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff) struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
...@@ -284,6 +311,54 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) ...@@ -284,6 +311,54 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
return 0; return 0;
} }
#ifdef ETHTOOL_PHYS_ID
/* toggle LED 4 times per second = 2 "blinks" per second */
#define E1000_ID_INTERVAL (HZ/4)
/* bit defines for adapter->led_status */
#define E1000_LED_ON 0
static void
e1000_led_blink_callback(unsigned long data)
{
struct e1000_adapter *adapter = (struct e1000_adapter *) data;
if(test_and_change_bit(E1000_LED_ON, &adapter->led_status))
e1000_led_off(&adapter->hw);
else
e1000_led_on(&adapter->hw);
mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
}
static int
e1000_ethtool_led_blink(struct e1000_adapter *adapter, struct ethtool_value *id)
{
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);
set_current_state(TASK_INTERRUPTIBLE);
if(id->data)
schedule_timeout(id->data * HZ);
else
schedule_timeout(MAX_SCHEDULE_TIMEOUT);
del_timer_sync(&adapter->blink_timer);
e1000_led_off(&adapter->hw);
clear_bit(E1000_LED_ON, &adapter->led_status);
e1000_cleanup_led(&adapter->hw);
return 0;
}
#endif /* ETHTOOL_PHYS_ID */
int int
e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr) e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
{ {
...@@ -317,6 +392,22 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr) ...@@ -317,6 +392,22 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
case ETHTOOL_GREGS: {
struct ethtool_regs regs = {ETHTOOL_GREGS};
uint32_t regs_buff[E1000_REGS_LEN];
if(copy_from_user(&regs, addr, sizeof(regs)))
return -EFAULT;
e1000_ethtool_gregs(adapter, &regs, regs_buff);
if(copy_to_user(addr, &regs, sizeof(regs)))
return -EFAULT;
addr += offsetof(struct ethtool_regs, data);
if(copy_to_user(addr, regs_buff, regs.len))
return -EFAULT;
return 0;
}
case ETHTOOL_NWAY_RST: { case ETHTOOL_NWAY_RST: {
if(!capable(CAP_NET_ADMIN)) if(!capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
...@@ -324,6 +415,14 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr) ...@@ -324,6 +415,14 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
e1000_up(adapter); e1000_up(adapter);
return 0; return 0;
} }
#ifdef ETHTOOL_PHYS_ID
case ETHTOOL_PHYS_ID: {
struct ethtool_value id;
if(copy_from_user(&id, addr, sizeof(id)))
return -EFAULT;
return e1000_ethtool_led_blink(adapter, &id);
}
#endif /* ETHTOOL_PHYS_ID */
case ETHTOOL_GLINK: { case ETHTOOL_GLINK: {
struct ethtool_value link = {ETHTOOL_GLINK}; struct ethtool_value link = {ETHTOOL_GLINK};
link.data = netif_carrier_ok(netdev); link.data = netif_carrier_ok(netdev);
......
...@@ -93,6 +93,7 @@ static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t ...@@ -93,6 +93,7 @@ static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t
static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw); static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw);
static void e1000_setup_eeprom(struct e1000_hw *hw); static void e1000_setup_eeprom(struct e1000_hw *hw);
static void e1000_standby_eeprom(struct e1000_hw *hw); static void e1000_standby_eeprom(struct e1000_hw *hw);
static int32_t e1000_id_led_init(struct e1000_hw * hw);
/****************************************************************************** /******************************************************************************
* Reset the transmit and receive units; mask and clear all interrupts. * Reset the transmit and receive units; mask and clear all interrupts.
...@@ -200,6 +201,13 @@ e1000_init_hw(struct e1000_hw *hw) ...@@ -200,6 +201,13 @@ e1000_init_hw(struct e1000_hw *hw)
DEBUGFUNC("e1000_init_hw"); DEBUGFUNC("e1000_init_hw");
/* Initialize Identification LED */
ret_val = e1000_id_led_init(hw);
if(ret_val < 0) {
DEBUGOUT("Error Initializing Identification LED\n");
return ret_val;
}
/* Set the Media Type and exit with error if it is not valid. */ /* Set the Media Type and exit with error if it is not valid. */
if(hw->mac_type != e1000_82543) { if(hw->mac_type != e1000_82543) {
/* tbi_compatibility is only valid on 82543 */ /* tbi_compatibility is only valid on 82543 */
...@@ -541,6 +549,7 @@ e1000_setup_copper_link(struct e1000_hw *hw) ...@@ -541,6 +549,7 @@ e1000_setup_copper_link(struct e1000_hw *hw)
*/ */
if(hw->mac_type > e1000_82543) { if(hw->mac_type > e1000_82543) {
ctrl |= E1000_CTRL_SLU; ctrl |= E1000_CTRL_SLU;
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
E1000_WRITE_REG(hw, CTRL, ctrl); E1000_WRITE_REG(hw, CTRL, ctrl);
} else { } else {
ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU); ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
...@@ -2087,9 +2096,9 @@ e1000_phy_reset_dsp(struct e1000_hw *hw) ...@@ -2087,9 +2096,9 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
DEBUGFUNC("e1000_phy_reset_dsp"); DEBUGFUNC("e1000_phy_reset_dsp");
do { do {
if(e1000_write_phy_reg(hw, 29, 0x1d) < 0) break; if(e1000_write_phy_reg(hw, 29, 0x001d) < 0) break;
if(e1000_write_phy_reg(hw, 30, 0xc1) < 0) break; if(e1000_write_phy_reg(hw, 30, 0x00c1) < 0) break;
if(e1000_write_phy_reg(hw, 30, 0x00) < 0) break; if(e1000_write_phy_reg(hw, 30, 0x0000) < 0) break;
ret_val = 0; ret_val = 0;
} while(0); } while(0);
...@@ -2785,6 +2794,74 @@ e1000_clear_vfta(struct e1000_hw *hw) ...@@ -2785,6 +2794,74 @@ e1000_clear_vfta(struct e1000_hw *hw)
E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0); E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
} }
static int32_t
e1000_id_led_init(struct e1000_hw * hw)
{
uint32_t ledctl;
const uint32_t ledctl_mask = 0x000000FF;
const uint32_t ledctl_on = E1000_LEDCTL_MODE_LED_ON;
const uint32_t ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
uint16_t eeprom_data, i, temp;
const uint16_t led_mask = 0x0F;
DEBUGFUNC("e1000_id_led_init");
if(hw->mac_type < e1000_82540) {
/* Nothing to do */
return 0;
}
ledctl = E1000_READ_REG(hw, LEDCTL);
hw->ledctl_default = ledctl;
hw->ledctl_mode1 = hw->ledctl_default;
hw->ledctl_mode2 = hw->ledctl_default;
if(e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
}
if((eeprom_data== ID_LED_RESERVED_0000) ||
(eeprom_data == ID_LED_RESERVED_FFFF)) eeprom_data = ID_LED_DEFAULT;
for(i = 0; i < 4; i++) {
temp = (eeprom_data >> (i << 2)) & led_mask;
switch(temp) {
case ID_LED_ON1_DEF2:
case ID_LED_ON1_ON2:
case ID_LED_ON1_OFF2:
hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
hw->ledctl_mode1 |= ledctl_on << (i << 3);
break;
case ID_LED_OFF1_DEF2:
case ID_LED_OFF1_ON2:
case ID_LED_OFF1_OFF2:
hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
hw->ledctl_mode1 |= ledctl_off << (i << 3);
break;
default:
/* Do nothing */
break;
}
switch(temp) {
case ID_LED_DEF1_ON2:
case ID_LED_ON1_ON2:
case ID_LED_OFF1_ON2:
hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
hw->ledctl_mode2 |= ledctl_on << (i << 3);
break;
case ID_LED_DEF1_OFF2:
case ID_LED_ON1_OFF2:
case ID_LED_OFF1_OFF2:
hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
hw->ledctl_mode2 |= ledctl_off << (i << 3);
break;
default:
/* Do nothing */
break;
}
}
return 0;
}
/****************************************************************************** /******************************************************************************
* Prepares SW controlable LED for use and saves the current state of the LED. * Prepares SW controlable LED for use and saves the current state of the LED.
* *
...@@ -2809,19 +2886,7 @@ e1000_setup_led(struct e1000_hw *hw) ...@@ -2809,19 +2886,7 @@ e1000_setup_led(struct e1000_hw *hw)
break; break;
case E1000_DEV_ID_82540EM: case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82540EM_LOM:
ledctl = E1000_READ_REG(hw, LEDCTL); E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
/* Save current LEDCTL settings */
hw->ledctl = ledctl;
/* Turn off LED2 and LED3 */
ledctl &= ~(E1000_LEDCTL_LED2_IVRT |
E1000_LEDCTL_LED2_BLINK |
E1000_LEDCTL_LED2_MODE_MASK);
ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED2_MODE_SHIFT);
ledctl &= ~(E1000_LEDCTL_LED3_IVRT |
E1000_LEDCTL_LED3_BLINK |
E1000_LEDCTL_LED3_MODE_MASK);
ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED3_MODE_SHIFT);
E1000_WRITE_REG(hw, LEDCTL, ledctl);
break; break;
default: default:
DEBUGOUT("Invalid device ID\n"); DEBUGOUT("Invalid device ID\n");
...@@ -2853,7 +2918,7 @@ e1000_cleanup_led(struct e1000_hw *hw) ...@@ -2853,7 +2918,7 @@ e1000_cleanup_led(struct e1000_hw *hw)
case E1000_DEV_ID_82540EM: case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82540EM_LOM:
/* Restore LEDCTL settings */ /* Restore LEDCTL settings */
E1000_WRITE_REG(hw, LEDCTL, hw->ledctl); E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
break; break;
default: default:
DEBUGOUT("Invalid device ID\n"); DEBUGOUT("Invalid device ID\n");
...@@ -2871,7 +2936,6 @@ int32_t ...@@ -2871,7 +2936,6 @@ int32_t
e1000_led_on(struct e1000_hw *hw) e1000_led_on(struct e1000_hw *hw)
{ {
uint32_t ctrl; uint32_t ctrl;
uint32_t ledctl;
DEBUGFUNC("e1000_led_on"); DEBUGFUNC("e1000_led_on");
...@@ -2897,11 +2961,7 @@ e1000_led_on(struct e1000_hw *hw) ...@@ -2897,11 +2961,7 @@ e1000_led_on(struct e1000_hw *hw)
break; break;
case E1000_DEV_ID_82540EM: case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82540EM_LOM:
ledctl = E1000_READ_REG(hw, LEDCTL); E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
/* Set LED 3 mode to on */
ledctl &= ~E1000_LEDCTL_LED3_MODE_MASK;
ledctl |= (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED3_MODE_SHIFT);
E1000_WRITE_REG(hw, LEDCTL, ledctl);
break; break;
default: default:
DEBUGOUT("Invalid device ID\n"); DEBUGOUT("Invalid device ID\n");
...@@ -2919,7 +2979,6 @@ int32_t ...@@ -2919,7 +2979,6 @@ int32_t
e1000_led_off(struct e1000_hw *hw) e1000_led_off(struct e1000_hw *hw)
{ {
uint32_t ctrl; uint32_t ctrl;
uint32_t ledctl;
DEBUGFUNC("e1000_led_off"); DEBUGFUNC("e1000_led_off");
...@@ -2945,11 +3004,7 @@ e1000_led_off(struct e1000_hw *hw) ...@@ -2945,11 +3004,7 @@ e1000_led_off(struct e1000_hw *hw)
break; break;
case E1000_DEV_ID_82540EM: case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82540EM_LOM: case E1000_DEV_ID_82540EM_LOM:
ledctl = E1000_READ_REG(hw, LEDCTL); E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
/* Set LED 3 mode to off */
ledctl &= ~E1000_LEDCTL_LED3_MODE_MASK;
ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED3_MODE_SHIFT);
E1000_WRITE_REG(hw, LEDCTL, ledctl);
break; break;
default: default:
DEBUGOUT("Invalid device ID\n"); DEBUGOUT("Invalid device ID\n");
......
...@@ -882,7 +882,9 @@ struct e1000_hw { ...@@ -882,7 +882,9 @@ struct e1000_hw {
uint32_t num_mc_addrs; uint32_t num_mc_addrs;
uint32_t collision_delta; uint32_t collision_delta;
uint32_t tx_packet_delta; uint32_t tx_packet_delta;
uint32_t ledctl; uint32_t ledctl_default;
uint32_t ledctl_mode1;
uint32_t ledctl_mode2;
uint16_t autoneg_advertised; uint16_t autoneg_advertised;
uint16_t pci_cmd_word; uint16_t pci_cmd_word;
uint16_t fc_high_water; uint16_t fc_high_water;
...@@ -1324,11 +1326,29 @@ struct e1000_hw { ...@@ -1324,11 +1326,29 @@ struct e1000_hw {
#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */ #define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */
/* EEPROM Word Offsets */ /* EEPROM Word Offsets */
#define EEPROM_ID_LED_SETTINGS 0x0004
#define EEPROM_INIT_CONTROL1_REG 0x000A #define EEPROM_INIT_CONTROL1_REG 0x000A
#define EEPROM_INIT_CONTROL2_REG 0x000F #define EEPROM_INIT_CONTROL2_REG 0x000F
#define EEPROM_FLASH_VERSION 0x0032 #define EEPROM_FLASH_VERSION 0x0032
#define EEPROM_CHECKSUM_REG 0x003F #define EEPROM_CHECKSUM_REG 0x003F
/* Word definitions for ID LED Settings */
#define ID_LED_RESERVED_0000 0x0000
#define ID_LED_RESERVED_FFFF 0xFFFF
#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \
(ID_LED_OFF1_OFF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2))
#define ID_LED_DEF1_DEF2 0x1
#define ID_LED_DEF1_ON2 0x2
#define ID_LED_DEF1_OFF2 0x3
#define ID_LED_ON1_DEF2 0x4
#define ID_LED_ON1_ON2 0x5
#define ID_LED_ON1_OFF2 0x6
#define ID_LED_OFF1_DEF2 0x7
#define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9
/* Mask bits for fields in Word 0x0a of the EEPROM */ /* Mask bits for fields in Word 0x0a of the EEPROM */
#define EEPROM_WORD0A_ILOS 0x0010 #define EEPROM_WORD0A_ILOS 0x0010
#define EEPROM_WORD0A_SWDPIO 0x01E0 #define EEPROM_WORD0A_SWDPIO 0x01E0
......
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
char e1000_driver_name[] = "e1000"; char e1000_driver_name[] = "e1000";
char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
char e1000_driver_version[] = "4.2.8"; char e1000_driver_version[] = "4.2.9-k1";
char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation."; char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table /* e1000_pci_tbl - PCI Device ID Table
...@@ -126,7 +126,7 @@ static char *e1000_strings[] = { ...@@ -126,7 +126,7 @@ static char *e1000_strings[] = {
"IBM Mobile, Desktop & Server Adapters" "IBM Mobile, Desktop & Server Adapters"
}; };
/* e1000_main.c Function Prototypes */ /* Local Function Prototypes */
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);
...@@ -403,8 +403,10 @@ e1000_probe(struct pci_dev *pdev, ...@@ -403,8 +403,10 @@ e1000_probe(struct pci_dev *pdev,
/* make sure the EEPROM is good */ /* make sure the EEPROM is good */
if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n");
goto err_eeprom; goto err_eeprom;
}
/* copy the MAC address out of the EEPROM */ /* copy the MAC address out of the EEPROM */
......
...@@ -86,12 +86,14 @@ ...@@ -86,12 +86,14 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#define usec_delay(x) udelay(x) #define usec_delay(x) udelay(x)
#ifndef msec_delay
#define msec_delay(x) do { if(in_interrupt()) { \ #define msec_delay(x) do { if(in_interrupt()) { \
mdelay(x); \ mdelay(x); \
} else { \ } else { \
set_current_state(TASK_UNINTERRUPTIBLE); \ set_current_state(TASK_UNINTERRUPTIBLE); \
schedule_timeout((x * HZ)/1000); \ schedule_timeout((x * HZ)/1000); \
} } while(0) } } while(0)
#endif
#define PCI_COMMAND_REGISTER PCI_COMMAND #define PCI_COMMAND_REGISTER PCI_COMMAND
#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE #define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
......
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