static irqreturn_t elp_interrupt(int irq, void *dev_id) { int len; int dlen; int icount = 0; struct net_device *dev; elp_device *adapter; unsigned long timeout; dev = dev_id; adapter = (elp_device *) dev->priv; spin_lock(&adapter->lock); do { /* * has a DMA transfer finished? */ if (inb_status(dev->base_addr) & DONE) { if (!adapter->dmaing) { printk(KERN_WARNING "%s: phantom DMA completed\n", dev->name); } if (elp_debug >= 3) { printk(KERN_DEBUG "%s: %s DMA complete, status %02x\n", dev->name, adapter->current_dma.direction ? "tx" : "rx", inb_status(dev->base_addr)); } outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev); if (adapter->current_dma.direction) { dev_kfree_skb_irq(adapter->current_dma.skb); } else { struct sk_buff *skb = adapter->current_dma.skb; if (skb) { if (adapter->current_dma.target) { /* have already done the skb_put() */ memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length); } skb->protocol = eth_type_trans(skb,dev); adapter->stats.rx_bytes += skb->len; netif_rx(skb); dev->last_rx = jiffies; } } adapter->dmaing = 0; if (adapter->rx_backlog.in != adapter->rx_backlog.out) { int t = adapter->rx_backlog.length[adapter->rx_backlog.out]; adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out); if (elp_debug >= 2) printk(KERN_DEBUG "%s: receiving backlogged packet (%d)\n", dev->name, t); receive_packet(dev, t); } else { adapter->busy = 0; } } else { /* has one timed out? */ check_3c505_dma(dev); } /* * receive a PCB from the adapter */ timeout = jiffies + 3*HZ/100; while ((inb_status(dev->base_addr) & ACRF) != 0 && time_before(jiffies, timeout)) { if (receive_pcb(dev, &adapter->irx_pcb)) { switch (adapter->irx_pcb.command) { case 0: break; /* * received a packet - this must be handled fast */ case 0xff: case CMD_RECEIVE_PACKET_COMPLETE: /* if the device isn't open, don't pass packets up the stack */ if (!netif_running(dev)) break; len = adapter->irx_pcb.data.rcv_resp.pkt_len; dlen = adapter->irx_pcb.data.rcv_resp.buf_len; if (adapter->irx_pcb.data.rcv_resp.timeout != 0) { printk(KERN_ERR "%s: interrupt - packet not received correctly\n", dev->name); } else { if (elp_debug >= 3) { printk(KERN_DEBUG "%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen); } if (adapter->irx_pcb.command == 0xff) { if (elp_debug >= 2) printk(KERN_DEBUG "%s: adding packet to backlog (len = %d)\n", dev->name, dlen); adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen; adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in); } else { receive_packet(dev, dlen); } if (elp_debug >= 3) printk(KERN_DEBUG "%s: packet received\n", dev->name); } break; /* * 82586 configured correctly */ case CMD_CONFIGURE_82586_RESPONSE: adapter->got[CMD_CONFIGURE_82586] = 1; if (elp_debug >= 3) printk(KERN_DEBUG "%s: interrupt - configure response received\n", dev->name); break; /* * Adapter memory configuration */ case CMD_CONFIGURE_ADAPTER_RESPONSE: adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1; if (elp_debug >= 3) printk(KERN_DEBUG "%s: Adapter memory configuration %s.\n", dev->name, adapter->irx_pcb.data.failed ? "failed" : "succeeded"); break; /* * Multicast list loading */ case CMD_LOAD_MULTICAST_RESPONSE: adapter->got[CMD_LOAD_MULTICAST_LIST] = 1; if (elp_debug >= 3) printk(KERN_DEBUG "%s: Multicast address list loading %s.\n", dev->name, adapter->irx_pcb.data.failed ? "failed" : "succeeded"); break; /* * Station address setting */ case CMD_SET_ADDRESS_RESPONSE: adapter->got[CMD_SET_STATION_ADDRESS] = 1; if (elp_debug >= 3) printk(KERN_DEBUG "%s: Ethernet address setting %s.\n", dev->name, adapter->irx_pcb.data.failed ? "failed" : "succeeded"); break; /* * received board statistics */ case CMD_NETWORK_STATISTICS_RESPONSE: adapter->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv; adapter->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit; adapter->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC; adapter->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align; adapter->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun; adapter->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res; adapter->got[CMD_NETWORK_STATISTICS] = 1; if (elp_debug >= 3) printk(KERN_DEBUG "%s: interrupt - statistics response received\n", dev->name); break; /* * sent a packet */ case CMD_TRANSMIT_PACKET_COMPLETE: if (elp_debug >= 3) printk(KERN_DEBUG "%s: interrupt - packet sent\n", dev->name); if (!netif_running(dev)) break; switch (adapter->irx_pcb.data.xmit_resp.c_stat) { case 0xffff: adapter->stats.tx_aborted_errors++; printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name); break; case 0xfffe: adapter->stats.tx_fifo_errors++; printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name); break; } netif_wake_queue(dev); break; /* * some unknown PCB */ default: printk(KERN_DEBUG "%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command); break; } } else { printk(KERN_WARNING "%s: failed to read PCB on interrupt\n", dev->name); adapter_reset(dev); } } } while (icount++ < 5 && (inb_status(dev->base_addr) & (ACRF | DONE))); prime_rx(dev); /* * indicate no longer in interrupt routine */ spin_unlock(&adapter->lock); return IRQ_HANDLED; }
static int __init elplus_setup(struct net_device *dev) { elp_device *adapter = dev->priv; int i, tries, tries1, okay; unsigned long timeout; unsigned long cookie = 0; int err = -ENODEV; SET_MODULE_OWNER(dev); /* * setup adapter structure */ dev->base_addr = elp_autodetect(dev); if (!dev->base_addr) return -ENODEV; adapter->send_pcb_semaphore = 0; for (tries1 = 0; tries1 < 3; tries1++) { outb_control((adapter->hcr_val | CMDE) & ~DIR, dev); /* First try to write just one byte, to see if the card is * responding at all normally. */ timeout = jiffies + 5*HZ/100; okay = 0; while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); if ((inb_status(dev->base_addr) & HCRE)) { outb_command(0, dev->base_addr); /* send a spurious byte */ timeout = jiffies + 5*HZ/100; while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); if (inb_status(dev->base_addr) & HCRE) okay = 1; } if (!okay) { /* Nope, it's ignoring the command register. This means that * either it's still booting up, or it's died. */ printk(KERN_ERR "%s: command register wouldn't drain, ", dev->name); if ((inb_status(dev->base_addr) & 7) == 3) { /* If the adapter status is 3, it *could* still be booting. * Give it the benefit of the doubt for 10 seconds. */ printk("assuming 3c505 still starting\n"); timeout = jiffies + 10*HZ; while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7)); if (inb_status(dev->base_addr) & 7) { printk(KERN_ERR "%s: 3c505 failed to start\n", dev->name); } else { okay = 1; /* It started */ } } else { /* Otherwise, it must just be in a strange * state. We probably need to kick it. */ printk("3c505 is sulking\n"); } } for (tries = 0; tries < 5 && okay; tries++) { /* * Try to set the Ethernet address, to make sure that the board * is working. */ adapter->tx_pcb.command = CMD_STATION_ADDRESS; adapter->tx_pcb.length = 0; cookie = probe_irq_on(); if (!send_pcb(dev, &adapter->tx_pcb)) { printk(KERN_ERR "%s: could not send first PCB\n", dev->name); probe_irq_off(cookie); continue; } if (!receive_pcb(dev, &adapter->rx_pcb)) { printk(KERN_ERR "%s: could not read first PCB\n", dev->name); probe_irq_off(cookie); continue; } if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) || (adapter->rx_pcb.length != 6)) { printk(KERN_ERR "%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length); probe_irq_off(cookie); continue; } goto okay; } /* It's broken. Do a hard reset to re-initialise the board, * and try again. */ printk(KERN_INFO "%s: resetting adapter\n", dev->name); outb_control(adapter->hcr_val | FLSH | ATTN, dev); outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev); } printk(KERN_ERR "%s: failed to initialise 3c505\n", dev->name); goto out; okay: if (dev->irq) { /* Is there a preset IRQ? */ int rpt = probe_irq_off(cookie); if (dev->irq != rpt) { printk(KERN_WARNING "%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt); } /* if dev->irq == probe_irq_off(cookie), all is well */ } else /* No preset IRQ; just use what we can detect */ dev->irq = probe_irq_off(cookie); switch (dev->irq) { /* Legal, sane? */ case 0: printk(KERN_ERR "%s: IRQ probe failed: check 3c505 jumpers.\n", dev->name); goto out; case 1: case 6: case 8: case 13: printk(KERN_ERR "%s: Impossible IRQ %d reported by probe_irq_off().\n", dev->name, dev->irq); goto out; } /* * Now we have the IRQ number so we can disable the interrupts from * the board until the board is opened. */ outb_control(adapter->hcr_val & ~CMDE, dev); /* * copy Ethernet address into structure */ for (i = 0; i < 6; i++) dev->dev_addr[i] = adapter->rx_pcb.data.eth_addr[i]; /* find a DMA channel */ if (!dev->dma) { if (dev->mem_start) { dev->dma = dev->mem_start & 7; } else { printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name); dev->dma = ELP_DMA; } } /* * print remainder of startup message */ printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, ", dev->name, dev->base_addr, dev->irq, dev->dma); printk("addr %02x:%02x:%02x:%02x:%02x:%02x, ", dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); /* * read more information from the adapter */ adapter->tx_pcb.command = CMD_ADAPTER_INFO; adapter->tx_pcb.length = 0; if (!send_pcb(dev, &adapter->tx_pcb) || !receive_pcb(dev, &adapter->rx_pcb) || (adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) || (adapter->rx_pcb.length != 10)) { printk("not responding to second PCB\n"); } printk("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz); /* * reconfigure the adapter memory to better suit our purposes */ adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; adapter->tx_pcb.length = 12; adapter->tx_pcb.data.memconf.cmd_q = 8; adapter->tx_pcb.data.memconf.rcv_q = 8; adapter->tx_pcb.data.memconf.mcast = 10; adapter->tx_pcb.data.memconf.frame = 10; adapter->tx_pcb.data.memconf.rcv_b = 10; adapter->tx_pcb.data.memconf.progs = 0; if (!send_pcb(dev, &adapter->tx_pcb) || !receive_pcb(dev, &adapter->rx_pcb) || (adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) || (adapter->rx_pcb.length != 2)) { printk(KERN_ERR "%s: could not configure adapter memory\n", dev->name); } if (adapter->rx_pcb.data.configure) { printk(KERN_ERR "%s: adapter configuration failed\n", dev->name); } dev->open = elp_open; /* local */ dev->stop = elp_close; /* local */ dev->get_stats = elp_get_stats; /* local */ dev->hard_start_xmit = elp_start_xmit; /* local */ dev->tx_timeout = elp_timeout; /* local */ dev->watchdog_timeo = 10*HZ; dev->set_multicast_list = elp_set_mc_list; /* local */ dev->ethtool_ops = &netdev_ethtool_ops; /* local */ memset(&(adapter->stats), 0, sizeof(struct net_device_stats)); dev->mem_start = dev->mem_end = 0; err = register_netdev(dev); if (err) goto out; return 0; out: release_region(dev->base_addr, ELP_IO_EXTENT); return err; }
int elplus_probe(struct device *dev) { elp_device adapter; int i; CHECK_NULL(dev); /* * setup adapter structure */ adapter.io_addr = dev->base_addr = elp_autodetect(dev); if ( !adapter.io_addr ) return -ENODEV; /* * As we enter here from bootup, the adapter should have IRQs enabled, * but we can as well enable them anyway. */ OUTB(INB(dev->base_addr+PORT_CONTROL) | CONTROL_CMDE, dev->base_addr+PORT_CONTROL); autoirq_setup(0); /* * use ethernet address command to probe for board in polled mode * (this also makes us the IRQ that we need for automatic detection) */ adapter.tx_pcb.command = CMD_STATION_ADDRESS; adapter.tx_pcb.length = 0; if (!send_pcb (&adapter, &adapter.tx_pcb) || !receive_pcb(&adapter, &adapter.rx_pcb) || (adapter.rx_pcb.command != CMD_ADDRESS_RESPONSE) || (adapter.rx_pcb.length != 6)) { printk("%s: not responding to first PCB\n", dev->name); return -ENODEV; } if (dev->irq) { /* Is there a preset IRQ? */ if (dev->irq != autoirq_report(0)) { printk("%s: Detected IRQ doesn't match user-defined one.\n",dev->name); return -ENODEV; } /* if dev->irq == autoirq_report(0), all is well */ } else /* No preset IRQ; just use what we can detect */ dev->irq=autoirq_report(0); switch (dev->irq) { /* Legal, sane? */ case 0: printk("%s: No IRQ reported by autoirq_report().\n",dev->name); printk("%s: Check the jumpers of your 3c505 board.\n",dev->name); return -ENODEV; case 1: case 6: case 8: case 13: printk("%s: Impossible IRQ %d reported by autoirq_report().\n", dev->name, dev->irq); return -ENODEV; } /* * Now we have the IRQ number so we can disable the interrupts from * the board until the board is opened. */ OUTB(INB(dev->base_addr+PORT_CONTROL) & ~CONTROL_CMDE, dev->base_addr+PORT_CONTROL); /* * copy ethernet address into structure */ for (i = 0; i < 6; i++) dev->dev_addr[i] = adapter.rx_pcb.data.eth_addr[i]; /* * print remainder of startup message */ #if (ELP_KERNEL_TYPE < 2) printk("%s: 3c505 card found at I/O 0x%x using IRQ%d has address %s\n", dev->name, dev->base_addr, dev->irq, eth_print(dev->dev_addr)); #else printk("%s: 3c505 card found at I/O 0x%x using IRQ%d has address %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, dev->base_addr, dev->irq, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); #endif /* * initialise the device */ elp_init(dev); return 0; }
static void elp_interrupt(int reg_ptr) { int len; int dlen; int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev; elp_device * adapter; int timeout; if (irq < 0 || irq > 15) { printk ("elp_interrupt(): illegal IRQ number found in interrupt routine (%i)\n", irq); return; } /* FIXME: How do I do this kind of check without a fixed IRQ? */ #if 0 if (irq != ELP_IRQ) { printk ("elp_interrupt(): - interrupt routine has incorrect IRQ of %i\n", irq); return; } #endif dev = irq2dev_map[irq]; if (dev == NULL) { printk ("elp_interrupt(): irq %d for unknown device.\n", irq); return; } adapter = (elp_device *) dev->priv; CHECK_NULL(adapter); if (dev->interrupt) if (elp_debug >= 2) printk("%s: Re-entering the interrupt handler.\n", dev->name); dev->interrupt = 1; /* * allow interrupts (we need timers!) */ sti(); /* * receive a PCB from the adapter */ timeout = jiffies + TIMEOUT; while ((INB(adapter->io_addr+PORT_STATUS)&STATUS_ACRF) != 0 && jiffies < timeout) { if (receive_pcb(adapter, &adapter->irx_pcb)) { switch (adapter->irx_pcb.command) { /* * 82586 configured correctly */ case CMD_CONFIGURE_82586_RESPONSE: adapter->got[CMD_CONFIGURE_82586] = 1; if (elp_debug >= 3) printk("%s: interrupt - configure response received\n", dev->name); break; /* * Adapter memory configuration */ case CMD_CONFIGURE_ADAPTER_RESPONSE: adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1; if (elp_debug >= 3) printk("%s: Adapter memory configuration %s.",dev->name, adapter->irx_pcb.data.failed?"failed":"succeeded"); break; /* * Multicast list loading */ case CMD_LOAD_MULTICAST_RESPONSE: adapter->got[CMD_LOAD_MULTICAST_LIST] = 1; if (elp_debug >= 3) printk("%s: Multicast address list loading %s.",dev->name, adapter->irx_pcb.data.failed?"failed":"succeeded"); break; /* * Station address setting */ case CMD_SET_ADDRESS_RESPONSE: adapter->got[CMD_SET_STATION_ADDRESS] = 1; if (elp_debug >= 3) printk("%s: Ethernet address setting %s.",dev->name, adapter->irx_pcb.data.failed?"failed":"succeeded"); break; /* * received board statistics */ case CMD_NETWORK_STATISTICS_RESPONSE: adapter->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv; adapter->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit; adapter->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC; adapter->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align; adapter->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun; adapter->got[CMD_NETWORK_STATISTICS] = 1; if (elp_debug >= 3) printk("%s: interrupt - statistics response received\n", dev->name); break; /* * received a packet */ case CMD_RECEIVE_PACKET_COMPLETE: /* if the device isn't open, don't pass packets up the stack */ if (dev->start == 0) break; len = adapter->irx_pcb.data.rcv_resp.pkt_len; dlen = adapter->irx_pcb.data.rcv_resp.buf_len; if (adapter->irx_pcb.data.rcv_resp.timeout != 0) { printk("%s: interrupt - packet not received correctly\n", dev->name); } else { if (elp_debug >= 3) printk("%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen); receive_packet(dev, adapter, dlen); if (elp_debug >= 3) printk("%s: packet received\n", dev->name); } if (dev->start && !start_receive(adapter, &adapter->itx_pcb)) if (elp_debug >= 2) printk("%s: interrupt - failed to send receive start PCB\n", dev->name); if (elp_debug >= 3) printk("%s: receive procedure complete\n", dev->name); break; /* * sent a packet */ case CMD_TRANSMIT_PACKET_COMPLETE: if (elp_debug >= 3) printk("%s: interrupt - packet sent\n", dev->name); if (dev->start == 0) break; if (adapter->irx_pcb.data.xmit_resp.c_stat != 0) if (elp_debug >= 2) printk("%s: interrupt - error sending packet %4.4x\n", dev->name, adapter->irx_pcb.data.xmit_resp.c_stat); dev->tbusy = 0; #if (ELP_KERNEL_TYPE < 3) mark_bh(INET_BH); #else mark_bh(NET_BH); #endif break; /* * some unknown PCB */ default: printk("%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command); break; } } else printk("%s: failed to read PCB on interrupt\n", dev->name); } if (jiffies >= timeout) TIMEOUT_MSG(); /* * indicate no longer in interrupt routine */ dev->interrupt = 0; }
static int __init elplus_setup(struct net_device *dev) { elp_device *adapter = netdev_priv(dev); int i, tries, tries1, okay; unsigned long timeout; unsigned long cookie = 0; int err = -ENODEV; dev->base_addr = elp_autodetect(dev); if (!dev->base_addr) return -ENODEV; adapter->send_pcb_semaphore = 0; for (tries1 = 0; tries1 < 3; tries1++) { outb_control((adapter->hcr_val | CMDE) & ~DIR, dev); timeout = jiffies + 5*HZ/100; okay = 0; while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); if ((inb_status(dev->base_addr) & HCRE)) { outb_command(0, dev->base_addr); timeout = jiffies + 5*HZ/100; while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); if (inb_status(dev->base_addr) & HCRE) okay = 1; } if (!okay) { pr_err("%s: command register wouldn't drain, ", dev->name); if ((inb_status(dev->base_addr) & 7) == 3) { pr_cont("assuming 3c505 still starting\n"); timeout = jiffies + 10*HZ; while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7)); if (inb_status(dev->base_addr) & 7) { pr_err("%s: 3c505 failed to start\n", dev->name); } else { okay = 1; } } else { pr_cont("3c505 is sulking\n"); } } for (tries = 0; tries < 5 && okay; tries++) { adapter->tx_pcb.command = CMD_STATION_ADDRESS; adapter->tx_pcb.length = 0; cookie = probe_irq_on(); if (!send_pcb(dev, &adapter->tx_pcb)) { pr_err("%s: could not send first PCB\n", dev->name); probe_irq_off(cookie); continue; } if (!receive_pcb(dev, &adapter->rx_pcb)) { pr_err("%s: could not read first PCB\n", dev->name); probe_irq_off(cookie); continue; } if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) || (adapter->rx_pcb.length != 6)) { pr_err("%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length); probe_irq_off(cookie); continue; } goto okay; } pr_info("%s: resetting adapter\n", dev->name); outb_control(adapter->hcr_val | FLSH | ATTN, dev); outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev); } pr_err("%s: failed to initialise 3c505\n", dev->name); goto out; okay: if (dev->irq) { int rpt = probe_irq_off(cookie); if (dev->irq != rpt) { pr_warning("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt); } } else dev->irq = probe_irq_off(cookie); switch (dev->irq) { case 0: pr_err("%s: IRQ probe failed: check 3c505 jumpers.\n", dev->name); goto out; case 1: case 6: case 8: case 13: pr_err("%s: Impossible IRQ %d reported by probe_irq_off().\n", dev->name, dev->irq); goto out; } outb_control(adapter->hcr_val & ~CMDE, dev); for (i = 0; i < 6; i++) dev->dev_addr[i] = adapter->rx_pcb.data.eth_addr[i]; if (!dev->dma) { if (dev->mem_start) { dev->dma = dev->mem_start & 7; } else { pr_warning("%s: warning, DMA channel not specified, using default\n", dev->name); dev->dma = ELP_DMA; } } pr_info("%s: 3c505 at %#lx, irq %d, dma %d, addr %pM, ", dev->name, dev->base_addr, dev->irq, dev->dma, dev->dev_addr); adapter->tx_pcb.command = CMD_ADAPTER_INFO; adapter->tx_pcb.length = 0; if (!send_pcb(dev, &adapter->tx_pcb) || !receive_pcb(dev, &adapter->rx_pcb) || (adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) || (adapter->rx_pcb.length != 10)) { pr_cont("not responding to second PCB\n"); } pr_cont("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz); adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; adapter->tx_pcb.length = 12; adapter->tx_pcb.data.memconf.cmd_q = 8; adapter->tx_pcb.data.memconf.rcv_q = 8; adapter->tx_pcb.data.memconf.mcast = 10; adapter->tx_pcb.data.memconf.frame = 10; adapter->tx_pcb.data.memconf.rcv_b = 10; adapter->tx_pcb.data.memconf.progs = 0; if (!send_pcb(dev, &adapter->tx_pcb) || !receive_pcb(dev, &adapter->rx_pcb) || (adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) || (adapter->rx_pcb.length != 2)) { pr_err("%s: could not configure adapter memory\n", dev->name); } if (adapter->rx_pcb.data.configure) { pr_err("%s: adapter configuration failed\n", dev->name); } dev->netdev_ops = &elp_netdev_ops; dev->watchdog_timeo = 10*HZ; dev->ethtool_ops = &netdev_ethtool_ops; dev->mem_start = dev->mem_end = 0; err = register_netdev(dev); if (err) goto out; return 0; out: release_region(dev->base_addr, ELP_IO_EXTENT); return err; }