// SPDX-License-Identifier: GPL-1.0+ /* A Linux device driver for PCI NE2000 clones. * * Authors and other copyright holders: * 1992-2000 by Donald Becker, NE2000 core and various modifications. * 1995-1998 by Paul Gortmaker, core modifications and PCI support. * Copyright 1993 assigned to the United States Government as represented * by the Director, National Security Agency. * * This software may be used and distributed according to the terms of * the GNU General Public License (GPL), incorporated herein by reference. * Drivers based on or derived from this code fall under the GPL and must * retain the authorship, copyright and license notice. This file is not * a complete program and may only be used when the entire operating * system is licensed under the GPL. * * The author may be reached as becker@scyld.com, or C/O * Scyld Computing Corporation * 410 Severn Ave., Suite 210 * Annapolis MD 21403 * * Issues remaining: * People are making PCI NE2000 clones! Oh the horror, the horror... * Limited full-duplex support.
*/
module_param_named(msg_enable, ne2k_msg_enable, int, 0444);
module_param_array(options, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
MODULE_PARM_DESC(options, "Bit 5: full duplex");
MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
/* Some defines that people can play with if so inclined.
*/
/* Use 32 bit data-movement operations instead of 16 bit. */ #define USE_LONGIO
/* Do we implement the read before write bugfix ? */ /* #define NE_RW_BUGFIX */
/* Flags. We rename an existing ei_status field to store flags! * Thus only the low 8 bits are usable for non-init-time flags.
*/ #define ne2k_flags reg0
enum { /* Chip can do only 16/32-bit xfers. */
ONLY_16BIT_IO = 8, ONLY_32BIT_IO = 4, /* User override. */
FORCE_FDX = 0x20,
REALTEK_FDX = 0x40, HOLTEK_FDX = 0x80,
STOP_PG_0x60 = 0x100,
};
/* NEx000-clone boards have a Station Address (SA) PROM (SAPROM) in the packet * buffer memory space. By-the-spec NE2000 clones have 0x57,0x57 in bytes * 0x0e,0x0f of the SAPROM, while other supposed NE2000 clones must be * detected by their SA prefix. * * Reading the SAPROM from a word-wide card with the 8390 set in byte-wide * mode results in doubled values, which can be detected and compensated for. * * The probe is also responsible for initializing the card and filling * in the 'dev' and 'ei_status' structures.
*/
/* Allocate net_device, dev->priv; fill in 8390 specific dev fields. */
dev = alloc_ei_netdev(); if (!dev) {
dev_err(&pdev->dev, "cannot allocate ethernet device\n"); goto err_out_free_res;
}
dev->netdev_ops = &ne2k_netdev_ops;
ei_local = netdev_priv(dev);
ei_local->msg_enable = netif_msg_init(ne2k_msg_enable, default_msg_level);
SET_NETDEV_DEV(dev, &pdev->dev);
/* Reset card. Who knows what dain-bramaged state it was left in. */
{ unsignedlong reset_start_time = jiffies;
outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
/* This looks like a horrible timing loop, but it should never * take more than a few cycles.
*/ while ((inb(ioaddr + EN0_ISR) & ENISR_RESET) == 0) /* Limit wait: '2' avoids jiffy roll-over. */ if (jiffies - reset_start_time > 2) {
dev_err(&pdev->dev, "Card failure (no reset ack).\n"); goto err_out_free_netdev;
} /* Ack all intr. */
outb(0xff, ioaddr + EN0_ISR);
}
/* Read the 16 bytes of station address PROM. * We must first initialize registers, similar * to NS8390_init(eifdev, 0). * We can't reliably read the SAPROM address without this. * (I learned the hard way!).
*/
{ struct {unsignedchar value, offset; } program_seq[] = { /* Select page 0 */
{E8390_NODMA + E8390_PAGE0 + E8390_STOP, E8390_CMD}, /* Set word-wide access */
{0x49, EN0_DCFG}, /* Clear the count regs. */
{0x00, EN0_RCNTLO}, /* Mask completion IRQ */
{0x00, EN0_RCNTHI},
{0x00, EN0_IMR},
{0xFF, EN0_ISR}, /* 0x20 Set to monitor */
{E8390_RXOFF, EN0_RXCR}, /* 0x02 and loopback mode */
{E8390_TXOFF, EN0_TXCR},
{32, EN0_RCNTLO},
{0x00, EN0_RCNTHI}, /* DMA starting at 0x0000 */
{0x00, EN0_RSARLO},
{0x00, EN0_RSARHI},
{E8390_RREAD+E8390_START, E8390_CMD},
}; for (i = 0; i < ARRAY_SIZE(program_seq); i++)
outb(program_seq[i].value,
ioaddr + program_seq[i].offset);
}
/* Note: all PCI cards have at least 16 bit access, so we don't have * to check for 8 bit cards. Most cards permit 32 bit access.
*/ if (flags & ONLY_32BIT_IO) { for (i = 0; i < 4 ; i++)
((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT));
} else for (i = 0; i < 32 /* sizeof(SA_prom )*/; i++)
SA_prom[i] = inb(ioaddr + NE_DATAPORT);
/* We always set the 8390 registers for word mode. */
outb(0x49, ioaddr + EN0_DCFG);
start_page = NESM_START_PG;
/* Magic incantation sequence for full duplex on the supported cards.
*/ staticinlineint set_realtek_fdx(struct net_device *dev)
{ long ioaddr = dev->base_addr;
/* Hard reset the card. This used to pause for the same period that a * 8390 reset command required, but that shouldn't be necessary.
*/ staticvoid ne2k_pci_reset_8390(struct net_device *dev)
{ unsignedlong reset_start_time = jiffies; struct ei_device *ei_local = netdev_priv(dev);
netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n",
jiffies);
/* This check _should_not_ be necessary, omit eventually. */ while ((inb(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) if (jiffies - reset_start_time > 2) {
netdev_err(dev, "%s did not complete.\n", __func__); break;
} /* Ack intr. */
outb(ENISR_RESET, NE_BASE + EN0_ISR);
}
/* Grab the 8390 specific header. Similar to the block_input routine, but * we don't need to be concerned with ring wrap as the header will be at * the start of a page, so we optimize accordingly.
*/
staticvoid ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
{
long nic_base = dev->base_addr;
/* This *shouldn't* happen. If it does, it's the last thing you'll see
*/ if (ei_status.dmaing) {
netdev_err(dev, "DMAing conflict in %s [DMAstat:%d][irqlock:%d].\n",
__func__, ei_status.dmaing, ei_status.irqlock); return;
}
/* Block input and output, similar to the Crynwr packet driver. If you *are porting to a new ethercard, look at the packet driver source for hints. *The NEx000 doesn't share the on-board packet memory -- you have to put *the packet out through the "remote DMA" dataport using outb.
*/
staticvoid ne2k_pci_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
{ long nic_base = dev->base_addr; char *buf = skb->data;
staticvoid ne2k_pci_block_output(struct net_device *dev, int count, constunsignedchar *buf, constint start_page)
{ long nic_base = NE_BASE; unsignedlong dma_start;
/* On little-endian it's always safe to round the count up for * word writes.
*/ if (ei_status.ne2k_flags & ONLY_32BIT_IO)
count = (count + 3) & 0xFFFC; else if (count & 0x01)
count++;
/* This *shouldn't* happen. * If it does, it's the last thing you'll see.
*/ if (ei_status.dmaing) {
netdev_err(dev, "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n",
__func__, ei_status.dmaing, ei_status.irqlock); return;
}
ei_status.dmaing |= 0x01; /* We should already be in page 0, but to be safe... */
outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
#ifdef NE_RW_BUGFIX /* Handle the read-before-write bug the same way as the * Crynwr packet driver -- the NatSemi method doesn't work. * Actually this doesn't always work either, but if you have * problems with your NEx000 this is better than nothing!
*/
outb(0x42, nic_base + EN0_RCNTLO);
outb(0x00, nic_base + EN0_RCNTHI);
outb(0x42, nic_base + EN0_RSARLO);
outb(0x00, nic_base + EN0_RSARHI);
outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); #endif
outb(ENISR_RDC, nic_base + EN0_ISR);
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.