#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
u_long shmem_base; /* Shared memory start address */
void __iomem *shmem;
u_long shmem_length; /* Shared memory window length */
- struct net_device_stats stats; /* Public stats */
struct ewrk3_stats pktStats; /* Private stats counters */
u_char irq_mask; /* Adapter IRQ mask bits */
u_char mPage; /* Maximum 2kB Page number */
** Public Functions
*/
static int ewrk3_open(struct net_device *dev);
-static int ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static netdev_tx_t ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev);
+static irqreturn_t ewrk3_interrupt(int irq, void *dev_id);
static int ewrk3_close(struct net_device *dev);
-static struct net_device_stats *ewrk3_get_stats(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static struct ethtool_ops ethtool_ops_203;
-static struct ethtool_ops ethtool_ops;
+static const struct ethtool_ops ethtool_ops_203;
+static const struct ethtool_ops ethtool_ops;
/*
** Private functions
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
}
- SET_MODULE_OWNER(dev);
err = ewrk3_probe1(dev, dev->base_addr, dev->irq);
- if (err)
+ if (err)
goto out;
return dev;
out:
free_netdev(dev);
return ERR_PTR(err);
-
+
}
#endif
/* Address PROM pattern */
err = isa_probe(dev, iobase);
- if (err != 0)
+ if (err != 0)
err = eisa_probe(dev, iobase);
if (err)
return err;
}
-static int __init
+static const struct net_device_ops ewrk3_netdev_ops = {
+ .ndo_open = ewrk3_open,
+ .ndo_start_xmit = ewrk3_queue_pkt,
+ .ndo_stop = ewrk3_close,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_do_ioctl = ewrk3_ioctl,
+ .ndo_tx_timeout = ewrk3_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static int __init
ewrk3_hw_init(struct net_device *dev, u_long iobase)
{
struct ewrk3_private *lp;
icr &= 0x70;
outb(icr, EWRK3_ICR); /* Disable all the IRQs */
- if (nicsr == (CSR_TXD | CSR_RXD))
+ if (nicsr != (CSR_TXD | CSR_RXD))
return -ENXIO;
-
/* Check that the EEPROM is alive and well and not living on Pluto... */
for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
union {
printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
return -ENXIO;
}
-
+
EthwrkSignature(name, eeprom_image);
- if (*name == '\0')
+ if (*name == '\0')
return -ENXIO;
dev->base_addr = iobase;
-
+
if (iobase > 0x400) {
outb(eisa_cr, EISA_CR); /* Rewrite the EISA CR */
}
lemac = eeprom_image[EEPROM_CHIPVER];
cmr = inb(EWRK3_CMR);
-
+
if (((lemac == LeMAC) && ((cmr & CMR_NO_EEPROM) != CMR_NO_EEPROM)) ||
((lemac == LeMAC2) && !(cmr & CMR_HS))) {
printk("%s: %s at %#4lx", dev->name, name, iobase);
if (lemac != LeMAC2)
DevicePresent(iobase); /* need after EWRK3_INIT */
status = get_hw_addr(dev, eeprom_image, lemac);
- for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet addr. */
- printk("%2.2x:", dev->dev_addr[i]);
- }
- printk("%2.2x,\n", dev->dev_addr[i]);
-
+ printk("%pM\n", dev->dev_addr);
+
if (status) {
printk(" which has an EEPROM CRC error.\n");
return -ENXIO;
if (eeprom_image[EEPROM_SETUP] & SETUP_DRAM)
cmr |= CMR_DRAM;
outb(cmr, EWRK3_CMR);
-
+
cr = inb(EWRK3_CR); /* Set up the Control Register */
cr |= eeprom_image[EEPROM_SETUP] & SETUP_APD;
if (cr & SETUP_APD)
** uncommenting this line.
*/
/* FORCE_2K_MODE; */
-
+
if (hard_strapped) {
printk(" is hard strapped.\n");
} else if (mem_start) {
lp->hard_strapped = hard_strapped;
lp->led_mask = CR_LED;
spin_lock_init(&lp->hw_lock);
-
+
lp->mPage = 64;
if (cmr & CMR_DRAM)
lp->mPage <<= 1; /* 2 DRAMS on module */
-
+
sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
-
+
lp->irq_mask = ICR_TNEM | ICR_TXDM | ICR_RNEM | ICR_RXDM;
-
+
if (!hard_strapped) {
/*
** Enable EWRK3 board interrupts for autoprobing
*/
icr |= ICR_IE; /* Enable interrupts */
outb(icr, EWRK3_ICR);
-
+
/* The DMA channel may be passed in on this parameter. */
dev->dma = 0;
-
+
/* To auto-IRQ we enable the initialization-done and DMA err,
interrupts. For now we will always get a DMA error. */
if (dev->irq < 2) {
#ifndef MODULE
u_char irqnum;
unsigned long irq_mask;
-
+
irq_mask = probe_irq_on();
-
+
/*
** Trigger a TNE interrupt.
*/
icr |= ICR_TNEM;
outb(1, EWRK3_TDQ); /* Write to the TX done queue */
outb(icr, EWRK3_ICR); /* Unmask the TXD interrupt */
-
+
irqnum = irq[((icr & IRQ_SEL) >> 4)];
-
+
mdelay(20);
dev->irq = probe_irq_off(irq_mask);
if ((dev->irq) && (irqnum == dev->irq)) {
printk(version);
}
/* The EWRK3-specific entries in the device structure. */
- dev->open = ewrk3_open;
- dev->hard_start_xmit = ewrk3_queue_pkt;
- dev->stop = ewrk3_close;
- dev->get_stats = ewrk3_get_stats;
- dev->set_multicast_list = set_multicast_list;
- dev->do_ioctl = ewrk3_ioctl;
+ dev->netdev_ops = &ewrk3_netdev_ops;
if (lp->adapter_name[4] == '3')
SET_ETHTOOL_OPS(dev, ðtool_ops_203);
else
SET_ETHTOOL_OPS(dev, ðtool_ops);
- dev->tx_timeout = ewrk3_timeout;
dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
-
+
dev->mem_start = 0;
return 0;
}
-\f
+
static int ewrk3_open(struct net_device *dev)
{
struct ewrk3_private *lp = netdev_priv(dev);
u_long iobase = dev->base_addr;
- int i, status = 0;
+ int status = 0;
u_char icr, csr;
/*
if (ewrk3_debug > 1) {
printk("%s: ewrk3 open with irq %d\n", dev->name, dev->irq);
- printk(" physical address: ");
- for (i = 0; i < 5; i++) {
- printk("%2.2x:", (u_char) dev->dev_addr[i]);
- }
- printk("%2.2x\n", (u_char) dev->dev_addr[i]);
+ printk(" physical address: %pM\n", dev->dev_addr);
if (lp->shmem_length == 0) {
printk(" no shared memory, I/O only mode\n");
} else {
/*
* Transmit timeout
*/
-
+
static void ewrk3_timeout(struct net_device *dev)
{
struct ewrk3_private *lp = netdev_priv(dev);
u_char icr, csr;
u_long iobase = dev->base_addr;
-
- if (!lp->hard_strapped)
+
+ if (!lp->hard_strapped)
{
printk(KERN_WARNING"%s: transmit timed/locked out, status %04x, resetting.\n",
dev->name, inb(EWRK3_CSR));
*/
ENABLE_IRQs;
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
netif_wake_queue(dev);
}
}
/*
** Writes a socket buffer to the free page queue
*/
-static int ewrk3_queue_pkt (struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev)
{
struct ewrk3_private *lp = netdev_priv(dev);
u_long iobase = dev->base_addr;
ENABLE_IRQs;
spin_unlock_irq (&lp->hw_lock);
- lp->stats.tx_bytes += skb->len;
- dev->trans_start = jiffies;
+ dev->stats.tx_bytes += skb->len;
dev_kfree_skb (skb);
/* Check for free resources: stop Tx queue if there are none */
if (inb (EWRK3_FMQC) == 0)
netif_stop_queue (dev);
- return 0;
+ return NETDEV_TX_OK;
err_out:
ENABLE_IRQs;
spin_unlock_irq (&lp->hw_lock);
- return 1;
+ return NETDEV_TX_BUSY;
}
/*
** The EWRK3 interrupt handler.
*/
-static irqreturn_t ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ewrk3_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct ewrk3_private *lp;
}
if (!(rx_status & R_ROK)) { /* There was an error. */
- lp->stats.rx_errors++; /* Update the error stats. */
+ dev->stats.rx_errors++; /* Update the error stats. */
if (rx_status & R_DBE)
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (rx_status & R_CRC)
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (rx_status & R_PLL)
- lp->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
} else {
struct sk_buff *skb;
if ((skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
unsigned char *p;
- skb->dev = dev;
skb_reserve(skb, 2); /* Align to 16 bytes */
p = skb_put(skb, pkt_len);
/*
** Update stats
*/
- dev->last_rx = jiffies;
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
} else {
printk("%s: Insufficient memory; nuking packet.\n", dev->name);
- lp->stats.rx_dropped++; /* Really, deferred. */
+ dev->stats.rx_dropped++; /* Really, deferred. */
break;
}
}
while ((tx_status = inb(EWRK3_TDQ)) > 0) { /* Whilst there's old buffers */
if (tx_status & T_VSTS) { /* The status is valid */
if (tx_status & T_TXE) {
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (tx_status & T_NCL)
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if (tx_status & T_LCL)
- lp->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
if (tx_status & T_CTU) {
if ((tx_status & T_COLL) ^ T_XUR) {
lp->pktStats.tx_underruns++;
}
} else if (tx_status & T_COLL) {
if ((tx_status & T_COLL) ^ T_XCOLL) {
- lp->stats.collisions++;
+ dev->stats.collisions++;
} else {
lp->pktStats.excessive_collisions++;
}
}
} else {
- lp->stats.tx_packets++;
+ dev->stats.tx_packets++;
}
}
}
u_char icr, csr;
netif_stop_queue(dev);
-
+
if (ewrk3_debug > 1) {
printk("%s: Shutting down ethercard, status was %2.2x.\n",
dev->name, inb(EWRK3_CSR));
return 0;
}
-static struct net_device_stats *ewrk3_get_stats(struct net_device *dev)
-{
- struct ewrk3_private *lp = netdev_priv(dev);
-
- /* Null body since there is no framing error counter */
- return &lp->stats;
-}
-
/*
** Set or clear the multicast filter for this adapter.
*/
static void SetMulticastFilter(struct net_device *dev)
{
struct ewrk3_private *lp = netdev_priv(dev);
- struct dev_mc_list *dmi = dev->mc_list;
+ struct netdev_hw_addr *ha;
u_long iobase = dev->base_addr;
int i;
char *addrs, bit, byte;
}
/* Update table */
- for (i = 0; i < dev->mc_count; i++) { /* for each address in the list */
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
+ netdev_for_each_mc_addr(ha, dev) {
+ addrs = ha->addr;
if ((*addrs & 0x01) == 1) { /* multicast address? */
crc = ether_crc_le(ETH_ALEN, addrs);
hashcode = crc & ((1 << 9) - 1); /* hashcode is 9 LSb of CRC */
if (ioaddr < 0x1000)
goto out;
- if (ioaddr == 0) { /* Autoprobing */
- iobase = EISA_SLOT_INC; /* Get the first slot address */
- i = 1;
- maxSlots = MAX_EISA_SLOTS;
- } else { /* Probe a specific location */
- iobase = ioaddr;
- i = (ioaddr >> 12);
- maxSlots = i + 1;
- }
+ iobase = ioaddr;
+ i = (ioaddr >> 12);
+ maxSlots = i + 1;
for (i = 1; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) {
if (EISA_signature(name, EISA_ID) == 0) {
name[EWRK3_STRLEN] = '\0';
} else
name[0] = '\0';
-
- return;
}
/*
return signal_pending(current) ? -ERESTARTSYS : 0;
}
-static struct ethtool_ops ethtool_ops_203 = {
+static const struct ethtool_ops ethtool_ops_203 = {
.get_drvinfo = ewrk3_get_drvinfo,
.get_settings = ewrk3_get_settings,
.set_settings = ewrk3_set_settings,
.phys_id = ewrk3_phys_id,
};
-static struct ethtool_ops ethtool_ops = {
+static const struct ethtool_ops ethtool_ops = {
.get_drvinfo = ewrk3_get_drvinfo,
.get_settings = ewrk3_get_settings,
.set_settings = ewrk3_set_settings,
u_char addr[HASH_TABLE_LEN * ETH_ALEN];
u_short val[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
};
-
+
union ewrk3_addr *tmp;
/* All we handle are private IOCTLs */
if (copy_to_user(ioc->data, tmp->addr, ioc->len))
status = -EFAULT;
break;
-
+
case EWRK3_SET_HWADDR: /* Set the hardware address */
if (capable(CAP_NET_ADMIN)) {
spin_lock_irqsave(&lp->hw_lock, flags);
break;
case EWRK3_SET_MCA: /* Set a multicast address */
if (capable(CAP_NET_ADMIN)) {
- if (ioc->len > 1024)
- {
+ if (ioc->len > HASH_TABLE_LEN) {
status = -EINVAL;
break;
}
module_init(ewrk3_init_module);
#endif /* MODULE */
MODULE_LICENSE("GPL");
-
-\f
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c"
- *
- * compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c"
- * End:
- */