// SPDX-License-Identifier: GPL-2.0-only /* * linux/drivers/acorn/net/etherh.c * * Copyright (C) 2000-2002 Russell King * * NS8390 I-cubed EtherH and ANT EtherM specific driver * Thanks to I-Cubed for information on their cards. * EtherM conversion (C) 1999 Chris Kemp and Tim Watterton * EtherM integration (C) 2000 Aleph One Ltd (Tak-Shing Chan) * EtherM integration re-engineered by Russell King. * * Changelog: * 08-12-1996 RMK 1.00 Created * RMK 1.03 Added support for EtherLan500 cards * 23-11-1997 RMK 1.04 Added media autodetection * 16-04-1998 RMK 1.05 Improved media autodetection * 10-02-2000 RMK 1.06 Updated for 2.3.43 * 13-05-2000 RMK 1.07 Updated for 2.3.99-pre8 * 12-10-1999 CK/TEW EtherM driver first release * 21-12-2000 TTC EtherH/EtherM integration * 25-12-2000 RMK 1.08 Clean integration of EtherM into this driver. * 03-01-2002 RMK 1.09 Always enable IRQs if we're in the nic slot.
*/
/* set the interface type */ switch (etherh_priv(dev)->id) { case PROD_I3_ETHERLAN600: case PROD_I3_ETHERLAN600A:
addr = (void __iomem *)dev->base_addr + EN0_RCNTHI;
case PROD_I3_ETHERLAN500: switch (dev->if_port) { case IF_PORT_10BASE2:
etherh_clr_ctrl(etherh_priv(dev), ETHERH_CP_IF); break;
case IF_PORT_10BASET:
etherh_set_ctrl(etherh_priv(dev), ETHERH_CP_IF); break;
} break;
default: break;
}
local_irq_restore(flags);
}
staticint
etherh_getifstat(struct net_device *dev)
{ struct ei_device *ei_local = netdev_priv(dev); void __iomem *addr; int stat = 0;
switch (etherh_priv(dev)->id) { case PROD_I3_ETHERLAN600: case PROD_I3_ETHERLAN600A:
addr = (void __iomem *)dev->base_addr + EN0_RCNTHI; switch (dev->if_port) { case IF_PORT_10BASE2:
stat = 1; break; case IF_PORT_10BASET:
stat = readb(addr) & 4; break;
} break;
case PROD_I3_ETHERLAN500: switch (dev->if_port) { case IF_PORT_10BASE2:
stat = 1; break; case IF_PORT_10BASET:
stat = etherh_get_stat(etherh_priv(dev)) & ETHERH_CP_HEARTBEAT; break;
} break;
default:
stat = 0; break;
}
return stat != 0;
}
/* * Configure the interface. Note that we ignore the other * parts of ifmap, since its mostly meaningless for this driver.
*/ staticint etherh_set_config(struct net_device *dev, struct ifmap *map)
{ switch (map->port) { case IF_PORT_10BASE2: case IF_PORT_10BASET: /* * If the user explicitly sets the interface * media type, turn off automedia detection.
*/
dev->flags &= ~IFF_AUTOMEDIA;
WRITE_ONCE(dev->if_port, map->port); break;
default: return -EINVAL;
}
etherh_setif(dev);
return 0;
}
/* * Reset the 8390 (hard reset). Note that we can't actually do this.
*/ staticvoid
etherh_reset(struct net_device *dev)
{ struct ei_device *ei_local = netdev_priv(dev); void __iomem *addr = (void __iomem *)dev->base_addr;
writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr);
/* * See if we need to change the interface type. * Note that we use 'interface_num' as a flag * to indicate that we need to change the media.
*/ if (dev->flags & IFF_AUTOMEDIA && ei_local->interface_num) {
ei_local->interface_num = 0;
/* * Write a block of data out to the 8390
*/ staticvoid
etherh_block_output (struct net_device *dev, int count, constunsignedchar *buf, int start_page)
{ struct ei_device *ei_local = netdev_priv(dev); unsignedlong dma_start; void __iomem *dma_base, *addr;
if (ei_local->dmaing) {
netdev_err(dev, "DMAing conflict in etherh_block_input: " " DMAstat %d irqlock %d\n",
ei_local->dmaing, ei_local->irqlock); return;
}
/* * Make sure we have a round number of bytes if we're in word mode.
*/ if (count & 1 && ei_local->word16)
count++;
/* * Read a block of data from the 8390
*/ staticvoid
etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
{ struct ei_device *ei_local = netdev_priv(dev); unsignedchar *buf; void __iomem *dma_base, *addr;
if (ei_local->dmaing) {
netdev_err(dev, "DMAing conflict in etherh_block_input: " " DMAstat %d irqlock %d\n",
ei_local->dmaing, ei_local->irqlock); return;
}
/* * Open/initialize the board. This is called (in the current kernel) * sometime after booting when the 'ifconfig' program is run. * * This routine should set everything up anew at each open, even * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong.
*/ staticint
etherh_open(struct net_device *dev)
{ struct ei_device *ei_local = netdev_priv(dev);
if (request_irq(dev->irq, __ei_interrupt, 0, dev->name, dev)) return -EAGAIN;
/* * Make sure that we aren't going to change the * media type on the next reset - we are about to * do automedia manually now.
*/
ei_local->interface_num = 0;
/* * If we are doing automedia detection, do it now. * This is more reliable than the 8390's detection.
*/ if (dev->flags & IFF_AUTOMEDIA) {
dev->if_port = IF_PORT_10BASET;
etherh_setif(dev);
mdelay(1); if (!etherh_getifstat(dev)) {
dev->if_port = IF_PORT_10BASE2;
etherh_setif(dev);
}
} else
etherh_setif(dev);
/* * Read the ethernet address string from the on board rom. * This is an ascii string...
*/ staticint etherh_addr(char *addr, struct expansion_card *ec)
{ struct in_chunk_dir cd; char *s;
if (!ecard_readchunk(&cd, ec, 0xf5, 0)) {
printk(KERN_ERR "%s: unable to read module description string\n",
dev_name(&ec->dev)); goto no_addr;
}
s = strchr(cd.d.string, '('); if (s) { int i;
for (i = 0; i < 6; i++) {
addr[i] = simple_strtoul(s + 1, &s, 0x10); if (*s != (i == 5? ')' : ':')) break;
}
if (i == 6) return 0;
}
printk(KERN_ERR "%s: unable to parse MAC address: %s\n",
dev_name(&ec->dev), cd.d.string);
no_addr: return -ENODEV;
}
/* * Create an ethernet address from the system serial number.
*/ staticint __init etherm_addr(char *addr)
{ unsignedint serial;
if (system_serial_low == 0 && system_serial_high == 0) return -ENODEV;
/* * IRQ and control port handling - only for non-NIC slot cards.
*/ if (ec->slot_no != 8) {
ecard_setirq(ec, ðerh_ops, eh);
} else { /* * If we're in the NIC slot, make sure the IRQ is enabled
*/
etherh_set_ctrl(eh, ETHERH_CP_IE);
}
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.