#define NE1SM_START_PG 0x20 /* First page of TX buffer */ #define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
#define AX_GPOC_PPDSET BIT(6)
/* device private data */
struct ax_device { struct mii_bus *mii_bus; struct mdiobb_ctrl bb_ctrl; void __iomem *addr_memr;
u8 reg_memr; int link; int speed; int duplex;
/* * ax_initial_check * * do an initial probe for the card to check whether it exists * and is functional
*/ staticint ax_initial_check(struct net_device *dev)
{ struct ei_device *ei_local = netdev_priv(dev); void __iomem *ioaddr = ei_local->mem; int reg0; int regd;
reg0 = ei_inb(ioaddr); if (reg0 == 0xFF) return -ENODEV;
/* * 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 ax_reset_8390(struct net_device *dev)
{ struct ei_device *ei_local = netdev_priv(dev); unsignedlong reset_start_time = jiffies; void __iomem *addr = (void __iomem *)dev->base_addr;
netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
/* Wrapper for __ei_interrupt for platforms that have a platform-specific * way to find out whether the interrupt request might be caused by * the ax88796 chip.
*/ static irqreturn_t ax_ei_interrupt_filtered(int irq, void *dev_id)
{ struct net_device *dev = dev_id; struct ax_device *ax = to_ax_dev(dev); struct platform_device *pdev = to_platform_device(dev->dev.parent);
/* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_local->dmaing) {
netdev_err(dev, "DMAing conflict in %s " "[DMAstat:%d][irqlock:%d].\n",
__func__,
ei_local->dmaing, ei_local->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 ei_outb.
*/ staticvoid ax_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
{ struct ei_device *ei_local = netdev_priv(dev); void __iomem *nic_base = ei_local->mem; char *buf = skb->data;
if (ei_local->dmaing) {
netdev_err(dev, "DMAing conflict in %s " "[DMAstat:%d][irqlock:%d].\n",
__func__,
ei_local->dmaing, ei_local->irqlock); return;
}
/* * Round the count up for word writes. Do we need to do this? * What effect will an odd byte count have on the 8390? I * should check someday.
*/ if (ei_local->word16 && (count & 0x01))
count++;
/* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_local->dmaing) {
netdev_err(dev, "DMAing conflict in %s." "[DMAstat:%d][irqlock:%d]\n",
__func__,
ei_local->dmaing, ei_local->irqlock); return;
}
ei_local->dmaing |= 0x01; /* We should already be in page 0, but to be safe... */
ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
ei_outb(ENISR_RDC, nic_base + EN0_ISR);
/* Now the normal output. */
ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
ei_outb(count >> 8, nic_base + EN0_RCNTHI);
ei_outb(0x00, nic_base + EN0_RSARLO);
ei_outb(start_page, nic_base + EN0_RSARHI);
/* find the first phy */
phy_dev = phy_find_first(ax->mii_bus); if (!phy_dev) {
netdev_err(dev, "no PHY found\n"); return -ENODEV;
}
ret = phy_connect_direct(dev, phy_dev, ax_handle_link_change,
PHY_INTERFACE_MODE_MII); if (ret) {
netdev_err(dev, "Could not attach to PHY\n"); return ret;
}
/* set to byte access */
ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG);
ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17));
}
/* * ax_init_dev * * initialise the specified device, taking care to note the MAC * address it may already have (if configured), ensure * the device is ready to be used by lib8390.c and registerd with * the network layer.
*/ staticint ax_init_dev(struct net_device *dev)
{ struct ei_device *ei_local = netdev_priv(dev); struct ax_device *ax = to_ax_dev(dev); void __iomem *ioaddr = ei_local->mem; unsignedint start_page; unsignedint stop_page; int ret; int i;
ret = ax_initial_check(dev); if (ret) goto err_out;
/* setup goes here */
ax_initial_setup(dev, ei_local);
/* read the mac from the card prom if we need it */
if (ax->plat->flags & AXFLG_HAS_EEPROM) { unsignedchar SA_prom[32];
#ifdef PACKETBUF_MEMSIZE /* Allow the packet buffer size to be overridden by know-it-alls. */
ei_local->stop_page = ei_local->tx_start_page + PACKETBUF_MEMSIZE; #endif
/* * ax_probe * * This is the entry point when the platform device system uses to * notify us of a new device to attach to. Allocate memory, find the * resources and information passed, and map the necessary registers.
*/ staticint ax_probe(struct platform_device *pdev)
{ struct net_device *dev; struct ei_device *ei_local; struct ax_device *ax; struct resource *irq, *mem, *mem2; unsignedlong mem_size, mem2_size = 0; int ret = 0;
dev = ax__alloc_ei_netdev(sizeof(struct ax_device)); if (dev == NULL) return -ENOMEM;
if (irq->flags & IORESOURCE_IRQ_SHAREABLE)
ax->irqflags |= IRQF_SHARED;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) {
dev_err(&pdev->dev, "no MEM specified\n");
ret = -ENXIO; goto exit_mem;
}
mem_size = resource_size(mem);
/* * setup the register offsets from either the platform data or * by using the size of the resource provided
*/ if (ax->plat->reg_offsets)
ei_local->reg_offset = ax->plat->reg_offsets; else {
ei_local->reg_offset = ax->reg_offsets; for (ret = 0; ret < 0x18; ret++)
ax->reg_offsets[ret] = (mem_size / 0x18) * ret;
}
if (!request_mem_region(mem->start, mem_size, pdev->name)) {
dev_err(&pdev->dev, "cannot reserve registers\n");
ret = -ENXIO; goto exit_mem;
}
¤ 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.0.18Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-06-07)
¤
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.