Commit 56970f58 authored by Linus Torvalds's avatar Linus Torvalds

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

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 39412eff 996dec15
......@@ -32,7 +32,7 @@
h/w stats can be reset only by software reset
* Tx checksumming
* Handle netif_rx return value
* ETHTOOL_GREGS, ETHTOOL_[GS]WOL,
* ETHTOOL_[GS]WOL,
* Investigate using skb->priority with h/w VLAN priority
* Investigate using High Priority Tx Queue with skb->priority
* Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
......@@ -41,12 +41,14 @@
Tx descriptor bit
* The real minimum of CP_MIN_MTU is 4 bytes. However,
for this to be supported, one must(?) turn on packet padding.
* Support 8169 GMII
* Support external MII transceivers
*/
#define DRV_NAME "8139cp"
#define DRV_VERSION "0.0.7"
#define DRV_RELDATE "Feb 27, 2002"
#define DRV_VERSION "0.1.0"
#define DRV_RELDATE "Jun 14, 2002"
#include <linux/config.h>
......@@ -99,6 +101,7 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139cp maximum number of filtered mul
NETIF_MSG_PROBE | \
NETIF_MSG_LINK)
#define CP_REGS_SIZE (0xff + 1)
#define CP_REGS_VER 1 /* version 1 */
#define CP_RX_RING_SIZE 64
#define CP_TX_RING_SIZE 64
#define CP_RING_BYTES \
......@@ -152,7 +155,9 @@ enum {
NWayExpansion = 0x6A, /* MII Expansion */
Config5 = 0xD8, /* Config5 */
TxPoll = 0xD9, /* Tell chip to check Tx descriptors for work */
RxMaxSize = 0xDA, /* Max size of an Rx packet (8169 only) */
CpCmd = 0xE0, /* C+ Command register (C+ mode only) */
IntrMitigate = 0xE2, /* rx/tx interrupt mitigation control */
RxRingAddr = 0xE4, /* 64-bit start addr of Rx ring */
TxThresh = 0xEC, /* Early Tx threshold */
OldRxBufAddr = 0x30, /* DMA address of Rx ring buffer (C mode) */
......@@ -313,6 +318,7 @@ struct cp_private {
struct sk_buff *frag_skb;
unsigned dropping_frag : 1;
unsigned int board_type;
struct mii_if_info mii_if;
};
......@@ -341,10 +347,28 @@ static void __cp_set_rx_mode (struct net_device *dev);
static void cp_tx (struct cp_private *cp);
static void cp_clean_rings (struct cp_private *cp);
enum board_type {
RTL8139Cp,
RTL8169,
};
static struct cp_board_info {
const char *name;
} cp_board_tbl[] __devinitdata = {
/* RTL8139Cp */
{ "RTL-8139C+" },
/* RTL8169 */
{ "RTL-8169" },
};
static struct pci_device_id cp_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139Cp },
#if 0
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8169,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8169 },
#endif
{ },
};
MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
......@@ -890,6 +914,9 @@ 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);
}
......@@ -912,16 +939,14 @@ static void cp_init_hw (struct cp_private *cp)
cpw32_f (TxConfig, IFG | (TX_DMA_BURST << TxDMAShift));
cpw8(Config1, cpr8(Config1) | DriverLoaded | PMEnable);
if (cp->board_type == RTL8139Cp)
cpw8(Config3, PARMEnable); /* disables magic packet and WOL */
cpw8(Config5, cpr8(Config5) & PMEStatus); /* disables more WOL stuff */
if (cp->board_type == RTL8169)
cpw16(RxMaxSize, cp->rx_buf_sz);
cpw32_f(HiTxRingAddr, 0);
cpw32_f(HiTxRingAddr + 4, 0);
cpw32_f(OldRxBufAddr, 0);
cpw32_f(OldTSD0, 0);
cpw32_f(OldTSD0 + 4, 0);
cpw32_f(OldTSD0 + 8, 0);
cpw32_f(OldTSD0 + 12, 0);
cpw32_f(RxRingAddr, cp->ring_dma);
cpw32_f(RxRingAddr + 4, 0);
......@@ -930,9 +955,9 @@ static void cp_init_hw (struct cp_private *cp)
cpw16(MultiIntr, 0);
cpw16(IntrMask, cp_intr_mask);
cpw16_f(IntrMask, cp_intr_mask);
cpw8_f (Cfg9346, Cfg9346_Lock);
cpw8_f(Cfg9346, Cfg9346_Lock);
}
static int cp_refill_rx (struct cp_private *cp)
......@@ -1094,6 +1119,8 @@ static int cp_change_mtu(struct net_device *dev, int new_mtu)
dev->mtu = new_mtu;
cp_set_rxbufsize(cp); /* set new rx buf size */
if (cp->board_type == RTL8169)
cpw16(RxMaxSize, cp->rx_buf_sz);
rc = cp_init_rings(cp); /* realloc and restart h/w */
cp_start_hw(cp);
......@@ -1153,6 +1180,7 @@ static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr)
strcpy (info.driver, DRV_NAME);
strcpy (info.version, DRV_VERSION);
strcpy (info.bus_info, cp->pdev->slot_name);
info.regdump_len = CP_REGS_SIZE;
if (copy_to_user (useraddr, &info, sizeof (info)))
return -EFAULT;
return 0;
......@@ -1209,6 +1237,128 @@ static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr)
return 0;
}
/* NIC register dump */
case ETHTOOL_GREGS: {
struct ethtool_regs regs;
u8 *regbuf = kmalloc(CP_REGS_SIZE, GFP_KERNEL);
int rc;
if (!regbuf)
return -ENOMEM;
memset(regbuf, 0, CP_REGS_SIZE);
rc = copy_from_user(&regs, useraddr, sizeof(regs));
if (rc) {
rc = -EFAULT;
goto err_out_gregs;
}
if (regs.len > CP_REGS_SIZE)
regs.len = CP_REGS_SIZE;
if (regs.len < CP_REGS_SIZE) {
rc = -EINVAL;
goto err_out_gregs;
}
regs.version = CP_REGS_VER;
rc = copy_to_user(useraddr, &regs, sizeof(regs));
if (rc) {
rc = -EFAULT;
goto err_out_gregs;
}
useraddr += offsetof(struct ethtool_regs, data);
spin_lock_irq(&cp->lock);
memcpy_fromio(regbuf, cp->regs, CP_REGS_SIZE);
spin_unlock_irq(&cp->lock);
if (copy_to_user(useraddr, regbuf, regs.len))
rc = -EFAULT;
err_out_gregs:
kfree(regbuf);
return rc;
}
/* get/set RX checksumming */
case ETHTOOL_GRXCSUM: {
struct ethtool_value edata = { ETHTOOL_GRXCSUM };
u16 cmd = cpr16(CpCmd) & RxChkSum;
edata.data = cmd ? 1 : 0;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
case ETHTOOL_SRXCSUM: {
struct ethtool_value edata;
u16 cmd = cpr16(CpCmd), newcmd;
newcmd = cmd;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
if (edata.data)
newcmd |= RxChkSum;
else
newcmd &= ~RxChkSum;
if (newcmd == cmd)
return 0;
spin_lock_irq(&cp->lock);
cpw16_f(CpCmd, newcmd);
spin_unlock_irq(&cp->lock);
}
/* get/set TX checksumming */
case ETHTOOL_GTXCSUM: {
struct ethtool_value edata = { ETHTOOL_GTXCSUM };
edata.data = (cp->dev->features & NETIF_F_IP_CSUM) != 0;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
case ETHTOOL_STXCSUM: {
struct ethtool_value edata;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
if (edata.data)
cp->dev->features |= NETIF_F_IP_CSUM;
else
cp->dev->features &= ~NETIF_F_IP_CSUM;
return 0;
}
/* get/set scatter-gather */
case ETHTOOL_GSG: {
struct ethtool_value edata = { ETHTOOL_GSG };
edata.data = (cp->dev->features & NETIF_F_SG) != 0;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
case ETHTOOL_SSG: {
struct ethtool_value edata;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
if (edata.data)
cp->dev->features |= NETIF_F_SG;
else
cp->dev->features &= ~NETIF_F_SG;
return 0;
}
default:
break;
}
......@@ -1332,6 +1482,7 @@ static int __devinit cp_init_one (struct pci_dev *pdev,
unsigned addr_len, i;
u8 pci_rev, cache_size;
u16 pci_command;
unsigned int board_type = (unsigned int) ent->driver_data;
#ifndef MODULE
static int version_printed;
......@@ -1355,6 +1506,7 @@ static int __devinit cp_init_one (struct pci_dev *pdev,
SET_MODULE_OWNER(dev);
cp = dev->priv;
cp->pdev = pdev;
cp->board_type = board_type;
cp->dev = dev;
cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);
spin_lock_init (&cp->lock);
......@@ -1440,7 +1592,7 @@ static int __devinit cp_init_one (struct pci_dev *pdev,
"%02x:%02x:%02x:%02x:%02x:%02x, "
"IRQ %d\n",
dev->name,
"RTL-8139C+",
cp_board_tbl[board_type].name,
dev->base_addr,
dev->dev_addr[0], dev->dev_addr[1],
dev->dev_addr[2], dev->dev_addr[3],
......
......@@ -546,8 +546,11 @@ static unsigned long __init lance_probe1( struct net_device *dev,
if (lp->cardtype == PAM_CARD ||
memaddr == (unsigned short *)0xffe00000) {
/* PAMs card and Riebl on ST use level 5 autovector */
request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO,
"PAM/Riebl-ST Ethernet", dev);
if (request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO,
"PAM/Riebl-ST Ethernet", dev)) {
printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 );
return( 0 );
}
dev->irq = (unsigned short)IRQ_AUTO_5;
}
else {
......@@ -560,8 +563,11 @@ static unsigned long __init lance_probe1( struct net_device *dev,
printk( "Lance: request for VME interrupt failed\n" );
return( 0 );
}
request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
"Riebl-VME Ethernet", dev);
if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
"Riebl-VME Ethernet", dev)) {
printk( "Lance: request for irq %d failed\n", irq );
return( 0 );
}
dev->irq = irq;
}
......
......@@ -257,7 +257,8 @@ write_blink_led_timer(struct file *file, const char *buffer,
if (count > WRITE_BUF_MAX_LEN) {
count = WRITE_BUF_MAX_LEN;
}
copy_from_user(s_blink_op, buffer, count);
if (copy_from_user(s_blink_op, buffer, count))
return -EFAULT;
s_blink_op[count] = '\0';
i_blink_op = simple_strtoul(s_blink_op, &res, 0);
if (res == s_blink_op) {
......
......@@ -828,8 +828,10 @@ static int __init eepro_probe1(struct net_device *dev, short ioaddr)
}
/* Grab the region so we can find another board if autoIRQ fails. */
request_region(ioaddr, EEPRO_IO_EXTENT, dev->name);
if (!request_region(ioaddr, EEPRO_IO_EXTENT, dev->name)) {
printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n", ioaddr);
goto freeall;
}
((struct eepro_local *)dev->priv)->lock = SPIN_LOCK_UNLOCKED;
dev->open = eepro_open;
......
......@@ -436,10 +436,26 @@ static int eexp_open(struct net_device *dev)
ret = request_irq(dev->irq,&eexp_irq,0,dev->name,dev);
if (ret) return ret;
request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress");
request_region(ioaddr+0x4000, 16, "EtherExpress shadow");
request_region(ioaddr+0x8000, 16, "EtherExpress shadow");
request_region(ioaddr+0xc000, 16, "EtherExpress shadow");
if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress")) {
printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
, ioaddr);
goto err_out1;
}
if (!request_region(ioaddr+0x4000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
, ioaddr+0x4000);
goto err_out2;
}
if (!request_region(ioaddr+0x8000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
, ioaddr+0x8000);
goto err_out3;
}
if (!request_region(ioaddr+0xc000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
, ioaddr+0xc000);
goto err_out4;
}
if (lp->width) {
printk("%s: forcing ASIC to 8-bit mode\n", dev->name);
......@@ -452,6 +468,16 @@ static int eexp_open(struct net_device *dev)
printk(KERN_DEBUG "%s: leaving eexp_open()\n", dev->name);
#endif
return 0;
err_out4:
release_region(ioaddr+0x8000, EEXP_IO_EXTENT);
err_out3:
release_region(ioaddr+0x4000, EEXP_IO_EXTENT);
err_out2:
release_region(ioaddr, EEXP_IO_EXTENT);
err_out1:
free_irq(dev->irq, dev);
return -EBUSY;
}
/*
......
......@@ -841,6 +841,7 @@ static int yam_open(struct net_device *dev)
struct yam_port *yp = (struct yam_port *) dev->priv;
enum uart u;
int i;
int ret=0;
printk(KERN_INFO "Trying %s at iobase 0x%lx irq %u\n", dev->name, dev->base_addr, dev->irq);
......@@ -850,24 +851,27 @@ static int yam_open(struct net_device *dev)
dev->irq < 2 || dev->irq > 15) {
return -ENXIO;
}
if (check_region(dev->base_addr, YAM_EXTENT)) {
if (!request_region(dev->base_addr, YAM_EXTENT, dev->name))
{
printk(KERN_ERR "%s: cannot 0x%lx busy\n", dev->name, dev->base_addr);
return -EACCES;
}
if ((u = yam_check_uart(dev->base_addr)) == c_uart_unknown) {
printk(KERN_ERR "%s: cannot find uart type\n", dev->name);
return -EIO;
ret = -EIO;
goto out_release_base;
}
if (fpga_download(dev->base_addr, yp->bitrate)) {
printk(KERN_ERR "%s: cannot init FPGA\n", dev->name);
return -EIO;
ret = -EIO;
goto out_release_base;
}
outb(0, IER(dev->base_addr));
if (request_irq(dev->irq, yam_interrupt, SA_INTERRUPT | SA_SHIRQ, dev->name, dev)) {
printk(KERN_ERR "%s: irq %d busy\n", dev->name, dev->irq);
return -EBUSY;
ret = -EBUSY;
goto out_release_base;
}
request_region(dev->base_addr, YAM_EXTENT, dev->name);
yam_set_uart(dev);
......@@ -884,6 +888,10 @@ static int yam_open(struct net_device *dev)
printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq,
uart_str[u]);
return 0;
out_release_base:
release_region(dev->base_addr, YAM_EXTENT);
return ret;
}
/* --------------------------------------------------------------------- */
......
......@@ -353,19 +353,22 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
unsigned long flags;
for(i=0;i<NUM_CARDS;i++) {
if(check_region(ioaddr, cards[i].total_size))
if(!request_region(ioaddr, cards[i].total_size, cards[i].cardname))
continue;
if(cards[i].id_offset >= 0) {
if(inb(ioaddr+cards[i].id_offset+0) != cards[i].id0 ||
inb(ioaddr+cards[i].id_offset+1) != cards[i].id1) {
release_region(ioaddr, cards[i].total_size);
continue;
}
}
if(cards[i].vendor_id) {
for(j=0;j<3;j++)
if(inb(ioaddr+cards[i].addr_offset+j) != cards[i].vendor_id[j])
if(inb(ioaddr+cards[i].addr_offset+j) != cards[i].vendor_id[j]) {
release_region(ioaddr, cards[i].total_size);
continue;
}
}
break;
}
if(i == NUM_CARDS)
......@@ -374,8 +377,10 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
for(j=0;j<6;j++)
dev->dev_addr[j] = inb(ioaddr+cards[i].addr_offset+j);
if( (j=ni65_alloc_buffer(dev)) < 0)
if( (j=ni65_alloc_buffer(dev)) < 0) {
release_region(ioaddr, cards[i].total_size);
return j;
}
p = (struct priv *) dev->priv;
p->cmdr_addr = ioaddr + cards[i].cmd_offset;
p->cardno = i;
......@@ -386,6 +391,7 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
if( (j=readreg(CSR0)) != 0x4) {
printk(KERN_ERR "can't RESET card: %04x\n",j);
ni65_free_buffer(p);
release_region(ioaddr, cards[p->cardno].total_size);
return -EAGAIN;
}
......@@ -437,6 +443,7 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
if(i == 5) {
printk("Can't detect DMA channel!\n");
ni65_free_buffer(p);
release_region(ioaddr, cards[p->cardno].total_size);
return -EAGAIN;
}
dev->dma = dmatab[i];
......@@ -459,6 +466,7 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
{
printk("Failed to detect IRQ line!\n");
ni65_free_buffer(p);
release_region(ioaddr, cards[p->cardno].total_size);
return -EAGAIN;
}
printk("IRQ %d (autodetected).\n",dev->irq);
......@@ -471,14 +479,10 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
{
printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma);
ni65_free_buffer(p);
release_region(ioaddr, cards[p->cardno].total_size);
return -EAGAIN;
}
/*
* Grab the region so we can find another board.
*/
request_region(ioaddr,cards[p->cardno].total_size,cards[p->cardno].cardname);
dev->base_addr = ioaddr;
dev->open = ni65_open;
......
......@@ -1316,9 +1316,12 @@ static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
err = -E2BIG;
break;
}
copy_from_user(card_essid,
if (copy_from_user(card_essid,
wrq->u.data.pointer,
wrq->u.data.length);
wrq->u.data.length)) {
err = -EFAULT;
break;
}
card_essid[IW_ESSID_MAX_SIZE] = '\0';
/* Set the ESSID in the card */
......
......@@ -466,16 +466,16 @@ static int COMX_open(struct net_device *dev)
}
if (!twin_open) {
if (check_region(dev->base_addr, hw->io_extent)) {
if (!request_region(dev->base_addr, hw->io_extent, dev->name)) {
return -EAGAIN;
}
if (request_irq(dev->irq, COMX_interrupt, 0, dev->name,
(void *)dev)) {
printk(KERN_ERR "comx-hw-comx: unable to obtain irq %d\n", dev->irq);
release_region(dev->base_addr, hw->io_extent);
return -EAGAIN;
}
ch->init_status |= IRQ_ALLOCATED;
request_region(dev->base_addr, hw->io_extent, dev->name);
if (!ch->HW_load_board || ch->HW_load_board(dev)) {
ch->init_status &= ~IRQ_ALLOCATED;
retval=-ENODEV;
......
......@@ -604,7 +604,13 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf)
/* Reserve I/O region and schedule background task */
if(card->hw.type != SDLA_S514 && !card->wandev.piggyback)
request_region(card->hw.port, card->hw.io_range, wandev->name);
if (!request_region(card->hw.port, card->hw.io_range,
wandev->name)) {
printk(KERN_WARNING "port 0x%04x busy\n", card->hw.port);
release_hw(card);
wandev->state = WAN_UNCONFIGURED;
return -EBUSY;
}
/* Only use the polling routine for the X25 protocol */
......
......@@ -2039,6 +2039,7 @@
8e2e 7000 KF-230TX
8e2e 7100 KF-230TX/2
a0a0 0007 ALN-325C
8169 RTL-8169
10ed Ascii Corporation
7310 V7310
10ee Xilinx, Inc.
......
......@@ -912,6 +912,7 @@
#define PCI_DEVICE_ID_REALTEK_8029 0x8029
#define PCI_DEVICE_ID_REALTEK_8129 0x8129
#define PCI_DEVICE_ID_REALTEK_8139 0x8139
#define PCI_DEVICE_ID_REALTEK_8169 0x8169
#define PCI_VENDOR_ID_XILINX 0x10ee
#define PCI_DEVICE_ID_TURBOPAM 0x4020
......
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