static void elp_set_mc_list(struct net_device *dev) { elp_device *adapter = netdev_priv(dev); struct netdev_hw_addr *ha; int i; unsigned long flags; if (elp_debug >= 3) pr_debug("%s: request to set multicast list\n", dev->name); spin_lock_irqsave(&adapter->lock, flags); if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) { /* */ /* */ adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST; adapter->tx_pcb.length = 6 * netdev_mc_count(dev); i = 0; netdev_for_each_mc_addr(ha, dev) memcpy(adapter->tx_pcb.data.multicast[i++], ha->addr, 6); adapter->got[CMD_LOAD_MULTICAST_LIST] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) pr_err("%s: couldn't send set_multicast command\n", dev->name); else { unsigned long timeout = jiffies + TIMEOUT; while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) { TIMEOUT_MSG(__LINE__); } } if (!netdev_mc_empty(dev)) adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI; else /* */ adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; } else adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC; /* */ if (elp_debug >= 3) pr_debug("%s: sending 82586 configure command\n", dev->name); adapter->tx_pcb.command = CMD_CONFIGURE_82586; adapter->tx_pcb.length = 2; adapter->got[CMD_CONFIGURE_82586] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) { spin_unlock_irqrestore(&adapter->lock, flags); pr_err("%s: couldn't send 82586 configure command\n", dev->name); } else { unsigned long timeout = jiffies + TIMEOUT; spin_unlock_irqrestore(&adapter->lock, flags); while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); } }
static void elp_set_mc_list(struct net_device *dev) { elp_device *adapter = (elp_device *) dev->priv; struct dev_mc_list *dmi = dev->mc_list; int i; unsigned long flags; if (elp_debug >= 3) printk(KERN_DEBUG "%s: request to set multicast list\n", dev->name); spin_lock_irqsave(&adapter->lock, flags); if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) { /* send a "load multicast list" command to the board, max 10 addrs/cmd */ /* if num_addrs==0 the list will be cleared */ adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST; adapter->tx_pcb.length = 6 * dev->mc_count; for (i = 0; i < dev->mc_count; i++) { memcpy(adapter->tx_pcb.data.multicast[i], dmi->dmi_addr, 6); dmi = dmi->next; } adapter->got[CMD_LOAD_MULTICAST_LIST] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) printk(KERN_ERR "%s: couldn't send set_multicast command\n", dev->name); else { unsigned long timeout = jiffies + TIMEOUT; while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) { TIMEOUT_MSG(__LINE__); } } if (dev->mc_count) adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI; else /* num_addrs == 0 */ adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; } else adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC; /* * configure adapter to receive messages (as specified above) * 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.length = 2; adapter->got[CMD_CONFIGURE_82586] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) { spin_unlock_irqrestore(&adapter->lock, flags); printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name); } else { unsigned long timeout = jiffies + TIMEOUT; spin_unlock_irqrestore(&adapter->lock, flags); while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); } }
static void elp_set_mc_list(struct device *dev, int num_addrs, void *addrs) { elp_device *adapter = (elp_device *) dev->priv; int i; if (elp_debug >= 3) printk("%s: request to set multicast list\n", dev->name); if (num_addrs != -1) { /* send a "load multicast list" command to the board, max 10 addrs/cmd */ /* if num_addrs==0 the list will be cleared */ adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST; adapter->tx_pcb.length = 6*num_addrs; for (i=0; i<num_addrs; i++) memcpy(adapter->tx_pcb.data.multicast[i], addrs+6*i,6); adapter->got[CMD_LOAD_MULTICAST_LIST] = 0; if (!send_pcb(adapter, &adapter->tx_pcb)) printk("%s: couldn't send set_multicast command\n", dev->name); else { int timeout = jiffies + TIMEOUT; while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && jiffies < timeout) ; if (jiffies >= timeout) { TIMEOUT_MSG(); } } if (num_addrs) adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI; else /* num_addrs == 0 */ adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; } else /* num_addrs == -1 */ adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_ALL; /* * configure adapter to receive messages (as specified above) * and wait for response */ if (elp_debug >= 3) printk("%s: sending 82586 configure command\n", dev->name); adapter->tx_pcb.command = CMD_CONFIGURE_82586; adapter->tx_pcb.length = 2; adapter->got[CMD_CONFIGURE_82586] = 0; if (!send_pcb(adapter, &adapter->tx_pcb)) printk("%s: couldn't send 82586 configure command\n", dev->name); else { int timeout = jiffies + TIMEOUT; while (adapter->got[CMD_CONFIGURE_82586] == 0 && jiffies < timeout) ; if (jiffies >= timeout) TIMEOUT_MSG(); } }
static struct net_device_stats *elp_get_stats(struct net_device *dev) { elp_device *adapter = (elp_device *) dev->priv; if (elp_debug >= 3) printk(KERN_DEBUG "%s: request for stats\n", dev->name); /* If the device is closed, just return the latest stats we have, - we cannot ask from the adapter without interrupts */ if (!netif_running(dev)) return &adapter->stats; /* send a get statistics command to the board */ adapter->tx_pcb.command = CMD_NETWORK_STATISTICS; adapter->tx_pcb.length = 0; adapter->got[CMD_NETWORK_STATISTICS] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) printk(KERN_ERR "%s: couldn't send get statistics command\n", dev->name); else { unsigned long timeout = jiffies + TIMEOUT; while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) { TIMEOUT_MSG(__LINE__); return &adapter->stats; } } /* statistics are now up to date */ return &adapter->stats; }
static struct enet_statistics * elp_get_stats(struct device *dev) { elp_device *adapter = (elp_device *) dev->priv; if (elp_debug >= 3) printk("%s: request for stats\n", dev->name); /* If the device is closed, just return the latest stats we have, - we cannot ask from the adapter without interrupts */ if (!dev->start) return &adapter->stats; /* send a get statistics command to the board */ adapter->tx_pcb.command = CMD_NETWORK_STATISTICS; adapter->tx_pcb.length = 0; adapter->got[CMD_NETWORK_STATISTICS] = 0; if (!send_pcb(adapter, &adapter->tx_pcb)) printk("%s: couldn't send get statistics command\n", dev->name); else { int timeout = jiffies + TIMEOUT; while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && jiffies < timeout) ; if (jiffies >= timeout) { TIMEOUT_MSG(); return &adapter->stats; } } /* statistics are now up to date */ return &adapter->stats; }
static struct net_device_stats *elp_get_stats(struct net_device *dev) { elp_device *adapter = netdev_priv(dev); if (elp_debug >= 3) pr_debug("%s: request for stats\n", dev->name); if (!netif_running(dev)) return &dev->stats; adapter->tx_pcb.command = CMD_NETWORK_STATISTICS; adapter->tx_pcb.length = 0; adapter->got[CMD_NETWORK_STATISTICS] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) pr_err("%s: couldn't send get statistics command\n", dev->name); else { unsigned long timeout = jiffies + TIMEOUT; while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) { TIMEOUT_MSG(__LINE__); return &dev->stats; } } return &dev->stats; }
static inline int get_status(unsigned int base_addr) { unsigned long timeout = jiffies + 10*HZ/100; register int stat1; do { stat1 = inb_status(base_addr); } while (stat1 != inb_status(base_addr) && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); return stat1; }
static int get_status (elp_device * adapter) { int timeout = jiffies + TIMEOUT; register int stat1; do { stat1 = INB(adapter->io_addr+PORT_STATUS); } while (stat1 != INB(adapter->io_addr+PORT_STATUS) && jiffies < timeout); if (jiffies >= timeout) TIMEOUT_MSG(); return stat1; }
static int wait_hcre(elp_device * adapter, int toval) { int timeout = jiffies + toval; while(((INB(adapter->io_addr+PORT_STATUS)&STATUS_HCRE)==0) && (jiffies <= timeout)) ; if (jiffies >= timeout) { TIMEOUT_MSG(); return FALSE; } return TRUE; }
static int elp_open (struct device *dev) { elp_device * adapter = (elp_device *) dev->priv; CHECK_NULL(dev); if (elp_debug >= 3) printk("%s: request to open device\n", dev->name); /* * make sure we actually found the device */ if (adapter == NULL) { printk("%s: Opening a non-existent physical device\n", dev->name); return -EAGAIN; } /* * disable interrupts on the board */ OUTB(0x00, adapter->io_addr+PORT_CONTROL); /* * clear any pending interrupts */ INB(adapter->io_addr+PORT_COMMAND); /* * interrupt routine not entered */ dev->interrupt = 0; /* * transmitter not busy */ dev->tbusy = 0; /* * install our interrupt service routine */ if (request_irq(dev->irq, &elp_interrupt, 0, "3c505")) return -EAGAIN; /* * make sure we can find the device header given the interrupt number */ irq2dev_map[dev->irq] = dev; /* * enable interrupts on the board */ OUTB(CONTROL_CMDE, adapter->io_addr+PORT_CONTROL); /* * device is now officially open! */ dev->start = 1; /* * configure adapter memory: we need 10 multicast addresses, default==0 */ if (elp_debug >= 3) printk("%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(adapter, &adapter->tx_pcb)) printk("%s: couldn't send memory configuration command\n", dev->name); else { int timeout = jiffies + TIMEOUT; while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && jiffies < timeout) ; if (jiffies >= timeout) TIMEOUT_MSG(); } /* * configure adapter to receive broadcast messages and wait for response */ if (elp_debug >= 3) printk("%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(adapter, &adapter->tx_pcb)) printk("%s: couldn't send 82586 configure command\n", dev->name); else { int timeout = jiffies + TIMEOUT; while (adapter->got[CMD_CONFIGURE_82586] == 0 && jiffies < timeout) ; if (jiffies >= timeout) TIMEOUT_MSG(); } /* * queue receive commands to provide buffering */ if (!start_receive(adapter, &adapter->tx_pcb)) printk("%s: start receive command failed \n", dev->name); if (elp_debug >= 3) printk("%s: start receive command sent\n", dev->name); return 0; /* Always succeed */ }
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 void receive_packet(struct device * dev, elp_device * adapter, int len) { register int i; unsigned short * ptr; short d; int timeout; int rlen; struct sk_buff *skb; /* * allocate a buffer to put the packet into. * (for kernels prior to 1.1.4 only) */ #if (ELP_KERNEL_TYPE < 2) int sksize = sizeof(struct sk_buff) + len + 4; #endif CHECK_NULL(dev); CHECK_NULL(adapter); if (len <= 0 || ((len & ~1) != len)) if (elp_debug >= 3) printk("*** bad packet len %d at %s(%d)\n",len,filename,__LINE__); rlen = (len+1) & ~1; #if (ELP_KERNEL_TYPE < 2) skb = alloc_skb(sksize, GFP_ATOMIC); #else skb = alloc_skb(rlen, GFP_ATOMIC); #endif /* * make sure the data register is going the right way */ OUTB(INB(adapter->io_addr+PORT_CONTROL)|CONTROL_DIR, adapter->io_addr+PORT_CONTROL); /* * if buffer could not be allocated, swallow it */ if (skb == NULL) { for (i = 0; i < (rlen/2); i++) { timeout = jiffies + TIMEOUT; while ((INB(adapter->io_addr+PORT_STATUS)&STATUS_HRDY) == 0 && jiffies < timeout) ; if (jiffies >= timeout) TIMEOUT_MSG(); d = inw(adapter->io_addr+PORT_DATA); } adapter->stats.rx_dropped++; } else { skb->lock = 0; skb->len = rlen; skb->dev = dev; /* * for kernels before 1.1.4, the driver allocated the buffer */ #if (ELP_KERNEL_TYPE < 2) skb->mem_len = sksize; skb->mem_addr = skb; #endif /* * now read the data from the adapter */ ptr = (unsigned short *)SKB_DATA; for (i = 0; i < (rlen/2); i++) { timeout = jiffies + TIMEOUT; while ((INB(adapter->io_addr+PORT_STATUS)&STATUS_HRDY) == 0 && jiffies < timeout) ; if (jiffies >= timeout) { printk("*** timeout at %s(%d) reading word %d of %d ***\n", filename,__LINE__, i, rlen/2); #if (ELP_KERNEL_TYPE < 2) kfree_s(skb, sksize); #else kfree_s(skb, rlen); #endif return; } *ptr = inw(adapter->io_addr+PORT_DATA); ptr++; } /* * the magic routine "dev_rint" passes the packet up the * protocol chain. If it returns 0, we can assume the packet was * swallowed up. If not, then we are responsible for freeing memory */ IS_SKB(skb); /* * for kernels before 1.1.4, the driver allocated the buffer, so it had * to free it */ #if (ELP_KERNEL_TYPE < 2) if (dev_rint((unsigned char *)skb, rlen, IN_SKBUFF, dev) != 0) { printk("%s: receive buffers full.\n", dev->name); kfree_s(skb, sksize); } #else netif_rx(skb); #endif } OUTB(INB(adapter->io_addr+PORT_CONTROL)&(~CONTROL_DIR), adapter->io_addr+PORT_CONTROL); }
static bool receive_pcb(struct net_device *dev, pcb_struct * pcb) { int i, j; int total_length; int stat; unsigned long timeout; unsigned long flags; elp_device *adapter = netdev_priv(dev); set_hsf(dev, 0); timeout = jiffies + 2*HZ/100; while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) { TIMEOUT_MSG(__LINE__); return false; } pcb->command = inb_command(dev->base_addr); timeout = jiffies + 3*HZ/100; while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) { TIMEOUT_MSG(__LINE__); pr_info("%s: status %02x\n", dev->name, stat); return false; } pcb->length = inb_command(dev->base_addr); if (pcb->length > MAX_PCB_DATA) { INVALID_PCB_MSG(pcb->length); adapter_reset(dev); return false; } spin_lock_irqsave(&adapter->lock, flags); for (i = 0; i < MAX_PCB_DATA; i++) { for (j = 0; j < 20000; j++) { stat = get_status(dev->base_addr); if (stat & ACRF) break; } pcb->data.raw[i] = inb_command(dev->base_addr); if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000) break; } spin_unlock_irqrestore(&adapter->lock, flags); if (i >= MAX_PCB_DATA) { INVALID_PCB_MSG(i); return false; } if (j >= 20000) { TIMEOUT_MSG(__LINE__); return false; } total_length = pcb->data.raw[i]; if (total_length != (pcb->length + 2)) { if (elp_debug >= 2) pr_warning("%s: mangled PCB received\n", dev->name); set_hsf(dev, HSF_PCB_NAK); return false; } if (pcb->command == CMD_RECEIVE_PACKET_COMPLETE) { if (test_and_set_bit(0, (void *) &adapter->busy)) { if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) { set_hsf(dev, HSF_PCB_NAK); pr_warning("%s: PCB rejected, transfer in progress and backlog full\n", dev->name); pcb->command = 0; return true; } else { pcb->command = 0xff; } } } set_hsf(dev, HSF_PCB_ACK); return true; }
static int send_pcb(elp_device * adapter, pcb_struct * pcb) { int i; int cont; int retry = 0; int timeout; CHECK_NULL(pcb); CHECK_NULL(adapter); if (pcb->length > MAX_PCB_DATA) printk(invalid_pcb_msg, pcb->length, filename, __LINE__); while (1) { cont = 1; /* * load each byte into the command register and * wait for the HCRE bit to indicate the adapter * had read the byte */ SET_HSF(0); OUTB(pcb->command, (adapter->io_addr)+PORT_COMMAND); cont = WAIT_HCRE(5); if (cont) { OUTB(pcb->length, (adapter->io_addr)+PORT_COMMAND); cont = WAIT_HCRE(2); } for (i = 0; cont && (i < pcb->length); i++) { OUTB(pcb->data.raw[i], (adapter->io_addr)+PORT_COMMAND); cont = WAIT_HCRE(2); } /* set the host status bits to indicate end of PCB */ /* send the total packet length as well */ /* wait for the adapter to indicate that it has read the PCB */ if (cont) { SET_HSF(HSF_PCB_END); OUTB(2+pcb->length, adapter->io_addr+PORT_COMMAND); timeout = jiffies + 6; while (jiffies < timeout) { i = GET_ASF(); if ((i == ASF_PCB_ACK) || (i == ASF_PCB_NAK)) break; } if (jiffies >= timeout) TIMEOUT_MSG(); if (i == ASF_PCB_ACK) { SET_HSF(0); return TRUE; } else if (i == ASF_PCB_NAK) { SET_HSF(0); printk("%s: PCB send was NAKed\n", adapter->name); { int to = jiffies + 5; while (jiffies < to) ; } } } if (elp_debug >= 2) printk("%s: NAK/timeout on send PCB\n", adapter->name); if ((retry++ & 7) == 0) printk("%s: retry #%i on send PCB\n", adapter->name, retry); } return FALSE; }
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; }
static int receive_pcb(struct net_device *dev, pcb_struct * pcb) { int i, j; int total_length; int stat; unsigned long timeout; unsigned long flags; elp_device *adapter = dev->priv; set_hsf(dev, 0); /* get the command code */ timeout = jiffies + 2*HZ/100; while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) { TIMEOUT_MSG(__LINE__); return FALSE; } pcb->command = inb_command(dev->base_addr); /* read the data length */ timeout = jiffies + 3*HZ/100; while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) { TIMEOUT_MSG(__LINE__); printk(KERN_INFO "%s: status %02x\n", dev->name, stat); return FALSE; } pcb->length = inb_command(dev->base_addr); if (pcb->length > MAX_PCB_DATA) { INVALID_PCB_MSG(pcb->length); adapter_reset(dev); return FALSE; } /* read the data */ spin_lock_irqsave(&adapter->lock, flags); i = 0; do { j = 0; while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000); pcb->data.raw[i++] = inb_command(dev->base_addr); if (i > MAX_PCB_DATA) INVALID_PCB_MSG(i); } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000); spin_unlock_irqrestore(&adapter->lock, flags); if (j >= 20000) { TIMEOUT_MSG(__LINE__); return FALSE; } /* woops, the last "data" byte was really the length! */ total_length = pcb->data.raw[--i]; /* safety check total length vs data length */ if (total_length != (pcb->length + 2)) { if (elp_debug >= 2) printk(KERN_WARNING "%s: mangled PCB received\n", dev->name); set_hsf(dev, HSF_PCB_NAK); return FALSE; } if (pcb->command == CMD_RECEIVE_PACKET_COMPLETE) { if (test_and_set_bit(0, (void *) &adapter->busy)) { if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) { set_hsf(dev, HSF_PCB_NAK); printk(KERN_WARNING "%s: PCB rejected, transfer in progress and backlog full\n", dev->name); pcb->command = 0; return TRUE; } else { pcb->command = 0xff; } } } set_hsf(dev, HSF_PCB_ACK); return TRUE; }
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 int receive_pcb(elp_device * adapter, pcb_struct * pcb) { int i; int total_length; int stat; int timeout; CHECK_NULL(pcb); CHECK_NULL(adapter); /* get the command code */ timeout = jiffies + TIMEOUT; while (((stat = GET_STATUS())&STATUS_ACRF) == 0 && jiffies < timeout) ; if (jiffies >= timeout) TIMEOUT_MSG(); SET_HSF(0); pcb->command = INB(adapter->io_addr+PORT_COMMAND); if ((stat & ASF_PCB_MASK) != ASF_PCB_END) { /* read the data length */ timeout = jiffies + TIMEOUT; while (((stat = GET_STATUS())&STATUS_ACRF) == 0 && jiffies < timeout) ; if (jiffies >= timeout) TIMEOUT_MSG(); pcb->length = INB(adapter->io_addr+PORT_COMMAND); if (pcb->length > MAX_PCB_DATA) printk(invalid_pcb_msg, pcb->length, filename,__LINE__); if ((stat & ASF_PCB_MASK) != ASF_PCB_END) { /* read the data */ i = 0; timeout = jiffies + TIMEOUT; do { while (((stat = GET_STATUS())&STATUS_ACRF) == 0 && jiffies < timeout) ; pcb->data.raw[i++] = INB(adapter->io_addr+PORT_COMMAND); if (i > MAX_PCB_DATA) printk(invalid_pcb_msg, i, filename, __LINE__); } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && jiffies < timeout); if (jiffies >= timeout) TIMEOUT_MSG(); /* woops, the last "data" byte was really the length! */ total_length = pcb->data.raw[--i]; /* safety check total length vs data length */ if (total_length != (pcb->length + 2)) { if (elp_debug >= 2) printk("%s: mangled PCB received\n", adapter->name); SET_HSF(HSF_PCB_NAK); return FALSE; } SET_HSF(HSF_PCB_ACK); return TRUE; } } SET_HSF(HSF_PCB_NAK); return FALSE; }