Commit 64de62b4 authored by Jeff Garzik's avatar Jeff Garzik

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

into redhat.com:/spare/repo/net-drivers-2.6
parents ee86da9d 3c08665c
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
*************************************************************************/ *************************************************************************/
#define DRV_NAME "pcnet32" #define DRV_NAME "pcnet32"
#define DRV_VERSION "1.29" #define DRV_VERSION "1.30c"
#define DRV_RELDATE "04.06.2004" #define DRV_RELDATE "05.25.2004"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
static const char *version = static const char *version =
...@@ -86,7 +86,7 @@ static int pcnet32vlb; /* check for VLB cards ? */ ...@@ -86,7 +86,7 @@ static int pcnet32vlb; /* check for VLB cards ? */
static struct net_device *pcnet32_dev; static struct net_device *pcnet32_dev;
static int max_interrupt_work = 80; static int max_interrupt_work = 2;
static int rx_copybreak = 200; static int rx_copybreak = 200;
#define PCNET32_PORT_AUI 0x00 #define PCNET32_PORT_AUI 0x00
...@@ -132,7 +132,7 @@ static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] = { ...@@ -132,7 +132,7 @@ static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] = {
}; };
#define PCNET32_TEST_LEN (sizeof(pcnet32_gstrings_test) / ETH_GSTRING_LEN) #define PCNET32_TEST_LEN (sizeof(pcnet32_gstrings_test) / ETH_GSTRING_LEN)
#define PCNET32_NUM_REGS 146 #define PCNET32_NUM_REGS 168
#define MAX_UNITS 8 /* More are supported, limit only on options */ #define MAX_UNITS 8 /* More are supported, limit only on options */
static int options[MAX_UNITS]; static int options[MAX_UNITS];
...@@ -239,6 +239,12 @@ static int full_duplex[MAX_UNITS]; ...@@ -239,6 +239,12 @@ static int full_duplex[MAX_UNITS];
* identification code (blink led's) and register dump. * identification code (blink led's) and register dump.
* Don Fry added timer for 971/972 so skbufs don't remain on tx ring * Don Fry added timer for 971/972 so skbufs don't remain on tx ring
* forever. * forever.
* v1.30 18 May 2004 Don Fry removed timer and Last Transmit Interrupt
* (ltint) as they added complexity and didn't give good throughput.
* v1.30a 22 May 2004 Don Fry limit frames received during interrupt.
* v1.30b 24 May 2004 Don Fry fix bogus tx carrier errors with 79c973,
* assisted by Bruce Penrod <bmpenrod@endruntechnologies.com>.
* v1.30c 25 May 2004 Don Fry added netif_wake_queue after pcnet32_restart.
*/ */
...@@ -343,7 +349,6 @@ struct pcnet32_private { ...@@ -343,7 +349,6 @@ struct pcnet32_private {
char tx_full; char tx_full;
int options; int options;
int shared_irq:1, /* shared irq possible */ int shared_irq:1, /* shared irq possible */
ltint:1, /* enable TxDone-intr inhibitor */
dxsuflo:1, /* disable transmit stop on uflo */ dxsuflo:1, /* disable transmit stop on uflo */
mii:1; /* mii port available */ mii:1; /* mii port available */
struct net_device *next; struct net_device *next;
...@@ -844,12 +849,12 @@ static int pcnet32_phys_id(struct net_device *dev, u32 data) ...@@ -844,12 +849,12 @@ static int pcnet32_phys_id(struct net_device *dev, u32 data)
return 0; return 0;
} }
int pcnet32_get_regs_len(struct net_device *dev) static int pcnet32_get_regs_len(struct net_device *dev)
{ {
return(PCNET32_NUM_REGS * sizeof(u16)); return(PCNET32_NUM_REGS * sizeof(u16));
} }
void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *ptr) void *ptr)
{ {
int i, csr0; int i, csr0;
...@@ -887,17 +892,27 @@ void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, ...@@ -887,17 +892,27 @@ void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
for (i=0; i<16; i += 2) for (i=0; i<16; i += 2)
*buff++ = inw(ioaddr + i); *buff++ = inw(ioaddr + i);
for (i = 0; i <= 89; i++) { /* read control and status registers */
for (i=0; i<90; i++) {
*buff++ = a->read_csr(ioaddr, i); *buff++ = a->read_csr(ioaddr, i);
} }
*buff++ = a->read_csr(ioaddr, 112); *buff++ = a->read_csr(ioaddr, 112);
*buff++ = a->read_csr(ioaddr, 114); *buff++ = a->read_csr(ioaddr, 114);
for (i = 0; i <= 35; i++) { /* read bus configuration registers */
for (i=0; i<36; i++) {
*buff++ = a->read_bcr(ioaddr, i); *buff++ = a->read_bcr(ioaddr, i);
} }
/* read mii phy registers */
if (lp->mii) {
for (i=0; i<32; i++) {
lp->a.write_bcr(ioaddr, 33, ((lp->mii_if.phy_id) << 5) | i);
*buff++ = lp->a.read_bcr(ioaddr, 34);
}
}
if (!(csr0 & 0x0004)) { /* If not stopped */ if (!(csr0 & 0x0004)) { /* If not stopped */
/* clear SUSPEND (SPND) - CSR5 bit 0 */ /* clear SUSPEND (SPND) - CSR5 bit 0 */
a->write_csr(ioaddr, 5, 0x0000); a->write_csr(ioaddr, 5, 0x0000);
...@@ -999,7 +1014,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared, ...@@ -999,7 +1014,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
struct pcnet32_private *lp; struct pcnet32_private *lp;
dma_addr_t lp_dma_addr; dma_addr_t lp_dma_addr;
int i, media; int i, media;
int fdx, mii, fset, dxsuflo, ltint; int fdx, mii, fset, dxsuflo;
int chip_version; int chip_version;
char *chipname; char *chipname;
struct net_device *dev; struct net_device *dev;
...@@ -1031,7 +1046,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared, ...@@ -1031,7 +1046,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
} }
/* initialize variables */ /* initialize variables */
fdx = mii = fset = dxsuflo = ltint = 0; fdx = mii = fset = dxsuflo = 0;
chip_version = (chip_version >> 12) & 0xffff; chip_version = (chip_version >> 12) & 0xffff;
switch (chip_version) { switch (chip_version) {
...@@ -1051,7 +1066,6 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared, ...@@ -1051,7 +1066,6 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
case 0x2623: case 0x2623:
chipname = "PCnet/FAST 79C971"; /* PCI */ chipname = "PCnet/FAST 79C971"; /* PCI */
fdx = 1; mii = 1; fset = 1; fdx = 1; mii = 1; fset = 1;
ltint = 1;
break; break;
case 0x2624: case 0x2624:
chipname = "PCnet/FAST+ 79C972"; /* PCI */ chipname = "PCnet/FAST+ 79C972"; /* PCI */
...@@ -1082,7 +1096,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared, ...@@ -1082,7 +1096,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
fdx = 1; mii = 1; fdx = 1; mii = 1;
break; break;
case 0x2628: case 0x2628:
chipname = "PCnet/FAST III 79C976"; chipname = "PCnet/PRO 79C976";
fdx = 1; mii = 1; fdx = 1; mii = 1;
break; break;
default: default:
...@@ -1104,14 +1118,6 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared, ...@@ -1104,14 +1118,6 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0860)); a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0860));
a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00); a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00);
dxsuflo = 1; dxsuflo = 1;
ltint = 1;
}
if (ltint) {
/* Enable timer to prevent skbuffs from remaining on the tx ring
* forever if no other tx being done. Set timer period to about
* 122 ms */
a->write_bcr(ioaddr, 31, 0x253b);
} }
dev = alloc_etherdev(0); dev = alloc_etherdev(0);
...@@ -1218,7 +1224,6 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared, ...@@ -1218,7 +1224,6 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
lp->mii_if.phy_id_mask = 0x1f; lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f; lp->mii_if.reg_num_mask = 0x1f;
lp->dxsuflo = dxsuflo; lp->dxsuflo = dxsuflo;
lp->ltint = ltint;
lp->mii = mii; lp->mii = mii;
lp->msg_enable = pcnet32_debug; lp->msg_enable = pcnet32_debug;
if ((cards_found >= MAX_UNITS) || (options[cards_found] > sizeof(options_mapping))) if ((cards_found >= MAX_UNITS) || (options[cards_found] > sizeof(options_mapping)))
...@@ -1437,12 +1442,6 @@ pcnet32_open(struct net_device *dev) ...@@ -1437,12 +1442,6 @@ pcnet32_open(struct net_device *dev)
} }
#endif #endif
if (lp->ltint) { /* Enable TxDone-intr inhibitor */
val = lp->a.read_csr (ioaddr, 5);
val |= (1<<14);
lp->a.write_csr (ioaddr, 5, val);
}
lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
pcnet32_load_multicast(dev); pcnet32_load_multicast(dev);
...@@ -1460,11 +1459,6 @@ pcnet32_open(struct net_device *dev) ...@@ -1460,11 +1459,6 @@ pcnet32_open(struct net_device *dev)
lp->a.write_csr (ioaddr, 4, 0x0915); lp->a.write_csr (ioaddr, 4, 0x0915);
lp->a.write_csr (ioaddr, 0, 0x0001); lp->a.write_csr (ioaddr, 0, 0x0001);
if (lp->ltint) {
/* start the software timer */
lp->a.write_csr(ioaddr, 7, 0x0400); /* set STINTE */
}
netif_start_queue(dev); netif_start_queue(dev);
/* If we have mii, print the link status and start the watchdog */ /* If we have mii, print the link status and start the watchdog */
...@@ -1640,12 +1634,16 @@ pcnet32_tx_timeout (struct net_device *dev) ...@@ -1640,12 +1634,16 @@ pcnet32_tx_timeout (struct net_device *dev)
lp->cur_rx); lp->cur_rx);
for (i = 0 ; i < RX_RING_SIZE; i++) for (i = 0 ; i < RX_RING_SIZE; i++)
printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ", printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
lp->rx_ring[i].base, -lp->rx_ring[i].buf_length, le32_to_cpu(lp->rx_ring[i].base),
lp->rx_ring[i].msg_length, (unsigned)lp->rx_ring[i].status); (-le16_to_cpu(lp->rx_ring[i].buf_length)) & 0xffff,
le32_to_cpu(lp->rx_ring[i].msg_length),
le16_to_cpu(lp->rx_ring[i].status));
for (i = 0 ; i < TX_RING_SIZE; i++) for (i = 0 ; i < TX_RING_SIZE; i++)
printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ", printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
lp->tx_ring[i].base, -lp->tx_ring[i].length, le32_to_cpu(lp->tx_ring[i].base),
lp->tx_ring[i].misc, (unsigned)lp->tx_ring[i].status); (-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff,
le32_to_cpu(lp->tx_ring[i].misc),
le16_to_cpu(lp->tx_ring[i].status));
printk("\n"); printk("\n");
} }
pcnet32_restart(dev, 0x0042); pcnet32_restart(dev, 0x0042);
...@@ -1677,19 +1675,6 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1677,19 +1675,6 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
* interrupt when that option is available to us. * interrupt when that option is available to us.
*/ */
status = 0x8300; status = 0x8300;
entry = (lp->cur_tx - lp->dirty_tx) & TX_RING_MOD_MASK;
if ((lp->ltint) &&
((entry == TX_RING_SIZE/3) ||
(entry == (TX_RING_SIZE*2)/3) ||
(entry >= TX_RING_SIZE-2)))
{
/* Enable Successful-TxDone interrupt if we have
* 1/3, 2/3 or nearly all of, our ring buffer Tx'd
* but not yet cleaned up. Thus, most of the time,
* we will not enable Successful-TxDone interrupts.
*/
status = 0x9300;
}
/* Fill in a Tx ring entry */ /* Fill in a Tx ring entry */
...@@ -1733,7 +1718,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) ...@@ -1733,7 +1718,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
struct net_device *dev = dev_id; struct net_device *dev = dev_id;
struct pcnet32_private *lp; struct pcnet32_private *lp;
unsigned long ioaddr; unsigned long ioaddr;
u16 csr0, csr7, rap; u16 csr0,rap;
int boguscnt = max_interrupt_work; int boguscnt = max_interrupt_work;
int must_restart; int must_restart;
...@@ -1750,19 +1735,13 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) ...@@ -1750,19 +1735,13 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
spin_lock(&lp->lock); spin_lock(&lp->lock);
rap = lp->a.read_rap(ioaddr); rap = lp->a.read_rap(ioaddr);
csr0 = lp->a.read_csr (ioaddr, 0); while ((csr0 = lp->a.read_csr (ioaddr, 0)) & 0x8600 && --boguscnt >= 0) {
csr7 = lp->ltint ? lp->a.read_csr(ioaddr, 7) : 0;
while ((csr0 & 0x8600 || csr7 & 0x0800) && --boguscnt >= 0) {
if (csr0 == 0xffff) { if (csr0 == 0xffff) {
break; /* PCMCIA remove happened */ break; /* PCMCIA remove happened */
} }
/* Acknowledge all of the current interrupt sources ASAP. */ /* Acknowledge all of the current interrupt sources ASAP. */
lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f); lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f);
if (csr7 & 0x0800)
lp->a.write_csr(ioaddr, 7, csr7);
must_restart = 0; must_restart = 0;
if (netif_msg_intr(lp)) if (netif_msg_intr(lp))
...@@ -1772,7 +1751,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) ...@@ -1772,7 +1751,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if (csr0 & 0x0400) /* Rx interrupt */ if (csr0 & 0x0400) /* Rx interrupt */
pcnet32_rx(dev); pcnet32_rx(dev);
if (csr0 & 0x0200 || csr7 & 0x0800) { /* Tx-done or Timer interrupt */ if (csr0 & 0x0200) { /* Tx-done interrupt */
unsigned int dirty_tx = lp->dirty_tx; unsigned int dirty_tx = lp->dirty_tx;
int delta; int delta;
...@@ -1789,6 +1768,9 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) ...@@ -1789,6 +1768,9 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* There was an major error, log it. */ /* There was an major error, log it. */
int err_status = le32_to_cpu(lp->tx_ring[entry].misc); int err_status = le32_to_cpu(lp->tx_ring[entry].misc);
lp->stats.tx_errors++; lp->stats.tx_errors++;
if (netif_msg_tx_err(lp))
printk(KERN_ERR "%s: Tx error status=%04x err_status=%08x\n",
dev->name, status, err_status);
if (err_status & 0x04000000) lp->stats.tx_aborted_errors++; if (err_status & 0x04000000) lp->stats.tx_aborted_errors++;
if (err_status & 0x08000000) lp->stats.tx_carrier_errors++; if (err_status & 0x08000000) lp->stats.tx_carrier_errors++;
if (err_status & 0x10000000) lp->stats.tx_window_errors++; if (err_status & 0x10000000) lp->stats.tx_window_errors++;
...@@ -1833,7 +1815,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) ...@@ -1833,7 +1815,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
} }
delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE); delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE);
if (delta >= TX_RING_SIZE) { if (delta > TX_RING_SIZE) {
if (netif_msg_drv(lp)) if (netif_msg_drv(lp))
printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n", printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
dev->name, dirty_tx, lp->cur_tx, lp->tx_full); dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
...@@ -1878,10 +1860,8 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) ...@@ -1878,10 +1860,8 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* stop the chip to clear the error condition, then restart */ /* stop the chip to clear the error condition, then restart */
lp->a.write_csr (ioaddr, 0, 0x0004); lp->a.write_csr (ioaddr, 0, 0x0004);
pcnet32_restart(dev, 0x0002); pcnet32_restart(dev, 0x0002);
netif_wake_queue(dev);
} }
csr0 = lp->a.read_csr (ioaddr, 0);
csr7 = lp->ltint ? lp->a.read_csr(ioaddr, 7) : 0;
} }
/* Clear any other interrupt, and set interrupt enable. */ /* Clear any other interrupt, and set interrupt enable. */
...@@ -1902,6 +1882,7 @@ pcnet32_rx(struct net_device *dev) ...@@ -1902,6 +1882,7 @@ pcnet32_rx(struct net_device *dev)
{ {
struct pcnet32_private *lp = dev->priv; struct pcnet32_private *lp = dev->priv;
int entry = lp->cur_rx & RX_RING_MOD_MASK; int entry = lp->cur_rx & RX_RING_MOD_MASK;
int boguscnt = RX_RING_SIZE / 2;
/* If we own the next entry, it's a new packet. Send it up. */ /* If we own the next entry, it's a new packet. Send it up. */
while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) { while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
...@@ -2004,6 +1985,7 @@ pcnet32_rx(struct net_device *dev) ...@@ -2004,6 +1985,7 @@ pcnet32_rx(struct net_device *dev)
wmb(); /* Make sure owner changes after all others are visible */ wmb(); /* Make sure owner changes after all others are visible */
lp->rx_ring[entry].status |= le16_to_cpu(0x8000); lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
entry = (++lp->cur_rx) & RX_RING_MOD_MASK; entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
if (--boguscnt <= 0) break; /* don't stay in loop forever */
} }
return 0; return 0;
...@@ -2032,10 +2014,6 @@ pcnet32_close(struct net_device *dev) ...@@ -2032,10 +2014,6 @@ pcnet32_close(struct net_device *dev)
/* We stop the PCNET32 here -- it occasionally polls memory if we don't. */ /* We stop the PCNET32 here -- it occasionally polls memory if we don't. */
lp->a.write_csr (ioaddr, 0, 0x0004); lp->a.write_csr (ioaddr, 0, 0x0004);
if (lp->ltint) { /* Disable timer interrupts */
lp->a.write_csr(ioaddr, 7, 0x0000);
}
/* /*
* Switch back to 16bit mode to avoid problems with dumb * Switch back to 16bit mode to avoid problems with dumb
* DOS packet driver after a warm reboot * DOS packet driver after a warm reboot
...@@ -2154,44 +2132,39 @@ static void pcnet32_set_multicast_list(struct net_device *dev) ...@@ -2154,44 +2132,39 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
} }
lp->a.write_csr (ioaddr, 0, 0x0004); /* Temporarily stop the lance. */ lp->a.write_csr (ioaddr, 0, 0x0004); /* Temporarily stop the lance. */
pcnet32_restart(dev, 0x0042); /* Resume normal operation */ pcnet32_restart(dev, 0x0042); /* Resume normal operation */
netif_wake_queue(dev);
spin_unlock_irqrestore(&lp->lock, flags); spin_unlock_irqrestore(&lp->lock, flags);
} }
/* This routine assumes that the lp->lock is held */
static int mdio_read(struct net_device *dev, int phy_id, int reg_num) static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
{ {
struct pcnet32_private *lp = dev->priv; struct pcnet32_private *lp = dev->priv;
unsigned long ioaddr = dev->base_addr; unsigned long ioaddr = dev->base_addr;
u16 val_out; u16 val_out;
int phyaddr;
if (!lp->mii) if (!lp->mii)
return 0; return 0;
phyaddr = lp->a.read_bcr(ioaddr, 33);
lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f)); lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
val_out = lp->a.read_bcr(ioaddr, 34); val_out = lp->a.read_bcr(ioaddr, 34);
lp->a.write_bcr(ioaddr, 33, phyaddr);
return val_out; return val_out;
} }
/* This routine assumes that the lp->lock is held */
static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val) static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
{ {
struct pcnet32_private *lp = dev->priv; struct pcnet32_private *lp = dev->priv;
unsigned long ioaddr = dev->base_addr; unsigned long ioaddr = dev->base_addr;
int phyaddr;
if (!lp->mii) if (!lp->mii)
return; return;
phyaddr = lp->a.read_bcr(ioaddr, 33);
lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f)); lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
lp->a.write_bcr(ioaddr, 34, val); lp->a.write_bcr(ioaddr, 34, val);
lp->a.write_bcr(ioaddr, 33, phyaddr);
} }
static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
......
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