Commit 7991c128 authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/spare/repo/netdev-2.6/e1000

into redhat.com:/spare/repo/net-drivers-2.6
parents b54885f9 a1360dde
......@@ -71,6 +71,7 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/moduleparam.h>
#define BAR_0 0
#define BAR_1 1
......@@ -89,6 +90,12 @@ struct e1000_adapter;
#define E1000_ERR(args...) printk(KERN_ERR "e1000: " args)
#define PFX "e1000: "
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
__FUNCTION__ , ## args))
#define E1000_MAX_INTR 10
/* How many descriptors for TX and RX ? */
......@@ -245,5 +252,6 @@ struct e1000_adapter {
uint32_t pci_state[16];
int msg_enable;
};
#endif /* _E1000_H_ */
......@@ -53,7 +53,7 @@ struct e1000_stats {
#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
offsetof(struct e1000_adapter, m)
static struct e1000_stats e1000_gstrings_stats[] = {
static const struct e1000_stats e1000_gstrings_stats[] = {
{ "rx_packets", E1000_STAT(net_stats.rx_packets) },
{ "tx_packets", E1000_STAT(net_stats.tx_packets) },
{ "rx_bytes", E1000_STAT(net_stats.rx_bytes) },
......@@ -89,20 +89,22 @@ static struct e1000_stats e1000_gstrings_stats[] = {
{ "tx_flow_control_xon", E1000_STAT(stats.xontxc) },
{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }
{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
{ "rx_long_byte_count", E1000_STAT(stats.gorcl) }
};
#define E1000_STATS_LEN \
sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
static char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
"Register test (offline)", "Eeprom test (offline)",
"Interrupt test (offline)", "Loopback test (offline)",
"Link test (on/offline)"
};
#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
static void
e1000_ethtool_gset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
static int
e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct e1000_adapter *adapter = netdev->priv;
struct e1000_hw *hw = &adapter->hw;
if(hw->media_type == e1000_media_type_copper) {
......@@ -169,11 +171,13 @@ e1000_ethtool_gset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
}
ecmd->autoneg = (hw->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
return 0;
}
static int
e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct e1000_adapter *adapter = netdev->priv;
struct e1000_hw *hw = &adapter->hw;
if(ecmd->autoneg == AUTONEG_ENABLE) {
......@@ -195,42 +199,41 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
return 0;
}
static int
e1000_ethtool_gpause(struct e1000_adapter *adapter,
struct ethtool_pauseparam *epause)
static void
e1000_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct e1000_adapter *adapter = netdev->priv;
struct e1000_hw *hw = &adapter->hw;
epause->autoneg =
pause->autoneg =
(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
if(hw->fc == e1000_fc_rx_pause)
epause->rx_pause = 1;
pause->rx_pause = 1;
else if(hw->fc == e1000_fc_tx_pause)
epause->tx_pause = 1;
pause->tx_pause = 1;
else if(hw->fc == e1000_fc_full) {
epause->rx_pause = 1;
epause->tx_pause = 1;
pause->rx_pause = 1;
pause->tx_pause = 1;
}
return 0;
}
static int
e1000_ethtool_spause(struct e1000_adapter *adapter,
struct ethtool_pauseparam *epause)
static int
e1000_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct e1000_adapter *adapter = netdev->priv;
struct e1000_hw *hw = &adapter->hw;
adapter->fc_autoneg = epause->autoneg;
adapter->fc_autoneg = pause->autoneg;
if(epause->rx_pause && epause->tx_pause)
if(pause->rx_pause && pause->tx_pause)
hw->fc = e1000_fc_full;
else if(epause->rx_pause && !epause->tx_pause)
else if(pause->rx_pause && !pause->tx_pause)
hw->fc = e1000_fc_rx_pause;
else if(!epause->rx_pause && epause->tx_pause)
else if(!pause->rx_pause && pause->tx_pause)
hw->fc = e1000_fc_tx_pause;
else if(!epause->rx_pause && !epause->tx_pause)
else if(!pause->rx_pause && !pause->tx_pause)
hw->fc = e1000_fc_none;
hw->original_fc = hw->fc;
......@@ -248,28 +251,124 @@ e1000_ethtool_spause(struct e1000_adapter *adapter,
return 0;
}
static uint32_t
e1000_get_rx_csum(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev->priv;
return adapter->rx_csum;
}
static int
e1000_set_rx_csum(struct net_device *netdev, uint32_t data)
{
struct e1000_adapter *adapter = netdev->priv;
adapter->rx_csum = data;
if(netif_running(netdev)) {
e1000_down(adapter);
e1000_up(adapter);
} else
e1000_reset(adapter);
return 0;
}
static uint32_t
e1000_get_tx_csum(struct net_device *netdev)
{
return (netdev->features & NETIF_F_HW_CSUM) != 0;
}
static int
e1000_set_tx_csum(struct net_device *netdev, uint32_t data)
{
struct e1000_adapter *adapter = netdev->priv;
if(adapter->hw.mac_type < e1000_82543) {
if (!data)
return -EINVAL;
return 0;
}
if (data)
netdev->features |= NETIF_F_HW_CSUM;
else
netdev->features &= ~NETIF_F_HW_CSUM;
return 0;
}
static uint32_t
e1000_get_sg(struct net_device *netdev)
{
return (netdev->features & NETIF_F_SG) != 0;
}
static int
e1000_set_sg(struct net_device *netdev, uint32_t data)
{
if (data)
netdev->features |= NETIF_F_SG;
else
netdev->features &= ~NETIF_F_SG;
return 0;
}
#ifdef NETIF_F_TSO
static uint32_t
e1000_get_tso(struct net_device *netdev)
{
return (netdev->features & NETIF_F_TSO) != 0;
}
static int
e1000_set_tso(struct net_device *netdev, uint32_t data)
{
struct e1000_adapter *adapter = netdev->priv;
if ((adapter->hw.mac_type < e1000_82544) ||
(adapter->hw.mac_type == e1000_82547))
return data ? -EINVAL : 0;
if (data)
netdev->features |= NETIF_F_TSO;
else
netdev->features &= ~NETIF_F_TSO;
return 0;
}
#endif /* NETIF_F_TSO */
static uint32_t
e1000_get_msglevel(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev->priv;
return adapter->msg_enable;
}
static void
e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
struct ethtool_drvinfo *drvinfo)
e1000_set_msglevel(struct net_device *netdev, uint32_t data)
{
struct e1000_adapter *adapter = netdev->priv;
adapter->msg_enable = data;
}
static int
e1000_get_regs_len(struct net_device *netdev)
{
strncpy(drvinfo->driver, e1000_driver_name, 32);
strncpy(drvinfo->version, e1000_driver_version, 32);
strncpy(drvinfo->fw_version, "N/A", 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_stats = E1000_STATS_LEN;
drvinfo->testinfo_len = E1000_TEST_LEN;
#define E1000_REGS_LEN 32
drvinfo->regdump_len = E1000_REGS_LEN * sizeof(uint32_t);
drvinfo->eedump_len = adapter->hw.eeprom.word_size * 2;
return E1000_REGS_LEN * sizeof(uint32_t);
}
static void
e1000_ethtool_gregs(struct e1000_adapter *adapter,
struct ethtool_regs *regs, uint32_t *regs_buff)
e1000_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *p)
{
struct e1000_adapter *adapter = netdev->priv;
struct e1000_hw *hw = &adapter->hw;
uint32_t *regs_buff = p;
uint16_t phy_data;
memset(p, 0, E1000_REGS_LEN * sizeof(uint32_t));
regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
regs_buff[0] = E1000_READ_REG(hw, CTRL);
......@@ -342,37 +441,39 @@ e1000_ethtool_gregs(struct e1000_adapter *adapter,
e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
regs_buff[24] = (uint32_t)phy_data; /* phy local receiver status */
regs_buff[25] = regs_buff[24]; /* phy remote receiver status */
}
return;
static int
e1000_get_eeprom_len(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev->priv;
return adapter->hw.eeprom.word_size * 2;
}
static int
e1000_ethtool_geeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
e1000_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, uint8_t *bytes)
{
struct e1000_adapter *adapter = netdev->priv;
struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff;
int first_word, last_word;
int ret_val = 0;
uint16_t i;
if(eeprom->len == 0) {
ret_val = -EINVAL;
goto geeprom_error;
}
if(eeprom->len == 0)
return -EINVAL;
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
if(eeprom->offset > eeprom->offset + eeprom->len) {
ret_val = -EINVAL;
goto geeprom_error;
}
if((eeprom->offset + eeprom->len) > (hw->eeprom.word_size * 2))
eeprom->len = ((hw->eeprom.word_size * 2) - eeprom->offset);
first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
eeprom_buff = kmalloc(sizeof(uint16_t) *
(last_word - first_word + 1), GFP_KERNEL);
if (!eeprom_buff)
return -ENOMEM;
if(hw->eeprom.type == e1000_eeprom_spi)
ret_val = e1000_read_eeprom(hw, first_word,
last_word - first_word + 1,
......@@ -388,14 +489,19 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
for (i = 0; i < last_word - first_word + 1; i++)
le16_to_cpus(&eeprom_buff[i]);
geeprom_error:
memcpy(bytes, (uint8_t *)eeprom_buff + (eeprom->offset%2),
eeprom->len);
kfree(eeprom_buff);
return ret_val;
}
static int
e1000_ethtool_seeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, void *user_data)
e1000_set_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, uint8_t *bytes)
{
struct e1000_adapter *adapter = netdev->priv;
struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff;
void *ptr;
......@@ -410,9 +516,6 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
max_len = hw->eeprom.word_size * 2;
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;
eeprom_buff = kmalloc(max_len, GFP_KERNEL);
......@@ -439,11 +542,7 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
for (i = 0; i < last_word - first_word + 1; i++)
le16_to_cpus(&eeprom_buff[i]);
if((ret_val != 0) || copy_from_user(ptr, user_data, eeprom->len)) {
ret_val = -EFAULT;
goto seeprom_error;
}
memcpy(ptr, bytes, eeprom->len);
for (i = 0; i < last_word - first_word + 1; i++)
eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);
......@@ -454,15 +553,31 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
e1000_update_eeprom_checksum(hw);
seeprom_error:
kfree(eeprom_buff);
return ret_val;
}
static int
e1000_ethtool_gring(struct e1000_adapter *adapter,
static void
e1000_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct e1000_adapter *adapter = netdev->priv;
strncpy(drvinfo->driver, e1000_driver_name, 32);
strncpy(drvinfo->version, e1000_driver_version, 32);
strncpy(drvinfo->fw_version, "N/A", 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_stats = E1000_STATS_LEN;
drvinfo->testinfo_len = E1000_TEST_LEN;
drvinfo->regdump_len = e1000_get_regs_len(netdev);
drvinfo->eedump_len = e1000_get_eeprom_len(netdev);
}
static void
e1000_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
struct e1000_adapter *adapter = netdev->priv;
e1000_mac_type mac_type = adapter->hw.mac_type;
struct e1000_desc_ring *txdr = &adapter->tx_ring;
struct e1000_desc_ring *rxdr = &adapter->rx_ring;
......@@ -477,14 +592,14 @@ e1000_ethtool_gring(struct e1000_adapter *adapter,
ring->tx_pending = txdr->count;
ring->rx_mini_pending = 0;
ring->rx_jumbo_pending = 0;
return 0;
}
static int
e1000_ethtool_sring(struct e1000_adapter *adapter,
e1000_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
int err;
struct e1000_adapter *adapter = netdev->priv;
e1000_mac_type mac_type = adapter->hw.mac_type;
struct e1000_desc_ring *txdr = &adapter->tx_ring;
struct e1000_desc_ring *rxdr = &adapter->rx_ring;
......@@ -538,6 +653,7 @@ e1000_ethtool_sring(struct e1000_adapter *adapter,
return err;
}
#define REG_PATTERN_TEST(R, M, W) \
{ \
uint32_t pat, value; \
......@@ -628,6 +744,7 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
for(i = 0; i < E1000_MC_TBL_SIZE; i++)
REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF);
*data = 0;
return 0;
}
......@@ -939,8 +1056,6 @@ e1000_phy_disable_receiver(struct e1000_adapter *adapter)
e1000_write_phy_reg(&adapter->hw, 30, 0x8FFC);
e1000_write_phy_reg(&adapter->hw, 29, 0x001A);
e1000_write_phy_reg(&adapter->hw, 30, 0x8FF0);
return;
}
static void
......@@ -1219,16 +1334,16 @@ e1000_run_loopback_test(struct e1000_adapter *adapter)
for(i = 0; i < 64; i++) {
e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024);
pci_dma_sync_single_for_device(pdev, txdr->buffer_info[i].dma,
txdr->buffer_info[i].length,
PCI_DMA_TODEVICE);
pci_dma_sync_single(pdev, txdr->buffer_info[i].dma,
txdr->buffer_info[i].length,
PCI_DMA_TODEVICE);
}
E1000_WRITE_REG(&adapter->hw, TDT, i);
msec_delay(200);
pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[0].dma,
rxdr->buffer_info[0].length, PCI_DMA_FROMDEVICE);
pci_dma_sync_single(pdev, rxdr->buffer_info[0].dma,
rxdr->buffer_info[0].length, PCI_DMA_FROMDEVICE);
return e1000_check_lbtest_frame(rxdr->buffer_info[0].skb, 1024);
}
......@@ -1257,15 +1372,27 @@ e1000_link_test(struct e1000_adapter *adapter, uint64_t *data)
return *data;
}
static int
e1000_ethtool_test(struct e1000_adapter *adapter,
static int
e1000_diag_test_count(struct net_device *netdev)
{
return E1000_TEST_LEN;
}
static void
e1000_diag_test(struct net_device *netdev,
struct ethtool_test *eth_test, uint64_t *data)
{
boolean_t if_running = netif_running(adapter->netdev);
struct e1000_adapter *adapter = netdev->priv;
boolean_t if_running = netif_running(netdev);
if(eth_test->flags == ETH_TEST_FL_OFFLINE) {
/* Offline tests */
/* save speed, duplex, autoneg settings */
uint16_t autoneg_advertised = adapter->hw.autoneg_advertised;
uint8_t forced_speed_duplex = adapter->hw.forced_speed_duplex;
uint8_t autoneg = adapter->hw.autoneg;
/* Link test performed before hardware reset so autoneg doesn't
* interfere with test result */
if(e1000_link_test(adapter, &data[4]))
......@@ -1291,6 +1418,10 @@ e1000_ethtool_test(struct e1000_adapter *adapter,
if(e1000_loopback_test(adapter, &data[3]))
eth_test->flags |= ETH_TEST_FL_FAILED;
/* restore Autoneg/speed/duplex settings */
adapter->hw.autoneg_advertised = autoneg_advertised;
adapter->hw.forced_speed_duplex = forced_speed_duplex;
adapter->hw.autoneg = autoneg;
e1000_reset(adapter);
if(if_running)
e1000_up(adapter);
......@@ -1305,12 +1436,12 @@ e1000_ethtool_test(struct e1000_adapter *adapter,
data[2] = 0;
data[3] = 0;
}
return 0;
}
static void
e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct e1000_adapter *adapter = netdev->priv;
struct e1000_hw *hw = &adapter->hw;
switch(adapter->hw.device_id) {
......@@ -1350,8 +1481,9 @@ e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
}
static int
e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct e1000_adapter *adapter = netdev->priv;
struct e1000_hw *hw = &adapter->hw;
switch(adapter->hw.device_id) {
......@@ -1387,7 +1519,6 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
return 0;
}
/* toggle LED 4 times per second = 2 "blinks" per second */
#define E1000_ID_INTERVAL (HZ/4)
......@@ -1408,8 +1539,13 @@ e1000_led_blink_callback(unsigned long data)
}
static int
e1000_ethtool_led_blink(struct e1000_adapter *adapter, struct ethtool_value *id)
e1000_phys_id(struct net_device *netdev, uint32_t data)
{
struct e1000_adapter *adapter = netdev->priv;
if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
if(!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function = e1000_led_blink_callback;
......@@ -1420,11 +1556,8 @@ e1000_ethtool_led_blink(struct e1000_adapter *adapter, struct ethtool_value *id)
mod_timer(&adapter->blink_timer, jiffies);
set_current_state(TASK_INTERRUPTIBLE);
if(id->data)
schedule_timeout(id->data * HZ);
else
schedule_timeout(MAX_SCHEDULE_TIMEOUT);
schedule_timeout(data * HZ);
del_timer_sync(&adapter->blink_timer);
e1000_led_off(&adapter->hw);
clear_bit(E1000_LED_ON, &adapter->led_status);
......@@ -1433,345 +1566,102 @@ e1000_ethtool_led_blink(struct e1000_adapter *adapter, struct ethtool_value *id)
return 0;
}
int
e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
static int
e1000_nway_reset(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev->priv;
void *addr = ifr->ifr_data;
uint32_t cmd;
if(get_user(cmd, (uint32_t *) addr))
return -EFAULT;
switch(cmd) {
case ETHTOOL_GSET: {
struct ethtool_cmd ecmd = {ETHTOOL_GSET};
e1000_ethtool_gset(adapter, &ecmd);
if(copy_to_user(addr, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
}
case ETHTOOL_SSET: {
struct ethtool_cmd ecmd;
if(copy_from_user(&ecmd, addr, sizeof(ecmd)))
return -EFAULT;
return e1000_ethtool_sset(adapter, &ecmd);
}
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo drvinfo = {ETHTOOL_GDRVINFO};
e1000_ethtool_gdrvinfo(adapter, &drvinfo);
if(copy_to_user(addr, &drvinfo, sizeof(drvinfo)))
return -EFAULT;
return 0;
}
case ETHTOOL_GSTRINGS: {
struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS };
char *strings = NULL;
int err = 0;
if(copy_from_user(&gstrings, addr, sizeof(gstrings)))
return -EFAULT;
switch(gstrings.string_set) {
case ETH_SS_TEST:
gstrings.len = E1000_TEST_LEN;
strings = kmalloc(E1000_TEST_LEN * ETH_GSTRING_LEN,
GFP_KERNEL);
if(!strings)
return -ENOMEM;
memcpy(strings, e1000_gstrings_test, E1000_TEST_LEN *
ETH_GSTRING_LEN);
break;
case ETH_SS_STATS: {
int i;
gstrings.len = E1000_STATS_LEN;
strings = kmalloc(E1000_STATS_LEN * ETH_GSTRING_LEN,
GFP_KERNEL);
if(!strings)
return -ENOMEM;
for(i=0; i < E1000_STATS_LEN; i++) {
memcpy(&strings[i * ETH_GSTRING_LEN],
e1000_gstrings_stats[i].stat_string,
ETH_GSTRING_LEN);
}
break;
}
default:
return -EOPNOTSUPP;
}
if(copy_to_user(addr, &gstrings, sizeof(gstrings)))
err = -EFAULT;
addr += offsetof(struct ethtool_gstrings, data);
if(!err && copy_to_user(addr, strings,
gstrings.len * ETH_GSTRING_LEN))
err = -EFAULT;
kfree(strings);
return err;
}
case ETHTOOL_GREGS: {
struct ethtool_regs regs = {ETHTOOL_GREGS};
uint32_t regs_buff[E1000_REGS_LEN];
if(copy_from_user(&regs, addr, sizeof(regs)))
return -EFAULT;
memset(regs_buff, 0, sizeof(regs_buff));
if (regs.len > E1000_REGS_LEN)
regs.len = E1000_REGS_LEN;
e1000_ethtool_gregs(adapter, &regs, regs_buff);
if(copy_to_user(addr, &regs, sizeof(regs)))
return -EFAULT;
addr += offsetof(struct ethtool_regs, data);
if(copy_to_user(addr, regs_buff, regs.len))
return -EFAULT;
return 0;
}
case ETHTOOL_NWAY_RST: {
if(netif_running(netdev)) {
e1000_down(adapter);
e1000_up(adapter);
}
return 0;
}
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);
}
case ETHTOOL_GLINK: {
struct ethtool_value link = {ETHTOOL_GLINK};
link.data = netif_carrier_ok(netdev);
if(copy_to_user(addr, &link, sizeof(link)))
return -EFAULT;
return 0;
}
case ETHTOOL_GWOL: {
struct ethtool_wolinfo wol = {ETHTOOL_GWOL};
e1000_ethtool_gwol(adapter, &wol);
if(copy_to_user(addr, &wol, sizeof(wol)) != 0)
return -EFAULT;
return 0;
}
case ETHTOOL_SWOL: {
struct ethtool_wolinfo wol;
if(copy_from_user(&wol, addr, sizeof(wol)) != 0)
return -EFAULT;
return e1000_ethtool_swol(adapter, &wol);
}
case ETHTOOL_GEEPROM: {
struct ethtool_eeprom eeprom = {ETHTOOL_GEEPROM};
struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff;
void *ptr;
int err = 0;
if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
return -EFAULT;
eeprom_buff = kmalloc(hw->eeprom.word_size * 2, GFP_KERNEL);
if(!eeprom_buff)
return -ENOMEM;
if((err = e1000_ethtool_geeprom(adapter, &eeprom,
eeprom_buff)))
goto err_geeprom_ioctl;
if(copy_to_user(addr, &eeprom, sizeof(eeprom))) {
err = -EFAULT;
goto err_geeprom_ioctl;
}
addr += offsetof(struct ethtool_eeprom, data);
ptr = ((void *)eeprom_buff) + (eeprom.offset & 1);
if(copy_to_user(addr, ptr, eeprom.len))
err = -EFAULT;
err_geeprom_ioctl:
kfree(eeprom_buff);
return err;
}
case ETHTOOL_SEEPROM: {
struct ethtool_eeprom eeprom;
if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
return -EFAULT;
addr += offsetof(struct ethtool_eeprom, data);
return e1000_ethtool_seeprom(adapter, &eeprom, addr);
}
case ETHTOOL_GRINGPARAM: {
struct ethtool_ringparam ering = {ETHTOOL_GRINGPARAM};
e1000_ethtool_gring(adapter, &ering);
if(copy_to_user(addr, &ering, sizeof(ering)))
return -EFAULT;
return 0;
}
case ETHTOOL_SRINGPARAM: {
struct ethtool_ringparam ering;
if(copy_from_user(&ering, addr, sizeof(ering)))
return -EFAULT;
return e1000_ethtool_sring(adapter, &ering);
}
case ETHTOOL_GPAUSEPARAM: {
struct ethtool_pauseparam epause = {ETHTOOL_GPAUSEPARAM};
e1000_ethtool_gpause(adapter, &epause);
if(copy_to_user(addr, &epause, sizeof(epause)))
return -EFAULT;
return 0;
}
case ETHTOOL_SPAUSEPARAM: {
struct ethtool_pauseparam epause;
if(copy_from_user(&epause, addr, sizeof(epause)))
return -EFAULT;
return e1000_ethtool_spause(adapter, &epause);
}
case ETHTOOL_GSTATS: {
struct {
struct ethtool_stats eth_stats;
uint64_t data[E1000_STATS_LEN];
} stats = { {ETHTOOL_GSTATS, E1000_STATS_LEN} };
int i;
e1000_update_stats(adapter);
for(i = 0; i < E1000_STATS_LEN; i++)
stats.data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
sizeof(uint64_t)) ?
*(uint64_t *)((char *)adapter +
e1000_gstrings_stats[i].stat_offset) :
*(uint32_t *)((char *)adapter +
e1000_gstrings_stats[i].stat_offset);
if(copy_to_user(addr, &stats, sizeof(stats)))
return -EFAULT;
return 0;
if(netif_running(netdev)) {
e1000_down(adapter);
e1000_up(adapter);
}
case ETHTOOL_TEST: {
struct {
struct ethtool_test eth_test;
uint64_t data[E1000_TEST_LEN];
} test = { {ETHTOOL_TEST} };
int err;
if(copy_from_user(&test.eth_test, addr, sizeof(test.eth_test)))
return -EFAULT;
test.eth_test.len = E1000_TEST_LEN;
if((err = e1000_ethtool_test(adapter, &test.eth_test,
test.data)))
return err;
return 0;
}
if(copy_to_user(addr, &test, sizeof(test)) != 0)
return -EFAULT;
return 0;
}
case ETHTOOL_GRXCSUM: {
struct ethtool_value edata = { ETHTOOL_GRXCSUM };
static uint32_t
e1000_get_link(struct net_device *netdev)
{
return netif_carrier_ok(netdev);
}
edata.data = adapter->rx_csum;
if (copy_to_user(addr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
case ETHTOOL_SRXCSUM: {
struct ethtool_value edata;
static int
e1000_get_stats_count(struct net_device *netdev)
{
return E1000_STATS_LEN;
}
if (copy_from_user(&edata, addr, sizeof(edata)))
return -EFAULT;
adapter->rx_csum = edata.data;
if(netif_running(netdev)) {
e1000_down(adapter);
e1000_up(adapter);
} else
e1000_reset(adapter);
return 0;
}
case ETHTOOL_GTXCSUM: {
struct ethtool_value edata = { ETHTOOL_GTXCSUM };
static void
e1000_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, uint64_t *data)
{
struct e1000_adapter *adapter = netdev->priv;
int i;
edata.data =
(netdev->features & NETIF_F_HW_CSUM) != 0;
if (copy_to_user(addr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
e1000_update_stats(adapter);
for(i = 0; i < E1000_STATS_LEN; i++) {
char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset;
data[i] = (e1000_gstrings_stats[i].sizeof_stat == sizeof(uint64_t))
? *(uint64_t *)p : *(uint32_t *)p;
}
case ETHTOOL_STXCSUM: {
struct ethtool_value edata;
}
if (copy_from_user(&edata, addr, sizeof(edata)))
return -EFAULT;
static void
e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
{
int i;
if(adapter->hw.mac_type < e1000_82543) {
if (edata.data != 0)
return -EINVAL;
return 0;
switch(stringset) {
case ETH_SS_TEST:
memcpy(data, *e1000_gstrings_test,
E1000_TEST_LEN*ETH_GSTRING_LEN);
break;
case ETH_SS_STATS:
for (i=0; i < E1000_STATS_LEN; i++) {
memcpy(data + i * ETH_GSTRING_LEN,
e1000_gstrings_stats[i].stat_string,
ETH_GSTRING_LEN);
}
if (edata.data)
netdev->features |= NETIF_F_HW_CSUM;
else
netdev->features &= ~NETIF_F_HW_CSUM;
return 0;
}
case ETHTOOL_GSG: {
struct ethtool_value edata = { ETHTOOL_GSG };
edata.data =
(netdev->features & NETIF_F_SG) != 0;
if (copy_to_user(addr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
break;
}
case ETHTOOL_SSG: {
struct ethtool_value edata;
if (copy_from_user(&edata, addr, sizeof(edata)))
return -EFAULT;
if (edata.data)
netdev->features |= NETIF_F_SG;
else
netdev->features &= ~NETIF_F_SG;
}
return 0;
}
struct ethtool_ops e1000_ethtool_ops = {
.get_settings = e1000_get_settings,
.set_settings = e1000_set_settings,
.get_drvinfo = e1000_get_drvinfo,
.get_regs_len = e1000_get_regs_len,
.get_regs = e1000_get_regs,
.get_wol = e1000_get_wol,
.set_wol = e1000_set_wol,
.get_msglevel = e1000_get_msglevel,
.set_msglevel = e1000_set_msglevel,
.nway_reset = e1000_nway_reset,
.get_link = e1000_get_link,
.get_eeprom_len = e1000_get_eeprom_len,
.get_eeprom = e1000_get_eeprom,
.set_eeprom = e1000_set_eeprom,
.get_ringparam = e1000_get_ringparam,
.set_ringparam = e1000_set_ringparam,
.get_pauseparam = e1000_get_pauseparam,
.set_pauseparam = e1000_set_pauseparam,
.get_rx_csum = e1000_get_rx_csum,
.set_rx_csum = e1000_set_rx_csum,
.get_tx_csum = e1000_get_tx_csum,
.set_tx_csum = e1000_set_tx_csum,
.get_sg = e1000_get_sg,
.set_sg = e1000_set_sg,
#ifdef NETIF_F_TSO
case ETHTOOL_GTSO: {
struct ethtool_value edata = { ETHTOOL_GTSO };
edata.data = (netdev->features & NETIF_F_TSO) != 0;
if (copy_to_user(addr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
case ETHTOOL_STSO: {
struct ethtool_value edata;
if (copy_from_user(&edata, addr, sizeof(edata)))
return -EFAULT;
if ((adapter->hw.mac_type < e1000_82544) ||
(adapter->hw.mac_type == e1000_82547)) {
if (edata.data != 0)
return -EINVAL;
return 0;
}
if (edata.data)
netdev->features |= NETIF_F_TSO;
else
netdev->features &= ~NETIF_F_TSO;
return 0;
}
.get_tso = e1000_get_tso,
.set_tso = e1000_set_tso,
#endif
default:
return -EOPNOTSUPP;
}
}
.self_test_count = e1000_diag_test_count,
.self_test = e1000_diag_test,
.get_strings = e1000_get_strings,
.phys_id = e1000_phys_id,
.get_stats_count = e1000_get_stats_count,
.get_ethtool_stats = e1000_get_ethtool_stats,
};
void set_ethtool_ops(struct net_device *netdev)
{
SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
}
......@@ -470,7 +470,6 @@ e1000_init_hw(struct e1000_hw *hw)
uint16_t pcix_stat_hi_word;
uint16_t cmd_mmrbc;
uint16_t stat_mmrbc;
DEBUGFUNC("e1000_init_hw");
/* Initialize Identification LED */
......@@ -910,6 +909,12 @@ e1000_setup_copper_link(struct e1000_hw *hw)
if(ret_val)
return ret_val;
if(hw->mac_type == e1000_82545_rev_3) {
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
phy_data |= 0x00000008;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
}
if(hw->mac_type <= e1000_82543 ||
hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
......@@ -1961,7 +1966,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
int32_t
e1000_check_for_link(struct e1000_hw *hw)
{
uint32_t rxcw;
uint32_t rxcw = 0;
uint32_t ctrl;
uint32_t status;
uint32_t rctl;
......@@ -1971,16 +1976,23 @@ e1000_check_for_link(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_for_link");
ctrl = E1000_READ_REG(hw, CTRL);
status = E1000_READ_REG(hw, STATUS);
/* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
* set when the optics detect a signal. On older adapters, it will be
* cleared when there is a signal. This applies to fiber media only.
*/
if(hw->media_type == e1000_media_type_fiber)
signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
if((hw->media_type == e1000_media_type_fiber) ||
(hw->media_type == e1000_media_type_internal_serdes)) {
rxcw = E1000_READ_REG(hw, RXCW);
ctrl = E1000_READ_REG(hw, CTRL);
status = E1000_READ_REG(hw, STATUS);
rxcw = E1000_READ_REG(hw, RXCW);
if(hw->media_type == e1000_media_type_fiber) {
signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
if(status & E1000_STATUS_LU)
hw->get_link_status = FALSE;
}
}
/* If we have a copper PHY then we only want to go out to the PHY
* registers to see if Auto-Neg has completed and/or if our link
......@@ -2093,8 +2105,8 @@ e1000_check_for_link(struct e1000_hw *hw)
* in. The autoneg_failed flag does this.
*/
else if((((hw->media_type == e1000_media_type_fiber) &&
((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
(hw->media_type == e1000_media_type_internal_serdes)) &&
((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
(hw->media_type == e1000_media_type_internal_serdes)) &&
(!(status & E1000_STATUS_LU)) &&
(!(rxcw & E1000_RXCW_C))) {
if(hw->autoneg_failed == 0) {
......@@ -2125,8 +2137,7 @@ e1000_check_for_link(struct e1000_hw *hw)
*/
else if(((hw->media_type == e1000_media_type_fiber) ||
(hw->media_type == e1000_media_type_internal_serdes)) &&
(ctrl & E1000_CTRL_SLU) &&
(rxcw & E1000_RXCW_C)) {
(ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
E1000_WRITE_REG(hw, TXCW, hw->txcw);
E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
......
......@@ -2019,7 +2019,7 @@ struct e1000_hw {
#define IGP01E1000_PSSR_MDIX_SHIFT 0x000B /* shift right 11 */
/* IGP01E1000 Specific Port Control Register - R/W */
#define IGP01E1000_PSCR_TP_LOOPBACK 0x0001
#define IGP01E1000_PSCR_TP_LOOPBACK 0x0010
#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR 0x0200
#define IGP01E1000_PSCR_TEN_CRS_SELECT 0x0400
#define IGP01E1000_PSCR_FLIP_CHIP 0x0800
......@@ -2029,16 +2029,18 @@ struct e1000_hw {
/* IGP01E1000 Specific Port Link Health Register */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR 0x4000
#define IGP01E1000_PLHR_MASTER_FAULT 0x2000
#define IGP01E1000_PLHR_MASTER_RESOLUTION 0x1000
#define IGP01E1000_PLHR_GIG_REM_RCVR_NOK 0x0800 /* LH */
#define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW 0x0400 /* LH */
#define IGP01E1000_PLHR_DATA_ERR_1 0x0200 /* LH */
#define IGP01E1000_PLHR_DATA_ERR_0 0x0100
#define IGP01E1000_PLHR_AUTONEG_FAULT 0x0010
#define IGP01E1000_PLHR_AUTONEG_ACTIVE 0x0008
#define IGP01E1000_PLHR_VALID_CHANNEL_D 0x0004
#define IGP01E1000_PLHR_VALID_CHANNEL_C 0x0002
#define IGP01E1000_PLHR_VALID_CHANNEL_B 0x0001
#define IGP01E1000_PLHR_VALID_CHANNEL_A 0x0000
#define IGP01E1000_PLHR_AUTONEG_FAULT 0x0040
#define IGP01E1000_PLHR_AUTONEG_ACTIVE 0x0010
#define IGP01E1000_PLHR_VALID_CHANNEL_D 0x0008
#define IGP01E1000_PLHR_VALID_CHANNEL_C 0x0004
#define IGP01E1000_PLHR_VALID_CHANNEL_B 0x0002
#define IGP01E1000_PLHR_VALID_CHANNEL_A 0x0001
/* IGP01E1000 Channel Quality Register */
#define IGP01E1000_MSE_CHANNEL_D 0x000F
......
......@@ -27,55 +27,32 @@
*******************************************************************************/
#include "e1000.h"
#include <linux/rtnetlink.h>
/* Change Log
*
* 5.2.51 5/14/04
* o set default configuration to 'NAPI disabled'. NAPI enabled driver
* causes kernel panic when the interface is shutdown while data is being
* transferred.
* 5.2.47 5/04/04
* o fixed ethtool -t implementation
* 5.2.45 4/29/04
* o fixed ethtool -e implementation
* o Support for ethtool ops [Stephen Hemminger (shemminger@osdl.org)]
* 5.2.42 4/26/04
* o Added support for the DPRINTK macro for enhanced error logging. Some
* parts of the patch were supplied by Jon Mason.
* o Move the register_netdevice() donw in the probe routine due to a
* loading/unloading test issue.
* o Added a long RX byte count the the extra ethtool data members for BER
* testing purposes.
* 5.2.39 3/12/04
* o Added support to read/write eeprom data in proper order.
* By default device eeprom is always little-endian, word
* addressable
* o Disable TSO as the default for the driver until hangs
* reported against non-IA acrhs can be root-caused.
* o Back out the CSA fix for 82547 as it continues to cause
* systems lock-ups with production systems.
* o Fixed FC high/low water mark values to actually be in the
* range of the Rx FIFO area. It was a math error.
* [Dainis Jonitis (dainis_jonitis@exigengroup.lv)]
* o Handle failure to get new resources when doing ethtool
* ring paramater changes. Previously, driver would free old,
* but fails to allocate new, causing problems. Now, driver
* allocates new, and if sucessful, frees old.
* o Changed collision threshold from 16 to 15 to comply with IEEE
* spec.
* o Toggle chip-select when checking ready status on SPI eeproms.
* o Put PHY into class A mode to pass IEEE tests on some designs.
* Designs with EEPROM word 0x7, bit 15 set will have their PHYs
* set to class A mode, rather than the default class AB.
* o Handle failures of register_netdev. Stephen Hemminger
* [shemminger@osdl.org].
* o updated README & MAN pages, number of Transmit/Receive
* descriptors may be denied depending on system resources.
*
* 5.2.30 1/14/03
* o Set VLAN filtering to IEEE 802.1Q after reset so we don't break
* SoL connections that use VLANs.
* o Allow 1000/Full setting for AutoNeg param for Fiber connections
* Jon D Mason [jonmason@us.ibm.com].
* o Race between Tx queue and Tx clean fixed with a spin lock.
* o Added netpoll support.
* o Fixed endianess bug causing ethtool loopback diags to fail on ppc.
* o Use pdev->irq rather than netdev->irq in preparation for MSI support.
* o Report driver message on user override of InterruptThrottleRate
* module parameter.
* o Change I/O address storage from uint32_t to unsigned long.
* o Added ethtool RINGPARAM support.
*
* 5.2.22 10/15/03
*/
char e1000_driver_name[] = "e1000";
char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
char e1000_driver_version[] = "5.2.39-k2";
char e1000_driver_version[] = "5.2.52-k2";
char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table
......@@ -170,6 +147,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
int cmd);
void set_ethtool_ops(struct net_device *netdev);
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
......@@ -206,7 +184,7 @@ struct notifier_block e1000_notifier_reboot = {
/* Exported from other modules */
extern void e1000_check_options(struct e1000_adapter *adapter);
extern int e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr);
static struct pci_driver e1000_driver = {
.name = e1000_driver_name,
......@@ -224,6 +202,10 @@ MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
MODULE_LICENSE("GPL");
static int debug = 3;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
/**
* e1000_init_module - Driver Registration Routine
*
......@@ -419,6 +401,12 @@ e1000_probe(struct pci_dev *pdev,
adapter->netdev = netdev;
adapter->pdev = pdev;
adapter->hw.back = adapter;
adapter->msg_enable = (1 << debug) - 1;
rtnl_lock();
/* we need to set the name early since the DPRINTK macro needs it set */
if (dev_alloc_name(netdev, netdev->name) < 0)
goto err_free_unlock;
mmio_start = pci_resource_start(pdev, BAR_0);
mmio_len = pci_resource_len(pdev, BAR_0);
......@@ -446,6 +434,7 @@ e1000_probe(struct pci_dev *pdev,
netdev->set_mac_address = &e1000_set_mac;
netdev->change_mtu = &e1000_change_mtu;
netdev->do_ioctl = &e1000_ioctl;
set_ethtool_ops(netdev);
netdev->tx_timeout = &e1000_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
#ifdef CONFIG_E1000_NAPI
......@@ -502,7 +491,7 @@ e1000_probe(struct pci_dev *pdev,
/* make sure the EEPROM is good */
if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n");
DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
err = -EIO;
goto err_eeprom;
}
......@@ -536,16 +525,12 @@ e1000_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->tx_timeout_task,
(void (*)(void *))e1000_tx_timeout_task, netdev);
if((err = register_netdev(netdev)))
goto err_register;
/* we're going to reset, so assume we have no link for now */
netif_carrier_off(netdev);
netif_stop_queue(netdev);
printk(KERN_INFO "%s: Intel(R) PRO/1000 Network Connection\n",
netdev->name);
DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
e1000_check_options(adapter);
/* Initial Wake on LAN setting
......@@ -579,7 +564,12 @@ e1000_probe(struct pci_dev *pdev,
e1000_reset(adapter);
/* since we are holding the rtnl lock already, call the no-lock version */
if((err = register_netdevice(netdev)))
goto err_register;
cards_found++;
rtnl_unlock();
return 0;
err_register:
......@@ -587,6 +577,8 @@ e1000_probe(struct pci_dev *pdev,
err_eeprom:
iounmap(adapter->hw.hw_addr);
err_ioremap:
err_free_unlock:
rtnl_unlock();
free_netdev(netdev);
err_alloc_etherdev:
pci_release_regions(pdev);
......@@ -664,7 +656,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
/* identify the MAC */
if (e1000_set_mac_type(hw)) {
E1000_ERR("Unknown MAC Type\n");
DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
return -EIO;
}
......@@ -1391,9 +1383,8 @@ e1000_watchdog(unsigned long data)
&adapter->link_speed,
&adapter->link_duplex);
printk(KERN_INFO
"e1000: %s NIC Link is Up %d Mbps %s\n",
netdev->name, adapter->link_speed,
DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s\n",
adapter->link_speed,
adapter->link_duplex == FULL_DUPLEX ?
"Full Duplex" : "Half Duplex");
......@@ -1406,9 +1397,7 @@ e1000_watchdog(unsigned long data)
if(netif_carrier_ok(netdev)) {
adapter->link_speed = 0;
adapter->link_duplex = 0;
printk(KERN_INFO
"e1000: %s NIC Link is Down\n",
netdev->name);
DPRINTK(LINK, INFO, "NIC Link is Down\n");
netif_carrier_off(netdev);
netif_stop_queue(netdev);
mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
......@@ -1560,33 +1549,17 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
static inline int
e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
unsigned int first)
unsigned int first, unsigned int max_per_txd,
unsigned int nr_frags, unsigned int mss)
{
struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct e1000_tx_desc *tx_desc;
struct e1000_buffer *buffer_info;
unsigned int len = skb->len, max_per_txd = E1000_MAX_DATA_PER_TXD;
unsigned int len = skb->len;
unsigned int offset = 0, size, count = 0, i;
#ifdef NETIF_F_TSO
unsigned int mss;
#endif
unsigned int nr_frags;
unsigned int f;
#ifdef NETIF_F_TSO
mss = skb_shinfo(skb)->tso_size;
/* The controller does a simple calculation to
* make sure there is enough room in the FIFO before
* initiating the DMA for each buffer. The calc is:
* 4 = ceil(buffer len/mss). To make sure we don't
* overrun the FIFO, adjust the max buffer len if mss
* drops. */
if(mss)
max_per_txd = min(mss << 2, max_per_txd);
#endif
nr_frags = skb_shinfo(skb)->nr_frags;
len -= skb->data_len;
i = tx_ring->next_to_use;
while(len) {
......@@ -1658,46 +1631,6 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
if(++i == tx_ring->count) i = 0;
}
}
if(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2) {
/* There aren't enough descriptors available to queue up
* this send (need: count + 1 context desc + 1 desc gap
* to keep tail from touching head), so undo the mapping
* and abort the send. We could have done the check before
* we mapped the skb, but because of all the workarounds
* (above), it's too difficult to predict how many we're
* going to need.*/
i = tx_ring->next_to_use;
if(i == first) {
/* Cleanup after e1000_tx_[csum|tso] scribbling
* on descriptors. */
tx_desc = E1000_TX_DESC(*tx_ring, first);
tx_desc->buffer_addr = 0;
tx_desc->lower.data = 0;
tx_desc->upper.data = 0;
}
while(count--) {
buffer_info = &tx_ring->buffer_info[i];
if(buffer_info->dma) {
pci_unmap_page(adapter->pdev,
buffer_info->dma,
buffer_info->length,
PCI_DMA_TODEVICE);
buffer_info->dma = 0;
}
if(++i == tx_ring->count) i = 0;
}
tx_ring->next_to_use = first;
return 0;
}
i = (i == 0) ? tx_ring->count - 1 : i - 1;
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
......@@ -1792,27 +1725,72 @@ e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb)
return 0;
}
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
static int
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev->priv;
unsigned int first;
unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
unsigned int tx_flags = 0;
unsigned long flags;
int count;
unsigned int len = skb->len;
int count = 0;
unsigned int mss = 0;
unsigned int nr_frags = 0;
unsigned int f;
nr_frags = skb_shinfo(skb)->nr_frags;
len -= skb->data_len;
if(skb->len <= 0) {
dev_kfree_skb_any(skb);
return 0;
}
#ifdef NETIF_F_TSO
mss = skb_shinfo(skb)->tso_size;
/* The controller does a simple calculation to
* make sure there is enough room in the FIFO before
* initiating the DMA for each buffer. The calc is:
* 4 = ceil(buffer len/mss). To make sure we don't
* overrun the FIFO, adjust the max buffer len if mss
* drops. */
if(mss) {
max_per_txd = min(mss << 2, max_per_txd);
max_txd_pwr = fls(max_per_txd) - 1;
}
if((mss) || (skb->ip_summed == CHECKSUM_HW))
count++;
count++; /*for sentinel desc*/
#else
if(skb->ip_summed == CHECKSUM_HW)
count++;
#endif
count += TXD_USE_COUNT(len, max_txd_pwr);
if(adapter->pcix_82544)
count++;
nr_frags = skb_shinfo(skb)->nr_frags;
for(f = 0; f < nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
max_txd_pwr);
if(adapter->pcix_82544)
count += nr_frags;
spin_lock_irqsave(&adapter->tx_lock, flags);
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */
if(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2 ) {
netif_stop_queue(netdev);
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return 1;
}
spin_unlock_irqrestore(&adapter->tx_lock, flags);
if(adapter->hw.mac_type == e1000_82547) {
if(e1000_82547_fifo_workaround(adapter, skb)) {
netif_stop_queue(netdev);
mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return 1;
}
}
......@@ -1829,18 +1807,12 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
else if(e1000_tx_csum(adapter, skb))
tx_flags |= E1000_TX_FLAGS_CSUM;
if((count = e1000_tx_map(adapter, skb, first)))
e1000_tx_queue(adapter, count, tx_flags);
else {
netif_stop_queue(netdev);
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return 1;
}
e1000_tx_queue(adapter,
e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss),
tx_flags);
netdev->trans_start = jiffies;
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return 0;
}
......@@ -1903,7 +1875,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
(max_frame > MAX_JUMBO_FRAME_SIZE)) {
E1000_ERR("Invalid MTU setting\n");
DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
return -EINVAL;
}
......@@ -1911,7 +1883,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
adapter->rx_buffer_len = E1000_RXBUFFER_2048;
} else if(adapter->hw.mac_type < e1000_82543) {
E1000_ERR("Jumbo Frames not supported on 82542\n");
DPRINTK(PROBE, ERR, "Jumbo Frames not supported on 82542\n");
return -EINVAL;
} else if(max_frame <= E1000_RXBUFFER_4096) {
......@@ -2193,7 +2165,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
unsigned int i, eop;
boolean_t cleaned = FALSE;
spin_lock(&adapter->tx_lock);
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
......@@ -2236,6 +2207,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
tx_ring->next_to_clean = i;
spin_lock(&adapter->tx_lock);
if(cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev))
netif_wake_queue(netdev);
......@@ -2296,7 +2269,8 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
/* All receives must fit into a single buffer */
E1000_DBG("Receive packet consumed multiple buffers\n");
E1000_DBG("%s: Receive packet consumed multiple buffers\n",
netdev->name);
dev_kfree_skb_irq(skb);
rx_desc->status = 0;
......@@ -2513,8 +2487,6 @@ e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
case SIOCGMIIREG:
case SIOCSMIIREG:
return e1000_mii_ioctl(netdev, ifr, cmd);
case SIOCETHTOOL:
return e1000_ethtool_ioctl(netdev, ifr);
default:
return -EOPNOTSUPP;
}
......
......@@ -234,7 +234,8 @@ struct e1000_option {
};
static int __devinit
e1000_validate_option(int *value, struct e1000_option *opt)
e1000_validate_option(int *value, struct e1000_option *opt,
struct e1000_adapter *adapter)
{
if(*value == OPTION_UNSET) {
*value = opt->def;
......@@ -245,16 +246,17 @@ e1000_validate_option(int *value, struct e1000_option *opt)
case enable_option:
switch (*value) {
case OPTION_ENABLED:
printk(KERN_INFO "%s Enabled\n", opt->name);
DPRINTK(PROBE, INFO, "%s Enabled\n", opt->name);
return 0;
case OPTION_DISABLED:
printk(KERN_INFO "%s Disabled\n", opt->name);
DPRINTK(PROBE, INFO, "%s Disabled\n", opt->name);
return 0;
}
break;
case range_option:
if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
printk(KERN_INFO "%s set to %i\n", opt->name, *value);
DPRINTK(PROBE, INFO,
"%s set to %i\n", opt->name, *value);
return 0;
}
break;
......@@ -266,7 +268,7 @@ e1000_validate_option(int *value, struct e1000_option *opt)
ent = &opt->arg.l.p[i];
if(*value == ent->i) {
if(ent->str[0] != '\0')
printk(KERN_INFO "%s\n", ent->str);
DPRINTK(PROBE, INFO, "%s\n", ent->str);
return 0;
}
}
......@@ -276,7 +278,7 @@ e1000_validate_option(int *value, struct e1000_option *opt)
BUG();
}
printk(KERN_INFO "Invalid %s specified (%i) %s\n",
DPRINTK(PROBE, INFO, "Invalid %s specified (%i) %s\n",
opt->name, *value, opt->err);
*value = opt->def;
return -1;
......@@ -300,9 +302,9 @@ e1000_check_options(struct e1000_adapter *adapter)
{
int bd = adapter->bd_number;
if(bd >= E1000_MAX_NIC) {
printk(KERN_NOTICE
DPRINTK(PROBE, NOTICE,
"Warning: no configuration for board #%i\n", bd);
printk(KERN_NOTICE "Using defaults for all values\n");
DPRINTK(PROBE, NOTICE, "Using defaults for all values\n");
bd = E1000_MAX_NIC;
}
......@@ -321,7 +323,7 @@ e1000_check_options(struct e1000_adapter *adapter)
E1000_MAX_TXD : E1000_MAX_82544_TXD;
tx_ring->count = TxDescriptors[bd];
e1000_validate_option(&tx_ring->count, &opt);
e1000_validate_option(&tx_ring->count, &opt, adapter);
E1000_ROUNDUP(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE);
}
{ /* Receive Descriptor Count */
......@@ -339,7 +341,7 @@ e1000_check_options(struct e1000_adapter *adapter)
E1000_MAX_82544_RXD;
rx_ring->count = RxDescriptors[bd];
e1000_validate_option(&rx_ring->count, &opt);
e1000_validate_option(&rx_ring->count, &opt, adapter);
E1000_ROUNDUP(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE);
}
{ /* Checksum Offload Enable/Disable */
......@@ -351,7 +353,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
int rx_csum = XsumRX[bd];
e1000_validate_option(&rx_csum, &opt);
e1000_validate_option(&rx_csum, &opt, adapter);
adapter->rx_csum = rx_csum;
}
{ /* Flow Control */
......@@ -373,7 +375,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
int fc = FlowControl[bd];
e1000_validate_option(&fc, &opt);
e1000_validate_option(&fc, &opt, adapter);
adapter->hw.fc = adapter->hw.original_fc = fc;
}
{ /* Transmit Interrupt Delay */
......@@ -387,7 +389,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
adapter->tx_int_delay = TxIntDelay[bd];
e1000_validate_option(&adapter->tx_int_delay, &opt);
e1000_validate_option(&adapter->tx_int_delay, &opt, adapter);
}
{ /* Transmit Absolute Interrupt Delay */
struct e1000_option opt = {
......@@ -400,7 +402,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
e1000_validate_option(&adapter->tx_abs_int_delay, &opt);
e1000_validate_option(&adapter->tx_abs_int_delay, &opt, adapter);
}
{ /* Receive Interrupt Delay */
struct e1000_option opt = {
......@@ -413,7 +415,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
adapter->rx_int_delay = RxIntDelay[bd];
e1000_validate_option(&adapter->rx_int_delay, &opt);
e1000_validate_option(&adapter->rx_int_delay, &opt, adapter);
}
{ /* Receive Absolute Interrupt Delay */
struct e1000_option opt = {
......@@ -426,7 +428,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
e1000_validate_option(&adapter->rx_abs_int_delay, &opt);
e1000_validate_option(&adapter->rx_abs_int_delay, &opt, adapter);
}
{ /* Interrupt Throttling Rate */
struct e1000_option opt = {
......@@ -444,13 +446,14 @@ e1000_check_options(struct e1000_adapter *adapter)
adapter->itr = 1;
break;
case 0:
printk(KERN_INFO "%s turned off\n", opt.name);
DPRINTK(PROBE, INFO, "%s turned off\n", opt.name);
break;
case 1:
printk(KERN_INFO "%s set to dynamic mode\n", opt.name);
DPRINTK(PROBE, INFO,
"%s set to dynamic mode\n", opt.name);
break;
default:
e1000_validate_option(&adapter->itr, &opt);
e1000_validate_option(&adapter->itr, &opt, adapter);
break;
}
}
......@@ -482,15 +485,15 @@ e1000_check_fiber_options(struct e1000_adapter *adapter)
bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd;
if((Speed[bd] != OPTION_UNSET)) {
printk(KERN_INFO "Speed not valid for fiber adapters, "
DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, "
"parameter ignored\n");
}
if((Duplex[bd] != OPTION_UNSET)) {
printk(KERN_INFO "Duplex not valid for fiber adapters, "
DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, "
"parameter ignored\n");
}
if((AutoNeg[bd] != OPTION_UNSET) && (AutoNeg[bd] != 0x20)) {
printk(KERN_INFO "AutoNeg other than Full/1000 is "
DPRINTK(PROBE, INFO, "AutoNeg other than Full/1000 is "
"not valid for fiber adapters, parameter ignored\n");
}
}
......@@ -525,7 +528,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
};
speed = Speed[bd];
e1000_validate_option(&speed, &opt);
e1000_validate_option(&speed, &opt, adapter);
}
{ /* Duplex */
struct e1000_opt_list dplx_list[] = {{ 0, "" },
......@@ -542,11 +545,11 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
};
dplx = Duplex[bd];
e1000_validate_option(&dplx, &opt);
e1000_validate_option(&dplx, &opt, adapter);
}
if(AutoNeg[bd] != OPTION_UNSET && (speed != 0 || dplx != 0)) {
printk(KERN_INFO
DPRINTK(PROBE, INFO,
"AutoNeg specified along with Speed or Duplex, "
"parameter ignored\n");
adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
......@@ -595,7 +598,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
};
int an = AutoNeg[bd];
e1000_validate_option(&an, &opt);
e1000_validate_option(&an, &opt, adapter);
adapter->hw.autoneg_advertised = an;
}
......@@ -603,78 +606,85 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
case 0:
adapter->hw.autoneg = adapter->fc_autoneg = 1;
if(Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET)
printk(KERN_INFO
DPRINTK(PROBE, INFO,
"Speed and duplex autonegotiation enabled\n");
break;
case HALF_DUPLEX:
printk(KERN_INFO "Half Duplex specified without Speed\n");
printk(KERN_INFO "Using Autonegotiation at Half Duplex only\n");
DPRINTK(PROBE, INFO, "Half Duplex specified without Speed\n");
DPRINTK(PROBE, INFO,
"Using Autonegotiation at Half Duplex only\n");
adapter->hw.autoneg = adapter->fc_autoneg = 1;
adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
ADVERTISE_100_HALF;
break;
case FULL_DUPLEX:
printk(KERN_INFO "Full Duplex specified without Speed\n");
printk(KERN_INFO "Using Autonegotiation at Full Duplex only\n");
DPRINTK(PROBE, INFO, "Full Duplex specified without Speed\n");
DPRINTK(PROBE, INFO,
"Using Autonegotiation at Full Duplex only\n");
adapter->hw.autoneg = adapter->fc_autoneg = 1;
adapter->hw.autoneg_advertised = ADVERTISE_10_FULL |
ADVERTISE_100_FULL |
ADVERTISE_1000_FULL;
break;
case SPEED_10:
printk(KERN_INFO "10 Mbps Speed specified without Duplex\n");
printk(KERN_INFO "Using Autonegotiation at 10 Mbps only\n");
DPRINTK(PROBE, INFO,
"10 Mbps Speed specified without Duplex\n");
DPRINTK(PROBE, INFO, "Using Autonegotiation at 10 Mbps only\n");
adapter->hw.autoneg = adapter->fc_autoneg = 1;
adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
ADVERTISE_10_FULL;
break;
case SPEED_10 + HALF_DUPLEX:
printk(KERN_INFO "Forcing to 10 Mbps Half Duplex\n");
DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Half Duplex\n");
adapter->hw.autoneg = adapter->fc_autoneg = 0;
adapter->hw.forced_speed_duplex = e1000_10_half;
adapter->hw.autoneg_advertised = 0;
break;
case SPEED_10 + FULL_DUPLEX:
printk(KERN_INFO "Forcing to 10 Mbps Full Duplex\n");
DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Full Duplex\n");
adapter->hw.autoneg = adapter->fc_autoneg = 0;
adapter->hw.forced_speed_duplex = e1000_10_full;
adapter->hw.autoneg_advertised = 0;
break;
case SPEED_100:
printk(KERN_INFO "100 Mbps Speed specified without Duplex\n");
printk(KERN_INFO "Using Autonegotiation at 100 Mbps only\n");
DPRINTK(PROBE, INFO,
"100 Mbps Speed specified without Duplex\n");
DPRINTK(PROBE, INFO,
"Using Autonegotiation at 100 Mbps only\n");
adapter->hw.autoneg = adapter->fc_autoneg = 1;
adapter->hw.autoneg_advertised = ADVERTISE_100_HALF |
ADVERTISE_100_FULL;
break;
case SPEED_100 + HALF_DUPLEX:
printk(KERN_INFO "Forcing to 100 Mbps Half Duplex\n");
DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Half Duplex\n");
adapter->hw.autoneg = adapter->fc_autoneg = 0;
adapter->hw.forced_speed_duplex = e1000_100_half;
adapter->hw.autoneg_advertised = 0;
break;
case SPEED_100 + FULL_DUPLEX:
printk(KERN_INFO "Forcing to 100 Mbps Full Duplex\n");
DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Full Duplex\n");
adapter->hw.autoneg = adapter->fc_autoneg = 0;
adapter->hw.forced_speed_duplex = e1000_100_full;
adapter->hw.autoneg_advertised = 0;
break;
case SPEED_1000:
printk(KERN_INFO "1000 Mbps Speed specified without Duplex\n");
printk(KERN_INFO
DPRINTK(PROBE, INFO,
"1000 Mbps Speed specified without Duplex\n");
DPRINTK(PROBE, INFO,
"Using Autonegotiation at 1000 Mbps Full Duplex only\n");
adapter->hw.autoneg = adapter->fc_autoneg = 1;
adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
break;
case SPEED_1000 + HALF_DUPLEX:
printk(KERN_INFO "Half Duplex is not supported at 1000 Mbps\n");
printk(KERN_INFO
DPRINTK(PROBE, INFO,
"Half Duplex is not supported at 1000 Mbps\n");
DPRINTK(PROBE, INFO,
"Using Autonegotiation at 1000 Mbps Full Duplex only\n");
adapter->hw.autoneg = adapter->fc_autoneg = 1;
adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
break;
case SPEED_1000 + FULL_DUPLEX:
printk(KERN_INFO
DPRINTK(PROBE, INFO,
"Using Autonegotiation at 1000 Mbps Full Duplex only\n");
adapter->hw.autoneg = adapter->fc_autoneg = 1;
adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
......@@ -685,7 +695,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
/* 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 "
DPRINTK(PROBE, INFO,
"Speed, AutoNeg and MDI-X specifications are "
"incompatible. Setting MDI-X to a compatible value.\n");
}
}
......
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