/* Set the number of Tx and Rx buffers, using Log_2(# buffers). Reasonabledefaultvaluesare16Txbuffers,and16Rxbuffers. Thattranslatesto4and4(16==2^^4). Thisisacompile-timeoptionforefficiency.
*/ #ifndef LANCE_LOG_TX_BUFFERS #define LANCE_LOG_TX_BUFFERS 4 #define LANCE_LOG_RX_BUFFERS 4 #endif
/* The LANCE Rx and Tx ring descriptors. */ struct lance_rx_head {
s32 base;
s16 buf_length; /* This length is 2s complement (negative)! */
s16 msg_length; /* This length is "normal". */
};
/* The LANCE initialization block, described in databook. */ struct lance_init_block {
u16 mode; /* Pre-set mode (reg. 15) */
u8 phys_addr[6]; /* Physical ethernet address */
u32 filter[2]; /* Multicast filter (unused). */ /* Receive and transmit ring base, along with extra bits. */
u32 rx_ring; /* Tx and Rx ring base pointers */
u32 tx_ring;
};
struct lance_private { /* The Tx and Rx ring entries must be aligned on 8-byte boundaries. */ struct lance_rx_head rx_ring[RX_RING_SIZE]; struct lance_tx_head tx_ring[TX_RING_SIZE]; struct lance_init_block init_block; constchar *name; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ struct sk_buff* tx_skbuff[TX_RING_SIZE]; /* The addresses of receive-in-place skbuffs. */ struct sk_buff* rx_skbuff[RX_RING_SIZE]; unsignedlong rx_buffs; /* Address of Rx and Tx buffers. */ /* Tx low-memory "bounce buffer" address. */ char (*tx_bounce_buffs)[PKT_BUF_SZ]; int cur_rx, cur_tx; /* The next free ring entry */ int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ int dma; unsignedchar chip_version; /* See lance_chip_type. */
spinlock_t devlock;
};
/* A mapping from the chip ID number to the part number and features. Thesearefromthedatasheets--inreallifethe'970version
reportedly has the same ID as the '965. */ staticstruct lance_chip_type { int id_number; constchar *name; int flags;
} chip_table[] = {
{0x0000, "LANCE 7990", /* Ancient lance chip. */
LANCE_MUST_PAD + LANCE_MUST_UNRESET},
{0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
{0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
{0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME}, /* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
it the PCnet32. */
{0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
{0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
{0x0, "PCnet (unknown)",
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
};
/* Non-zero if lance_probe1() needs to allocate low-memory bounce buffers.
Assume yes until we know the memory size. */ staticunsignedchar lance_need_isa_bounce_buffers = 1;
/* Starting in v2.1.*, the LANCE/PCnet probe is now similar to the other boardprobesnowthatkmalloc()canallocateISADMA-ableregions. ThisalsoallowstheLANCEdrivertobeusedasamodule.
*/ staticint __init do_lance_probe(struct net_device *dev)
{ unsignedint *port; int result;
if (high_memory <= phys_to_virt(16*1024*1024))
lance_need_isa_bounce_buffers = 0;
for (port = lance_portlist; *port; port++) { int ioaddr = *port; struct resource *r = request_region(ioaddr, LANCE_TOTAL_SIZE, "lance-probe");
if (r) { /* Detect the card with minimal I/O reads */ char offset14 = inb(ioaddr + 14); int card; for (card = 0; card < NUM_CARDS; ++card) if (cards[card].id_offset14 == offset14) break; if (card < NUM_CARDS) {/*yes, the first byte matches*/ char offset15 = inb(ioaddr + 15); for (card = 0; card < NUM_CARDS; ++card) if ((cards[card].id_offset14 == offset14) &&
(cards[card].id_offset15 == offset15)) break;
} if (card < NUM_CARDS) { /*Signature OK*/
result = lance_probe1(dev, ioaddr, 0, 0); if (!result) { struct lance_private *lp = dev->ml_priv; int ver = lp->chip_version;
staticint __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
{ struct lance_private *lp; unsignedlong dma_channels; /* Mark spuriously-busy DMA channels */ int i, reset_val, lance_version; constchar *chipname; /* Flags for specific chips or boards. */ unsignedchar hpJ2405A = 0; /* HP ISA adaptor */ int hp_builtin = 0; /* HP on-board ethernet. */ staticint did_version; /* Already printed version info. */ unsignedlong flags; int err = -ENOMEM; void __iomem *bios;
u8 addr[ETH_ALEN];
/* First we look for special cases. CheckforHP'son-boardethernetbylookingfor'HP'intheBIOS. TherearetwoHPversions,checktheBIOSfortheconfigurationport. ThismethodprovidedbyL.Julliard,Laurent_Julliard@grenoble.hp.com.
*/
bios = ioremap(0xf00f0, 0x14); if (!bios) return -ENOMEM; if (readw(bios + 0x12) == 0x5048) { staticconstshort ioaddr_table[] = { 0x300, 0x320, 0x340, 0x360}; int hp_port = (readl(bios + 1) & 1) ? 0x499 : 0x99; /* We can have boards other than the built-in! Verify this is on-board. */ if ((inb(hp_port) & 0xc0) == 0x80 &&
ioaddr_table[inb(hp_port) & 3] == ioaddr)
hp_builtin = hp_port;
}
iounmap(bios); /* We also recognize the HP Vectra on-board here, but check below. */
hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00 &&
inb(ioaddr+2) == 0x09);
/* Reset the LANCE. */
reset_val = inw(ioaddr+LANCE_RESET); /* Reset the LANCE */
/* The Un-Reset needed is only needed for the real NE2100, and will
confuse the HP board. */ if (!hpJ2405A)
outw(reset_val, ioaddr+LANCE_RESET);
outw(0x0000, ioaddr+LANCE_ADDR); /* Switch to window 0 */ if (inw(ioaddr+LANCE_DATA) != 0x0004) return -ENODEV;
/* Get the version of the chip. */
outw(88, ioaddr+LANCE_ADDR); if (inw(ioaddr+LANCE_ADDR) != 88) {
lance_version = 0;
} else { /* Good, it's a newer chip. */ int chip_version = inw(ioaddr+LANCE_DATA);
outw(89, ioaddr+LANCE_ADDR);
chip_version |= inw(ioaddr+LANCE_DATA) << 16; if (lance_debug > 2)
printk(" LANCE chip version is %#x.\n", chip_version); if ((chip_version & 0xfff) != 0x003) return -ENODEV;
chip_version = (chip_version >> 12) & 0xffff; for (lance_version = 1; chip_table[lance_version].id_number; lance_version++) { if (chip_table[lance_version].id_number == chip_version) break;
}
}
/* We can't allocate private data from alloc_etherdev() because it must
a ISA DMA-able region. */
chipname = chip_table[lance_version].name;
printk("%s: %s at %#3x, ", dev->name, chipname, ioaddr);
/* There is a 16 byte station address PROM at the base address.
The first six bytes are the station address. */ for (i = 0; i < 6; i++)
addr[i] = inb(ioaddr + i);
eth_hw_addr_set(dev, addr);
printk("%pM", dev->dev_addr);
dev->base_addr = ioaddr; /* Make certain the data structures used by the LANCE are aligned and DMAble. */
if (dev->dma == 0) { /* Read the DMA channel status register, so that we can avoid
stuck DMA channels in the DMA detection below. */
dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
(inb(DMA2_STAT_REG) & 0xf0);
}
err = -ENODEV; if (dev->irq >= 2)
printk(" assigned IRQ %d", dev->irq); elseif (lance_version != 0) { /* 7990 boards need DMA detection first. */ unsignedlong irq_mask;
/* To auto-IRQ we enable the initialization-done and DMA error interrupts.ForISAboardswegetaDMAerror,butVLBandPCI
boards will work. */
irq_mask = probe_irq_on();
/* Trigger an initialization just for the interrupt. */
outw(0x0041, ioaddr+LANCE_DATA);
/* Check for the initialization done bit, 0x0100, which means
that we don't need a DMA channel. */ if (inw(ioaddr+LANCE_DATA) & 0x0100)
dev->dma = 4;
}
if (dev->dma == 4) {
printk(", no DMA needed.\n");
} elseif (dev->dma) { if (request_dma(dev->dma, chipname)) {
printk("DMA %d allocation failed.\n", dev->dma); goto out_tx;
} else
printk(", assigned DMA %d.\n", dev->dma);
} else { /* OK, we have to auto-DMA. */ for (i = 0; i < 4; i++) { staticconstchar dmas[] = { 5, 6, 7, 3 }; int dma = dmas[i]; int boguscnt;
/* Don't enable a permanently busy DMA channel, or the machine
will hang. */ if (test_bit(dma, &dma_channels)) continue;
outw(0x7f04, ioaddr+LANCE_DATA); /* Clear the memory error bits. */ if (request_dma(dma, chipname)) continue;
/* Trigger an initialization. */
outw(0x0001, ioaddr+LANCE_DATA); for (boguscnt = 100; boguscnt > 0; --boguscnt) if (inw(ioaddr+LANCE_DATA) & 0x0900) break; if (inw(ioaddr+LANCE_DATA) & 0x0100) {
dev->dma = dma;
printk(", DMA %d.\n", dev->dma); break;
} else {
flags=claim_dma_lock();
disable_dma(dma);
release_dma_lock(flags);
free_dma(dma);
}
} if (i == 4) { /* Failure: bail. */
printk("DMA detection failed.\n"); goto out_tx;
}
}
if (lance_version == 0 && dev->irq == 0) { /* We may auto-IRQ now that we have a DMA channel. */ /* Trigger an initialization just for the interrupt. */ unsignedlong irq_mask;
mdelay(40);
dev->irq = probe_irq_off(irq_mask); if (dev->irq == 0) {
printk(" Failed to detect the 7990 IRQ line.\n"); goto out_dma;
}
printk(" Auto-IRQ detected IRQ%d.\n", dev->irq);
}
if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) { /* Turn on auto-select of media (10baseT or BNC) so that the user
can watch the LEDs even if the board isn't opened. */
outw(0x0002, ioaddr+LANCE_ADDR); /* Don't touch 10base2 power bit. */
outw(inw(ioaddr+LANCE_BUS_IF) | 0x0002, ioaddr+LANCE_BUS_IF);
}
if (lance_debug > 0 && did_version++ == 0)
printk(version);
/* The LANCE-specific entries in the device structure. */
dev->netdev_ops = &lance_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
/* We used to allocate DMA here, but that was silly.
DMA lines can't be shared! We now permanently allocate them. */
/* Reset the LANCE */
inw(ioaddr+LANCE_RESET);
/* The DMA controller is used as a no-operation slave, "cascade mode". */ if (dev->dma != 4) { unsignedlong flags=claim_dma_lock();
enable_dma(dev->dma);
set_dma_mode(dev->dma, DMA_MODE_CASCADE);
release_dma_lock(flags);
}
/* Un-Reset the LANCE, needed only for the NE2100. */ if (chip_table[lp->chip_version].flags & LANCE_MUST_UNRESET)
outw(0, ioaddr+LANCE_RESET);
if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) { /* This is 79C960-specific: Turn on auto-select of media (AUI, BNC). */
outw(0x0002, ioaddr+LANCE_ADDR); /* Only touch autoselect bit. */
outw(inw(ioaddr+LANCE_BUS_IF) | 0x0002, ioaddr+LANCE_BUS_IF);
}
i = 0; while (i++ < 100) if (inw(ioaddr+LANCE_DATA) & 0x0100) break; /* *WeusedtocleartheInitDonebit,0x0100,herebutMarkStockton *reportsthatdoingsotriggersabuginthe'974.
*/
outw(0x0042, ioaddr+LANCE_DATA);
if (lance_debug > 2)
printk("%s: LANCE open after %d ticks, init block %#x csr0 %4.4x.\n",
dev->name, i, (u32) isa_virt_to_bus(&lp->init_block), inw(ioaddr+LANCE_DATA));
return0; /* Always succeed */
}
/* The LANCE has been halted for one reason or another (busmaster memory arbitrationerror,TxFIFOunderflow,driverstoppedittoreconfigure, etc.).ModernLANCEvariantsalwaysreloadtheirring-buffer configurationwhenrestarted,sowemustreinitializeourring contextbeforerestarting.Aspartofthisreinitialization, findallpacketsstillontheTxringandpretendthattheyhadbeen sent(ineffect,dropthepacketsonthefloor)-thehigher-level protocolswilltimeoutandretransmit.It'dbebettertoshuffle theseskbstoatemplistandthenactuallyre-Txthemafter restartingthechip,butI'mtoolazytodosorightnow.dplatt@3do.com
*/
/* Free all the skbuffs in the Rx and Tx queues. */ for (i = 0; i < RX_RING_SIZE; i++) { struct sk_buff *skb = lp->rx_skbuff[i];
lp->rx_skbuff[i] = NULL;
lp->rx_ring[i].base = 0; /* Not owned by LANCE chip. */ if (skb)
dev_kfree_skb_any(skb);
} for (i = 0; i < TX_RING_SIZE; i++) { if (lp->tx_skbuff[i]) {
dev_kfree_skb_any(lp->tx_skbuff[i]);
lp->tx_skbuff[i] = NULL;
}
}
}
/* Initialize the LANCE Rx and Tx rings. */ staticvoid
lance_init_ring(struct net_device *dev, gfp_t gfp)
{ struct lance_private *lp = dev->ml_priv; int i;
for (i = 0; i < RX_RING_SIZE; i++) { struct sk_buff *skb; void *rx_buff;
skb = alloc_skb(PKT_BUF_SZ, GFP_DMA | gfp);
lp->rx_skbuff[i] = skb; if (skb)
rx_buff = skb->data; else
rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp); if (!rx_buff)
lp->rx_ring[i].base = 0; else
lp->rx_ring[i].base = (u32)isa_virt_to_bus(rx_buff) | 0x80000000;
lp->rx_ring[i].buf_length = -PKT_BUF_SZ;
} /* The Tx buffer address is filled in as needed, but we do need to clear
the upper ownership bit. */ for (i = 0; i < TX_RING_SIZE; i++) {
lp->tx_skbuff[i] = NULL;
lp->tx_ring[i].base = 0;
}
/* Mask to ring buffer boundary. */
entry = lp->cur_tx & TX_RING_MOD_MASK;
/* Caution: the write order is important here, set the base address
with the "ownership" bits last. */
/* The old LANCE chips doesn't automatically pad buffers to min. size. */ if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) { if (skb->len < ETH_ZLEN) { if (skb_padto(skb, ETH_ZLEN)) goto out;
lp->tx_ring[entry].length = -ETH_ZLEN;
} else
lp->tx_ring[entry].length = -skb->len;
} else
lp->tx_ring[entry].length = -skb->len;
lp->tx_ring[entry].misc = 0x0000;
dev->stats.tx_bytes += skb->len;
/* If any part of this buffer is >16M we must copy it to a low-memory
buffer. */ if ((u32)isa_virt_to_bus(skb->data) + skb->len > 0x01000000) { if (lance_debug > 5)
printk("%s: bouncing a high-memory packet (%#x).\n",
dev->name, (u32)isa_virt_to_bus(skb->data));
skb_copy_from_linear_data(skb, &lp->tx_bounce_buffs[entry], skb->len);
lp->tx_ring[entry].base =
((u32)isa_virt_to_bus((lp->tx_bounce_buffs + entry)) & 0xffffff) | 0x83000000;
dev_consume_skb_irq(skb);
} else {
lp->tx_skbuff[entry] = skb;
lp->tx_ring[entry].base = ((u32)isa_virt_to_bus(skb->data) & 0xffffff) | 0x83000000;
}
lp->cur_tx++;
/* The LANCE interrupt handler. */ static irqreturn_t lance_interrupt(int irq, void *dev_id)
{ struct net_device *dev = dev_id; struct lance_private *lp; int csr0, ioaddr, boguscnt=10; int must_restart;
ioaddr = dev->base_addr;
lp = dev->ml_priv;
spin_lock (&lp->devlock);
outw(0x00, dev->base_addr + LANCE_ADDR); while ((csr0 = inw(dev->base_addr + LANCE_DATA)) & 0x8600 &&
--boguscnt >= 0) { /* Acknowledge all of the current interrupt sources ASAP. */
outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA);
must_restart = 0;
if (lance_debug > 5)
printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n",
dev->name, csr0, inw(dev->base_addr + LANCE_DATA));
if (csr0 & 0x0400) /* Rx interrupt */
lance_rx(dev);
if (csr0 & 0x0200) { /* Tx-done interrupt */ int dirty_tx = lp->dirty_tx;
while (dirty_tx < lp->cur_tx) { int entry = dirty_tx & TX_RING_MOD_MASK; int status = lp->tx_ring[entry].base;
if (status < 0) break; /* It still hasn't been Txed */
lp->tx_ring[entry].base = 0;
if (status & 0x40000000) { /* There was an major error, log it. */ int err_status = lp->tx_ring[entry].misc;
dev->stats.tx_errors++; if (err_status & 0x0400)
dev->stats.tx_aborted_errors++; if (err_status & 0x0800)
dev->stats.tx_carrier_errors++; if (err_status & 0x1000)
dev->stats.tx_window_errors++; if (err_status & 0x4000) { /* Ackk! On FIFO errors the Tx unit is turned off! */
dev->stats.tx_fifo_errors++; /* Remove this verbosity later! */
printk("%s: Tx FIFO error! Status %4.4x.\n",
dev->name, csr0); /* Restart the chip. */
must_restart = 1;
}
} else { if (status & 0x18000000)
dev->stats.collisions++;
dev->stats.tx_packets++;
}
/* We must free the original skb if it's not a data-only copy
in the bounce buffer. */ if (lp->tx_skbuff[entry]) {
dev_consume_skb_irq(lp->tx_skbuff[entry]);
lp->tx_skbuff[entry] = NULL;
}
dirty_tx++;
}
/* if the ring is no longer full, accept more packets */ if (netif_queue_stopped(dev) &&
dirty_tx > lp->cur_tx - TX_RING_SIZE + 2)
netif_wake_queue (dev);
lp->dirty_tx = dirty_tx;
}
/* Log misc errors. */ if (csr0 & 0x4000)
dev->stats.tx_errors++; /* Tx babble. */ if (csr0 & 0x1000)
dev->stats.rx_errors++; /* Missed a Rx frame. */ if (csr0 & 0x0800) {
printk("%s: Bus master arbitration failure, status %4.4x.\n",
dev->name, csr0); /* Restart the chip. */
must_restart = 1;
}
if (must_restart) { /* stop the chip to clear the error condition, then restart */
outw(0x0000, dev->base_addr + LANCE_ADDR);
outw(0x0004, dev->base_addr + LANCE_DATA);
lance_restart(dev, 0x0002, 0);
}
}
/* Clear any other interrupt, and set interrupt enable. */
outw(0x0000, dev->base_addr + LANCE_ADDR);
outw(0x7940, dev->base_addr + LANCE_DATA);
staticint
lance_rx(struct net_device *dev)
{ struct lance_private *lp = dev->ml_priv; int entry = lp->cur_rx & RX_RING_MOD_MASK; int i;
/* If we own the next entry, it's a new packet. Send it up. */ while (lp->rx_ring[entry].base >= 0) { int status = lp->rx_ring[entry].base >> 24;
if (status != 0x03) { /* There was an error. */ /* There is a tricky error noted by John Murphy, <murf@perftech.com>toRussNelson:Evenwithfull-sized buffersit'spossibleforajabberpackettousetwo
buffers, with only the last correctly noting the error. */ if (status & 0x01) /* Only count a general error at the */
dev->stats.rx_errors++; /* end of a packet.*/ if (status & 0x20)
dev->stats.rx_frame_errors++; if (status & 0x10)
dev->stats.rx_over_errors++; if (status & 0x08)
dev->stats.rx_crc_errors++; if (status & 0x04)
dev->stats.rx_fifo_errors++;
lp->rx_ring[entry].base &= 0x03ffffff;
} else
{ /* Malloc up new buffer, compatible with net3. */ short pkt_len = (lp->rx_ring[entry].msg_length & 0xfff)-4; struct sk_buff *skb;
if(pkt_len<60)
{
printk("%s: Runt packet!\n",dev->name);
dev->stats.rx_errors++;
} else
{
skb = dev_alloc_skb(pkt_len+2); if (!skb)
{
printk("%s: Memory squeeze, deferring packet.\n", dev->name); for (i=0; i < RX_RING_SIZE; i++) if (lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].base < 0) break;
if (i > RX_RING_SIZE -2)
{
dev->stats.rx_dropped++;
lp->rx_ring[entry].base |= 0x80000000;
lp->cur_rx++;
} break;
}
skb_reserve(skb,2); /* 16 byte align */
skb_put(skb,pkt_len); /* Make room */
skb_copy_to_linear_data(skb,
(unsignedchar *)isa_bus_to_virt((lp->rx_ring[entry].base & 0x00ffffff)),
pkt_len);
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
}
} /* The docs say that the buffer length isn't touched, but Andrew Boyd
of QNX reports that some revs of the 79C965 clear it. */
lp->rx_ring[entry].buf_length = -PKT_BUF_SZ;
lp->rx_ring[entry].base |= 0x80000000;
entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
}
/* We should check that at least two ring entries are free. If not,
we should free one and mark stats->rx_dropped++. */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.