Commit 50dc2599 authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/home/jgarzik/repo/linus-2.5

into redhat.com:/home/jgarzik/repo/net-drivers-2.5
parents 2622cf1d 2bf2d024
...@@ -1222,6 +1222,20 @@ config PCNET32 ...@@ -1222,6 +1222,20 @@ config PCNET32
module, say M here and read <file:Documentation/modules.txt> as well module, say M here and read <file:Documentation/modules.txt> as well
as <file:Documentation/networking/net-modules.txt>. as <file:Documentation/networking/net-modules.txt>.
config AMD8111_ETH
tristate "AMD 8111 (new PCI lance) support"
depends on NET_PCI && PCI
help
If you have an AMD 8111-based PCI lance ethernet card,
answer Y here and read the Ethernet-HOWTO, available from
<http://www.linuxdoc.org/docs.html#howto>.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called amd8111e.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt> as well
as <file:Documentation/networking/net-modules.txt>.
config ADAPTEC_STARFIRE config ADAPTEC_STARFIRE
tristate "Adaptec Starfire/DuraLAN support" tristate "Adaptec Starfire/DuraLAN support"
depends on NET_PCI && PCI depends on NET_PCI && PCI
......
...@@ -183,6 +183,7 @@ obj-$(CONFIG_MAC89x0) += mac89x0.o ...@@ -183,6 +183,7 @@ obj-$(CONFIG_MAC89x0) += mac89x0.o
obj-$(CONFIG_TUN) += tun.o obj-$(CONFIG_TUN) += tun.o
obj-$(CONFIG_DL2K) += dl2k.o obj-$(CONFIG_DL2K) += dl2k.o
obj-$(CONFIG_R8169) += r8169.o obj-$(CONFIG_R8169) += r8169.o
obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
# non-drivers/net drivers who want mii lib # non-drivers/net drivers who want mii lib
obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o
......
...@@ -37,6 +37,7 @@ obj-$(CONFIG_VIA_RHINE) += crc32.o ...@@ -37,6 +37,7 @@ obj-$(CONFIG_VIA_RHINE) += crc32.o
obj-$(CONFIG_YELLOWFIN) += crc32.o obj-$(CONFIG_YELLOWFIN) += crc32.o
obj-$(CONFIG_WINBOND_840) += crc32.o obj-$(CONFIG_WINBOND_840) += crc32.o
obj-$(CONFIG_R8169) += crc32.o obj-$(CONFIG_R8169) += crc32.o
obj-$(CONFIG_AMD8111_ETH) += crc32.o
# These rely on drivers/net/7990.o which requires crc32.o # These rely on drivers/net/7990.o which requires crc32.o
......
This diff is collapsed.
This diff is collapsed.
...@@ -268,6 +268,7 @@ struct driver_stats { ...@@ -268,6 +268,7 @@ struct driver_stats {
#define SCB_CUC_NOOP 0 #define SCB_CUC_NOOP 0
#define SCB_CUC_START BIT_4 /* CU Start */ #define SCB_CUC_START BIT_4 /* CU Start */
#define SCB_CUC_RESUME BIT_5 /* CU Resume */ #define SCB_CUC_RESUME BIT_5 /* CU Resume */
#define SCB_CUC_UNKNOWN BIT_7 /* CU unknown command */
/* Changed for 82558 enhancements */ /* Changed for 82558 enhancements */
#define SCB_CUC_STATIC_RESUME (BIT_5 | BIT_7) /* 82558/9 Static Resume */ #define SCB_CUC_STATIC_RESUME (BIT_5 | BIT_7) /* 82558/9 Static Resume */
#define SCB_CUC_DUMP_ADDR BIT_6 /* CU Dump Counters Address */ #define SCB_CUC_DUMP_ADDR BIT_6 /* CU Dump Counters Address */
...@@ -953,6 +954,10 @@ struct e100_private { ...@@ -953,6 +954,10 @@ struct e100_private {
u32 pci_state[16]; u32 pci_state[16];
#endif #endif
char ifname[IFNAMSIZ]; char ifname[IFNAMSIZ];
#ifdef E100_CU_DEBUG
u8 last_cmd;
u8 last_sub_cmd;
#endif
}; };
#define E100_AUTONEG 0 #define E100_AUTONEG 0
...@@ -964,7 +969,7 @@ struct e100_private { ...@@ -964,7 +969,7 @@ struct e100_private {
/********* function prototypes *************/ /********* function prototypes *************/
extern void e100_isolate_driver(struct e100_private *bdp); extern void e100_isolate_driver(struct e100_private *bdp);
extern void e100_sw_reset(struct e100_private *bdp, u32 reset_cmd); extern void e100_sw_reset(struct e100_private *bdp, u32 reset_cmd);
extern void e100_start_cu(struct e100_private *bdp, tcb_t *tcb); extern u8 e100_start_cu(struct e100_private *bdp, tcb_t *tcb);
extern void e100_free_non_tx_cmd(struct e100_private *bdp, extern void e100_free_non_tx_cmd(struct e100_private *bdp,
nxmit_cb_entry_t *non_tx_cmd); nxmit_cb_entry_t *non_tx_cmd);
extern nxmit_cb_entry_t *e100_alloc_non_tx_cmd(struct e100_private *bdp); extern nxmit_cb_entry_t *e100_alloc_non_tx_cmd(struct e100_private *bdp);
...@@ -976,8 +981,10 @@ extern unsigned char e100_get_link_state(struct e100_private *bdp); ...@@ -976,8 +981,10 @@ extern unsigned char e100_get_link_state(struct e100_private *bdp);
extern unsigned char e100_wait_scb(struct e100_private *bdp); extern unsigned char e100_wait_scb(struct e100_private *bdp);
extern void e100_deisolate_driver(struct e100_private *bdp, u8 full_reset); extern void e100_deisolate_driver(struct e100_private *bdp, u8 full_reset);
extern unsigned char e100_hw_reset_recover(struct e100_private *bdp, extern unsigned char e100_configure_device(struct e100_private *bdp);
u32 reset_cmd); #ifdef E100_CU_DEBUG
extern unsigned char e100_cu_unknown_state(struct e100_private *bdp);
#endif
#define ROM_TEST_FAIL 0x01 #define ROM_TEST_FAIL 0x01
#define REGISTER_TEST_FAIL 0x02 #define REGISTER_TEST_FAIL 0x02
......
...@@ -494,8 +494,7 @@ e100_config_long_rx(struct e100_private *bdp, unsigned char enable) ...@@ -494,8 +494,7 @@ e100_config_long_rx(struct e100_private *bdp, unsigned char enable)
* e100_config_wol * e100_config_wol
* @bdp: atapter's private data struct * @bdp: atapter's private data struct
* *
* This sets configuration options for Wake On LAN functionality (WOL) in the * This sets configuration options for PHY and Magic Packet WoL
* config record. WOL options are retrieved from wolinfo_wolopts in @bdp
*/ */
void void
e100_config_wol(struct e100_private *bdp) e100_config_wol(struct e100_private *bdp)
...@@ -504,14 +503,21 @@ e100_config_wol(struct e100_private *bdp) ...@@ -504,14 +503,21 @@ e100_config_wol(struct e100_private *bdp)
if (bdp->wolopts & WAKE_PHY) { if (bdp->wolopts & WAKE_PHY) {
bdp->config[9] |= CB_LINK_STATUS_WOL; bdp->config[9] |= CB_LINK_STATUS_WOL;
E100_CONFIG(bdp, 9); }
else {
/* Disable PHY WoL */
bdp->config[9] &= ~CB_LINK_STATUS_WOL;
} }
if (!(bdp->wolopts & WAKE_MAGIC)) { if (bdp->wolopts & WAKE_MAGIC) {
bdp->config[19] &= ~CB_DISABLE_MAGPAK_WAKE;
}
else {
/* Disable Magic Packet WoL */
bdp->config[19] |= CB_DISABLE_MAGPAK_WAKE; bdp->config[19] |= CB_DISABLE_MAGPAK_WAKE;
E100_CONFIG(bdp, 19);
} }
E100_CONFIG(bdp, 19);
spin_unlock_bh(&(bdp->config_lock)); spin_unlock_bh(&(bdp->config_lock));
} }
......
This diff is collapsed.
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "e100_config.h" #include "e100_config.h"
extern u16 e100_eeprom_read(struct e100_private *, u16); extern u16 e100_eeprom_read(struct e100_private *, u16);
extern int e100_wait_exec_cmplx(struct e100_private *, u32,u8); extern int e100_wait_exec_cmplx(struct e100_private *, u32,u8, u8);
extern void e100_phy_reset(struct e100_private *bdp); extern void e100_phy_reset(struct e100_private *bdp);
extern void e100_phy_autoneg(struct e100_private *bdp); extern void e100_phy_autoneg(struct e100_private *bdp);
extern void e100_phy_set_loopback(struct e100_private *bdp); extern void e100_phy_set_loopback(struct e100_private *bdp);
...@@ -95,11 +95,9 @@ e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags) ...@@ -95,11 +95,9 @@ e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags)
test_info [E100_EEPROM_TEST_FAIL] = true; test_info [E100_EEPROM_TEST_FAIL] = true;
} }
e100_deisolate_driver(bdp, false);
/*Let card recover from the test*/
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ * 2); schedule_timeout(HZ * 2);
e100_deisolate_driver(bdp, false);
return flags | (test_result ? 0 : ETH_TEST_FL_FAILED); return flags | (test_result ? 0 : ETH_TEST_FL_FAILED);
} }
...@@ -128,7 +126,7 @@ e100_diag_selftest(struct net_device *dev) ...@@ -128,7 +126,7 @@ e100_diag_selftest(struct net_device *dev)
} }
} }
e100_hw_reset_recover(bdp,PORT_SOFTWARE_RESET); e100_configure_device(bdp);
return retval; return retval;
} }
...@@ -166,13 +164,19 @@ e100_diag_loopback (struct net_device *dev) ...@@ -166,13 +164,19 @@ e100_diag_loopback (struct net_device *dev)
{ {
u8 rc = 0; u8 rc = 0;
printk(KERN_DEBUG "%s: PHY loopback test starts\n", dev->name);
e100_sw_reset(dev->priv, PORT_SELECTIVE_RESET);
if (!e100_diag_one_loopback(dev, PHY_LOOPBACK)) { if (!e100_diag_one_loopback(dev, PHY_LOOPBACK)) {
rc |= PHY_LOOPBACK; rc |= PHY_LOOPBACK;
} }
printk(KERN_DEBUG "%s: PHY loopback test ends\n", dev->name);
printk(KERN_DEBUG "%s: MAC loopback test starts\n", dev->name);
e100_sw_reset(dev->priv, PORT_SELECTIVE_RESET);
if (!e100_diag_one_loopback(dev, MAC_LOOPBACK)) { if (!e100_diag_one_loopback(dev, MAC_LOOPBACK)) {
rc |= MAC_LOOPBACK; rc |= MAC_LOOPBACK;
} }
printk(KERN_DEBUG "%s: MAC loopback test ends\n", dev->name);
return rc; return rc;
} }
...@@ -341,12 +345,12 @@ static void ...@@ -341,12 +345,12 @@ static void
e100_diag_loopback_cu_ru_exec(struct e100_private *bdp) e100_diag_loopback_cu_ru_exec(struct e100_private *bdp)
{ {
/*load CU & RU base */ /*load CU & RU base */
if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE)) if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE, 0))
printk("e100: SCB_CUC_LOAD_BASE failed\n"); printk(KERN_ERR "e100: SCB_CUC_LOAD_BASE failed\n");
if(!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE)) if(!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE, 0))
printk("e100: SCB_RUC_LOAD_BASE failed!\n"); printk(KERN_ERR "e100: SCB_RUC_LOAD_BASE failed!\n");
if(!e100_wait_exec_cmplx(bdp, bdp->loopback.dma_handle, SCB_RUC_START)) if(!e100_wait_exec_cmplx(bdp, bdp->loopback.dma_handle, SCB_RUC_START, 0))
printk("e100: SCB_RUC_START failed!\n"); printk(KERN_ERR "e100: SCB_RUC_START failed!\n");
bdp->next_cu_cmd = START_WAIT; bdp->next_cu_cmd = START_WAIT;
e100_start_cu(bdp, bdp->loopback.tcb); e100_start_cu(bdp, bdp->loopback.tcb);
......
...@@ -113,6 +113,7 @@ struct e1000_adapter; ...@@ -113,6 +113,7 @@ struct e1000_adapter;
#define E1000_DEFAULT_PBA 0x00000030 #define E1000_DEFAULT_PBA 0x00000030
#define AUTO_ALL_MODES 0 #define AUTO_ALL_MODES 0
#define E1000_EEPROM_APME 4
/* only works for sizes that are powers of 2 */ /* only works for sizes that are powers of 2 */
#define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
......
...@@ -194,7 +194,7 @@ e1000_ethtool_gregs(struct e1000_adapter *adapter, ...@@ -194,7 +194,7 @@ e1000_ethtool_gregs(struct e1000_adapter *adapter,
regs_buff[4] = E1000_READ_REG(hw, RDH); regs_buff[4] = E1000_READ_REG(hw, RDH);
regs_buff[5] = E1000_READ_REG(hw, RDT); regs_buff[5] = E1000_READ_REG(hw, RDT);
regs_buff[6] = E1000_READ_REG(hw, RDTR); regs_buff[6] = E1000_READ_REG(hw, RDTR);
regs_buff[7] = E1000_READ_REG(hw, TCTL); regs_buff[7] = E1000_READ_REG(hw, TCTL);
regs_buff[8] = E1000_READ_REG(hw, TDLEN); regs_buff[8] = E1000_READ_REG(hw, TDLEN);
regs_buff[9] = E1000_READ_REG(hw, TDH); regs_buff[9] = E1000_READ_REG(hw, TDH);
...@@ -233,7 +233,7 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter, ...@@ -233,7 +233,7 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
return 0; return 0;
} }
static int static int
e1000_ethtool_seeprom(struct e1000_adapter *adapter, e1000_ethtool_seeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, void *user_data) struct ethtool_eeprom *eeprom, void *user_data)
{ {
...@@ -306,12 +306,10 @@ e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) ...@@ -306,12 +306,10 @@ e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
/* Fall Through */ /* Fall Through */
default: default:
wol->supported = WAKE_PHY | WAKE_UCAST | wol->supported = WAKE_UCAST | WAKE_MCAST
WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; | WAKE_BCAST | WAKE_MAGIC;
wol->wolopts = 0; wol->wolopts = 0;
if(adapter->wol & E1000_WUFC_LNKC)
wol->wolopts |= WAKE_PHY;
if(adapter->wol & E1000_WUFC_EX) if(adapter->wol & E1000_WUFC_EX)
wol->wolopts |= WAKE_UCAST; wol->wolopts |= WAKE_UCAST;
if(adapter->wol & E1000_WUFC_MC) if(adapter->wol & E1000_WUFC_MC)
...@@ -343,13 +341,11 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) ...@@ -343,13 +341,11 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
/* Fall Through */ /* Fall Through */
default: default:
if(wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)) if(wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | WAKE_PHY))
return -EOPNOTSUPP; return -EOPNOTSUPP;
adapter->wol = 0; adapter->wol = 0;
if(wol->wolopts & WAKE_PHY)
adapter->wol |= E1000_WUFC_LNKC;
if(wol->wolopts & WAKE_UCAST) if(wol->wolopts & WAKE_UCAST)
adapter->wol |= E1000_WUFC_EX; adapter->wol |= E1000_WUFC_EX;
if(wol->wolopts & WAKE_MCAST) if(wol->wolopts & WAKE_MCAST)
...@@ -374,7 +370,7 @@ static void ...@@ -374,7 +370,7 @@ static void
e1000_led_blink_callback(unsigned long data) e1000_led_blink_callback(unsigned long data)
{ {
struct e1000_adapter *adapter = (struct e1000_adapter *) data; struct e1000_adapter *adapter = (struct e1000_adapter *) data;
if(test_and_change_bit(E1000_LED_ON, &adapter->led_status)) if(test_and_change_bit(E1000_LED_ON, &adapter->led_status))
e1000_led_off(&adapter->hw); e1000_led_off(&adapter->hw);
else else
...@@ -394,13 +390,13 @@ e1000_ethtool_led_blink(struct e1000_adapter *adapter, struct ethtool_value *id) ...@@ -394,13 +390,13 @@ e1000_ethtool_led_blink(struct e1000_adapter *adapter, struct ethtool_value *id)
e1000_setup_led(&adapter->hw); e1000_setup_led(&adapter->hw);
mod_timer(&adapter->blink_timer, jiffies); mod_timer(&adapter->blink_timer, jiffies);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if(id->data) if(id->data)
schedule_timeout(id->data * HZ); schedule_timeout(id->data * HZ);
else else
schedule_timeout(MAX_SCHEDULE_TIMEOUT); schedule_timeout(MAX_SCHEDULE_TIMEOUT);
del_timer_sync(&adapter->blink_timer); del_timer_sync(&adapter->blink_timer);
e1000_led_off(&adapter->hw); e1000_led_off(&adapter->hw);
clear_bit(E1000_LED_ON, &adapter->led_status); clear_bit(E1000_LED_ON, &adapter->led_status);
......
...@@ -26,11 +26,21 @@ ...@@ -26,11 +26,21 @@
*******************************************************************************/ *******************************************************************************/
#define __E1000_MAIN__
#include "e1000.h" #include "e1000.h"
/* Change Log /* Change Log
* *
* 4.4.19 11/27/02
* o Feature: Added user-settable knob for interrupt throttle rate (ITR).
* o Cleanup: removed large static array allocations.
* o Cleanup: C99 struct initializer format.
* o Bug fix: restore VLAN settings when interface is brought up.
* o Bug fix: return cleanly in probe if error in detecting MAC type.
* o Bug fix: Wake up on magic packet by default only if enabled in eeprom.
* o Bug fix: Validate MAC address in set_mac.
* o Bug fix: Throw away zero-length Tx skbs.
* o Bug fix: Make ethtool EEPROM acceses work on older versions of ethtool.
*
* 4.4.12 10/15/02 * 4.4.12 10/15/02
* o Clean up: use members of pci_device rather than direct calls to * o Clean up: use members of pci_device rather than direct calls to
* pci_read_config_word. * pci_read_config_word.
...@@ -43,30 +53,13 @@ ...@@ -43,30 +53,13 @@
* o Now setting netdev->mem_end in e1000_probe. * o Now setting netdev->mem_end in e1000_probe.
* o Clean up: Moved tx_timeout from interrupt context to process context * o Clean up: Moved tx_timeout from interrupt context to process context
* using schedule_task. * using schedule_task.
* *
* o Feature: merged in modified NAPI patch from Robert Olsson * 4.3.15 8/9/02
* <Robert.Olsson@its.uu.se> Uppsala Univeristy, Sweden.
*
* 4.3.15 8/9/02
* o Converted from Dual BSD/GPL license to GPL license.
* o Clean up: use pci_[clear|set]_mwi rather than direct calls to
* pci_write_config_word.
* o Bug fix: added read-behind-write calls to post writes before delays.
* o Bug fix: removed mdelay busy-waits in interrupt context.
* o Clean up: direct clear of descriptor bits rather than using memset.
* o Bug fix: added wmb() for ia-64 between descritor writes and advancing
* descriptor tail.
* o Feature: added locking mechanism for asf functionality.
* o Feature: exposed two Tx and one Rx interrupt delay knobs for finer
* control over interurpt rate tuning.
* o Misc ethtool bug fixes.
*
* 4.3.2 7/5/02
*/ */
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.4.12-k1"; char e1000_driver_version[] = "4.4.19-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
...@@ -175,6 +168,7 @@ static void e1000_tx_timeout_task(struct net_device *dev); ...@@ -175,6 +168,7 @@ static void e1000_tx_timeout_task(struct net_device *dev);
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
static void e1000_restore_vlan(struct e1000_adapter *adapter);
static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
static int e1000_notify_netdev(struct notifier_block *, unsigned long event, void *ptr); static int e1000_notify_netdev(struct notifier_block *, unsigned long event, void *ptr);
...@@ -274,6 +268,7 @@ e1000_up(struct e1000_adapter *adapter) ...@@ -274,6 +268,7 @@ e1000_up(struct e1000_adapter *adapter)
/* hardware has been reset, we need to reload some things */ /* hardware has been reset, we need to reload some things */
e1000_set_multi(netdev); e1000_set_multi(netdev);
e1000_restore_vlan(adapter);
e1000_configure_tx(adapter); e1000_configure_tx(adapter);
e1000_setup_rctl(adapter); e1000_setup_rctl(adapter);
...@@ -349,6 +344,7 @@ e1000_probe(struct pci_dev *pdev, ...@@ -349,6 +344,7 @@ e1000_probe(struct pci_dev *pdev,
int mmio_len; int mmio_len;
int pci_using_dac; int pci_using_dac;
int i; int i;
uint16_t eeprom_data;
if((i = pci_enable_device(pdev))) if((i = pci_enable_device(pdev)))
return i; return i;
...@@ -501,8 +497,9 @@ e1000_probe(struct pci_dev *pdev, ...@@ -501,8 +497,9 @@ e1000_probe(struct pci_dev *pdev,
* enable the ACPI Magic Packet filter * enable the ACPI Magic Packet filter
*/ */
e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data);
if((adapter->hw.mac_type >= e1000_82544) && if((adapter->hw.mac_type >= e1000_82544) &&
(E1000_READ_REG(&adapter->hw, WUC) & E1000_WUC_APME)) (eeprom_data & E1000_EEPROM_APME))
adapter->wol |= E1000_WUFC_MAG; adapter->wol |= E1000_WUFC_MAG;
/* reset the hardware with the new settings */ /* reset the hardware with the new settings */
...@@ -583,6 +580,7 @@ e1000_sw_init(struct e1000_adapter *adapter) ...@@ -583,6 +580,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw->subsystem_id = pdev->subsystem_device; hw->subsystem_id = pdev->subsystem_device;
pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
adapter->rx_buffer_len = E1000_RXBUFFER_2048; adapter->rx_buffer_len = E1000_RXBUFFER_2048;
...@@ -627,7 +625,7 @@ e1000_sw_init(struct e1000_adapter *adapter) ...@@ -627,7 +625,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw->adaptive_ifs = TRUE; hw->adaptive_ifs = TRUE;
/* Copper options */ /* Copper options */
if(hw->media_type == e1000_media_type_copper) { if(hw->media_type == e1000_media_type_copper) {
hw->mdix = AUTO_ALL_MODES; hw->mdix = AUTO_ALL_MODES;
hw->disable_polarity_correction = FALSE; hw->disable_polarity_correction = FALSE;
...@@ -1144,6 +1142,9 @@ e1000_set_mac(struct net_device *netdev, void *p) ...@@ -1144,6 +1142,9 @@ e1000_set_mac(struct net_device *netdev, void *p)
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
struct sockaddr *addr = p; struct sockaddr *addr = p;
if(!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
/* 82542 2.0 needs to be in reset to write receive address registers */ /* 82542 2.0 needs to be in reset to write receive address registers */
if(adapter->hw.mac_type == e1000_82542_rev2_0) if(adapter->hw.mac_type == e1000_82542_rev2_0)
...@@ -1400,7 +1401,6 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb) ...@@ -1400,7 +1401,6 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
int f; int f;
len = skb->len - skb->data_len; len = skb->len - skb->data_len;
i = (tx_ring->next_to_use + tx_ring->count - 1) % tx_ring->count; i = (tx_ring->next_to_use + tx_ring->count - 1) % tx_ring->count;
count = 0; count = 0;
...@@ -1507,11 +1507,16 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -1507,11 +1507,16 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
int tx_flags = 0, count; int tx_flags = 0, count;
int f; int f;
count = TXD_USE_COUNT(skb->len - skb->data_len, count = TXD_USE_COUNT(skb->len - skb->data_len,
adapter->max_data_per_txd); adapter->max_data_per_txd);
if(count == 0) {
dev_kfree_skb_any(skb);
return 0;
}
for(f = 0; f < skb_shinfo(skb)->nr_frags; f++) for(f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
adapter->max_data_per_txd); adapter->max_data_per_txd);
...@@ -2392,6 +2397,21 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) ...@@ -2392,6 +2397,21 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
e1000_write_vfta(&adapter->hw, index, vfta); e1000_write_vfta(&adapter->hw, index, vfta);
} }
static void
e1000_restore_vlan(struct e1000_adapter *adapter)
{
e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
if(adapter->vlgrp) {
uint16_t vid;
for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
if(!adapter->vlgrp->vlan_devices[vid])
continue;
e1000_vlan_rx_add_vid(adapter->netdev, vid);
}
}
}
static int static int
e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
{ {
...@@ -2437,14 +2457,19 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) ...@@ -2437,14 +2457,19 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
uint32_t ctrl, ctrl_ext, rctl, manc; uint32_t ctrl, ctrl_ext, rctl, manc, status;
uint32_t wufc = adapter->wol;
netif_device_detach(netdev); netif_device_detach(netdev);
if(netif_running(netdev)) if(netif_running(netdev))
e1000_down(adapter); e1000_down(adapter);
if(adapter->wol) { status = E1000_READ_REG(&adapter->hw, STATUS);
if(status & E1000_STATUS_LU)
wufc &= ~E1000_WUFC_LNKC;
if(wufc) {
e1000_setup_rctl(adapter); e1000_setup_rctl(adapter);
e1000_set_multi(netdev); e1000_set_multi(netdev);
...@@ -2474,7 +2499,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) ...@@ -2474,7 +2499,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
} }
E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN); E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
E1000_WRITE_REG(&adapter->hw, WUFC, adapter->wol); E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
pci_enable_wake(pdev, 3, 1); pci_enable_wake(pdev, 3, 1);
pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */ pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */
} else { } else {
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
*******************************************************************************/ *******************************************************************************/
/* glue for the OS independant part of e1000 /* glue for the OS independant part of e1000
* includes register access macros * includes register access macros
*/ */
......
...@@ -230,7 +230,6 @@ struct e1000_option { ...@@ -230,7 +230,6 @@ struct e1000_option {
} arg; } arg;
}; };
static int __devinit static int __devinit
e1000_validate_option(int *value, struct e1000_option *opt) e1000_validate_option(int *value, struct e1000_option *opt)
{ {
...@@ -273,7 +272,7 @@ e1000_validate_option(int *value, struct e1000_option *opt) ...@@ -273,7 +272,7 @@ e1000_validate_option(int *value, struct e1000_option *opt)
default: default:
BUG(); BUG();
} }
printk(KERN_INFO "Invalid %s specified (%i) %s\n", printk(KERN_INFO "Invalid %s specified (%i) %s\n",
opt->name, *value, opt->err); opt->name, *value, opt->err);
*value = opt->def; *value = opt->def;
...@@ -298,7 +297,7 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -298,7 +297,7 @@ e1000_check_options(struct e1000_adapter *adapter)
{ {
int bd = adapter->bd_number; int bd = adapter->bd_number;
if(bd >= E1000_MAX_NIC) { if(bd >= E1000_MAX_NIC) {
printk(KERN_NOTICE printk(KERN_NOTICE
"Warning: no configuration for board #%i\n", bd); "Warning: no configuration for board #%i\n", bd);
printk(KERN_NOTICE "Using defaults for all values\n"); printk(KERN_NOTICE "Using defaults for all values\n");
bd = E1000_MAX_NIC; bd = E1000_MAX_NIC;
...@@ -314,7 +313,7 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -314,7 +313,7 @@ e1000_check_options(struct e1000_adapter *adapter)
}; };
struct e1000_desc_ring *tx_ring = &adapter->tx_ring; struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
e1000_mac_type mac_type = adapter->hw.mac_type; e1000_mac_type mac_type = adapter->hw.mac_type;
opt.arg.r.max = mac_type < e1000_82544 ? opt.arg.r.max = mac_type < e1000_82544 ?
MAX_TXD : MAX_82544_TXD; MAX_TXD : MAX_82544_TXD;
tx_ring->count = TxDescriptors[bd]; tx_ring->count = TxDescriptors[bd];
...@@ -344,13 +343,13 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -344,13 +343,13 @@ e1000_check_options(struct e1000_adapter *adapter)
.err = "defaulting to Enabled", .err = "defaulting to Enabled",
.def = OPTION_ENABLED .def = OPTION_ENABLED
}; };
int rx_csum = XsumRX[bd]; int rx_csum = XsumRX[bd];
e1000_validate_option(&rx_csum, &opt); e1000_validate_option(&rx_csum, &opt);
adapter->rx_csum = rx_csum; adapter->rx_csum = rx_csum;
} }
{ /* Flow Control */ { /* Flow Control */
struct e1000_opt_list fc_list[] = struct e1000_opt_list fc_list[] =
{{ e1000_fc_none, "Flow Control Disabled" }, {{ e1000_fc_none, "Flow Control Disabled" },
{ e1000_fc_rx_pause,"Flow Control Receive Only" }, { e1000_fc_rx_pause,"Flow Control Receive Only" },
...@@ -478,9 +477,10 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -478,9 +477,10 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
{ /* Speed */ { /* Speed */
struct e1000_opt_list speed_list[] = {{ 0, "" }, struct e1000_opt_list speed_list[] = {{ 0, "" },
{ SPEED_10, "" }, { SPEED_10, "" },
{ SPEED_100, "" }, { SPEED_100, "" },
{ SPEED_1000, "" }}; { SPEED_1000, "" }};
struct e1000_option opt = { struct e1000_option opt = {
.type = list_option, .type = list_option,
.name = "Speed", .name = "Speed",
...@@ -494,8 +494,9 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -494,8 +494,9 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
} }
{ /* Duplex */ { /* Duplex */
struct e1000_opt_list dplx_list[] = {{ 0, "" }, struct e1000_opt_list dplx_list[] = {{ 0, "" },
{ HALF_DUPLEX, "" }, { HALF_DUPLEX, "" },
{ FULL_DUPLEX, "" }}; { FULL_DUPLEX, "" }};
struct e1000_option opt = { struct e1000_option opt = {
.type = list_option, .type = list_option,
.name = "Duplex", .name = "Duplex",
...@@ -572,7 +573,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -572,7 +573,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
printk(KERN_INFO "Half Duplex specified without Speed\n"); printk(KERN_INFO "Half Duplex specified without Speed\n");
printk(KERN_INFO "Using Autonegotiation at Half Duplex only\n"); printk(KERN_INFO "Using Autonegotiation at Half Duplex only\n");
adapter->hw.autoneg = 1; adapter->hw.autoneg = 1;
adapter->hw.autoneg_advertised = ADVERTISE_10_HALF | adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
ADVERTISE_100_HALF; ADVERTISE_100_HALF;
break; break;
case FULL_DUPLEX: case FULL_DUPLEX:
......
...@@ -109,7 +109,7 @@ e1000_proc_info_read(char *page, char **start, off_t off, ...@@ -109,7 +109,7 @@ e1000_proc_info_read(char *page, char **start, off_t off,
if(!strlen(elem->tag)) if(!strlen(elem->tag))
p += sprintf(p, "\n"); p += sprintf(p, "\n");
else else
p += sprintf(p, "%-*.*s %.*s\n", p += sprintf(p, "%-*.*s %.*s\n",
TAG_MAX_LENGTH, TAG_MAX_LENGTH, TAG_MAX_LENGTH, TAG_MAX_LENGTH,
elem->tag, FIELD_MAX_LENGTH, elem->tag, FIELD_MAX_LENGTH,
elem->func(elem->data, elem->len, buf)); elem->func(elem->data, elem->len, buf));
...@@ -126,7 +126,7 @@ e1000_proc_single_read(char *page, char **start, off_t off, ...@@ -126,7 +126,7 @@ e1000_proc_single_read(char *page, char **start, off_t off,
{ {
struct proc_list *elem = data; struct proc_list *elem = data;
sprintf(page, "%.*s", FIELD_MAX_LENGTH, elem->func(elem->data, sprintf(page, "%.*s", FIELD_MAX_LENGTH, elem->func(elem->data,
elem->len, page)); elem->len, page));
return e1000_proc_read(page, start, off, count, eof); return e1000_proc_read(page, start, off, count, eof);
...@@ -216,7 +216,7 @@ e1000_proc_singles_create(struct proc_dir_entry *parent, ...@@ -216,7 +216,7 @@ e1000_proc_singles_create(struct proc_dir_entry *parent,
} }
static void static void
e1000_proc_dirs_create(void *data, char *name, e1000_proc_dirs_create(void *data, char *name,
struct list_head *proc_list_head) struct list_head *proc_list_head)
{ {
struct proc_dir_entry *intel_proc_dir, *proc_dir, *info_entry; struct proc_dir_entry *intel_proc_dir, *proc_dir, *info_entry;
...@@ -257,7 +257,7 @@ e1000_proc_dirs_create(void *data, char *name, ...@@ -257,7 +257,7 @@ e1000_proc_dirs_create(void *data, char *name,
static void static void
e1000_proc_list_add(struct list_head *proc_list_head, char *tag, e1000_proc_list_add(struct list_head *proc_list_head, char *tag,
void *data, size_t len, void *data, size_t len,
char *(*func)(void *, size_t, char *)) char *(*func)(void *, size_t, char *))
{ {
struct proc_list *new = (struct proc_list *) struct proc_list *new = (struct proc_list *)
...@@ -509,8 +509,8 @@ e1000_proc_mdi_x_enabled(void *data, size_t len, char *buf) ...@@ -509,8 +509,8 @@ e1000_proc_mdi_x_enabled(void *data, size_t len, char *buf)
{ {
struct e1000_adapter *adapter = data; struct e1000_adapter *adapter = data;
e1000_auto_x_mode mdix_mode = adapter->phy_info.mdix_mode; e1000_auto_x_mode mdix_mode = adapter->phy_info.mdix_mode;
sprintf(buf, sprintf(buf,
mdix_mode == e1000_auto_x_mode_manual_mdi ? "MDI" : mdix_mode == e1000_auto_x_mode_manual_mdi ? "MDI" :
mdix_mode == e1000_auto_x_mode_manual_mdix ? "MDI-X" : mdix_mode == e1000_auto_x_mode_manual_mdix ? "MDI-X" :
"Unknown"); "Unknown");
return buf; return buf;
...@@ -531,7 +531,7 @@ e1000_proc_rx_status(void *data, size_t len, char *buf) ...@@ -531,7 +531,7 @@ e1000_proc_rx_status(void *data, size_t len, char *buf)
* e1000_proc_list_setup - build link list of proc praramters * e1000_proc_list_setup - build link list of proc praramters
* @adapter: board private structure * @adapter: board private structure
* *
* Order matters - ethx.info entries are ordered in the order links * Order matters - ethx.info entries are ordered in the order links
* are added to list. * are added to list.
*/ */
...@@ -610,7 +610,7 @@ e1000_proc_list_setup(struct e1000_adapter *adapter) ...@@ -610,7 +610,7 @@ e1000_proc_list_setup(struct e1000_adapter *adapter)
LIST_ADD_U("Tx_Aborted_Errors", &adapter->net_stats.tx_aborted_errors); LIST_ADD_U("Tx_Aborted_Errors", &adapter->net_stats.tx_aborted_errors);
LIST_ADD_U("Tx_Carrier_Errors", &adapter->net_stats.tx_carrier_errors); LIST_ADD_U("Tx_Carrier_Errors", &adapter->net_stats.tx_carrier_errors);
LIST_ADD_U("Tx_FIFO_Errors", &adapter->net_stats.tx_fifo_errors); LIST_ADD_U("Tx_FIFO_Errors", &adapter->net_stats.tx_fifo_errors);
LIST_ADD_U("Tx_Heartbeat_Errors", LIST_ADD_U("Tx_Heartbeat_Errors",
&adapter->net_stats.tx_heartbeat_errors); &adapter->net_stats.tx_heartbeat_errors);
LIST_ADD_U("Tx_Window_Errors", &adapter->net_stats.tx_window_errors); LIST_ADD_U("Tx_Window_Errors", &adapter->net_stats.tx_window_errors);
...@@ -649,17 +649,17 @@ e1000_proc_list_setup(struct e1000_adapter *adapter) ...@@ -649,17 +649,17 @@ e1000_proc_list_setup(struct e1000_adapter *adapter)
adapter, e1000_proc_cable_polarity); adapter, e1000_proc_cable_polarity);
LIST_ADD_F("PHY_Disable_Polarity_Correction", LIST_ADD_F("PHY_Disable_Polarity_Correction",
adapter, e1000_proc_polarity_correction); adapter, e1000_proc_polarity_correction);
LIST_ADD_U("PHY_Idle_Errors", LIST_ADD_U("PHY_Idle_Errors",
&adapter->phy_stats.idle_errors); &adapter->phy_stats.idle_errors);
LIST_ADD_U("PHY_Receive_Errors", LIST_ADD_U("PHY_Receive_Errors",
&adapter->phy_stats.receive_errors); &adapter->phy_stats.receive_errors);
LIST_ADD_F("PHY_MDI_X_Enabled", LIST_ADD_F("PHY_MDI_X_Enabled",
adapter, e1000_proc_mdi_x_enabled); adapter, e1000_proc_mdi_x_enabled);
LIST_ADD_F("PHY_Local_Receiver_Status", LIST_ADD_F("PHY_Local_Receiver_Status",
&adapter->phy_info.local_rx, &adapter->phy_info.local_rx,
e1000_proc_rx_status); e1000_proc_rx_status);
LIST_ADD_F("PHY_Remote_Receiver_Status", LIST_ADD_F("PHY_Remote_Receiver_Status",
&adapter->phy_info.remote_rx, &adapter->phy_info.remote_rx,
e1000_proc_rx_status); e1000_proc_rx_status);
} }
...@@ -675,7 +675,7 @@ e1000_proc_dev_setup(struct e1000_adapter *adapter) ...@@ -675,7 +675,7 @@ e1000_proc_dev_setup(struct e1000_adapter *adapter)
{ {
e1000_proc_list_setup(adapter); e1000_proc_list_setup(adapter);
e1000_proc_dirs_create(adapter, e1000_proc_dirs_create(adapter,
adapter->ifname, adapter->ifname,
&adapter->proc_list_head); &adapter->proc_list_head);
} }
......
...@@ -2383,6 +2383,7 @@ static struct pci_device_id eepro100_pci_tbl[] __devinitdata = { ...@@ -2383,6 +2383,7 @@ static struct pci_device_id eepro100_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, 0x1228, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x1228, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
......
...@@ -124,13 +124,13 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) ...@@ -124,13 +124,13 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
/* advertise only what has been requested */ /* advertise only what has been requested */
advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE); advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4); tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
if (ADVERTISED_10baseT_Half) if (ecmd->advertising & ADVERTISED_10baseT_Half)
tmp |= ADVERTISE_10HALF; tmp |= ADVERTISE_10HALF;
if (ADVERTISED_10baseT_Full) if (ecmd->advertising & ADVERTISED_10baseT_Full)
tmp |= ADVERTISE_10FULL; tmp |= ADVERTISE_10FULL;
if (ADVERTISED_100baseT_Half) if (ecmd->advertising & ADVERTISED_100baseT_Half)
tmp |= ADVERTISE_100HALF; tmp |= ADVERTISE_100HALF;
if (ADVERTISED_100baseT_Full) if (ecmd->advertising & ADVERTISED_100baseT_Full)
tmp |= ADVERTISE_100FULL; tmp |= ADVERTISE_100FULL;
if (advert != tmp) { if (advert != tmp) {
mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp); mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
......
...@@ -164,6 +164,7 @@ ...@@ -164,6 +164,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <linux/crc32.h>
#include <asm/processor.h> /* Processor type for cache alignment. */ #include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -1898,44 +1899,6 @@ static struct net_device_stats *get_stats(struct net_device *dev) ...@@ -1898,44 +1899,6 @@ static struct net_device_stats *get_stats(struct net_device *dev)
return &np->stats; return &np->stats;
} }
/**
* dp83815_crc - computer CRC for hash table entries
*
* Note - this is, for some reason, *not* the same function
* as ether_crc_le() or ether_crc(), though it uses the
* same big-endian polynomial.
*/
#define DP_POLYNOMIAL 0x04C11DB7
static unsigned dp83815_crc(int length, unsigned char *data)
{
u32 crc;
u8 cur_byte;
u8 msb;
u8 byte, bit;
crc = ~0;
for (byte=0; byte<length; byte++) {
cur_byte = *data++;
for (bit=0; bit<8; bit++) {
msb = crc >> 31;
crc <<= 1;
if (msb ^ (cur_byte & 1)) {
crc ^= DP_POLYNOMIAL;
crc |= 1;
}
cur_byte >>= 1;
}
}
crc >>= 23;
return (crc);
}
void set_bit_le(int offset, unsigned char * data)
{
data[offset >> 3] |= (1 << (offset & 0x07));
}
#define HASH_TABLE 0x200 #define HASH_TABLE 0x200
static void __set_rx_mode(struct net_device *dev) static void __set_rx_mode(struct net_device *dev)
{ {
...@@ -1960,9 +1923,8 @@ static void __set_rx_mode(struct net_device *dev) ...@@ -1960,9 +1923,8 @@ static void __set_rx_mode(struct net_device *dev)
memset(mc_filter, 0, sizeof(mc_filter)); memset(mc_filter, 0, sizeof(mc_filter));
for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
i++, mclist = mclist->next) { i++, mclist = mclist->next) {
set_bit_le( int i = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 23) & 0x1ff;
dp83815_crc(ETH_ALEN, mclist->dmi_addr) & 0x1ff, mc_filter[i/8] |= (1 << (i & 0x07));
mc_filter);
} }
rx_mode = RxFilterEnable | AcceptBroadcast rx_mode = RxFilterEnable | AcceptBroadcast
| AcceptMulticast | AcceptMyPhys; | AcceptMulticast | AcceptMyPhys;
......
...@@ -1223,6 +1223,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev) ...@@ -1223,6 +1223,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct pci_dev *pdev)
lp->pdev = pdev; lp->pdev = pdev;
memcpy((char *)&lp->srom,(char *)&bus.srom,sizeof(struct de4x5_srom)); memcpy((char *)&lp->srom,(char *)&bus.srom,sizeof(struct de4x5_srom));
lp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED; lp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
init_timer(&lp->timer);
de4x5_parse_params(dev); de4x5_parse_params(dev);
/* /*
......
...@@ -9,9 +9,19 @@ ...@@ -9,9 +9,19 @@
extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len); extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len);
extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len); extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len);
extern u32 bitreverse(u32 in);
#define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)data, length) #define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)data, length)
/*
* Helpers for hash table generation of ethernet nics:
*
* Ethernet sends the least significant bit of a byte first, thus crc32_le
* is used. The output of crc32_le is bit reversed [most significant bit
* is in bit nr 0], thus it must be reversed before use. Except for
* nics that bit swap the result internally...
*/
#define ether_crc(length, data) bitreverse(crc32_le(~0, data, length))
#define ether_crc_le(length, data) crc32_le(~0, data, length) #define ether_crc_le(length, data) crc32_le(~0, data, length)
#define ether_crc(length, data) crc32_be(~0, data, length)
#endif /* _LINUX_CRC32_H */ #endif /* _LINUX_CRC32_H */
...@@ -265,8 +265,19 @@ u32 attribute((pure)) crc32_be(u32 crc, unsigned char const *p, size_t len) ...@@ -265,8 +265,19 @@ u32 attribute((pure)) crc32_be(u32 crc, unsigned char const *p, size_t len)
} }
#endif #endif
u32 bitreverse(u32 x)
{
x = (x >> 16) | (x << 16);
x = (x >> 8 & 0x00ff00ff) | (x << 8 & 0xff00ff00);
x = (x >> 4 & 0x0f0f0f0f) | (x << 4 & 0xf0f0f0f0);
x = (x >> 2 & 0x33333333) | (x << 2 & 0xcccccccc);
x = (x >> 1 & 0x55555555) | (x << 1 & 0xaaaaaaaa);
return x;
}
EXPORT_SYMBOL(crc32_le); EXPORT_SYMBOL(crc32_le);
EXPORT_SYMBOL(crc32_be); EXPORT_SYMBOL(crc32_be);
EXPORT_SYMBOL(bitreverse);
/* /*
* A brief CRC tutorial. * A brief CRC tutorial.
...@@ -412,16 +423,6 @@ buf_dump(char const *prefix, unsigned char const *buf, size_t len) ...@@ -412,16 +423,6 @@ buf_dump(char const *prefix, unsigned char const *buf, size_t len)
} }
#endif #endif
static u32 attribute((const)) bitreverse(u32 x)
{
x = (x >> 16) | (x << 16);
x = (x >> 8 & 0x00ff00ff) | (x << 8 & 0xff00ff00);
x = (x >> 4 & 0x0f0f0f0f) | (x << 4 & 0xf0f0f0f0);
x = (x >> 2 & 0x33333333) | (x << 2 & 0xcccccccc);
x = (x >> 1 & 0x55555555) | (x << 1 & 0xaaaaaaaa);
return x;
}
static void bytereverse(unsigned char *buf, size_t len) static void bytereverse(unsigned char *buf, size_t len)
{ {
while (len--) { while (len--) {
......
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