Commit 3334a8ca authored by Linus Torvalds's avatar Linus Torvalds Committed by Linus Torvalds

Merge http://gkernel.bkbits.net/net-drivers-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 95c26f5a 67c5f644
Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
===============================================================
April 23, 2002
June 11, 2002
Contents
......@@ -95,8 +95,8 @@ For the latest Intel network drivers for Linux, go to:
Command Line Parameters
=======================
If the driver is built as a module, the following parameters are used by
entering them on the command line with the modprobe or insmod command.
If the driver is built as a module, the following optional parameters are
used by entering them on the command line with the modprobe or insmod command.
For example, with two PRO/1000 PCI adapters, entering:
insmod e1000 TxDescriptors=80,128
......@@ -141,7 +141,7 @@ Default Value: 80
RxIntDelay
Valid Range: 0-65535 (0=off)
Default Value: 64 (82542, 82543, and 82544-based adapters)
Default Value: 0 (82542, 82543, and 82544-based adapters)
128 (82540, 82545, and 82546-based adapters)
This value delays the generation of receive interrupts in units of 1.024
microseconds. Receive interrupt reduction can improve CPU efficiency if
......@@ -151,6 +151,14 @@ Default Value: 64 (82542, 82543, and 82544-based adapters)
may be set too high, causing the driver to run out of available receive
descriptors.
CAUTION: When setting RxIntDelay to a value other than 0, adapters based
on the Intel 82543 and 82544 LAN controllers may hang (stop
transmitting) under certain network conditions. If this occurs a
message is logged in the system event log. In addition, the
controller is automatically reset, restoring the network
connection. To eliminate the potential for the hang ensure that
RxIntDelay is set to 0.
Speed (adapters using copper connections only)
Valid Settings: 0, 10, 100, 1000
Default Value: 0 (auto-negotiate at all supported speeds)
......@@ -229,16 +237,6 @@ Additional Configurations
Known Issues
============
Inconsistent Driver Behavior Under Heavy Traffic Loads
------------------------------------------------------
Adapters based on the Intel 82543 and 82544 LAN controllers may hang (stop
transmitting) under certain network conditions. If this occurs a message
is logged in the system event log. In addition, the controller is
automatically reset, restoring the network connection. To eliminate the
potential for the hang change the RxIntDelay parameter to zero. For details
on the RxIntDelay parameter see the Command Line Parameters section.
Jumbo Frames System Requirement
-------------------------------
......
......@@ -21,13 +21,13 @@
Contributors:
Wake-on-LAN support - Felipe Damasio <felipewd@terra.com.br>
PCI suspend/resume - Felipe Damasio <felipewd@terra.com.br>
TODO, in rough priority order:
* dev->tx_timeout
* LinkChg interrupt
* Support forcing media type with a module parameter,
like dl2k.c/sundance.c
* Implement PCI suspend/resume
* Constants (module parms?) for Rx work limit
* support 64-bit PCI DMA
* Complete reset on PciErr
......@@ -360,6 +360,7 @@ struct cp_private {
unsigned int board_type;
unsigned int wol_enabled : 1; /* Is Wake-on-LAN enabled? */
u32 power_state[16];
struct mii_if_info mii_if;
};
......@@ -976,11 +977,11 @@ static void cp_reset_hw (struct cp_private *cp)
static inline void cp_start_hw (struct cp_private *cp)
{
cpw8(Cmd, RxOn | TxOn);
if (cp->board_type == RTL8169)
cpw16(CpCmd, PCIMulRW | RxChkSum);
else
cpw16(CpCmd, PCIMulRW | RxChkSum | CpRxOn | CpTxOn);
cpw8(Cmd, RxOn | TxOn);
}
static void cp_init_hw (struct cp_private *cp)
......@@ -1896,11 +1897,68 @@ static void __devexit cp_remove_one (struct pci_dev *pdev)
kfree(dev);
}
#ifdef CONFIG_PM
static int cp_suspend (struct pci_dev *pdev, u32 state)
{
struct net_device *dev;
struct cp_private *cp;
unsigned long flags;
dev = pci_get_drvdata (pdev);
cp = dev->priv;
if (!dev || !netif_running (dev)) return 0;
netif_device_detach (dev);
netif_stop_queue (dev);
spin_lock_irqsave (&cp->lock, flags);
/* Disable Rx and Tx */
cpw16 (IntrMask, 0);
cpw8 (Cmd, cpr8 (Cmd) & (~RxOn | ~TxOn));
spin_unlock_irqrestore (&cp->lock, flags);
if (cp->pdev && cp->wol_enabled) {
pci_save_state (cp->pdev, cp->power_state);
cp_set_d3_state (cp);
}
return 0;
}
static int cp_resume (struct pci_dev *pdev)
{
struct net_device *dev;
struct cp_private *cp;
dev = pci_get_drvdata (pdev);
cp = dev->priv;
netif_device_attach (dev);
if (cp->pdev && cp->wol_enabled) {
pci_set_power_state (cp->pdev, 0);
pci_restore_state (cp->pdev, cp->power_state);
}
cp_init_hw (cp);
netif_start_queue (dev);
return 0;
}
#endif /* CONFIG_PM */
static struct pci_driver cp_driver = {
.name = DRV_NAME,
.id_table = cp_pci_tbl,
.probe = cp_init_one,
.remove = __devexit_p(cp_remove_one),
#ifdef CONFIG_PM
.resume = cp_resume,
.suspend = cp_suspend,
#endif
};
static int __init cp_init (void)
......
......@@ -91,13 +91,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <linux/version.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/reboot.h>
#include <asm/io.h>
#include <asm/unaligned.h>
#include <asm/processor.h>
#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
#include <linux/inetdevice.h>
#endif
#include <linux/if.h>
#include <asm/uaccess.h>
......@@ -147,6 +146,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define E100_MAX_SCB_WAIT 100 /* Max udelays in wait_scb */
#define E100_MAX_CU_IDLE_WAIT 50 /* Max udelays in wait_cus_idle */
/* HWI feature related constant */
#define HWI_MAX_LOOP 100
#define MAX_SAME_RESULTS 3
#define HWI_REGISTER_GRANULARITY 80 /* register granularity = 80 Cm */
#define HWI_NEAR_END_BOUNDARY 1000 /* Near end is defined as < 10 meters */
/* CPUSAVER_BUNDLE_MAX: Sets the maximum number of frames that will be bundled.
* In some situations, such as the TCP windowing algorithm, it may be
* better to limit the growth of the bundle size than let it go as
......@@ -504,6 +509,7 @@ enum led_state_e {
#define IS_ICH 0x00000020
#define DF_SPEED_FORCED 0x00000040 /* set if speed is forced */
#define LED_IS_ON 0x00000080 /* LED is turned ON by the driver */
#define DF_LINK_FC_TX_ONLY 0x00000100 /* Received PAUSE frames are honored*/
typedef struct net_device_stats net_dev_stats_t;
......@@ -774,15 +780,7 @@ typedef struct _tcb_ipcb_t {
u16 total_tcp_payload;
} tcb_ipcb_t __attribute__ ((__packed__));
#ifdef MAX_SKB_FRAGS
#define E100_ZEROCOPY
#endif
#ifdef E100_ZEROCOPY
#define E100_TBD_ARRAY_SIZE (2+MAX_SKB_FRAGS)
#else
#define E100_TBD_ARRAY_SIZE 2
#endif /*E100_ZEROCOPY */
/* Transmit Command Block (TCB)*/
struct _tcb_t {
......@@ -803,19 +801,15 @@ struct _tcb_t {
*/
tbd_t *tbd_ptr;
#ifdef E100_ZEROCOPY
u32 tcb_tbd_dflt_ptr; /* TBD address for non-segmented packet */
u32 tcb_tbd_expand_ptr; /* TBD address for segmented packet */
#endif /*E100_ZEROCOPY */
struct sk_buff *tcb_skb; /* the associated socket buffer */
dma_addr_t tcb_phys; /* phys addr of the TCB */
} __attribute__ ((__packed__));
#ifndef _TCB_T_
#define _TCB_T_
typedef struct _tcb_t tcb_t;
#endif
/* Receive Frame Descriptor (RFD) - will be using the simple model*/
struct _rfd_t {
......@@ -836,10 +830,8 @@ struct _rfd_t {
} __attribute__ ((__packed__));
#ifndef _RFD_T_
#define _RFD_T_
typedef struct _rfd_t rfd_t;
#endif
/* Receive Buffer Descriptor (RBD)*/
typedef struct _rbd_t {
......@@ -901,14 +893,12 @@ struct cfg_params {
int PollingMaxWork;
u32 b_params;
};
#ifdef ETHTOOL_TEST
struct ethtool_lpbk_data{
dma_addr_t dma_handle;
tcb_t *tcb;
rfd_t *rfd;
};
#endif
struct e100_private {
u32 flags; /* board management flags */
......@@ -987,28 +977,33 @@ struct e100_private {
rwlock_t isolate_lock;
int driver_isolated;
char *id_string;
char *cable_status;
char *mdix_status;
/* Variables for HWI */
int saved_open_circut;
int saved_short_circut;
int saved_distance;
int saved_i;
int saved_same;
unsigned char hwi_started;
struct timer_list hwi_timer; /* hwi timer id */
u32 speed_duplex_caps; /* adapter's speed/duplex capabilities */
struct tasklet_struct polling_tasklet;
#ifdef ETHTOOL_GWOL
/* WOL params for ethtool */
u32 wolsupported;
u32 wolopts;
u16 ip_lbytes;
#endif
#ifdef ETHTOOL_TEST
struct ethtool_lpbk_data loopback;
#endif
#ifdef ETHTOOL_PHYS_ID
struct timer_list blink_timer; /* led blink timer id */
#endif
#ifdef CONFIG_PM
u32 pci_state[16];
#endif
};
#define E100_AUTONEG 0
......@@ -1036,8 +1031,6 @@ extern void e100_deisolate_driver(struct e100_private *bdp,
extern unsigned char e100_hw_reset_recover(struct e100_private *bdp,
u32 reset_cmd);
#ifdef ETHTOOL_TEST
#define ROM_TEST_FAIL 0x01
#define REGISTER_TEST_FAIL 0x02
#define SELF_TEST_FAIL 0x04
......@@ -1053,6 +1046,5 @@ enum test_offsets {
E100_LPBK_PHY_FAIL,
E100_MAX_TEST_RES
};
#endif
#endif
......@@ -86,10 +86,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* operating system. *
* *
**********************************************************************/
#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
#endif
#include "e100_config.h"
static void e100_config_long_rx(struct e100_private *bdp, unsigned char enable);
......@@ -308,85 +304,58 @@ e100_config(struct e100_private *bdp)
/**
* e100_config_fc - config flow-control state
* @bdp: atapter's private data struct
* @bdp: adapter's private data struct
*
* This routine will enable or disable flow control support in the adapter's
* config block. Flow control will be enable only if requested using the command
* line option, and if the link is flow-contorl capable (both us and the link
* partner).
*
* Returns:
* true: if then option was indeed changed
* false: if no change was needed
* partner). But, if link partner is capable of autoneg, but not capable of
* flow control, received PAUSE frames are still honored.
*/
unsigned char
void
e100_config_fc(struct e100_private *bdp)
{
unsigned char enable = false;
unsigned char changed = false;
/* 82557 doesn't support fc. Don't touch this option */
if (!(bdp->flags & IS_BACHELOR))
return false;
return;
/* Enable fc if requested and if the link supports it */
if ((bdp->params.b_params & PRM_FC) && (bdp->flags & DF_LINK_FC_CAP)) {
if ((bdp->params.b_params & PRM_FC) && (bdp->flags &
(DF_LINK_FC_CAP | DF_LINK_FC_TX_ONLY))) {
enable = true;
}
spin_lock_bh(&(bdp->config_lock));
if (enable) {
if (bdp->config[16] != DFLT_FC_DELAY_LSB) {
if (bdp->flags & DF_LINK_FC_TX_ONLY) {
/* If link partner is capable of autoneg, but */
/* not capable of flow control, Received PAUSE */
/* frames are still honored, i.e., */
/* transmitted frames would be paused by */
/* incoming PAUSE frames */
bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
bdp->config[19] &= ~(CB_CFIG_FC_RESTOP | CB_CFIG_FC_RESTART);
bdp->config[19] |= CB_CFIG_FC_REJECT;
bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
} else {
bdp->config[16] = DFLT_FC_DELAY_LSB;
E100_CONFIG(bdp, 16);
changed = true;
}
if (bdp->config[17] != DFLT_FC_DELAY_LSB) {
bdp->config[17] = DFLT_FC_DELAY_MSB;
E100_CONFIG(bdp, 17);
changed = true;
}
/* check if *all* fc config options were already set */
if (((bdp->config[19] & CB_CFIG_FC_OPTS) != CB_CFIG_FC_OPTS) ||
(bdp->config[19] & CB_CFIG_TX_FC_DIS)) {
bdp->config[19] |= CB_CFIG_FC_OPTS;
bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
E100_CONFIG(bdp, 19);
changed = true;
}
} else {
if (bdp->config[16] != DFLT_NO_FC_DELAY_LSB) {
bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
E100_CONFIG(bdp, 16);
changed = true;
}
if (bdp->config[17] != DFLT_NO_FC_DELAY_MSB) {
bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
E100_CONFIG(bdp, 17);
changed = true;
}
/* check if *any* fc config options was already set */
if ((bdp->config[19] & CB_CFIG_FC_OPTS) ||
!(bdp->config[19] & CB_CFIG_TX_FC_DIS)) {
bdp->config[19] &= ~CB_CFIG_FC_OPTS;
bdp->config[19] |= CB_CFIG_TX_FC_DIS;
E100_CONFIG(bdp, 19);
changed = true;
}
bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
bdp->config[19] &= ~CB_CFIG_FC_OPTS;
bdp->config[19] |= CB_CFIG_TX_FC_DIS;
}
E100_CONFIG(bdp, 19);
spin_unlock_bh(&(bdp->config_lock));
return changed;
return;
}
/**
......@@ -566,7 +535,6 @@ e100_config_long_rx(struct e100_private *bdp, unsigned char enable)
}
}
#ifdef ETHTOOL_GWOL
/**
* e100_config_wol
* @bdp: atapter's private data struct
......@@ -591,7 +559,6 @@ e100_config_wol(struct e100_private *bdp)
spin_unlock_bh(&(bdp->config_lock));
}
#endif
/**
* e100_config_loopback_mode
......@@ -618,7 +585,7 @@ e100_config_loopback_mode(struct e100_private *bdp, u8 mode)
config_byte = CB_CFIG_LOOPBACK_EXTERNAL;
break;
default:
printk(KERN_NOTICE "e100_config_loopback_mode: "
printk(KERN_NOTICE "e100: e100_config_loopback_mode: "
"Invalid argument 'mode': %d\n", mode);
goto exit;
}
......
......@@ -198,7 +198,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern void e100_config_init(struct e100_private *bdp);
extern unsigned char e100_force_config(struct e100_private *bdp);
extern unsigned char e100_config(struct e100_private *bdp);
extern unsigned char e100_config_fc(struct e100_private *bdp);
extern void e100_config_fc(struct e100_private *bdp);
extern void e100_config_promisc(struct e100_private *bdp, unsigned char enable);
extern void e100_config_brdcast_dsbl(struct e100_private *bdp);
extern void e100_config_mulcast_enbl(struct e100_private *bdp,
......
......@@ -145,8 +145,6 @@ eeprom_set_semaphore(struct e100_private *adapter)
data |= SCB_GCR2_EEPROM_ACCESS_SEMAPHORE;
writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));
barrier();
// Check to see if this bit set or not.
data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
......@@ -224,6 +222,7 @@ e100_eeprom_size(struct e100_private *adapter)
x &= ~EEDI; // address consists of all zeros
writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
readw(&(adapter->scb->scb_status));
udelay(EEPROM_STALL_TIME);
raise_clock(adapter, &x);
lower_clock(adapter, &x);
......
......@@ -93,8 +93,30 @@ Portions (C) 2002 Red Hat, Inc. under the terms of the GNU GPL v2.
* *
**********************************************************************/
#undef __NO_VERSION__
/* Change Log
*
* 2.1.6 7/5/02
* o Added device ID support for Dell LOM.
* o Added device ID support for 82511QM mobile nics.
* o Bug fix: ethtool get/set EEPROM routines modified to use byte
* addressing rather than word addressing.
* o Feature: added MDIX mode support for 82550 and up.
* o Bug fix: added reboot notifer to setup WOL settings when
* shutting system down.
* o Cleanup: removed yield() redefinition (Andrew Morton,
* akpm@zip.com.au).
* o Bug fix: flow control now working when link partner is
* autoneg capable but not flow control capable.
* o Bug fix: added check for corrupted EEPROM
* o Bug fix: don't report checksum offloading for the older
* controllers that don't support the feature.
* o Bug fix: calculate cable diagnostics when link goes down
* rather than when queuering /proc file.
* o Cleanup: move mdi_access_lock to local get/set mdi routines.
*
* 2.0.30 5/30/02
*/
#include <linux/config.h>
#include <net/checksum.h>
#include <linux/tcp.h>
......@@ -105,11 +127,7 @@ Portions (C) 2002 Red Hat, Inc. under the terms of the GNU GPL v2.
#include "e100_phy.h"
#include "e100_vendor.h"
#ifndef CONFIG_PROC_FS
#undef E100_CONFIG_PROC_FS
#endif
#ifdef E100_CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
extern int e100_create_proc_subdir(struct e100_private *);
extern void e100_remove_proc_subdir(struct e100_private *);
#else
......@@ -117,41 +135,24 @@ extern void e100_remove_proc_subdir(struct e100_private *);
#define e100_remove_proc_subdir(X) do {} while(0)
#endif
#ifdef SIOCETHTOOL
#define E100_ETHTOOL_IOCTL
#endif
#ifdef E100_ETHTOOL_IOCTL
static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *);
static void e100_get_speed_duplex_caps(struct e100_private *);
static int e100_ethtool_get_settings(struct net_device *, struct ifreq *);
static int e100_ethtool_set_settings(struct net_device *, struct ifreq *);
#ifdef ETHTOOL_GDRVINFO
static int e100_ethtool_get_drvinfo(struct net_device *, struct ifreq *);
#endif
#ifdef ETHTOOL_GEEPROM
static int e100_ethtool_eeprom(struct net_device *, struct ifreq *);
#define E100_EEPROM_MAGIC 0x1234
#endif
#ifdef ETHTOOL_GLINK
static int e100_ethtool_glink(struct net_device *, struct ifreq *);
#endif
#ifdef ETHTOOL_NWAY_RST
static int e100_ethtool_nway_rst(struct net_device *, struct ifreq *);
#endif
#ifdef ETHTOOL_GWOL
static int e100_ethtool_wol(struct net_device *, struct ifreq *);
static unsigned char e100_setup_filter(struct e100_private *bdp);
static void e100_do_wol(struct pci_dev *pcid, struct e100_private *bdp);
static u16 e100_get_ip_lbytes(struct net_device *dev);
extern void e100_config_wol(struct e100_private *bdp);
#endif
#ifdef ETHTOOL_TEST
extern u32 e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags);
static int e100_ethtool_test(struct net_device *, struct ifreq *);
#endif
#ifdef ETHTOOL_GSTRINGS
static int e100_ethtool_gstrings(struct net_device *, struct ifreq *);
static char *test_strings[] = {
"E100_EEPROM_TEST_FAIL",
......@@ -163,19 +164,10 @@ static char *test_strings[] = {
"E100_LPBK_PHY_FAIL"
};
#endif
#ifdef ETHTOOL_PHYS_ID
static int e100_ethtool_led_blink(struct net_device *, struct ifreq *);
#endif
#endif /*E100_ETHTOOL_IOCTL */
#ifdef SIOCGMIIPHY
#define E100_MII_IOCTL
#endif
#ifdef E100_MII_IOCTL
#include <linux/mii.h>
static int e100_mii_ioctl(struct net_device *, struct ifreq *, int);
#endif /*E100_MII_IOCTL */
static unsigned char e100_delayed_exec_non_cu_cmd(struct e100_private *,
nxmit_cb_entry_t *);
......@@ -184,23 +176,24 @@ static void e100_non_tx_background(unsigned long);
/* Global Data structures and variables */
char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation";
#define E100_VERSION "2.0.30-k1"
#define E100_FULL_DRIVER_NAME "Intel(R) PRO/100 Fast Ethernet Adapter - Loadable driver, ver "
const char *e100_version = E100_VERSION;
const char *e100_full_driver_name = E100_FULL_DRIVER_NAME E100_VERSION;
char *e100_short_driver_name = "e100";
char e100_driver_version[]="2.1.6-k1";
const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver";
char e100_short_driver_name[] = "e100";
static int e100nics = 0;
#ifdef CONFIG_PM
static int e100_save_state(struct pci_dev *pcid, u32 state);
static int e100_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
static int e100_suspend(struct pci_dev *pcid, u32 state);
static int e100_enable_wake(struct pci_dev *pcid, u32 state, int enable);
static int e100_resume(struct pci_dev *pcid);
struct notifier_block e100_notifier = {
notifier_call: e100_notify_reboot,
next: NULL,
priority: 0
};
#endif
static void e100_get_mdix_status(struct e100_private *bdp);
/*********************************************************************/
/*! This is a GCC extension to ANSI C.
* See the item "Labeled Elements in Initializers" in the section
......@@ -250,6 +243,7 @@ static void e100_rd_pwa_no(struct e100_private *);
extern u16 e100_eeprom_read(struct e100_private *, u16);
extern void e100_eeprom_write_block(struct e100_private *, u16, u16 *, u16);
extern u16 e100_eeprom_size(struct e100_private *);
u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);
static unsigned char e100_clr_cntrs(struct e100_private *);
static unsigned char e100_load_microcode(struct e100_private *);
......@@ -391,6 +385,8 @@ u32 e100_rx_srv(struct e100_private *, u32, int *);
void e100_polling_tasklet(unsigned long);
void e100_watchdog(struct net_device *);
static void e100_do_hwi(struct net_device *);
static void e100_hwi_restore(struct e100_private *);
void e100_refresh_txthld(struct e100_private *);
void e100_manage_adaptive_ifs(struct e100_private *);
void e100_clear_pools(struct e100_private *);
......@@ -400,7 +396,7 @@ static inline tcb_t *e100_prepare_xmit_buff(struct e100_private *,
static void e100_set_multi_exec(struct net_device *dev);
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION(E100_FULL_DRIVER_NAME E100_VERSION);
MODULE_DESCRIPTION("Intel(R) PRO/100 Network Driver");
MODULE_LICENSE("Dual BSD/GPL");
E100_PARAM(TxDescriptors, "Number of transmit descriptors");
......@@ -429,7 +425,7 @@ static inline void
e100_exec_cmd(struct e100_private *bdp, u8 cmd_low)
{
writeb(cmd_low, &(bdp->scb->scb_cmd_low));
readw(&(bdp->scb->scb_status)); /* flashes last write, read-safe */
readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
}
/**
......@@ -484,7 +480,7 @@ inline unsigned char
e100_wait_exec_simple(struct e100_private *bdp, u8 scb_cmd_low)
{
if (!e100_wait_scb(bdp)) {
printk(KERN_DEBUG "%s e100_wait_exec_simple: Wait failed\n",
printk(KERN_DEBUG "e100: %s: e100_wait_exec_simple: failed\n",
bdp->device->name);
return false;
}
......@@ -496,7 +492,7 @@ void
e100_exec_cmplx(struct e100_private *bdp, u32 phys_addr, u8 cmd)
{
writel(phys_addr, &(bdp->scb->scb_gen_ptr));
readw(&(bdp->scb->scb_status)); /* flashes last write, read-safe */
readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
e100_exec_cmd(bdp, cmd);
}
......@@ -580,10 +576,11 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
struct net_device *dev = NULL;
struct e100_private *bdp = NULL;
int rc = 0;
u16 cal_checksum, read_checksum;
dev = alloc_etherdev(sizeof (struct e100_private));
if (dev == NULL) {
printk(KERN_ERR "Not able to alloc etherdev struct\n");
printk(KERN_ERR "e100: Not able to alloc etherdev struct\n");
rc = -ENODEV;
goto out;
}
......@@ -592,7 +589,8 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
if (first_time) {
first_time = false;
printk(KERN_NOTICE "%s\n", e100_full_driver_name);
printk(KERN_NOTICE "%s - version %s\n",
e100_full_driver_name, e100_driver_version);
printk(KERN_NOTICE "%s\n", e100_copyright);
printk(KERN_NOTICE "\n");
}
......@@ -622,6 +620,10 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
bdp->watchdog_timer.data = (unsigned long) dev;
bdp->watchdog_timer.function = (void *) &e100_watchdog;
init_timer(&bdp->hwi_timer);
bdp->hwi_timer.data = (unsigned long) dev;
bdp->hwi_timer.function = (void *) &e100_do_hwi;
if ((rc = e100_pci_setup(pcid, bdp)) != 0) {
goto err_dealloc;
}
......@@ -647,16 +649,25 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
} else {
bdp->rfd_size = 16;
}
e100_check_options(e100nics, bdp);
if (!e100_init(bdp)) {
printk(KERN_ERR "Failed to initialize e100, instance #%d\n",
printk(KERN_ERR "e100: Failed to initialize, instance #%d\n",
e100nics);
rc = -ENODEV;
goto err_pci;
}
/* Check if checksum is valid */
cal_checksum = e100_eeprom_calculate_chksum(bdp);
read_checksum = e100_eeprom_read(bdp, (bdp->eeprom_size - 1));
if (cal_checksum != read_checksum) {
printk(KERN_ERR "e100: Corrupted EERPROM on instance #%d\n",
e100nics);
rc = -ENODEV;
goto err_pci;
}
dev->irq = pcid->irq;
dev->open = &e100_open;
dev->hard_start_xmit = &e100_xmit_frame;
......@@ -666,16 +677,12 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
dev->set_multicast_list = &e100_set_multi;
dev->set_mac_address = &e100_set_mac;
dev->do_ioctl = &e100_ioctl;
#ifdef E100_ZEROCOPY
if (bdp->flags & USE_IPCB) {
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
}
#endif
e100nics++;
#ifdef E100_ETHTOOL_IOCTL
e100_get_speed_duplex_caps(bdp);
#endif /*E100_ETHTOOL_IOCTL */
if ((rc = register_netdev(dev)) != 0) {
goto err_pci;
......@@ -683,15 +690,26 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
bdp->device_type = ent->driver_data;
printk(KERN_NOTICE
"%s: %s\n", bdp->device->name, e100_get_brand_msg(bdp));
"e100: %s: %s\n",
bdp->device->name, e100_get_brand_msg(bdp));
e100_print_brd_conf(bdp);
bdp->id_string = e100_get_brand_msg(bdp);
e100_get_mdix_status(bdp);
if (netif_carrier_ok(bdp->device))
bdp->cable_status = "Cable OK";
else {
if (bdp->rev_id < D102_REV_ID)
bdp->cable_status = "Not supported";
else
bdp->cable_status = "Not available";
}
if (e100_create_proc_subdir(bdp) < 0) {
printk(KERN_ERR "Failed to create proc directory for %s\n",
printk(KERN_ERR "e100: Failed to create proc dir for %s\n",
bdp->device->name);
}
#ifdef ETHTOOL_GWOL
/* Disabling all WOLs as initialization */
bdp->wolsupported = bdp->wolopts = 0;
if (bdp->rev_id >= D101A4_REV_ID) {
......@@ -700,7 +718,6 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
bdp->wolsupported |= WAKE_UCAST | WAKE_ARP;
bdp->wolopts = WAKE_MAGIC;
}
#endif
printk(KERN_NOTICE "\n");
......@@ -762,7 +779,6 @@ e100_remove1(struct pci_dev *pcid)
bdp->non_tx_command_state = E100_NON_TX_IDLE;
}
#ifdef ETHTOOL_GWOL
/* Set up wol options and enable PME if wol is enabled */
if (bdp->wolopts) {
e100_do_wol(pcid, bdp);
......@@ -772,7 +788,6 @@ e100_remove1(struct pci_dev *pcid)
/* If system powers down, device is switched from D1 to D3 */
pci_set_power_state(pcid, 1);
}
#endif
e100_clear_structs(dev);
......@@ -786,27 +801,33 @@ static struct pci_driver e100_driver = {
id_table: e100_id_table,
probe: e100_found1,
remove: __devexit_p(e100_remove1),
#ifdef CONFIG_PM
#ifdef CONFIG_PM
suspend: e100_suspend,
resume: e100_resume,
save_state: e100_save_state,
enable_wake: e100_enable_wake,
#else
suspend: NULL,
resume: NULL,
#endif
};
static int __init
e100_init_module(void)
{
return pci_module_init(&e100_driver);
int ret;
ret = pci_module_init(&e100_driver);
#ifdef CONFIG_PM
if(ret >= 0)
register_reboot_notifier(&e100_notifier);
#endif
return ret;
}
static void __exit
e100_cleanup_module(void)
{
#ifdef CONFIG_PM
unregister_reboot_notifier(&e100_notifier);
#endif
pci_unregister_driver(&e100_driver);
}
......@@ -824,9 +845,10 @@ void __devinit
e100_check_options(int board, struct e100_private *bdp)
{
if (board >= E100_MAX_NIC) {
printk(KERN_NOTICE "No configuration available for board #%d\n",
printk(KERN_NOTICE
"e100: No configuration available for board #%d\n",
board);
printk(KERN_NOTICE "Using defaults for all values\n");
printk(KERN_NOTICE "e100: Using defaults for all values\n");
board = E100_MAX_NIC;
}
......@@ -907,13 +929,14 @@ e100_set_int_option(int *option, int val, int min, int max, int default_val,
} else if ((val < min) || (val > max)) {
printk(KERN_NOTICE
"Invalid %s specified (%i). Valid range is %i-%i\n",
"e100: Invalid %s specified (%i). "
"Valid range is %i-%i\n",
name, val, min, max);
printk(KERN_NOTICE "Using default %s of %i\n", name,
printk(KERN_NOTICE "e100: Using default %s of %i\n", name,
default_val);
*option = default_val;
} else {
printk(KERN_INFO "Using specified %s of %i\n", name, val);
printk(KERN_INFO "e100: Using specified %s of %i\n", name, val);
*option = val;
}
}
......@@ -941,15 +964,16 @@ e100_set_bool_option(struct e100_private *bdp, int val, u32 mask,
} else if ((val != true) && (val != false)) {
printk(KERN_NOTICE
"Invalid %s specified (%i). Valid values are %i/%i\n",
"e100: Invalid %s specified (%i). "
"Valid values are %i/%i\n",
name, val, false, true);
printk(KERN_NOTICE "Using default %s of %i\n", name,
printk(KERN_NOTICE "e100: Using default %s of %i\n", name,
default_val);
if (default_val)
bdp->params.b_params |= mask;
} else {
printk(KERN_INFO "Using specified %s of %i\n", name, val);
printk(KERN_INFO "e100: Using specified %s of %i\n", name, val);
if (val)
bdp->params.b_params |= mask;
}
......@@ -1035,9 +1059,7 @@ e100_close(struct net_device *dev)
bdp->intr_mask = SCB_INT_MASK;
e100_isolate_driver(bdp);
#ifdef ETHTOOL_GWOL
bdp->ip_lbytes = e100_get_ip_lbytes(dev);
#endif
free_irq(dev->irq, dev);
e100_clear_pools(bdp);
......@@ -1198,7 +1220,8 @@ e100_set_multi_exec(struct net_device *dev)
}
if (!e100_exec_non_cu_cmd(bdp, cmd)) {
printk(KERN_WARNING "%s: Multicast setup failed\n", dev->name);
printk(KERN_WARNING "e100: %s: Multicast setup failed\n",
dev->name);
}
}
......@@ -1247,19 +1270,15 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
switch (cmd) {
#ifdef E100_ETHTOOL_IOCTL
case SIOCETHTOOL:
return e100_do_ethtool_ioctl(dev, ifr);
break;
#endif /*E100_ETHTOOL_IOCTL */
#ifdef E100_MII_IOCTL
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCSMIIREG: /* Write to MII PHY register. */
return e100_mii_ioctl(dev, ifr, cmd);
break;
#endif /*E100_MII_IOCTL */
default:
return -EOPNOTSUPP;
......@@ -1286,7 +1305,7 @@ e100_init(struct e100_private *bdp)
e100_sw_init(bdp);
if (!e100_selftest(bdp, NULL, NULL)) {
printk(KERN_ERR "selftest failed\n");
printk(KERN_ERR "e100: selftest failed\n");
return false;
}
......@@ -1296,7 +1315,7 @@ e100_init(struct e100_private *bdp)
e100_rd_pwa_no(bdp);
if (!e100_hw_init(bdp, PORT_SOFTWARE_RESET)) {
printk(KERN_ERR "hw init failed\n");
printk(KERN_ERR "e100: hw init failed\n");
return false;
}
e100_dis_intr(bdp);
......@@ -1462,7 +1481,6 @@ e100_setup_tcb_pool(tcb_t *head, unsigned int qlen, struct e100_private *bdp)
cpu_to_le32(pcurr_tcb->tcb_phys + 0x10);
}
#ifdef E100_ZEROCOPY
if (bdp->flags & IS_BACHELOR) {
pcurr_tcb->tcb_tbd_expand_ptr =
cpu_to_le32(pcurr_tcb->tcb_phys + 0x20);
......@@ -1471,7 +1489,6 @@ e100_setup_tcb_pool(tcb_t *head, unsigned int qlen, struct e100_private *bdp)
cpu_to_le32(pcurr_tcb->tcb_phys + 0x10);
}
pcurr_tcb->tcb_tbd_dflt_ptr = pcurr_tcb->tcb_tbd_ptr;
#endif
if (bdp->flags & USE_IPCB) {
pcurr_tcb->tbd_ptr = &(pcurr_tcb->tcbu.tbd_array[1]);
......@@ -1532,7 +1549,7 @@ e100_alloc_space(struct e100_private *bdp)
err:
printk(KERN_ERR
"%s - Failed to allocate memory\n", e100_short_driver_name);
"e100: Failed to allocate memory\n");
return -ENOMEM;
}
......@@ -1665,7 +1682,7 @@ e100_watchdog(struct net_device *dev)
if (!netif_running(dev)) {
goto exit;
}
spin_lock_bh(&(bdp->mdi_access_lock));
e100_get_mdix_status(bdp);
/* check if link state has changed */
if (e100_phy_check(bdp)) {
......@@ -1677,11 +1694,38 @@ e100_watchdog(struct net_device *dev)
"Half" : "Full");
e100_config_fc(bdp);
e100_config(bdp);
e100_config(bdp);
bdp->cable_status = "Cable OK";
} else {
printk(KERN_ERR "e100: %s NIC Link is Down\n",
bdp->device->name);
if (bdp->rev_id < D102_REV_ID)
bdp->cable_status = "Not supported";
else {
/* Initiate hwi, ie, cable diagnostic */
bdp->saved_open_circut = 0xffff;
bdp->saved_short_circut = 0xffff;
bdp->saved_distance = 0xffff;
bdp->saved_i = 0;
bdp->saved_same = 0;
bdp->hwi_started = 1;
/* Disable MDI/MDI-X auto switching */
e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
MDI_MDIX_RESET_ALL_MASK);
/* Set to 100 Full as required by hwi test */
e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr,
BMCR_SPEED100 | BMCR_FULLDPLX);
/* Enable and execute HWI test */
e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
(HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
/* Launch hwi timer in 1 msec */
mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) );
}
}
}
......@@ -1722,8 +1766,6 @@ e100_watchdog(struct net_device *dev)
wmb();
spin_unlock_bh(&(bdp->mdi_access_lock));
/* relaunch watchdog timer in 2 sec */
mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ));
......@@ -1869,6 +1911,7 @@ e100intr(int irq, void *dev_inst, struct pt_regs *regs)
e100_dis_intr(bdp);
writew(intr_status, &bdp->scb->scb_status); /* ack intrs */
readw(&bdp->scb->scb_status);
/* the device is closed, don't continue or else bad things may happen. */
if (!netif_running(dev)) {
......@@ -1923,7 +1966,6 @@ static void inline
e100_tx_skb_free(struct e100_private *bdp, tcb_t *tcb)
{
if (tcb->tcb_skb) {
#ifdef E100_ZEROCOPY
int i;
tbd_t *tbd_arr = tcb->tbd_ptr;
int frags = skb_shinfo(tcb->tcb_skb)->nr_frags;
......@@ -1934,11 +1976,6 @@ e100_tx_skb_free(struct e100_private *bdp, tcb_t *tcb)
le16_to_cpu(tbd_arr->tbd_buf_cnt),
PCI_DMA_TODEVICE);
}
#else
pci_unmap_single(bdp->pdev,
le32_to_cpu((tcb->tbd_ptr)->tbd_buf_addr),
tcb->tcb_skb->len, PCI_DMA_TODEVICE);
#endif
dev_kfree_skb_irq(tcb->tcb_skb);
tcb->tcb_skb = NULL;
}
......@@ -2181,7 +2218,6 @@ e100_refresh_txthld(struct e100_private *bdp)
} /* end underrun check */
}
#ifdef E100_ZEROCOPY
/**
* e100_pseudo_hdr_csum - compute IP pseudo-header checksum
* @ip: points to the header of the IP packet
......@@ -2207,7 +2243,6 @@ e100_pseudo_hdr_csum(const struct iphdr *ip)
return FOLD_CSUM(pseudo);
}
#endif /* E100_ZEROCOPY */
/**
* e100_prepare_xmit_buff - prepare a buffer for transmission
......@@ -2247,7 +2282,6 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
tcb->tcb_skb = skb;
#ifdef E100_ZEROCOPY
if (skb->ip_summed == CHECKSUM_HW) {
const struct iphdr *ip = skb->nh.iph;
......@@ -2312,12 +2346,6 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
tcb->tcb_tbd_num = skb_shinfo(skb)->nr_frags + 1;
tcb->tcb_tbd_ptr = tcb->tcb_tbd_expand_ptr;
}
#else
(tcb->tbd_ptr)->tbd_buf_addr =
cpu_to_le32(pci_map_single(bdp->pdev, skb->data,
skb->len, PCI_DMA_TODEVICE));
(tcb->tbd_ptr)->tbd_buf_cnt = cpu_to_le16(skb->len);
#endif
/* clear the S-BIT on the previous tcb */
prev_tcb = bdp->tcb_pool.data;
......@@ -2377,12 +2405,12 @@ e100_start_cu(struct e100_private *bdp, tcb_t *tcb)
// The last command was a non_tx CU command
if (!e100_wait_cus_idle(bdp))
printk(KERN_DEBUG
"%s cu_start: timeout waiting for cu\n",
"e100: %s: cu_start: timeout waiting for cu\n",
bdp->device->name);
if (!e100_wait_exec_cmplx(bdp, (u32) (tcb->tcb_phys),
SCB_CUC_START)) {
printk(KERN_DEBUG
"%s cu_start: timeout waiting for scb\n",
"e100: %s: cu_start: timeout waiting for scb\n",
bdp->device->name);
e100_exec_cmplx(bdp, (u32) (tcb->tcb_phys),
SCB_CUC_START);
......@@ -2498,7 +2526,8 @@ e100_setup_iaaddr(struct e100_private *bdp, u8 *eaddr)
res = e100_exec_non_cu_cmd(bdp, cmd);
if (!res)
printk(KERN_WARNING "%s IA setup failed\n", bdp->device->name);
printk(KERN_WARNING "e100: %s: IA setup failed\n",
bdp->device->name);
exit:
return res;
......@@ -2544,7 +2573,8 @@ e100_start_ru(struct e100_private *bdp)
if (!e100_wait_exec_cmplx(bdp, rx_struct->dma_addr, SCB_RUC_START)) {
printk(KERN_DEBUG
"%s start_ru: wait_scb failed\n", bdp->device->name);
"e100: %s: start_ru: wait_scb failed\n",
bdp->device->name);
e100_exec_cmplx(bdp, rx_struct->dma_addr, SCB_RUC_START);
}
if (bdp->next_cu_cmd == RESUME_NO_WAIT) {
......@@ -3051,8 +3081,10 @@ e100_print_brd_conf(struct e100_private *bdp)
/* Print the string if checksum Offloading was enabled */
if (bdp->flags & DF_CSUM_OFFLOAD)
printk(KERN_NOTICE " Hardware receive checksums enabled\n");
else
printk(KERN_NOTICE " Hardware receive checksums disabled\n");
else {
if (bdp->rev_id >= D101MA_REV_ID)
printk(KERN_NOTICE " Hardware receive checksums disabled\n");
}
if ((bdp->flags & DF_UCODE_LOADED))
printk(KERN_NOTICE " cpu cycle saver enabled\n");
......@@ -3125,9 +3157,8 @@ e100_pci_setup(struct pci_dev *pcid, struct e100_private *bdp)
bdp->scb = (scb_t *) ioremap_nocache(dev->mem_start, sizeof (scb_t));
if (!bdp->scb) {
printk(KERN_ERR "%s - %s: Failed to map PCI address 0x%lX\n",
e100_short_driver_name, dev->name,
pci_resource_start(pcid, 0));
printk(KERN_ERR "e100: %s: Failed to map PCI address 0x%lX\n",
dev->name, pci_resource_start(pcid, 0));
rc = -ENOMEM;
goto err_region;
}
......@@ -3151,6 +3182,13 @@ e100_isolate_driver(struct e100_private *bdp)
del_timer_sync(&bdp->watchdog_timer);
del_timer_sync(&bdp->hwi_timer);
/* If in middle of cable diag, */
if (bdp->hwi_started) {
bdp->hwi_started = 0;
e100_hwi_restore(bdp);
}
if (netif_running(bdp->device))
netif_stop_queue(bdp->device);
......@@ -3218,7 +3256,8 @@ e100_hw_reset_recover(struct e100_private *bdp, u32 reset_cmd)
if (!e100_setup_iaaddr(bdp, bdp->device->dev_addr)) {
printk(KERN_ERR
"e100_hw_reset_recover: setup iaaddr failed\n");
"e100: e100_hw_reset_recover: "
"setup iaaddr failed\n");
return false;
}
......@@ -3248,7 +3287,7 @@ e100_deisolate_driver(struct e100_private *bdp, u8 recover, u8 full_init)
if (full_init) {
e100_sw_reset(bdp, PORT_SOFTWARE_RESET);
if (!e100_hw_reset_recover(bdp, PORT_SOFTWARE_RESET))
printk(KERN_ERR "e100_deisolate_driver:"
printk(KERN_ERR "e100: e100_deisolate_driver:"
" HW SOFTWARE reset recover failed\n");
}
......@@ -3262,7 +3301,7 @@ e100_deisolate_driver(struct e100_private *bdp, u8 recover, u8 full_init)
e100_sw_reset(bdp, PORT_SELECTIVE_RESET);
if (!e100_hw_reset_recover(bdp, PORT_SELECTIVE_RESET)) {
printk(KERN_ERR "e100_deisolate_driver:"
printk(KERN_ERR "e100: e100_deisolate_driver:"
" HW reset recover failed\n");
}
}
......@@ -3285,7 +3324,6 @@ e100_deisolate_driver(struct e100_private *bdp, u8 recover, u8 full_init)
bdp->driver_isolated = false;
}
#ifdef E100_ETHTOOL_IOCTL
static int
e100_do_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
{
......@@ -3302,48 +3340,32 @@ e100_do_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
case ETHTOOL_SSET:
rc = e100_ethtool_set_settings(dev, ifr);
break;
#ifdef ETHTOOL_GDRVINFO
case ETHTOOL_GDRVINFO:
rc = e100_ethtool_get_drvinfo(dev, ifr);
break;
#endif
#ifdef ETHTOOL_NWAY_RST
case ETHTOOL_NWAY_RST:
rc = e100_ethtool_nway_rst(dev, ifr);
break;
#endif
#ifdef ETHTOOL_GLINK
case ETHTOOL_GLINK:
rc = e100_ethtool_glink(dev, ifr);
break;
#endif
#ifdef ETHTOOL_GEEPROM
case ETHTOOL_GEEPROM:
case ETHTOOL_SEEPROM:
rc = e100_ethtool_eeprom(dev, ifr);
break;
#endif
#ifdef ETHTOOL_GWOL
case ETHTOOL_GWOL:
case ETHTOOL_SWOL:
rc = e100_ethtool_wol(dev, ifr);
break;
#endif
#ifdef ETHTOOL_TEST
case ETHTOOL_TEST:
rc = e100_ethtool_test(dev, ifr);
break;
#endif
#ifdef ETHTOOL_GSTRINGS
case ETHTOOL_GSTRINGS:
rc = e100_ethtool_gstrings(dev,ifr);
break;
#endif
#ifdef ETHTOOL_PHYS_ID
case ETHTOOL_PHYS_ID:
rc = e100_ethtool_led_blink(dev,ifr);
break;
#endif
default:
break;
} //switch
......@@ -3382,9 +3404,7 @@ e100_ethtool_get_settings(struct net_device *dev, struct ifreq *ifr)
}
if (bdp->speed_duplex_caps & SUPPORTED_MII) {
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_read(bdp, MII_ADVERTISE, bdp->phy_addr, &advert);
spin_unlock_bh(&(bdp->mdi_access_lock));
if (advert & ADVERTISE_10HALF)
ecmd.advertising |= ADVERTISED_10baseT_Half;
......@@ -3483,7 +3503,6 @@ e100_ethtool_set_settings(struct net_device *dev, struct ifreq *ifr)
return 0;
}
#ifdef ETHTOOL_GLINK
static int
e100_ethtool_glink(struct net_device *dev, struct ifreq *ifr)
{
......@@ -3495,18 +3514,14 @@ e100_ethtool_glink(struct net_device *dev, struct ifreq *ifr)
bdp = dev->priv;
info.cmd = ETHTOOL_GLINK;
spin_lock_bh(&(bdp->mdi_access_lock));
info.data = e100_get_link_state(bdp);
spin_unlock_bh(&(bdp->mdi_access_lock));
if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
return -EFAULT;
return 0;
}
#endif
#ifdef ETHTOOL_TEST
static int
e100_ethtool_test(struct net_device *dev, struct ifreq *ifr)
{
......@@ -3534,9 +3549,7 @@ e100_ethtool_test(struct net_device *dev, struct ifreq *ifr)
kfree(info);
return rc;
}
#endif
#ifdef ETHTOOL_NWAY_RST
static int
e100_ethtool_nway_rst(struct net_device *dev, struct ifreq *ifr)
{
......@@ -3555,9 +3568,7 @@ e100_ethtool_nway_rst(struct net_device *dev, struct ifreq *ifr)
}
return 0;
}
#endif
#ifdef ETHTOOL_GDRVINFO
static int
e100_ethtool_get_drvinfo(struct net_device *dev, struct ifreq *ifr)
{
......@@ -3569,25 +3580,19 @@ e100_ethtool_get_drvinfo(struct net_device *dev, struct ifreq *ifr)
bdp = dev->priv;
strncpy(info.driver, e100_short_driver_name, sizeof (info.driver) - 1);
strncpy(info.version, e100_version, sizeof (info.version) - 1);
strncpy(info.version, e100_driver_version, sizeof (info.version) - 1);
strncpy(info.fw_version, e100_get_brand_msg(bdp),
sizeof (info.fw_version) - 1);
strncpy(info.bus_info, bdp->pdev->slot_name,
sizeof (info.bus_info) - 1);
#ifdef ETHTOOL_GEEPROM
info.eedump_len = (bdp->eeprom_size << 1);
#endif
#ifdef ETHTOOL_TEST
info.testinfo_len = E100_MAX_TEST_RES;
#endif
if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
return -EFAULT;
return 0;
}
#endif //ETHTOOL_GDRVINFO
#ifdef ETHTOOL_GEEPROM
static int
e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr)
{
......@@ -3595,8 +3600,9 @@ e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr)
struct ethtool_eeprom ecmd;
u16 eeprom_data[256];
u16 *usr_eeprom_ptr;
u16 word_length, word_offset;
int i;
u16 first_word, last_word;
int i, max_len;
void *ptr;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
......@@ -3609,48 +3615,56 @@ e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr)
usr_eeprom_ptr =
(u16 *) (ifr->ifr_data + offsetof(struct ethtool_eeprom, data));
word_offset = (ecmd.offset >> 1);
if (word_offset >= bdp->eeprom_size)
return -EFAULT;
max_len = bdp->eeprom_size * 2;
if ((ecmd.offset + ecmd.len) > max_len)
ecmd.len = (max_len - ecmd.offset);
word_length =
min_t(u32, (ecmd.len >> 1), (bdp->eeprom_size - word_offset));
first_word = ecmd.offset >> 1;
last_word = (ecmd.offset + ecmd.len - 1) >> 1;
if (first_word >= bdp->eeprom_size)
return -EFAULT;
if (ecmd.cmd == ETHTOOL_GEEPROM) {
for (i = word_offset; i < (word_length + word_offset); i++)
eeprom_data[i] = e100_eeprom_read(bdp, i);
for(i = 0; i <= (last_word - first_word); i++)
eeprom_data[i] = e100_eeprom_read(bdp, first_word + i);
ecmd.len = (word_length << 1);
ecmd.magic = E100_EEPROM_MAGIC;
if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
return -EFAULT;
if (copy_to_user(usr_eeprom_ptr, &(eeprom_data[word_offset]),
(ecmd.len << 1)))
if (copy_to_user(usr_eeprom_ptr, eeprom_data, ecmd.len))
return -EFAULT;
} else {
if (ecmd.magic != E100_EEPROM_MAGIC)
return -EFAULT;
if (copy_from_user(&(eeprom_data[word_offset]), usr_eeprom_ptr,
(ecmd.len << 1)))
return -EFAULT;
e100_eeprom_write_block(bdp, word_offset,
&(eeprom_data[word_offset]),
word_length);
ptr = (void *)eeprom_data;
if(ecmd.offset & 1) {
/* need modification of first changed EEPROM word */
/* only the second byte of the word is being modified */
eeprom_data[0] = e100_eeprom_read(bdp, first_word);
ptr++;
}
if((ecmd.offset + ecmd.len) & 1) {
/* need modification of last changed EEPROM word */
/* only the first byte of the word is being modified */
eeprom_data[last_word - first_word] =
e100_eeprom_read(bdp, last_word);
}
if(copy_from_user(ptr, usr_eeprom_ptr, ecmd.len))
return -EFAULT;
ecmd.len = (word_length << 1);
e100_eeprom_write_block(bdp, first_word, eeprom_data,
last_word - first_word + 1);
if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
return -EFAULT;
}
return 0;
}
#endif
#ifdef ETHTOOL_PHYS_ID
#define E100_BLINK_INTERVAL (HZ/4)
/**
* e100_led_control
......@@ -3663,12 +3677,9 @@ e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr)
static void
e100_led_control(struct e100_private *bdp, u16 led_mdi_op)
{
spin_lock_bh(&bdp->mdi_access_lock);
e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
bdp->phy_addr, led_mdi_op);
spin_unlock_bh(&bdp->mdi_access_lock);
}
/**
* e100_led_blink_callback
......@@ -3736,7 +3747,6 @@ e100_ethtool_led_blink(struct net_device *dev, struct ifreq *ifr)
return 0;
}
#endif
static inline int __devinit
e100_10BaseT_adapter(struct e100_private *bdp)
......@@ -3785,7 +3795,6 @@ e100_get_speed_duplex_caps(struct e100_private *bdp)
}
#ifdef ETHTOOL_GWOL
static unsigned char
e100_setup_filter(struct e100_private *bdp)
{
......@@ -3818,7 +3827,7 @@ e100_setup_filter(struct e100_private *bdp)
res = e100_exec_non_cu_cmd(bdp, cmd);
if (!res)
printk(KERN_WARNING "%s Filter setup failed\n",
printk(KERN_WARNING "e100: %s: Filter setup failed\n",
bdp->device->name);
exit:
......@@ -3835,9 +3844,9 @@ e100_do_wol(struct pci_dev *pcid, struct e100_private *bdp)
if (bdp->wolopts & (WAKE_UCAST | WAKE_ARP))
if (!e100_setup_filter(bdp))
printk(KERN_ERR
"e100_config WOL options failed\n");
"e100: WOL options failed\n");
} else {
printk(KERN_ERR "e100_config WOL failed\n");
printk(KERN_ERR "e100: config WOL failed\n");
}
}
......@@ -3899,9 +3908,6 @@ e100_ethtool_wol(struct net_device *dev, struct ifreq *ifr)
return res;
}
#endif
#ifdef ETHTOOL_GSTRINGS
static int e100_ethtool_gstrings(struct net_device *dev, struct ifreq *ifr)
{
struct ethtool_gstrings info;
......@@ -3944,10 +3950,7 @@ static int e100_ethtool_gstrings(struct net_device *dev, struct ifreq *ifr)
kfree(strings);
return 0;
}
#endif
#endif /*E100_ETHTOOL_IOCTL */
#ifdef E100_MII_IOCTL
static int
e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
......@@ -3965,10 +3968,8 @@ e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case SIOCGMIIREG:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_read(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr,
&(data_ptr->val_out));
spin_unlock_bh(&(bdp->mdi_access_lock));
break;
case SIOCSMIIREG:
......@@ -3977,10 +3978,8 @@ e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (netif_running(dev)) {
return -EBUSY;
}
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_write(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr,
data_ptr->val_in);
spin_unlock_bh(&(bdp->mdi_access_lock));
break;
default:
......@@ -3988,7 +3987,6 @@ e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
}
return 0;
}
#endif //E100_MII_IOCTL
nxmit_cb_entry_t *
e100_alloc_non_tx_cmd(struct e100_private *bdp)
......@@ -4149,17 +4147,22 @@ e100_non_tx_background(unsigned long ptr)
#ifdef CONFIG_PM
static int
e100_save_state(struct pci_dev *pcid, u32 state)
e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
{
struct net_device *dev;
struct e100_private *bdp;
/* Actually, PCI PM does NOT call this entry */
if (!(dev = (struct net_device *) pci_get_drvdata(pcid)))
return -1;
bdp = dev->priv;
pci_save_state(pcid, bdp->pci_state);
return 0;
struct pci_dev *pdev = NULL;
switch(event) {
case SYS_DOWN:
case SYS_HALT:
case SYS_POWER_OFF:
pci_for_each_dev(pdev) {
if(pci_dev_driver(pdev) == &e100_driver) {
/* If net_device struct is allocated? */
if (pci_get_drvdata(pdev))
e100_suspend(pdev, 3);
}
}
}
return NOTIFY_DONE;
}
static int
......@@ -4169,10 +4172,9 @@ e100_suspend(struct pci_dev *pcid, u32 state)
struct e100_private *bdp = netdev->priv;
e100_isolate_driver(bdp);
e100_save_state(pcid, state);
pci_save_state(pcid, bdp->pci_state);
/* If wol is enabled */
#ifdef ETHTOOL_GWOL
if (bdp->wolopts) {
bdp->ip_lbytes = e100_get_ip_lbytes(netdev);
e100_do_wol(pcid, bdp);
......@@ -4183,10 +4185,6 @@ e100_suspend(struct pci_dev *pcid, u32 state)
pci_disable_device(pcid);
pci_set_power_state(pcid, state);
}
#else
pci_disable_device(pcid);
pci_set_power_state(pcid, state);
#endif
return 0;
}
......@@ -4207,23 +4205,135 @@ e100_resume(struct pci_dev *pcid)
recover = true;
}
#ifdef ETHTOOL_GWOL
if (bdp->wolopts & (WAKE_UCAST | WAKE_ARP)) {
full_init = true;
}
#endif
e100_deisolate_driver(bdp, recover, full_init);
return 0;
}
static int
e100_enable_wake(struct pci_dev *pcid, u32 state, int enable)
#endif /* CONFIG_PM */
static void
e100_get_mdix_status(struct e100_private *bdp)
{
if (bdp->rev_id < D102_REV_ID) {
if (netif_carrier_ok(bdp->device))
bdp->mdix_status = "MDI";
else
bdp->mdix_status = "None";
} else {
u16 ctrl_reg;
/* Read the MDIX control register */
e100_mdi_read(bdp, MII_NCONFIG, bdp->phy_addr, &ctrl_reg);
if (ctrl_reg & MDI_MDIX_CONFIG_IS_OK) {
if (ctrl_reg & MDI_MDIX_STATUS)
bdp->mdix_status = "MDI-X";
else
bdp->mdix_status = "MDI";
} else
bdp->mdix_status = "None";
}
}
static void
e100_do_hwi(struct net_device *dev)
{
/* Driver doesn't need to do anything because it will enable */
/* wol when suspended. */
/* Actually, PCI PM does NOT call this entry. */
return 0;
struct e100_private *bdp = dev->priv;
u16 ctrl_reg;
int distance, open_circut, short_circut;
e100_mdi_read(bdp, HWI_CONTROL_REG, bdp->phy_addr, &ctrl_reg);
distance = ctrl_reg & HWI_TEST_DISTANCE;
open_circut = ctrl_reg & HWI_TEST_HIGHZ_PROBLEM;
short_circut = ctrl_reg & HWI_TEST_LOWZ_PROBLEM;
if ((distance == bdp->saved_distance) &&
(open_circut == bdp->saved_open_circut) &&
(short_circut == bdp->saved_short_circut))
bdp->saved_same++;
else {
bdp->saved_same = 0;
bdp->saved_distance = distance;
bdp->saved_open_circut = open_circut;
bdp->saved_short_circut = short_circut;
}
if (bdp->saved_same == MAX_SAME_RESULTS) {
if ((open_circut && !(short_circut)) ||
(!(open_circut) && short_circut)) {
u8 near_end = ((distance * HWI_REGISTER_GRANULARITY) <
HWI_NEAR_END_BOUNDARY);
if (open_circut) {
if (near_end)
bdp->cable_status = "Open Circut Near End";
else
bdp->cable_status = "Open Circut Far End";
} else {
if (near_end)
bdp->cable_status = "Short Circut Near End";
else
bdp->cable_status = "Short Circut Far End";
}
goto done;
}
}
else if (bdp->saved_i == HWI_MAX_LOOP) {
bdp->cable_status = "Test failed";
goto done;
}
/* Do another hwi test */
e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
(HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
bdp->saved_i++;
/* relaunch hwi timer in 1 msec */
mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) );
return;
done:
e100_hwi_restore(bdp);
bdp->hwi_started = 0;
return;
}
static void e100_hwi_restore(struct e100_private *bdp)
{
u16 control = 0;
/* Restore speed, duplex and autoneg before */
/* hwi test, i.e., cable diagnostic */
/* Reset hwi test */
e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr, HWI_RESET_ALL_MASK);
if ((bdp->params.e100_speed_duplex == E100_AUTONEG) &&
(bdp->rev_id >= D102_REV_ID))
/* Enable MDI/MDI-X auto switching */
e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
MDI_MDIX_AUTO_SWITCH_ENABLE);
switch (bdp->params.e100_speed_duplex) {
case E100_SPEED_10_HALF:
break;
case E100_SPEED_10_FULL:
control = BMCR_FULLDPLX;
break;
case E100_SPEED_100_HALF:
control = BMCR_SPEED100;
break;
case E100_SPEED_100_FULL:
control = BMCR_SPEED100 | BMCR_FULLDPLX;
break;
case E100_AUTONEG:
control = BMCR_ANENABLE | BMCR_ANRESTART;
break;
}
/* Restore original speed/duplex */
e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control);
return;
}
#endif /* CONFIG_PM */
......@@ -96,9 +96,11 @@ e100_mdi_write(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 data)
int e100_retry;
u32 temp_val;
spin_lock_bh(&bdp->mdi_access_lock);
temp_val = (((u32) data) | (reg_addr << 16) |
(phy_addr << 21) | (MDI_WRITE << 26));
writel(temp_val, &bdp->scb->scb_mdi_cntrl);
readw(&bdp->scb->scb_status);
/* wait 20usec before checking status */
udelay(20);
......@@ -111,6 +113,7 @@ e100_mdi_write(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 data)
udelay(20);
e100_retry--;
}
spin_unlock_bh(&bdp->mdi_access_lock);
}
/*
......@@ -138,9 +141,11 @@ e100_mdi_read(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 *data)
int e100_retry;
u32 temp_val;
spin_lock_bh(&bdp->mdi_access_lock);
/* Issue the read command to the MDI control register. */
temp_val = ((reg_addr << 16) | (phy_addr << 21) | (MDI_READ << 26));
writel(temp_val, &bdp->scb->scb_mdi_cntrl);
readw(&bdp->scb->scb_status);
/* wait 20usec before checking status */
udelay(20);
......@@ -156,6 +161,7 @@ e100_mdi_read(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 *data)
// return the lower word
*data = (u16) readl(&bdp->scb->scb_mdi_cntrl);
spin_unlock_bh(&bdp->mdi_access_lock);
}
static unsigned char __devinit
......@@ -263,21 +269,22 @@ e100_phy_specific_setup(struct e100_private *bdp)
case E100_AUTONEG:
/* The adapter can't autoneg. so set to 10/HALF */
printk(KERN_INFO
"503 serial component detected which "
"e100: 503 serial component detected which "
"cannot autonegotiate\n");
printk(KERN_INFO
"speed/duplex forced to 10Mbps / Half duplex\n");
"e100: speed/duplex forced to "
"10Mbps / Half duplex\n");
bdp->params.e100_speed_duplex = E100_SPEED_10_HALF;
break;
case E100_SPEED_100_HALF:
case E100_SPEED_100_FULL:
printk(KERN_ERR
"503 serial component detected which does not "
"support 100Mbps\n");
"e100: 503 serial component detected "
"which does not support 100Mbps\n");
printk(KERN_ERR
"Change the forced speed/duplex to a supported "
"setting\n");
"e100: Change the forced speed/duplex "
"to a supported setting\n");
return false;
}
......@@ -294,7 +301,7 @@ e100_phy_specific_setup(struct e100_private *bdp)
if ((bdp->params.e100_speed_duplex != E100_AUTONEG) &&
(bdp->params.e100_speed_duplex != E100_SPEED_100_FULL)) {
/* just inform user about 100 full */
printk(KERN_ERR "NC3133 NIC can only run "
printk(KERN_ERR "e100: NC3133 NIC can only run "
"at 100Mbps full duplex\n");
}
......@@ -657,8 +664,6 @@ e100_force_speed_duplex(struct e100_private *bdp)
bdp->flags |= DF_SPEED_FORCED;
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &control);
control &= ~BMCR_ANENABLE;
......@@ -702,14 +707,10 @@ e100_force_speed_duplex(struct e100_private *bdp)
time_after(jiffies, expires)) {
break;
} else {
spin_unlock_bh(&(bdp->mdi_access_lock));
yield();
spin_lock_bh(&(bdp->mdi_access_lock));
}
} while (true);
spin_unlock_bh(&(bdp->mdi_access_lock));
}
/*
......@@ -753,7 +754,12 @@ e100_set_fc(struct e100_private *bdp)
if (ad_reg & NWAY_AD_FC_SUPPORTED)
bdp->flags |= DF_LINK_FC_CAP;
else
bdp->flags &= ~DF_LINK_FC_CAP;
/* If link partner is capable of autoneg, but */
/* not capable of flow control, Received PAUSE */
/* frames are still honored, i.e., */
/* transmitted frames would be paused */
/* by incoming PAUSE frames */
bdp->flags |= DF_LINK_FC_TX_ONLY;
} else {
bdp->flags &= ~DF_LINK_FC_CAP;
......@@ -821,8 +827,6 @@ e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
bdp->flags &= ~DF_SPEED_FORCED;
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
......@@ -848,25 +852,30 @@ e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
time_after(jiffies, expires) ) {
goto exit;
} else {
spin_unlock_bh(&(bdp->mdi_access_lock));
yield();
spin_lock_bh(&(bdp->mdi_access_lock));
}
} while (true);
}
exit:
e100_find_speed_duplex(bdp);
spin_unlock_bh(&(bdp->mdi_access_lock));
}
void
e100_phy_set_speed_duplex(struct e100_private *bdp, unsigned char force_restart)
{
if (bdp->params.e100_speed_duplex == E100_AUTONEG) {
if (bdp->rev_id >= D102_REV_ID)
/* Enable MDI/MDI-X auto switching */
e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
MDI_MDIX_AUTO_SWITCH_ENABLE);
e100_auto_neg(bdp, force_restart);
} else {
if (bdp->rev_id >= D102_REV_ID)
/* Disable MDI/MDI-X auto switching */
e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
MDI_MDIX_RESET_ALL_MASK);
e100_force_speed_duplex(bdp);
}
......
......@@ -124,6 +124,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define NSC_CONG_CONTROL_REG 0x17 /* National (TX) congestion control */
#define NSC_SPEED_IND_REG 0x19 /* National (TX) speed indication */
#define HWI_CONTROL_REG 0x1D /* HWI Control register */
/* MDI/MDI-X Control Register bit definitions */
#define MDI_MDIX_RES_TIMER BIT_0_3 /* minimum slot time for resolution timer */
#define MDI_MDIX_CONFIG_IS_OK BIT_4 /* 1 = resolution algorithm completes OK */
#define MDI_MDIX_STATUS BIT_5 /* 1 = MDIX (croos over), 0 = MDI (straight through) */
#define MDI_MDIX_SWITCH BIT_6 /* 1 = Forces to MDIX, 0 = Forces to MDI */
#define MDI_MDIX_AUTO_SWITCH_ENABLE BIT_7 /* 1 = MDI/MDI-X feature enabled */
#define MDI_MDIX_CONCT_CONFIG BIT_8 /* Sets the MDI/MDI-X connectivity configuration (test prupose only) */
#define MDI_MDIX_CONCT_TEST_ENABLE BIT_9 /* 1 = Enables connectivity testing */
#define MDI_MDIX_RESET_ALL_MASK 0x0000
/* HWI Control Register bit definitions */
#define HWI_TEST_DISTANCE BIT_0_8 /* distance to cable problem */
#define HWI_TEST_HIGHZ_PROBLEM BIT_9 /* 1 = Open Circuit */
#define HWI_TEST_LOWZ_PROBLEM BIT_10 /* 1 = Short Circuit */
#define HWI_TEST_RESERVED (BIT_11 | BIT_12) /* reserved */
#define HWI_TEST_EXECUTE BIT_13 /* 1 = Execute the HWI test on the PHY */
#define HWI_TEST_ABILITY BIT_14 /* 1 = test passed */
#define HWI_TEST_ENABLE BIT_15 /* 1 = Enables the HWI feature */
#define HWI_RESET_ALL_MASK 0x0000
/* ############Start of 82555 specific defines################## */
/* Intel 82555 specific registers */
......
......@@ -91,11 +91,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <linux/config.h>
#ifndef CONFIG_PROC_FS
#undef E100_CONFIG_PROC_FS
#endif
#ifdef E100_CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
#include "e100.h"
/* MDI sleep time is at least 50 ms, in jiffies */
#define MDI_SLEEP_TIME ((HZ / 20) + 1)
......@@ -106,8 +102,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static struct proc_dir_entry *adapters_proc_dir = 0;
/* externs from e100_main.c */
extern const char *e100_short_driver_name;
extern const char *e100_version;
extern char e100_short_driver_name[];
extern char e100_driver_version[];
extern struct net_device_stats *e100_get_stats(struct net_device *dev);
extern char *e100_get_brand_msg(struct e100_private *bdp);
extern void e100_mdi_write(struct e100_private *, u32, u32, u16);
......@@ -115,8 +111,6 @@ extern void e100_mdi_write(struct e100_private *, u32, u32, u16);
static void e100_proc_cleanup(void);
static unsigned char e100_init_proc_dir(void);
#define E100_EOU
#define ADAPTERS_PROC_DIR "PRO_LAN_Adapters"
#define WRITE_BUF_MAX_LEN 20
#define READ_BUF_MAX_LEN 256
......@@ -191,7 +185,7 @@ read_descr(char *page, char **start, off_t off, int count, int *eof, void *data)
struct e100_private *bdp = data;
int len;
len = sprintf(page, "%s\n", e100_get_brand_msg(bdp));
len = sprintf(page, "%s\n", bdp->id_string);
return generic_read(page, start, off, count, eof, len);
}
......@@ -223,23 +217,15 @@ read_part_number(char *page, char **start, off_t off,
static void
set_led(struct e100_private *bdp, u16 led_mdi_op)
{
spin_lock_bh(&bdp->mdi_access_lock);
e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
bdp->phy_addr, led_mdi_op);
spin_unlock_bh(&bdp->mdi_access_lock);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(MDI_SLEEP_TIME);
spin_lock_bh(&bdp->mdi_access_lock);
/* turn led ownership to the chip */
e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
bdp->phy_addr, PHY_82555_LED_NORMAL_CONTROL);
spin_unlock_bh(&bdp->mdi_access_lock);
}
static int
......@@ -350,335 +336,6 @@ read_info(char *page, char **start, off_t off, int count, int *eof, void *data)
return generic_read(page, start, off, count, eof, len);
}
#ifdef E100_EOU
/**********************
* parameter entries
**********************/
static int
read_int_param(char *page, char *name, char *desc, int def, int min, int max)
{
int len;
len = sprintf(page, "Name: %s\n", name);
len += sprintf(page + len, "Description: %s\n", desc);
len += sprintf(page + len, "Default_Value: %d\n", def);
len += sprintf(page + len, "Type: Range\n");
len += sprintf(page + len, "Min: %d\n", min);
len += sprintf(page + len, "Max: %d\n", max);
len += sprintf(page + len, "Step:1\n");
len += sprintf(page + len, "Radix: dec\n");
return len;
}
static int
read_bool_param(char *page, char *name, char *desc, int def)
{
int len;
len = sprintf(page, "Name: %s\n", name);
len += sprintf(page + len, "Description: %s\n", desc);
len += sprintf(page + len, "Default_Value: %d\n", def);
len += sprintf(page + len, "Type: Enum\n");
len += sprintf(page + len, "0: Off\n");
len += sprintf(page + len, "1: On\n");
return len;
}
static int
read_speed_duplex_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = sprintf(page, "Name: Speed and Duplex\n");
len += sprintf(page + len, "Description: Sets the adapter's "
"speed and duplex mode\n");
len += sprintf(page + len, "Default_Value: 0\n");
len += sprintf(page + len, "Type: Enum\n");
len += sprintf(page + len, "0: Auto-Negotiate\n");
len += sprintf(page + len, "1: 10 Mbps / Half Duplex\n");
len += sprintf(page + len, "2: 10 Mbps / Full Duplex\n");
len += sprintf(page + len, "3: 100 Mbps / Half Duplex\n");
len += sprintf(page + len, "4: 100 Mbps / Full Duplex\n");
return generic_read(page, start, off, count, eof, len);
}
static int
read_tx_desc_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_int_param(page, "Transmit Descriptors",
"Sets the number of Tx descriptors "
"available for the adapter",
E100_DEFAULT_TCB, E100_MIN_TCB, E100_MAX_TCB);
return generic_read(page, start, off, count, eof, len);
}
static int
read_rx_desc_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_int_param(page, "Receive Descriptors",
"Sets the number of Rx descriptors "
"available for the adapter",
E100_DEFAULT_RFD, E100_MIN_RFD, E100_MAX_RFD);
return generic_read(page, start, off, count, eof, len);
}
static int
read_ber_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_int_param(page, "Bit Error Rate",
"Sets the value for the BER correction algorithm",
E100_DEFAULT_BER, 0, ZLOCK_MAX_ERRORS);
return generic_read(page, start, off, count, eof, len);
}
static int
read_xsum_rx_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_bool_param(page, "RX Checksum",
"Setting this value to \"On\" enables "
"receive checksum", E100_DEFAULT_XSUM);
return generic_read(page, start, off, count, eof, len);
}
static int
read_ucode_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_bool_param(page, "Microcode",
"Setting this value to \"On\" enables "
"the adapter's microcode", E100_DEFAULT_UCODE);
return generic_read(page, start, off, count, eof, len);
}
static int
read_bundle_small_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_bool_param(page, "Bundle Small Frames",
"Setting this value to \"On\" enables "
"interrupt bundling of small frames",
E100_DEFAULT_BUNDLE_SMALL_FR);
return generic_read(page, start, off, count, eof, len);
}
static int
read_fc_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_bool_param(page, "Flow Control",
"Setting this value to \"On\" enables processing "
"flow-control packets", E100_DEFAULT_FC);
return generic_read(page, start, off, count, eof, len);
}
static int
read_rcv_cong_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_bool_param(page, "Receive Congestion Control",
"Setting this value to \"On\" enables switching "
"to polling mode on receive",
E100_DEFAULT_RX_CONGESTION_CONTROL);
return generic_read(page, start, off, count, eof, len);
}
static int
read_poll_max_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct e100_private *bdp = data;
int len;
len = read_int_param(page, "Maximum Polling Work",
"Sets the max number of RX packets processed"
" by single polling function call",
bdp->params.RxDescriptors, 1, E100_MAX_RFD);
return generic_read(page, start, off, count, eof, len);
}
static int
read_int_delay_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_int_param(page, "CPU Saver Interrupt Delay",
"Sets the value for CPU saver's interrupt delay",
E100_DEFAULT_CPUSAVER_INTERRUPT_DELAY, 0x0,
0xFFFF);
return generic_read(page, start, off, count, eof, len);
}
static int
read_bundle_max_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_int_param(page, "CPU Saver Maximum Bundle",
"Sets CPU saver's maximum value",
E100_DEFAULT_CPUSAVER_BUNDLE_MAX, 0x1, 0xFFFF);
return generic_read(page, start, off, count, eof, len);
}
static int
read_ifs_def(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = read_bool_param(page, "IFS",
"Setting this value to \"On\" enables "
"the adaptive IFS algorithm", E100_DEFAULT_IFS);
return generic_read(page, start, off, count, eof, len);
}
static int
read_xsum_rx_val(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct e100_private *bdp = data;
unsigned long val;
val = (bdp->params.b_params & PRM_XSUMRX) ? 1 : 0;
return read_ulong(page, start, off, count, eof, val);
}
static int
read_ucode_val(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct e100_private *bdp = data;
unsigned long val;
val = (bdp->params.b_params & PRM_UCODE) ? 1 : 0;
return read_ulong(page, start, off, count, eof, val);
}
static int
read_fc_val(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct e100_private *bdp = data;
unsigned long val;
val = (bdp->params.b_params & PRM_FC) ? 1 : 0;
return read_ulong(page, start, off, count, eof, val);
}
static int
read_ifs_val(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct e100_private *bdp = data;
unsigned long val;
val = (bdp->params.b_params & PRM_IFS) ? 1 : 0;
return read_ulong(page, start, off, count, eof, val);
}
static int
read_bundle_small_val(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct e100_private *bdp = data;
unsigned long val;
val = (bdp->params.b_params & PRM_BUNDLE_SMALL) ? 1 : 0;
return read_ulong(page, start, off, count, eof, val);
}
static int
read_rcv_cong_val(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct e100_private *bdp = data;
unsigned long val;
val = (bdp->params.b_params & PRM_RX_CONG) ? 1 : 0;
return read_ulong(page, start, off, count, eof, val);
}
static int
read_gen_prm(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int val = 0;
if (data)
val = *((int *) data);
return read_ulong(page, start, off, count, eof, (unsigned long) val);
}
static e100_proc_entry e100_proc_params[] = {
/* definitions */
{"e100_speed_duplex.def", read_speed_duplex_def, 0, 0},
{"RxDescriptors.def", read_rx_desc_def, 0, 0},
{"TxDescriptors.def", read_tx_desc_def, 0, 0},
{"XsumRX.def", read_xsum_rx_def, 0, 0},
{"ucode.def", read_ucode_def, 0, 0},
{"BundleSmallFr.def", read_bundle_small_def, 0, 0},
{"IntDelay.def", read_int_delay_def, 0, 0},
{"BundleMax.def", read_bundle_max_def, 0, 0},
{"ber.def", read_ber_def, 0, 0},
{"flow_control.def", read_fc_def, 0, 0},
{"IFS.def", read_ifs_def, 0, 0},
{"RxCongestionControl.def", read_rcv_cong_def, 0, 0},
{"PollingMaxWork.def", read_poll_max_def, 0, 0},
/* values */
{"e100_speed_duplex.val", read_gen_prm, 0, bdp_prm_off(e100_speed_duplex)},
{"RxDescriptors.val", read_gen_prm, 0, bdp_prm_off(RxDescriptors)},
{"TxDescriptors.val", read_gen_prm, 0, bdp_prm_off(TxDescriptors)},
{"XsumRX.val", read_xsum_rx_val, 0, 0},
{"ucode.val", read_ucode_val, 0, 0},
{"BundleSmallFr.val", read_bundle_small_val, 0, 0},
{"IntDelay.val", read_gen_prm, 0, bdp_prm_off(IntDelay)},
{"BundleMax.val", read_gen_prm, 0, bdp_prm_off(BundleMax)},
{"ber.val", read_gen_prm, 0, bdp_prm_off(ber)},
{"flow_control.val", read_fc_val, 0, 0},
{"IFS.val", read_ifs_val, 0, 0},
{"RxCongestionControl.val", read_rcv_cong_val, 0, 0},
{"PollingMaxWork.val", read_gen_prm, 0, bdp_prm_off(PollingMaxWork)},
{"", 0, 0, 0}
};
#endif /* E100_EOU */
static struct proc_dir_entry * __devinit
create_proc_rw(char *name, void *data, struct proc_dir_entry *parent,
read_proc_t * read_proc, write_proc_t * write_proc)
......@@ -705,58 +362,6 @@ create_proc_rw(char *name, void *data, struct proc_dir_entry *parent,
return pdep;
}
#ifdef E100_EOU
static int __devinit
create_proc_param_subdir(struct e100_private *bdp,
struct proc_dir_entry *dev_dir)
{
struct proc_dir_entry *param_dir;
e100_proc_entry *pe;
void *data;
param_dir = create_proc_entry("LoadParameters", S_IFDIR, dev_dir);
if (!param_dir)
return -ENOMEM;
for (pe = e100_proc_params; pe->name[0]; pe++) {
data = ((char *) bdp) + pe->offset;
if (!(create_proc_rw(pe->name, data, param_dir,
pe->read_proc, pe->write_proc))) {
return -ENOMEM;
}
}
return 0;
}
static void
remove_proc_param_subdir(struct proc_dir_entry *parent)
{
struct proc_dir_entry *de;
e100_proc_entry *pe;
int len;
len = strlen("LoadParameters");
for (de = parent->subdir; de; de = de->next) {
if ((de->namelen == len) &&
(!memcmp(de->name, "LoadParameters", len)))
break;
}
if (!de)
return;
for (pe = e100_proc_params; pe->name[0]; pe++) {
remove_proc_entry(pe->name, de);
}
remove_proc_entry("LoadParameters", parent);
}
#endif /* E100_EOU */
void
e100_remove_proc_subdir(struct e100_private *bdp)
{
......@@ -781,9 +386,6 @@ e100_remove_proc_subdir(struct e100_private *bdp)
remove_proc_entry(pe->name, bdp->proc_parent);
}
#ifdef E100_EOU
remove_proc_param_subdir(bdp->proc_parent);
#endif
remove_proc_entry(bdp->device->name, adapters_proc_dir);
bdp->proc_parent = NULL;
}
......@@ -844,13 +446,6 @@ e100_create_proc_subdir(struct e100_private *bdp)
}
}
#ifdef E100_EOU
if (create_proc_param_subdir(bdp, dev_dir)) {
e100_remove_proc_subdir(bdp);
return -ENOMEM;
}
#endif
return 0;
}
......
......@@ -72,7 +72,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "e100.h"
#include "e100_config.h"
#ifdef ETHTOOL_TEST
extern u16 e100_eeprom_read(struct e100_private *, u16);
extern int e100_wait_exec_cmplx(struct e100_private *, u32,u8);
......@@ -380,11 +379,11 @@ e100_diag_loopback_cu_ru_exec(struct e100_private *bdp)
{
/*load CU & RU base */
if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE))
printk("@@@ SCB_CUC_LOAD_BASE failed\n");
printk("e100: SCB_CUC_LOAD_BASE failed\n");
if(!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE))
printk("@@@ SCB_RUC_LOAD_BASE failed!\n");
printk("e100: SCB_RUC_LOAD_BASE failed!\n");
if(!e100_wait_exec_cmplx(bdp, bdp->loopback.dma_handle, SCB_RUC_START))
printk("@@@ SCB_RUC_START failed!\n");
printk("e100: SCB_RUC_START failed!\n");
bdp->next_cu_cmd = START_WAIT;
e100_start_cu(bdp, bdp->loopback.tcb);
......@@ -457,5 +456,3 @@ e100_diag_loopback_free (struct e100_private *bdp)
bdp->loopback.dma_handle);
}
#endif
......@@ -125,6 +125,7 @@ enum e100_device_type {
E100_82559_LOM,
E100_82559_LOM_AOL,
E100_82559_LOM_AOL2,
E100_82559_LOM_DELL,
E100_IBM_MDS,
E100_CMPQ_S,
E100_PROVE_DA,
......@@ -132,7 +133,8 @@ enum e100_device_type {
E100_PROVE_LOM,
E100_PROVE_NET,
E100_82562,
E100_ALL_BOARDS,
E100_82551QM,
E100_ALL_BOARDS
};
struct e100_vendor_info e100_vendor_info_array[] = {
......@@ -147,6 +149,7 @@ struct e100_vendor_info e100_vendor_info_array[] = {
{ E100_BRD_100, "Intel(R) PRO/100+ PCI Adapter"},
{ E100_BRD_100M, "Intel(R) PRO/100+ Management Adapter"},
{ E100_BRD_AOL2, "Intel(R) PRO/100+ Alert on LAN* 2 Management Adapter"},
{ E100_82559_LOM_DELL, "Intel(R) 8255x Based Network Connection"},
{ E100_BRD_AOL, "Intel(R) PRO/100+ Alert on LAN* Management Adapter"},
{ E100_PROS_M, "Intel(R) PRO/100 S Management Adapter"},
{ E100_PROS_AM, "Intel(R) PRO/100 S Advanced Management Adapter"},
......@@ -186,6 +189,7 @@ struct e100_vendor_info e100_vendor_info_array[] = {
{ E100_PROVE_LOM, "Intel(R) PRO/100 VE Network ConnectionPLC LOM" },
{ E100_PROVE_NET, "Intel(R) PRO/100 VE Network Connection"},
{ E100_82562, "Intel(R)82562 based Fast Ethernet Connection"},
{ E100_82551QM, "Intel(R) PRO/100 M Mobile Connection"},
{ E100_ALL_BOARDS, "Intel(R) 8255x-based Ethernet Adapter"},
{0,NULL}
};
......@@ -309,6 +313,7 @@ static struct pci_device_id e100_id_table[] __devinitdata = {
{0x8086, 0x1229, 0x0E11, 0xB144, 0, 0, E100_CMPQ_S},
{0x8086, 0x1229, 0x0E11, 0xB163, 0, 0, E100_CMPQ_S},
{0x8086, 0x1229, 0x0E11, 0xB164, 0, 0, E100_CMPQ_S},
{0x8086, 0x1229, 0x1028, PCI_ANY_ID, 0, 0, E100_82559_LOM_DELL},
{0x8086, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
{0x8086, 0x2449, 0x1014, 0x0265, 0, 0, E100_PROVE_D},
......@@ -324,7 +329,11 @@ static struct pci_device_id e100_id_table[] __devinitdata = {
{0x8086, 0x2449, 0x0E11, PCI_ANY_ID, 0, 0, E100_PROVM_NET},
{0x8086, 0x2449, 0x1014, PCI_ANY_ID, 0, 0, E100_PROVE_D},
{0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
{0x8086, 0x1059, 0x1179, 0x0005, 0, 0, E100_82551QM},
{0x8086, 0x1059, 0x1033, 0x8191, 0, 0, E100_82551QM},
{0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_82551QM},
{0x8086, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
{0x8086, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
{0x8086, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
......
......@@ -109,11 +109,11 @@
#include <linux/list.h>
#include <linux/reboot.h>
#include <linux/ethtool.h>
#ifdef NETIF_F_HW_VLAN_TX
#include <linux/if_vlan.h>
#endif
#define BAR_0 0
#define BAR_1 1
#define BAR_5 5
#define PCI_DMA_64BIT 0xffffffffffffffffULL
#define PCI_DMA_32BIT 0x00000000ffffffffULL
......@@ -150,6 +150,8 @@ struct e1000_adapter;
#define E1000_JUMBO_PBA 0x00000028
#define E1000_DEFAULT_PBA 0x00000030
#define AUTO_ALL_MODES 0
/* only works for sizes that are powers of 2 */
#define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
......@@ -195,9 +197,7 @@ struct e1000_adapter {
#ifdef CONFIG_PROC_FS
struct list_head proc_list_head;
#endif
#ifdef NETIF_F_HW_VLAN_TX
struct vlan_group *vlgrp;
#endif
char *id_string;
uint32_t bd_number;
uint32_t rx_buffer_len;
......@@ -208,10 +208,8 @@ struct e1000_adapter {
spinlock_t stats_lock;
atomic_t irq_sem;
#ifdef ETHTOOL_PHYS_ID
struct timer_list blink_timer;
unsigned long led_status;
#endif
/* TX */
struct e1000_desc_ring tx_ring;
......
......@@ -249,17 +249,70 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
{
struct e1000_hw *hw = &adapter->hw;
int i, max_len;
int i, max_len, first_word, last_word;
if(eeprom->len == 0) return;
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
max_len = e1000_eeprom_size(hw);
if ((eeprom->offset + eeprom->len) > max_len)
if((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
for(i = 0; i < (max_len >> 1); i++)
e1000_read_eeprom(&adapter->hw, i, &eeprom_buff[i]);
first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
for(i = 0; i <= (last_word - first_word); i++)
e1000_read_eeprom(hw, first_word + i, &eeprom_buff[i]);
}
static int
e1000_ethtool_seeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, void *user_data)
{
struct e1000_hw *hw = &adapter->hw;
uint16_t eeprom_buff[256];
int i, max_len, first_word, last_word;
void *ptr;
if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT;
if(eeprom->len == 0) return 0;
max_len = e1000_eeprom_size(hw);
if((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
ptr = (void *)eeprom_buff;
if(eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
e1000_read_eeprom(hw, first_word, &eeprom_buff[0]);
ptr++;
}
if((eeprom->offset + eeprom->len) & 1) {
/* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */
e1000_read_eeprom(hw, last_word,
&eeprom_buff[last_word - first_word]);
}
if(copy_from_user(ptr, user_data, eeprom->len))
return -EFAULT;
for(i = 0; i <= (last_word - first_word); i++)
e1000_write_eeprom(hw, first_word + i, eeprom_buff[i]);
/* Update the checksum over the first part of the EEPROM if needed */
if(first_word <= EEPROM_CHECKSUM_REG)
e1000_update_eeprom_checksum(hw);
return 0;
}
static void
......@@ -339,7 +392,7 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
case E1000_DEV_ID_82545EM_COPPER:
case E1000_DEV_ID_82545EM_FIBER:
case E1000_DEV_ID_82546EB_COPPER:
if(wol->wolopts & WAKE_ARP)
if(wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
return -EOPNOTSUPP;
adapter->wol = 0;
......@@ -359,7 +412,6 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
return 0;
}
#ifdef ETHTOOL_PHYS_ID
/* toggle LED 4 times per second = 2 "blinks" per second */
#define E1000_ID_INTERVAL (HZ/4)
......@@ -405,7 +457,6 @@ e1000_ethtool_led_blink(struct e1000_adapter *adapter, struct ethtool_value *id)
return 0;
}
#endif /* ETHTOOL_PHYS_ID */
int
e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
......@@ -463,14 +514,12 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
e1000_up(adapter);
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: {
struct ethtool_value link = {ETHTOOL_GLINK};
link.data = netif_carrier_ok(netdev);
......@@ -496,6 +545,7 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
case ETHTOOL_GEEPROM: {
struct ethtool_eeprom eeprom = {ETHTOOL_GEEPROM};
uint16_t eeprom_buff[256];
void *ptr;
if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
return -EFAULT;
......@@ -506,11 +556,24 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
return -EFAULT;
addr += offsetof(struct ethtool_eeprom, data);
ptr = ((void *)eeprom_buff) + (eeprom.offset & 1);
if(copy_to_user(addr, eeprom_buff + eeprom.offset, eeprom.len))
if(copy_to_user(addr, ptr, eeprom.len))
return -EFAULT;
return 0;
}
case ETHTOOL_SEEPROM: {
struct ethtool_eeprom eeprom;
if(!capable(CAP_NET_ADMIN))
return -EPERM;
if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
return -EFAULT;
addr += offsetof(struct ethtool_eeprom, data);
return e1000_ethtool_seeprom(adapter, &eeprom, addr);
}
default:
return -EOPNOTSUPP;
}
......
......@@ -107,17 +107,13 @@ e1000_reset_hw(struct e1000_hw *hw)
uint32_t ctrl_ext;
uint32_t icr;
uint32_t manc;
uint16_t pci_cmd_word;
DEBUGFUNC("e1000_reset_hw");
/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
if(hw->mac_type == e1000_82542_rev2_0) {
if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
pci_cmd_word = hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;
e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &pci_cmd_word);
}
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
e1000_pci_clear_mwi(hw);
}
/* Clear interrupt mask to stop board from generating interrupts */
......@@ -130,6 +126,7 @@ e1000_reset_hw(struct e1000_hw *hw)
*/
E1000_WRITE_REG(hw, RCTL, 0);
E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
E1000_WRITE_FLUSH(hw);
/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
hw->tbi_compatibility_on = FALSE;
......@@ -146,7 +143,11 @@ e1000_reset_hw(struct e1000_hw *hw)
*/
DEBUGOUT("Issuing a global reset to MAC\n");
ctrl = E1000_READ_REG(hw, CTRL);
E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
if(hw->mac_type > e1000_82543)
E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
else
E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
/* Force a reload from the EEPROM if necessary */
if(hw->mac_type < e1000_82540) {
......@@ -155,6 +156,7 @@ e1000_reset_hw(struct e1000_hw *hw)
ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
ctrl_ext |= E1000_CTRL_EXT_EE_RST;
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
/* Wait for EEPROM reload */
msec_delay(2);
} else {
......@@ -176,7 +178,7 @@ e1000_reset_hw(struct e1000_hw *hw)
/* If MWI was previously enabled, reenable it. */
if(hw->mac_type == e1000_82542_rev2_0) {
if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &hw->pci_cmd_word);
e1000_pci_set_mwi(hw);
}
}
......@@ -197,7 +199,6 @@ e1000_init_hw(struct e1000_hw *hw)
uint32_t ctrl, status;
uint32_t i;
int32_t ret_val;
uint16_t pci_cmd_word;
uint16_t pcix_cmd_word;
uint16_t pcix_stat_hi_word;
uint16_t cmd_mmrbc;
......@@ -240,12 +241,10 @@ e1000_init_hw(struct e1000_hw *hw)
/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
if(hw->mac_type == e1000_82542_rev2_0) {
if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
pci_cmd_word = hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;
e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &pci_cmd_word);
}
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
e1000_pci_clear_mwi(hw);
E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
E1000_WRITE_FLUSH(hw);
msec_delay(5);
}
......@@ -257,9 +256,10 @@ e1000_init_hw(struct e1000_hw *hw)
/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
if(hw->mac_type == e1000_82542_rev2_0) {
E1000_WRITE_REG(hw, RCTL, 0);
E1000_WRITE_FLUSH(hw);
msec_delay(1);
if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &hw->pci_cmd_word);
e1000_pci_set_mwi(hw);
}
/* Zero out the Multicast HASH table */
......@@ -505,6 +505,7 @@ e1000_setup_fiber_link(struct e1000_hw *hw)
E1000_WRITE_REG(hw, TXCW, txcw);
E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw);
hw->txcw = txcw;
msec_delay(1);
......@@ -1118,6 +1119,7 @@ e1000_config_collision_dist(struct e1000_hw *hw)
tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
E1000_WRITE_REG(hw, TCTL, tctl);
E1000_WRITE_FLUSH(hw);
}
/******************************************************************************
......@@ -1715,6 +1717,7 @@ e1000_raise_mdi_clk(struct e1000_hw *hw,
* bit), and then delay 2 microseconds.
*/
E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
E1000_WRITE_FLUSH(hw);
usec_delay(2);
}
......@@ -1732,6 +1735,7 @@ e1000_lower_mdi_clk(struct e1000_hw *hw,
* bit), and then delay 2 microseconds.
*/
E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
E1000_WRITE_FLUSH(hw);
usec_delay(2);
}
......@@ -1774,6 +1778,7 @@ e1000_shift_out_mdi_bits(struct e1000_hw *hw,
else ctrl &= ~E1000_CTRL_MDIO;
E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw);
usec_delay(2);
......@@ -1782,9 +1787,6 @@ e1000_shift_out_mdi_bits(struct e1000_hw *hw,
mask = mask >> 1;
}
/* Clear the data bit just before leaving this routine. */
ctrl &= ~E1000_CTRL_MDIO;
}
/******************************************************************************
......@@ -1815,6 +1817,7 @@ e1000_shift_in_mdi_bits(struct e1000_hw *hw)
ctrl &= ~E1000_CTRL_MDIO;
E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw);
/* Raise and Lower the clock before reading in the data. This accounts for
* the turnaround bits. The first clock occurred when we clocked out the
......@@ -1835,9 +1838,6 @@ e1000_shift_in_mdi_bits(struct e1000_hw *hw)
e1000_raise_mdi_clk(hw, &ctrl);
e1000_lower_mdi_clk(hw, &ctrl);
/* Clear the MDIO bit just before leaving this routine. */
ctrl &= ~E1000_CTRL_MDIO;
return data;
}
......@@ -2011,8 +2011,10 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
*/
ctrl = E1000_READ_REG(hw, CTRL);
E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
E1000_WRITE_FLUSH(hw);
msec_delay(10);
E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw);
} else {
/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
* bit to put the PHY into reset. Then, take it out of reset.
......@@ -2021,9 +2023,11 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
msec_delay(10);
ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
}
usec_delay(150);
}
......@@ -2226,6 +2230,7 @@ e1000_raise_ee_clk(struct e1000_hw *hw,
*/
*eecd = *eecd | E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
}
......@@ -2244,6 +2249,7 @@ e1000_lower_ee_clk(struct e1000_hw *hw,
*/
*eecd = *eecd & ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
}
......@@ -2281,6 +2287,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
eecd |= E1000_EECD_DI;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
......@@ -2375,24 +2382,71 @@ e1000_standby_eeprom(struct e1000_hw *hw)
/* Deselct EEPROM */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
/* Clock high */
eecd |= E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
/* Select EEPROM */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
/* Clock low */
eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
}
/******************************************************************************
* Raises then lowers the EEPROM's clock pin
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
e1000_clock_eeprom(struct e1000_hw *hw)
{
uint32_t eecd;
eecd = E1000_READ_REG(hw, EECD);
/* Rising edge of clock */
eecd |= E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
/* Falling edge of clock */
eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
}
/******************************************************************************
* Terminates a command by lowering the EEPROM's chip select pin
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
e1000_cleanup_eeprom(struct e1000_hw *hw)
{
uint32_t eecd;
eecd = E1000_READ_REG(hw, EECD);
eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
E1000_WRITE_REG(hw, EECD, eecd);
e1000_clock_eeprom(hw);
}
/******************************************************************************
* Reads a 16 bit word from the EEPROM.
......@@ -2494,6 +2548,152 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw)
}
}
/******************************************************************************
* Calculates the EEPROM checksum and writes it to the EEPROM
*
* hw - Struct containing variables accessed by shared code
*
* Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
* Writes the difference to word offset 63 of the EEPROM.
*****************************************************************************/
int32_t
e1000_update_eeprom_checksum(struct e1000_hw *hw)
{
uint16_t checksum = 0;
uint16_t i, eeprom_data;
DEBUGFUNC("e1000_update_eeprom_checksum");
for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
if(e1000_read_eeprom(hw, i, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
}
checksum += eeprom_data;
}
checksum = (uint16_t) EEPROM_SUM - checksum;
if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum) < 0) {
DEBUGOUT("EEPROM Write Error\n");
return -E1000_ERR_EEPROM;
}
return 0;
}
/******************************************************************************
* Writes a 16 bit word to a given offset in the EEPROM.
*
* hw - Struct containing variables accessed by shared code
* offset - offset within the EEPROM to be written to
* data - 16 bit word to be writen to the EEPROM
*
* If e1000_update_eeprom_checksum is not called after this function, the
* EEPROM will most likely contain an invalid checksum.
*****************************************************************************/
int32_t
e1000_write_eeprom(struct e1000_hw *hw,
uint16_t offset,
uint16_t data)
{
uint32_t eecd;
uint32_t i = 0;
int32_t status = 0;
boolean_t large_eeprom = FALSE;
DEBUGFUNC("e1000_write_eeprom");
/* Request EEPROM Access */
if(hw->mac_type > e1000_82544) {
eecd = E1000_READ_REG(hw, EECD);
if(eecd & E1000_EECD_SIZE) large_eeprom = TRUE;
eecd |= E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
eecd = E1000_READ_REG(hw, EECD);
while((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
i++;
usec_delay(5);
eecd = E1000_READ_REG(hw, EECD);
}
if(!(eecd & E1000_EECD_GNT)) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
DEBUGOUT("Could not acquire EEPROM grant\n");
return -E1000_ERR_EEPROM;
}
}
/* Prepare the EEPROM for writing */
e1000_setup_eeprom(hw);
/* Send the 9-bit (or 11-bit on large EEPROM) EWEN (write enable) command
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This puts the EEPROM
* into write/erase mode.
*/
e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE, 5);
if(large_eeprom)
e1000_shift_out_ee_bits(hw, 0, 6);
else
e1000_shift_out_ee_bits(hw, 0, 4);
/* Prepare the EEPROM */
e1000_standby_eeprom(hw);
/* Send the Write command (3-bit opcode + addr) */
e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE, 3);
if(large_eeprom)
/* If we have a 256 word EEPROM, there are 8 address bits */
e1000_shift_out_ee_bits(hw, offset, 8);
else
/* If we have a 64 word EEPROM, there are 6 address bits */
e1000_shift_out_ee_bits(hw, offset, 6);
/* Send the data */
e1000_shift_out_ee_bits(hw, data, 16);
/* Toggle the CS line. This in effect tells to EEPROM to actually execute
* the command in question.
*/
e1000_standby_eeprom(hw);
/* Now read DO repeatedly until is high (equal to '1'). The EEEPROM will
* signal that the command has been completed by raising the DO signal.
* If DO does not go high in 10 milliseconds, then error out.
*/
for(i = 0; i < 200; i++) {
eecd = E1000_READ_REG(hw, EECD);
if(eecd & E1000_EECD_DO) break;
usec_delay(50);
}
if(i == 200) {
DEBUGOUT("EEPROM Write did not complete\n");
status = -E1000_ERR_EEPROM;
}
/* Recover from write */
e1000_standby_eeprom(hw);
/* Send the 9-bit (or 11-bit on large EEPROM) EWDS (write disable) command
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This takes the EEPROM
* out of write/erase mode.
*/
e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5);
if(large_eeprom)
e1000_shift_out_ee_bits(hw, 0, 6);
else
e1000_shift_out_ee_bits(hw, 0, 4);
/* Done with writing */
e1000_cleanup_eeprom(hw);
/* Stop requesting EEPROM access */
if(hw->mac_type > e1000_82544) {
eecd = E1000_READ_REG(hw, EECD);
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
}
return status;
}
/******************************************************************************
* Reads the adapter's part number from the EEPROM
*
......@@ -3334,4 +3534,41 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw->bus_width = (status & E1000_STATUS_BUS64) ?
e1000_bus_width_64 : e1000_bus_width_32;
}
/******************************************************************************
* Reads a value from one of the devices registers using port I/O (as opposed
* memory mapped I/O). Only 82544 and newer devices support port I/O.
*
* hw - Struct containing variables accessed by shared code
* offset - offset to read from
*****************************************************************************/
uint32_t
e1000_read_reg_io(struct e1000_hw *hw,
uint32_t offset)
{
uint32_t io_addr = hw->io_base;
uint32_t io_data = hw->io_base + 4;
e1000_io_write(hw, io_addr, offset);
return e1000_io_read(hw, io_data);
}
/******************************************************************************
* Writes a value to one of the devices registers using port I/O (as opposed to
* memory mapped I/O). Only 82544 and newer devices support port I/O.
*
* hw - Struct containing variables accessed by shared code
* offset - offset to write to
* value - value to write
*****************************************************************************/
void
e1000_write_reg_io(struct e1000_hw *hw,
uint32_t offset,
uint32_t value)
{
uint32_t io_addr = hw->io_base;
uint32_t io_data = hw->io_base + 4;
e1000_io_write(hw, io_addr, offset);
e1000_io_write(hw, io_data, value);
}
......@@ -236,6 +236,8 @@ int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
/* EEPROM Functions */
int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t *data);
int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t data);
int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
int32_t e1000_read_mac_addr(struct e1000_hw * hw);
......@@ -262,8 +264,19 @@ void e1000_reset_adaptive(struct e1000_hw *hw);
void e1000_update_adaptive(struct e1000_hw *hw);
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, uint32_t frame_len, uint8_t * mac_addr);
void e1000_get_bus_info(struct e1000_hw *hw);
void e1000_pci_set_mwi(struct e1000_hw *hw);
void e1000_pci_clear_mwi(struct e1000_hw *hw);
void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
/* Port I/O is only supported on 82544 and newer */
uint32_t e1000_io_read(struct e1000_hw *hw, uint32_t port);
uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
void e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value);
void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
#define E1000_READ_REG_IO(a, reg) \
e1000_read_reg_io((a), E1000_##reg)
#define E1000_WRITE_REG_IO(a, reg, val) \
e1000_write_reg_io((a), E1000_##reg, val)
/* PCI Device IDs */
#define E1000_DEV_ID_82542 0x1000
......@@ -878,6 +891,7 @@ struct e1000_hw {
e1000_bus_speed bus_speed;
e1000_bus_width bus_width;
e1000_bus_type bus_type;
uint32_t io_base;
uint32_t phy_id;
uint32_t phy_addr;
uint32_t original_fc;
......@@ -1333,6 +1347,7 @@ struct e1000_hw {
#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */
/* EEPROM Word Offsets */
#define EEPROM_COMPAT 0x0003
#define EEPROM_ID_LED_SETTINGS 0x0004
#define EEPROM_INIT_CONTROL1_REG 0x000A
#define EEPROM_INIT_CONTROL2_REG 0x000F
......@@ -1343,9 +1358,9 @@ struct e1000_hw {
#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))
(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
......@@ -1356,6 +1371,10 @@ struct e1000_hw {
#define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9
/* Mask bits for fields in Word 0x03 of the EEPROM */
#define EEPROM_COMPAT_SERVER 0x0400
#define EEPROM_COMPAT_CLIENT 0x0200
/* Mask bits for fields in Word 0x0a of the EEPROM */
#define EEPROM_WORD0A_ILOS 0x0010
#define EEPROM_WORD0A_SWDPIO 0x01E0
......
......@@ -70,13 +70,35 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#define __E1000_MAIN__
#include "e1000.h"
/* Change Log
*
* 4.3.2 7/5/02
* o Bug fix: perform controller reset using I/O rather than mmio because
* some chipsets try to perform a 64-bit write, but the controller ignores
* the upper 32-bit write once the reset is intiated by the lower 32-bit
* write, causing a master abort.
* o Bug fix: fixed jumbo frames sized from 1514 to 2048.
* o ASF support: disable ARP when driver is loaded or resumed; enable when
* driver is removed or suspended.
* o Bug fix: changed default setting for RxIntDelay to 0 for 82542/3/4
* controllers to workaround h/w errata where controller will hang when
* RxIntDelay <> 0 under certian network conditions.
* o Clean up: removed unused and undocumented user-settable settings for
* PHY.
* o Bug fix: ethtool GEEPROM was using byte address rather than word
* addressing.
* o Feature: added support for ethtool SEEPROM.
* o Feature: added support for entropy pool.
*
* 4.2.17 5/30/02
*/
char e1000_driver_name[] = "e1000";
char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
char e1000_driver_version[] = "4.2.17-k1";
char e1000_driver_version[] = "4.3.2-k1";
char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table
......@@ -156,7 +178,6 @@ static void e1000_set_multi(struct net_device *netdev);
static void e1000_update_phy_info(unsigned long data);
static void e1000_watchdog(unsigned long data);
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
static void e1000_tx_timeout(struct net_device *dev);
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
static int e1000_set_mac(struct net_device *netdev, void *p);
......@@ -173,11 +194,11 @@ static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
struct e1000_rx_desc *rx_desc,
struct sk_buff *skb);
#ifdef NETIF_F_HW_VLAN_TX
static void e1000_tx_timeout(struct net_device *dev);
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_kill_vid(struct net_device *netdev, uint16_t vid);
#endif
static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
static int e1000_suspend(struct pci_dev *pdev, uint32_t state);
......@@ -260,7 +281,7 @@ e1000_up(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ,
if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
netdev->name, netdev))
return -1;
......@@ -380,6 +401,15 @@ e1000_probe(struct pci_dev *pdev,
if(!adapter->hw.hw_addr)
goto err_ioremap;
for(i = BAR_1; i <= BAR_5; i++) {
if(pci_resource_len(pdev, i) == 0)
continue;
if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
adapter->hw.io_base = pci_resource_start(pdev, i);
break;
}
}
netdev->open = &e1000_open;
netdev->stop = &e1000_close;
netdev->hard_start_xmit = &e1000_xmit_frame;
......@@ -390,14 +420,13 @@ e1000_probe(struct pci_dev *pdev,
netdev->do_ioctl = &e1000_ioctl;
netdev->tx_timeout = &e1000_tx_timeout;
netdev->watchdog_timeo = HZ;
#ifdef NETIF_F_HW_VLAN_TX
netdev->vlan_rx_register = e1000_vlan_rx_register;
netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
#endif
netdev->irq = pdev->irq;
netdev->base_addr = mmio_start;
netdev->mem_start = mmio_start;
netdev->base_addr = adapter->hw.io_base;
adapter->bd_number = cards_found;
adapter->id_string = e1000_strings[ent->driver_data];
......@@ -407,15 +436,11 @@ e1000_probe(struct pci_dev *pdev,
e1000_sw_init(adapter);
if(adapter->hw.mac_type >= e1000_82543) {
#ifdef NETIF_F_HW_VLAN_TX
netdev->features = NETIF_F_SG |
NETIF_F_HW_CSUM |
NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
#else
netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM;
#endif
} else {
netdev->features = NETIF_F_SG;
}
......@@ -509,7 +534,16 @@ e1000_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv;
uint32_t manc;
if(adapter->hw.mac_type >= e1000_82540) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if(manc & E1000_MANC_SMBUS_EN) {
manc |= E1000_MANC_ARP_EN;
E1000_WRITE_REG(&adapter->hw, MANC, manc);
}
}
unregister_netdev(netdev);
e1000_phy_hw_reset(&adapter->hw);
......@@ -540,18 +574,12 @@ e1000_sw_init(struct e1000_adapter *adapter)
/* PCI config space info */
uint16_t *vendor = &hw->vendor_id;
uint16_t *device = &hw->device_id;
uint16_t *subvendor = &hw->subsystem_vendor_id;
uint16_t *subsystem = &hw->subsystem_id;
uint8_t *revision = &hw->revision_id;
pci_read_config_word(pdev, PCI_VENDOR_ID, vendor);
pci_read_config_word(pdev, PCI_DEVICE_ID, device);
pci_read_config_byte(pdev, PCI_REVISION_ID, revision);
pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, subvendor);
pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, subsystem);
pci_read_config_word(pdev, PCI_VENDOR_ID, &hw->vendor_id);
pci_read_config_word(pdev, PCI_DEVICE_ID, &hw->device_id);
pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID,
&hw->subsystem_vendor_id);
pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id);
pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
adapter->rx_buffer_len = E1000_RXBUFFER_2048;
......@@ -561,9 +589,9 @@ e1000_sw_init(struct e1000_adapter *adapter)
/* identify the MAC */
switch (*device) {
switch (hw->device_id) {
case E1000_DEV_ID_82542:
switch (*revision) {
switch (hw->revision_id) {
case E1000_82542_2_0_REV_ID:
hw->mac_type = e1000_82542_rev2_0;
break;
......@@ -597,7 +625,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw->mac_type = e1000_82546;
break;
default:
/* should never have loaded on this device */
E1000_ERR("Should never have loaded on this device\n");
BUG();
}
......@@ -630,6 +658,13 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw->tbi_compatibility_en = TRUE;
hw->adaptive_ifs = TRUE;
/* Copper options */
if(hw->media_type == e1000_media_type_copper) {
hw->mdix = AUTO_ALL_MODES;
hw->disable_polarity_correction = FALSE;
}
atomic_set(&adapter->irq_sem, 1);
spin_lock_init(&adapter->stats_lock);
}
......@@ -1089,20 +1124,16 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter)
static void
e1000_enter_82542_rst(struct e1000_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
uint16_t pci_command_word = adapter->hw.pci_cmd_word;
uint32_t rctl;
if(pci_command_word & PCI_COMMAND_INVALIDATE) {
pci_command_word &= ~PCI_COMMAND_INVALIDATE;
pci_write_config_word(pdev, PCI_COMMAND, pci_command_word);
}
e1000_pci_clear_mwi(&adapter->hw);
rctl = E1000_READ_REG(&adapter->hw, RCTL);
rctl |= E1000_RCTL_RST;
E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
msec_delay(5);
E1000_WRITE_FLUSH(&adapter->hw);
mdelay(5);
if(netif_running(netdev))
e1000_clean_rx_ring(adapter);
......@@ -1111,18 +1142,17 @@ e1000_enter_82542_rst(struct e1000_adapter *adapter)
static void
e1000_leave_82542_rst(struct e1000_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
uint16_t pci_command_word = adapter->hw.pci_cmd_word;
uint32_t rctl;
rctl = E1000_READ_REG(&adapter->hw, RCTL);
rctl &= ~E1000_RCTL_RST;
E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
msec_delay(5);
E1000_WRITE_FLUSH(&adapter->hw);
mdelay(5);
if(pci_command_word & PCI_COMMAND_INVALIDATE)
pci_write_config_word(pdev, PCI_COMMAND, pci_command_word);
if(adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE)
e1000_pci_set_mwi(&adapter->hw);
if(netif_running(netdev)) {
e1000_configure_rx(adapter);
......@@ -1429,6 +1459,7 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
tx_ring->next_to_use = i;
E1000_WRITE_REG(&adapter->hw, TDT, i);
E1000_WRITE_FLUSH(&adapter->hw);
}
#define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0))
......@@ -1458,12 +1489,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if(e1000_tx_csum(adapter, skb))
tx_flags |= E1000_TX_FLAGS_CSUM;
#ifdef NETIF_F_HW_VLAN_TX
if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= E1000_TX_FLAGS_VLAN;
tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
}
#endif
count = e1000_tx_map(adapter, skb);
......@@ -1525,7 +1554,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
}
if(max_frame <= E1000_RXBUFFER_2048) {
if(max_frame <= MAXIMUM_ETHERNET_FRAME_SIZE) {
adapter->rx_buffer_len = E1000_RXBUFFER_2048;
} else if(adapter->hw.mac_type < e1000_82543) {
......@@ -1699,6 +1728,7 @@ e1000_irq_disable(struct e1000_adapter *adapter)
{
atomic_inc(&adapter->irq_sem);
E1000_WRITE_REG(&adapter->hw, IMC, ~0);
E1000_WRITE_FLUSH(&adapter->hw);
synchronize_irq(adapter->netdev->irq);
}
......@@ -1710,8 +1740,10 @@ e1000_irq_disable(struct e1000_adapter *adapter)
static inline void
e1000_irq_enable(struct e1000_adapter *adapter)
{
if(atomic_dec_and_test(&adapter->irq_sem))
if(atomic_dec_and_test(&adapter->irq_sem)) {
E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
E1000_WRITE_FLUSH(&adapter->hw);
}
}
/**
......@@ -1779,8 +1811,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
tx_ring->buffer_info[i].skb = NULL;
}
memset(tx_desc, 0, sizeof(struct e1000_tx_desc));
mb();
tx_desc->upper.data = 0;
i = (i + 1) % tx_ring->count;
tx_desc = E1000_TX_DESC(*tx_ring, i);
......@@ -1833,8 +1864,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
E1000_DBG("Receive packet consumed multiple buffers\n");
dev_kfree_skb_irq(skb);
memset(rx_desc, 0, sizeof(struct e1000_rx_desc));
mb();
rx_desc->status = 0;
rx_ring->buffer_info[i].skb = NULL;
i = (i + 1) % rx_ring->count;
......@@ -1862,8 +1892,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
} else {
dev_kfree_skb_irq(skb);
memset(rx_desc, 0, sizeof(struct e1000_rx_desc));
mb();
rx_desc->status = 0;
rx_ring->buffer_info[i].skb = NULL;
i = (i + 1) % rx_ring->count;
......@@ -1880,20 +1909,15 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
e1000_rx_checksum(adapter, rx_desc, skb);
skb->protocol = eth_type_trans(skb, netdev);
#ifdef NETIF_F_HW_VLAN_TX
if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) {
vlan_hwaccel_rx(skb, adapter->vlgrp,
(rx_desc->special & E1000_RXD_SPC_VLAN_MASK));
} else {
netif_rx(skb);
}
#else
netif_rx(skb);
#endif
netdev->last_rx = jiffies;
memset(rx_desc, 0, sizeof(struct e1000_rx_desc));
mb();
rx_desc->status = 0;
rx_ring->buffer_info[i].skb = NULL;
i = (i + 1) % rx_ring->count;
......@@ -2017,6 +2041,22 @@ e1000_rx_checksum(struct e1000_adapter *adapter,
}
}
void
e1000_pci_set_mwi(struct e1000_hw *hw)
{
struct e1000_adapter *adapter = hw->back;
pci_set_mwi(adapter->pdev);
}
void
e1000_pci_clear_mwi(struct e1000_hw *hw)
{
struct e1000_adapter *adapter = hw->back;
pci_clear_mwi(adapter->pdev);
}
void
e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
{
......@@ -2033,7 +2073,18 @@ e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
pci_write_config_word(adapter->pdev, reg, *value);
}
#ifdef NETIF_F_HW_VLAN_TX
uint32_t
e1000_io_read(struct e1000_hw *hw, uint32_t port)
{
return inl(port);
}
void
e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value)
{
outl(value, port);
}
static void
e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
{
......@@ -2109,7 +2160,6 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
vfta &= ~(1 << (vid & 0x1F));
e1000_write_vfta(&adapter->hw, index, vfta);
}
#endif
static int
e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
......@@ -2133,7 +2183,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv;
uint32_t ctrl, ctrl_ext, rctl;
uint32_t ctrl, ctrl_ext, rctl, manc;
netif_device_detach(netdev);
......@@ -2171,7 +2221,15 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
}
pci_save_state(pdev, adapter->pci_state);
pci_set_power_state(pdev, 3);
if(adapter->hw.mac_type >= e1000_82540) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if(manc & E1000_MANC_SMBUS_EN) {
manc |= E1000_MANC_ARP_EN;
E1000_WRITE_REG(&adapter->hw, MANC, manc);
}
} else
pci_set_power_state(pdev, 3);
return 0;
}
......@@ -2182,6 +2240,7 @@ e1000_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv;
uint32_t manc;
pci_set_power_state(pdev, 0);
pci_restore_state(pdev, adapter->pci_state);
......@@ -2196,6 +2255,12 @@ e1000_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
if(adapter->hw.mac_type >= e1000_82540) {
manc = E1000_READ_REG(&adapter->hw, MANC);
manc &= ~(E1000_MANC_ARP_EN);
E1000_WRITE_REG(&adapter->hw, MANC, manc);
}
return 0;
}
#endif
......
......@@ -88,7 +88,8 @@
#define usec_delay(x) udelay(x)
#ifndef msec_delay
#define msec_delay(x) do { if(in_interrupt()) { \
mdelay(x); \
/* Don't mdelay in interrupt context! */ \
BUG(); \
} else { \
set_current_state(TASK_UNINTERRUPTIBLE); \
schedule_timeout((x * HZ)/1000); \
......@@ -140,4 +141,6 @@ typedef enum {
readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) : \
readl((a)->hw_addr + E1000_82542_##reg + ((offset) << 2)))
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS);
#endif /* _E1000_OSDEP_H_ */
......@@ -196,38 +196,11 @@ E1000_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
*
* Valid Range: 0-65535
*
* Default Value: 64/128
* Default Value: 0/128
*/
E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
/* MDI-X Support Enable/Disable - Applies only to Copper PHY
*
* Valid Range: 0, 3
* - 0 - Auto in all modes
* - 1 - MDI
* - 2 - MDI-X
* - 3 - Auto in 1000 Base-T mode (MDI in 10 Base-T and 100 Base-T)
*
* Default Value: 0 (Auto)
*/
E1000_PARAM(MdiX, "Set MDI/MDI-X Mode");
/* Automatic Correction of Reversed Cable Polarity Enable/Disable
* This setting applies only to Copper PHY
*
* Valid Range: 0, 1
* - 0 - Disabled
* - 1 - Enabled
*
* Default Value: 1 (Enabled)
*/
E1000_PARAM(DisablePolarityCorrection,
"Disable or enable Automatic Correction for Reversed Cable Polarity");
#define AUTONEG_ADV_DEFAULT 0x2F
#define AUTONEG_ADV_MASK 0x2F
#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
......@@ -242,16 +215,11 @@ E1000_PARAM(DisablePolarityCorrection,
#define MIN_RXD 80
#define MAX_82544_RXD 4096
#define DEFAULT_RDTR 64
#define DEFAULT_RDTR 0
#define DEFAULT_RADV 128
#define MAX_RXDELAY 0xFFFF
#define MIN_RXDELAY 0
#define DEFAULT_MDIX 0
#define MAX_MDIX 3
#define MIN_MDIX 0
struct e1000_option {
enum { enable_option, range_option, list_option } type;
char *name;
......@@ -646,36 +614,6 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
BUG();
}
/* a few other copper only options */
{ /* MDI/MDI-X */
struct e1000_option opt = {
type: range_option,
name: "MDI/MDI-X",
err: "using default of " __MODULE_STRING(DEFAULT_MDIX),
def: DEFAULT_MDIX,
arg: { r: { min: MIN_MDIX, max: MAX_MDIX }}
};
int mdix = MdiX[bd];
e1000_validate_option(&mdix, &opt);
adapter->hw.mdix = mdix;
}
{ /* Automatic Correction for Reverse Cable Polarity */
/* option is actually to disable polarity correction,
* so setting to OPTION_ENABLED turns the hardware feature off */
struct e1000_option opt = {
type: enable_option,
name: "Disable Polarity Correction",
err: "defaulting to Disabled",
def: OPTION_DISABLED,
};
int dpc = DisablePolarityCorrection[bd];
e1000_validate_option(&dpc, &opt);
adapter->hw.disable_polarity_correction = dpc;
}
/* Speed, AutoNeg and MDI/MDI-X must all play nice */
if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) {
printk(KERN_INFO "Speed, AutoNeg and MDI-X specifications are "
......
......@@ -25,6 +25,8 @@
Disabled FC and ER, to avoid lockups when when we get FCP interrupts.
2000 Jul 17 Goutham Rao <goutham.rao@intel.com>
PCI DMA API fixes, adding pci_dma_sync_single calls where neccesary
2000 Aug 31 David Mosberger <davidm@hpl.hp.com>
RX_ALIGN support: enables rx DMA without causing unaligned accesses.
*/
static const char *version =
......@@ -41,14 +43,18 @@ static int rxfifo = 8; /* Rx FIFO threshold, default 32 bytes. */
static int txdmacount = 128;
static int rxdmacount /* = 0 */;
#if defined(__ia64__) || defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
defined(__arm__)
/* align rx buffers to 2 bytes so that IP header is aligned */
# define RX_ALIGN
# define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
#else
# define RxFD_ALIGNMENT
#endif
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
Lower values use more memory, but are faster. */
#if defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
defined(__arm__)
static int rx_copybreak = 1518;
#else
static int rx_copybreak = 200;
#endif
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static int max_interrupt_work = 20;
......@@ -377,18 +383,18 @@ enum SCBPort_cmds {
/* The Speedo3 Rx and Tx frame/buffer descriptors. */
struct descriptor { /* A generic descriptor. */
s32 cmd_status; /* All command and status fields. */
volatile s32 cmd_status; /* All command and status fields. */
u32 link; /* struct descriptor * */
unsigned char params[0];
};
/* The Speedo3 Rx and Tx buffer descriptors. */
struct RxFD { /* Receive frame descriptor. */
s32 status;
volatile s32 status;
u32 link; /* struct RxFD * */
u32 rx_buf_addr; /* void * */
u32 count;
};
} RxFD_ALIGNMENT;
/* Selected elements of the Tx/RxFD.status word. */
enum RxFD_bits {
......@@ -523,7 +529,12 @@ static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 };
static int eepro100_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent);
static void eepro100_remove_one (struct pci_dev *pdev);
#ifdef CONFIG_PM
static int eepro100_suspend (struct pci_dev *pdev, u32 state);
static int eepro100_resume (struct pci_dev *pdev);
#endif
static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len);
static int mdio_read(long ioaddr, int phy_id, int location);
......@@ -1229,6 +1240,9 @@ speedo_init_rx_ring(struct net_device *dev)
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
#ifdef RX_ALIGN
skb_reserve(skb, 2); /* Align IP on 16 byte boundary */
#endif
sp->rx_skbuff[i] = skb;
if (skb == NULL)
break; /* OK. Just initially short of Rx bufs. */
......@@ -1620,6 +1634,9 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
struct sk_buff *skb;
/* Get a fresh skbuff to replace the consumed one. */
skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
#ifdef RX_ALIGN
skb_reserve(skb, 2); /* Align IP on 16 byte boundary */
#endif
sp->rx_skbuff[entry] = skb;
if (skb == NULL) {
sp->rx_ringp[entry] = NULL;
......@@ -2303,7 +2320,9 @@ static struct pci_driver eepro100_driver = {
name: "eepro100",
id_table: eepro100_pci_tbl,
probe: eepro100_init_one,
# if defined(MODULE) || defined(CONFIG_HOTPLUG)
remove: __devexit_p(eepro100_remove_one),
# endif
#ifdef CONFIG_PM
suspend: eepro100_suspend,
resume: eepro100_resume,
......
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