static netdev_tx_t elp_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned long flags; elp_device *adapter = netdev_priv(dev); spin_lock_irqsave(&adapter->lock, flags); check_3c505_dma(dev); if (elp_debug >= 3) pr_debug("%s: request to send packet of length %d\n", dev->name, (int) skb->len); netif_stop_queue(dev); /* * send the packet at skb->data for skb->len */ if (!send_packet(dev, skb)) { if (elp_debug >= 2) { pr_debug("%s: failed to transmit packet\n", dev->name); } spin_unlock_irqrestore(&adapter->lock, flags); return NETDEV_TX_BUSY; } if (elp_debug >= 3) pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len); prime_rx(dev); spin_unlock_irqrestore(&adapter->lock, flags); netif_start_queue(dev); return NETDEV_TX_OK; }
static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned long flags; elp_device *adapter = dev->priv; spin_lock_irqsave(&adapter->lock, flags); check_3c505_dma(dev); if (elp_debug >= 3) printk(KERN_DEBUG "%s: request to send packet of length %d\n", dev->name, (int) skb->len); netif_stop_queue(dev); /* * send the packet at skb->data for skb->len */ if (!send_packet(dev, skb)) { if (elp_debug >= 2) { printk(KERN_DEBUG "%s: failed to transmit packet\n", dev->name); } spin_unlock_irqrestore(&adapter->lock, flags); return 1; } if (elp_debug >= 3) printk(KERN_DEBUG "%s: packet of length %d sent\n", dev->name, (int) skb->len); /* * start the transmit timeout */ dev->trans_start = jiffies; prime_rx(dev); spin_unlock_irqrestore(&adapter->lock, flags); netif_start_queue(dev); return 0; }
static int elp_open(struct net_device *dev) { elp_device *adapter; int retval; adapter = dev->priv; if (elp_debug >= 3) printk(KERN_DEBUG "%s: request to open device\n", dev->name); /* * make sure we actually found the device */ if (adapter == NULL) { printk(KERN_ERR "%s: Opening a non-existent physical device\n", dev->name); return -EAGAIN; } /* * disable interrupts on the board */ outb_control(0, dev); /* * clear any pending interrupts */ inb_command(dev->base_addr); adapter_reset(dev); /* * no receive PCBs active */ adapter->rx_active = 0; adapter->busy = 0; adapter->send_pcb_semaphore = 0; adapter->rx_backlog.in = 0; adapter->rx_backlog.out = 0; spin_lock_init(&adapter->lock); /* * install our interrupt service routine */ if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) { printk(KERN_ERR "%s: could not allocate IRQ%d\n", dev->name, dev->irq); return retval; } if ((retval = request_dma(dev->dma, dev->name))) { free_irq(dev->irq, dev); printk(KERN_ERR "%s: could not allocate DMA%d channel\n", dev->name, dev->dma); return retval; } adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE); if (!adapter->dma_buffer) { printk(KERN_ERR "%s: could not allocate DMA buffer\n", dev->name); free_dma(dev->dma); free_irq(dev->irq, dev); return -ENOMEM; } adapter->dmaing = 0; /* * enable interrupts on the board */ outb_control(CMDE, dev); /* * configure adapter memory: we need 10 multicast addresses, default==0 */ if (elp_debug >= 3) printk(KERN_DEBUG "%s: sending 3c505 memory configuration command\n", dev->name); adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; adapter->tx_pcb.data.memconf.cmd_q = 10; adapter->tx_pcb.data.memconf.rcv_q = 20; adapter->tx_pcb.data.memconf.mcast = 10; adapter->tx_pcb.data.memconf.frame = 20; adapter->tx_pcb.data.memconf.rcv_b = 20; adapter->tx_pcb.data.memconf.progs = 0; adapter->tx_pcb.length = sizeof(struct Memconf); adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) printk(KERN_ERR "%s: couldn't send memory configuration command\n", dev->name); else { unsigned long timeout = jiffies + TIMEOUT; while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); } /* * configure adapter to receive broadcast messages and wait for response */ if (elp_debug >= 3) printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name); adapter->tx_pcb.command = CMD_CONFIGURE_82586; adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; adapter->tx_pcb.length = 2; adapter->got[CMD_CONFIGURE_82586] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name); else { unsigned long timeout = jiffies + TIMEOUT; while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); } /* enable burst-mode DMA */ /* outb(0x1, dev->base_addr + PORT_AUXDMA); */ /* * queue receive commands to provide buffering */ prime_rx(dev); if (elp_debug >= 3) printk(KERN_DEBUG "%s: %d receive PCBs active\n", dev->name, adapter->rx_active); /* * device is now officially open! */ netif_start_queue(dev); return 0; }
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 elp_open(struct net_device *dev) { elp_device *adapter = netdev_priv(dev); int retval; if (elp_debug >= 3) pr_debug("%s: request to open device\n", dev->name); if (adapter == NULL) { pr_err("%s: Opening a non-existent physical device\n", dev->name); return -EAGAIN; } outb_control(0, dev); inb_command(dev->base_addr); adapter_reset(dev); adapter->rx_active = 0; adapter->busy = 0; adapter->send_pcb_semaphore = 0; adapter->rx_backlog.in = 0; adapter->rx_backlog.out = 0; spin_lock_init(&adapter->lock); if ((retval = request_irq(dev->irq, elp_interrupt, 0, dev->name, dev))) { pr_err("%s: could not allocate IRQ%d\n", dev->name, dev->irq); return retval; } if ((retval = request_dma(dev->dma, dev->name))) { free_irq(dev->irq, dev); pr_err("%s: could not allocate DMA%d channel\n", dev->name, dev->dma); return retval; } adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE); if (!adapter->dma_buffer) { pr_err("%s: could not allocate DMA buffer\n", dev->name); free_dma(dev->dma); free_irq(dev->irq, dev); return -ENOMEM; } adapter->dmaing = 0; outb_control(CMDE, dev); if (elp_debug >= 3) pr_debug("%s: sending 3c505 memory configuration command\n", dev->name); adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; adapter->tx_pcb.data.memconf.cmd_q = 10; adapter->tx_pcb.data.memconf.rcv_q = 20; adapter->tx_pcb.data.memconf.mcast = 10; adapter->tx_pcb.data.memconf.frame = 20; adapter->tx_pcb.data.memconf.rcv_b = 20; adapter->tx_pcb.data.memconf.progs = 0; adapter->tx_pcb.length = sizeof(struct Memconf); adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) pr_err("%s: couldn't send memory configuration command\n", dev->name); else { unsigned long timeout = jiffies + TIMEOUT; while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); } if (elp_debug >= 3) pr_debug("%s: sending 82586 configure command\n", dev->name); adapter->tx_pcb.command = CMD_CONFIGURE_82586; adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; adapter->tx_pcb.length = 2; adapter->got[CMD_CONFIGURE_82586] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) pr_err("%s: couldn't send 82586 configure command\n", dev->name); else { unsigned long timeout = jiffies + TIMEOUT; while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); } prime_rx(dev); if (elp_debug >= 3) pr_debug("%s: %d receive PCBs active\n", dev->name, adapter->rx_active); netif_start_queue(dev); return 0; }