📄 lmc_main.c
字号:
*/ sc->lmc_gpio &= ~(LMC_GEP_RESET | LMC_GEP_DP); LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); /* * hold for more than 10 microseconds */ udelay(50); sc->lmc_gpio |= LMC_GEP_DP | LMC_GEP_RESET; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); /* * busy wait for the chip to reset */ while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && (timeout-- > 0)) ; /* * stop driving Xilinx-related signals */ lmc_gpio_mkinput(sc, 0xff); ret = 0x0; break; } case lmc_xilinx_load: /*fold02*/ { char *data; int pos; int timeout = 500000; if(xc.data == 0x0){ ret = -EINVAL; break; } data = kmalloc(xc.len, GFP_KERNEL); if(data == 0x0){ printk(KERN_WARNING "%s: Failed to allocate memory for copy\n", dev->name); ret = -ENOMEM; break; } if(copy_from_user(data, xc.data, xc.len)) { kfree(data); ret = -ENOMEM; break; } printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data); lmc_gpio_mkinput(sc, 0xff); /* * Clear the Xilinx and start prgramming from the DEC */ /* * Set ouput as: * Reset: 0 (active) * DP: 0 (active) * Mode: 1 * */ sc->lmc_gpio = 0x00; sc->lmc_gpio &= ~LMC_GEP_DP; sc->lmc_gpio &= ~LMC_GEP_RESET; sc->lmc_gpio |= LMC_GEP_MODE; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); lmc_gpio_mkoutput(sc, LMC_GEP_MODE | LMC_GEP_DP | LMC_GEP_RESET); /* * Wait at least 10 us 20 to be safe */ udelay(50); /* * Clear reset and activate programming lines * Reset: Input * DP: Input * Clock: Output * Data: Output * Mode: Output */ lmc_gpio_mkinput(sc, LMC_GEP_DP | LMC_GEP_RESET); /* * Set LOAD, DATA, Clock to 1 */ sc->lmc_gpio = 0x00; sc->lmc_gpio |= LMC_GEP_MODE; sc->lmc_gpio |= LMC_GEP_DATA; sc->lmc_gpio |= LMC_GEP_CLK; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); lmc_gpio_mkoutput(sc, LMC_GEP_DATA | LMC_GEP_CLK | LMC_GEP_MODE ); /* * busy wait for the chip to reset */ while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && (timeout-- > 0)) ; printk(KERN_DEBUG "%s: Waited %d for the Xilinx to clear it's memory\n", dev->name, 500000-timeout); for(pos = 0; pos < xc.len; pos++){ switch(data[pos]){ case 0: sc->lmc_gpio &= ~LMC_GEP_DATA; /* Data is 0 */ break; case 1: sc->lmc_gpio |= LMC_GEP_DATA; /* Data is 1 */ break; default: printk(KERN_WARNING "%s Bad data in xilinx programming data at %d, got %d wanted 0 or 1\n", dev->name, pos, data[pos]); sc->lmc_gpio |= LMC_GEP_DATA; /* Assume it's 1 */ } sc->lmc_gpio &= ~LMC_GEP_CLK; /* Clock to zero */ sc->lmc_gpio |= LMC_GEP_MODE; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); udelay(1); sc->lmc_gpio |= LMC_GEP_CLK; /* Put the clack back to one */ sc->lmc_gpio |= LMC_GEP_MODE; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); udelay(1); } if((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0){ printk(KERN_WARNING "%s: Reprogramming FAILED. Needs to be reprogrammed. (corrupted data)\n", dev->name); } else if((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0){ printk(KERN_WARNING "%s: Reprogramming FAILED. Needs to be reprogrammed. (done)\n", dev->name); } else { printk(KERN_DEBUG "%s: Done reprogramming Xilinx, %d bits, good luck!\n", dev->name, pos); } lmc_gpio_mkinput(sc, 0xff); sc->lmc_miireg16 |= LMC_MII16_FIFO_RESET; lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16); sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET; lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16); kfree(data); ret = 0; break; } default: /*fold02*/ ret = -EBADE; break; } netif_wake_queue(dev); sc->lmc_txfull = 0; } break; default: /*fold01*/ /* If we don't know what to do, give the protocol a shot. */ ret = lmc_proto_ioctl (sc, ifr, cmd); break; } spin_unlock_irqrestore(&sc->lmc_lock, flags); /*fold01*/ lmc_trace(dev, "lmc_ioctl out"); return ret;}/* the watchdog process that cruises around */static void lmc_watchdog (unsigned long data) /*fold00*/{ struct net_device *dev = (struct net_device *) data; lmc_softc_t *sc; int link_status; u_int32_t ticks; unsigned long flags; sc = dev->priv; lmc_trace(dev, "lmc_watchdog in"); spin_lock_irqsave(&sc->lmc_lock, flags); if(sc->check != 0xBEAFCAFE){ printk("LMC: Corrupt net_device stuct, breaking out\n"); spin_unlock_irqrestore(&sc->lmc_lock, flags); return; } /* Make sure the tx jabber and rx watchdog are off, * and the transmit and receive processes are running. */ LMC_CSR_WRITE (sc, csr_15, 0x00000011); sc->lmc_cmdmode |= TULIP_CMD_TXRUN | TULIP_CMD_RXRUN; LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode); if (sc->lmc_ok == 0) goto kick_timer; LMC_EVENT_LOG(LMC_EVENT_WATCHDOG, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16)); /* --- begin time out check ----------------------------------- * check for a transmit interrupt timeout * Has the packet xmt vs xmt serviced threshold been exceeded */ if (sc->lmc_taint_tx == sc->lastlmc_taint_tx && sc->stats.tx_packets > sc->lasttx_packets && sc->tx_TimeoutInd == 0) { /* wait for the watchdog to come around again */ sc->tx_TimeoutInd = 1; } else if (sc->lmc_taint_tx == sc->lastlmc_taint_tx && sc->stats.tx_packets > sc->lasttx_packets && sc->tx_TimeoutInd) { LMC_EVENT_LOG(LMC_EVENT_XMTINTTMO, LMC_CSR_READ (sc, csr_status), 0); sc->tx_TimeoutDisplay = 1; sc->stats.tx_TimeoutCnt++; /* DEC chip is stuck, hit it with a RESET!!!! */ lmc_running_reset (dev); /* look at receive & transmit process state to make sure they are running */ LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0); /* look at: DSR - 02 for Reg 16 * CTS - 08 * DCD - 10 * RI - 20 * for Reg 17 */ LMC_EVENT_LOG(LMC_EVENT_RESET2, lmc_mii_readreg (sc, 0, 16), lmc_mii_readreg (sc, 0, 17)); /* reset the transmit timeout detection flag */ sc->tx_TimeoutInd = 0; sc->lastlmc_taint_tx = sc->lmc_taint_tx; sc->lasttx_packets = sc->stats.tx_packets; } else { sc->tx_TimeoutInd = 0; sc->lastlmc_taint_tx = sc->lmc_taint_tx; sc->lasttx_packets = sc->stats.tx_packets; } /* --- end time out check ----------------------------------- */ link_status = sc->lmc_media->get_link_status (sc); /* * hardware level link lost, but the interface is marked as up. * Mark it as down. */ if ((link_status == 0) && (sc->last_link_status != 0)) { printk(KERN_WARNING "%s: hardware/physical link down\n", dev->name); sc->last_link_status = 0; /* lmc_reset (sc); Why reset??? The link can go down ok */ /* Inform the world that link has been lost */ netif_carrier_off(dev); } /* * hardware link is up, but the interface is marked as down. * Bring it back up again. */ if (link_status != 0 && sc->last_link_status == 0) { printk(KERN_WARNING "%s: hardware/physical link up\n", dev->name); sc->last_link_status = 1; /* lmc_reset (sc); Again why reset??? */ /* Inform the world that link protocol is back up. */ netif_carrier_on(dev); /* Now we have to tell the syncppp that we had an outage * and that it should deal. Calling sppp_reopen here * should do the trick, but we may have to call sppp_close * when the link goes down, and call sppp_open here. * Subject to more testing. * --bbraun */ lmc_proto_reopen(sc); } /* Call media specific watchdog functions */ sc->lmc_media->watchdog(sc); /* * Poke the transmitter to make sure it * never stops, even if we run out of mem */ LMC_CSR_WRITE(sc, csr_rxpoll, 0); /* * Check for code that failed * and try and fix it as appropriate */ if(sc->failed_ring == 1){ /* * Failed to setup the recv/xmit rin * Try again */ sc->failed_ring = 0; lmc_softreset(sc); } if(sc->failed_recv_alloc == 1){ /* * We failed to alloc mem in the * interrupt handler, go through the rings * and rebuild them */ sc->failed_recv_alloc = 0; lmc_softreset(sc); } /* * remember the timer value */kick_timer: ticks = LMC_CSR_READ (sc, csr_gp_timer); LMC_CSR_WRITE (sc, csr_gp_timer, 0xffffffffUL); sc->ictl.ticks = 0x0000ffff - (ticks & 0x0000ffff); /* * restart this timer. */ sc->timer.expires = jiffies + (HZ); add_timer (&sc->timer); spin_unlock_irqrestore(&sc->lmc_lock, flags); lmc_trace(dev, "lmc_watchdog out");}static void lmc_setup(struct net_device * const dev) /*fold00*/{ lmc_trace(dev, "lmc_setup in"); dev->type = ARPHRD_HDLC; dev->hard_start_xmit = lmc_start_xmit; dev->open = lmc_open; dev->stop = lmc_close; dev->get_stats = lmc_get_stats; dev->do_ioctl = lmc_ioctl; dev->tx_timeout = lmc_driver_timeout; dev->watchdog_timeo = (HZ); /* 1 second */ lmc_trace(dev, "lmc_setup out");}static int __devinit lmc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent){ struct net_device *dev; lmc_softc_t *sc; u16 subdevice; u_int16_t AdapModelNum; int err = -ENOMEM; static int cards_found;#ifndef GCOM /* We name by type not by vendor */ static const char lmcname[] = "hdlc%d";#else /* * GCOM uses LMC vendor name so that clients can know which card * to attach to. */ static const char lmcname[] = "lmc%d";#endif /* * Allocate our own device structure */ dev = alloc_netdev(sizeof(lmc_softc_t), lmcname, lmc_setup); if (!dev) { printk (KERN_ERR "lmc:alloc_netdev for device failed\n"); goto out1; } lmc_trace(dev, "lmc_init_one in"); err = pci_enable_device(pdev); if (err) { printk(KERN_ERR "lmc: pci enable failed:%d\n", err); goto out2; } if (pci_request_regions(pdev, "lmc")) { printk(KERN_ERR "lmc: pci_request_region failed\n"); err = -EIO; goto out3; } pci_set_drvdata(pdev, dev); if(lmc_first_load == 0){ printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n", DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION); lmc_first_load = 1; } sc = dev->priv; sc->lmc_device = dev; sc->name = dev->name; /* Initialize the sppp layer */ /* An ioctl can cause a subsequent detach for raw frame interface */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -