⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lmc_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
                     */                    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 + -