Commit eca5c07f authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.5

into home.osdl.org:/home/torvalds/v2.5/linux
parents 7aa3b084 2967abcf
...@@ -1618,7 +1618,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1618,7 +1618,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
void *regs; void *regs;
long pciaddr; long pciaddr;
unsigned int addr_len, i, pci_using_dac; unsigned int addr_len, i, pci_using_dac;
u8 pci_rev, cache_size; u8 pci_rev;
#ifndef MODULE #ifndef MODULE
static int version_printed; static int version_printed;
...@@ -1659,10 +1659,14 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1659,10 +1659,14 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) if (rc)
goto err_out_free; goto err_out_free;
rc = pci_request_regions(pdev, DRV_NAME); rc = pci_set_mwi(pdev);
if (rc) if (rc)
goto err_out_disable; goto err_out_disable;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
goto err_out_mwi;
if (pdev->irq < 2) { if (pdev->irq < 2) {
rc = -EIO; rc = -EIO;
printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n", printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n",
...@@ -1759,29 +1763,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1759,29 +1763,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
/*
* Looks like this is necessary to deal with on all architectures,
* even this %$#%$# N440BX Intel based thing doesn't get it right.
* Ie. having two NICs in the machine, one will have the cache
* line set at boot time, the other will not.
*/
pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_size);
cache_size <<= 2;
if (cache_size != SMP_CACHE_BYTES) {
printk(KERN_INFO "%s: PCI cache line size set incorrectly "
"(%i bytes) by BIOS/FW, ", dev->name, cache_size);
if (cache_size > SMP_CACHE_BYTES)
printk("expecting %i\n", SMP_CACHE_BYTES);
else {
printk("correcting to %i\n", SMP_CACHE_BYTES);
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
SMP_CACHE_BYTES >> 2);
}
}
/* enable busmastering and memory-write-invalidate */ /* enable busmastering and memory-write-invalidate */
pci_set_master(pdev); pci_set_master(pdev);
pci_set_mwi(pdev);
if (cp->wol_enabled) cp_set_d3_state (cp); if (cp->wol_enabled) cp_set_d3_state (cp);
...@@ -1791,6 +1774,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1791,6 +1774,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(regs); iounmap(regs);
err_out_res: err_out_res:
pci_release_regions(pdev); pci_release_regions(pdev);
err_out_mwi:
pci_clear_mwi(pdev);
err_out_disable: err_out_disable:
pci_disable_device(pdev); pci_disable_device(pdev);
err_out_free: err_out_free:
...@@ -1809,6 +1794,7 @@ static void cp_remove_one (struct pci_dev *pdev) ...@@ -1809,6 +1794,7 @@ static void cp_remove_one (struct pci_dev *pdev)
iounmap(cp->regs); iounmap(cp->regs);
if (cp->wol_enabled) pci_set_power_state (pdev, 0); if (cp->wol_enabled) pci_set_power_state (pdev, 0);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_clear_mwi(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
free_netdev(dev); free_netdev(dev);
......
/* de2104x.c: A Linux PCI Ethernet driver for Intel/Digital 21040/1 chips. */ /* de2104x.c: A Linux PCI Ethernet driver for Intel/Digital 21040/1 chips. */
/* /*
Copyright 2001 Jeff Garzik <jgarzik@pobox.com> Copyright 2001,2003 Jeff Garzik <jgarzik@pobox.com>
Copyright 1994, 1995 Digital Equipment Corporation. [de4x5.c] Copyright 1994, 1995 Digital Equipment Corporation. [de4x5.c]
Written/copyright 1994-2001 by Donald Becker. [tulip.c] Written/copyright 1994-2001 by Donald Becker. [tulip.c]
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
*/ */
#define DRV_NAME "de2104x" #define DRV_NAME "de2104x"
#define DRV_VERSION "0.5.4" #define DRV_VERSION "0.6"
#define DRV_RELDATE "Jan 1, 2002" #define DRV_RELDATE "Sep 1, 2003"
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -1464,7 +1464,7 @@ static void de_tx_timeout (struct net_device *dev) ...@@ -1464,7 +1464,7 @@ static void de_tx_timeout (struct net_device *dev)
netif_wake_queue(dev); netif_wake_queue(dev);
} }
static int de_get_regs(struct de_private *de, u8 *buf) static void __de_get_regs(struct de_private *de, u8 *buf)
{ {
int i; int i;
u32 *rbuf = (u32 *)buf; u32 *rbuf = (u32 *)buf;
...@@ -1475,11 +1475,9 @@ static int de_get_regs(struct de_private *de, u8 *buf) ...@@ -1475,11 +1475,9 @@ static int de_get_regs(struct de_private *de, u8 *buf)
/* handle self-clearing RxMissed counter, CSR8 */ /* handle self-clearing RxMissed counter, CSR8 */
de_rx_missed(de, rbuf[8]); de_rx_missed(de, rbuf[8]);
return 0;
} }
static int de_ethtool_gset(struct de_private *de, struct ethtool_cmd *ecmd) static int __de_get_settings(struct de_private *de, struct ethtool_cmd *ecmd)
{ {
ecmd->supported = de->media_supported; ecmd->supported = de->media_supported;
ecmd->transceiver = XCVR_INTERNAL; ecmd->transceiver = XCVR_INTERNAL;
...@@ -1516,7 +1514,7 @@ static int de_ethtool_gset(struct de_private *de, struct ethtool_cmd *ecmd) ...@@ -1516,7 +1514,7 @@ static int de_ethtool_gset(struct de_private *de, struct ethtool_cmd *ecmd)
return 0; return 0;
} }
static int de_ethtool_sset(struct de_private *de, struct ethtool_cmd *ecmd) static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd)
{ {
u32 new_media; u32 new_media;
unsigned int media_lock; unsigned int media_lock;
...@@ -1584,169 +1582,121 @@ static int de_ethtool_sset(struct de_private *de, struct ethtool_cmd *ecmd) ...@@ -1584,169 +1582,121 @@ static int de_ethtool_sset(struct de_private *de, struct ethtool_cmd *ecmd)
return 0; return 0;
} }
static int de_ethtool_ioctl (struct de_private *de, void *useraddr) static void de_get_drvinfo (struct net_device *dev,struct ethtool_drvinfo *info)
{ {
u32 ethcmd; struct de_private *de = dev->priv;
/* dev_ioctl() in ../../net/core/dev.c has already checked
capable(CAP_NET_ADMIN), so don't bother with that here. */
if (get_user(ethcmd, (u32 *)useraddr)) strcpy (info->driver, DRV_NAME);
return -EFAULT; strcpy (info->version, DRV_VERSION);
strcpy (info->bus_info, pci_name(de->pdev));
info->eedump_len = DE_EEPROM_SIZE;
}
switch (ethcmd) { static int de_get_regs_len(struct net_device *dev)
{
return DE_REGS_SIZE;
}
case ETHTOOL_GDRVINFO: { static int de_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; {
strcpy (info.driver, DRV_NAME); struct de_private *de = dev->priv;
strcpy (info.version, DRV_VERSION); int rc;
strcpy (info.bus_info, pci_name(de->pdev));
info.eedump_len = DE_EEPROM_SIZE;
info.regdump_len = DE_REGS_SIZE;
if (copy_to_user (useraddr, &info, sizeof (info)))
return -EFAULT;
return 0;
}
/* get settings */
case ETHTOOL_GSET: {
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
spin_lock_irq(&de->lock); spin_lock_irq(&de->lock);
de_ethtool_gset(de, &ecmd); rc = __de_get_settings(de, ecmd);
spin_unlock_irq(&de->lock); spin_unlock_irq(&de->lock);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
}
/* set settings */
case ETHTOOL_SSET: {
struct ethtool_cmd ecmd;
int r;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
spin_lock_irq(&de->lock);
r = de_ethtool_sset(de, &ecmd);
spin_unlock_irq(&de->lock);
return r;
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
u32 status;
if (de->media_type != DE_MEDIA_TP_AUTO)
return -EINVAL;
if (netif_carrier_ok(de->dev))
de_link_down(de);
status = dr32(SIAStatus); return rc;
dw32(SIAStatus, (status & ~NWayState) | NWayRestart); }
if (netif_msg_link(de))
printk(KERN_INFO "%s: link nway restart, status %x,%x\n",
de->dev->name, status, dr32(SIAStatus));
return 0;
}
/* get link status */
case ETHTOOL_GLINK: {
struct ethtool_value edata = {ETHTOOL_GLINK};
edata.data = (netif_carrier_ok(de->dev)) ? 1 : 0;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
/* get message-level */ static int de_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
case ETHTOOL_GMSGLVL: { {
struct ethtool_value edata = {ETHTOOL_GMSGLVL}; struct de_private *de = dev->priv;
edata.data = de->msg_enable; int rc;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
/* set message-level */
case ETHTOOL_SMSGLVL: {
struct ethtool_value edata;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
de->msg_enable = edata.data;
return 0;
}
/* get registers */ spin_lock_irq(&de->lock);
case ETHTOOL_GREGS: { rc = __de_set_settings(de, ecmd);
struct ethtool_regs regs; spin_unlock_irq(&de->lock);
u8 regbuf[DE_REGS_SIZE];
int r;
if (copy_from_user(&regs, useraddr, sizeof(regs))) return rc;
return -EFAULT; }
if (regs.len > DE_REGS_SIZE) { static u32 de_get_msglevel(struct net_device *dev)
regs.len = DE_REGS_SIZE; {
} struct de_private *de = dev->priv;
regs.version = (DE_REGS_VER << 2) | de->de21040;
if (copy_to_user(useraddr, &regs, sizeof(regs)))
return -EFAULT;
useraddr += offsetof(struct ethtool_regs, data); return de->msg_enable;
}
spin_lock_irq(&de->lock); static void de_set_msglevel(struct net_device *dev, u32 msglvl)
r = de_get_regs(de, regbuf); {
spin_unlock_irq(&de->lock); struct de_private *de = dev->priv;
if (r) de->msg_enable = msglvl;
return r; }
if (copy_to_user(useraddr, regbuf, regs.len))
return -EFAULT;
return 0;
}
/* get SROM dump */ static int de_get_eeprom(struct net_device *dev,
case ETHTOOL_GEEPROM: { struct ethtool_eeprom *eeprom, u8 *data)
struct ethtool_eeprom eeprom; {
struct de_private *de = dev->priv;
if (!de->ee_data) if (!de->ee_data)
break; return -EOPNOTSUPP;
if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) if ((eeprom->offset != 0) || (eeprom->magic != 0) ||
return -EFAULT; (eeprom->len != DE_EEPROM_SIZE))
if ((eeprom.offset != 0) || (eeprom.magic != 0) ||
(eeprom.len != DE_EEPROM_SIZE))
return -EINVAL; return -EINVAL;
memcpy(data, de->ee_data, eeprom->len);
useraddr += offsetof(struct ethtool_regs, data); return 0;
if (copy_to_user(useraddr, de->ee_data, DE_EEPROM_SIZE))
return -EFAULT;
}
default:
break;
}
return -EOPNOTSUPP;
} }
static int de_nway_reset(struct net_device *dev)
static int de_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{ {
struct de_private *de = dev->priv; struct de_private *de = dev->priv;
int rc = 0; u32 status;
if (!netif_running(dev)) if (de->media_type != DE_MEDIA_TP_AUTO)
return -EINVAL; return -EINVAL;
if (netif_carrier_ok(de->dev))
de_link_down(de);
switch (cmd) { status = dr32(SIAStatus);
case SIOCETHTOOL: dw32(SIAStatus, (status & ~NWayState) | NWayRestart);
return de_ethtool_ioctl(de, (void *) rq->ifr_data); if (netif_msg_link(de))
printk(KERN_INFO "%s: link nway restart, status %x,%x\n",
de->dev->name, status, dr32(SIAStatus));
return 0;
}
default: static void de_get_regs(struct net_device *dev, struct ethtool_regs *regs,
rc = -EOPNOTSUPP; void *data)
break; {
} struct de_private *de = dev->priv;
return rc; if (regs->len > DE_REGS_SIZE)
regs->len = DE_REGS_SIZE;
regs->version = (DE_REGS_VER << 2) | de->de21040;
spin_lock_irq(&de->lock);
__de_get_regs(de, data);
spin_unlock_irq(&de->lock);
} }
static struct ethtool_ops de_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.get_drvinfo = de_get_drvinfo,
.get_regs_len = de_get_regs_len,
.get_settings = de_get_settings,
.set_settings = de_set_settings,
.get_msglevel = de_get_msglevel,
.set_msglevel = de_set_msglevel,
.get_eeprom = de_get_eeprom,
.nway_reset = de_nway_reset,
.get_regs = de_get_regs,
};
static void __init de21040_get_mac_address (struct de_private *de) static void __init de21040_get_mac_address (struct de_private *de)
{ {
unsigned i; unsigned i;
...@@ -2011,7 +1961,7 @@ static int __init de_init_one (struct pci_dev *pdev, ...@@ -2011,7 +1961,7 @@ static int __init de_init_one (struct pci_dev *pdev,
dev->set_multicast_list = de_set_rx_mode; dev->set_multicast_list = de_set_rx_mode;
dev->hard_start_xmit = de_start_xmit; dev->hard_start_xmit = de_start_xmit;
dev->get_stats = de_get_stats; dev->get_stats = de_get_stats;
dev->do_ioctl = de_ioctl; dev->ethtool_ops = &de_ethtool_ops;
dev->tx_timeout = de_tx_timeout; dev->tx_timeout = de_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
......
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