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

📄 lmc_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
    sc->if_type = LMC_PPP;    sc->check = 0xBEAFCAFE;    dev->base_addr = pci_resource_start(pdev, 0);    dev->irq = pdev->irq;    SET_MODULE_OWNER(dev);    SET_NETDEV_DEV(dev, &pdev->dev);    /*     * This will get the protocol layer ready and do any 1 time init's     * Must have a valid sc and dev structure     */    lmc_proto_init(sc);    lmc_proto_attach(sc);    /*     * Why were we changing this???     dev->tx_queue_len = 100;     */    /* Init the spin lock so can call it latter */    spin_lock_init(&sc->lmc_lock);    pci_set_master(pdev);    printk ("%s: detected at %lx, irq %d\n", dev->name,	    dev->base_addr, dev->irq);    if (register_netdev (dev) != 0) {        printk (KERN_ERR "%s: register_netdev failed.\n", dev->name);	goto out4;    }    sc->lmc_cardtype = LMC_CARDTYPE_UNKNOWN;    sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;    /*     *     * Check either the subvendor or the subdevice, some systems reverse     * the setting in the bois, seems to be version and arch dependent?     * Fix the error, exchange the two values      */    if ((subdevice = pdev->subsystem_device) == PCI_VENDOR_ID_LMC)	    subdevice = pdev->subsystem_vendor;    switch (subdevice) {    case PCI_DEVICE_ID_LMC_HSSI:        printk ("%s: LMC HSSI\n", dev->name);        sc->lmc_cardtype = LMC_CARDTYPE_HSSI;        sc->lmc_media = &lmc_hssi_media;        break;    case PCI_DEVICE_ID_LMC_DS3:        printk ("%s: LMC DS3\n", dev->name);        sc->lmc_cardtype = LMC_CARDTYPE_DS3;        sc->lmc_media = &lmc_ds3_media;        break;    case PCI_DEVICE_ID_LMC_SSI:        printk ("%s: LMC SSI\n", dev->name);        sc->lmc_cardtype = LMC_CARDTYPE_SSI;        sc->lmc_media = &lmc_ssi_media;        break;    case PCI_DEVICE_ID_LMC_T1:        printk ("%s: LMC T1\n", dev->name);        sc->lmc_cardtype = LMC_CARDTYPE_T1;        sc->lmc_media = &lmc_t1_media;        break;    default:        printk (KERN_WARNING "%s: LMC UNKOWN CARD!\n", dev->name);        break;    }    lmc_initcsrs (sc, dev->base_addr, 8);    lmc_gpio_mkinput (sc, 0xff);    sc->lmc_gpio = 0;		/* drive no signals yet */    sc->lmc_media->defaults (sc);    sc->lmc_media->set_link_status (sc, LMC_LINK_UP);    /* verify that the PCI Sub System ID matches the Adapter Model number     * from the MII register     */    AdapModelNum = (lmc_mii_readreg (sc, 0, 3) & 0x3f0) >> 4;    if ((AdapModelNum == LMC_ADAP_T1         && subdevice == PCI_DEVICE_ID_LMC_T1) ||	/* detect LMC1200 */        (AdapModelNum == LMC_ADAP_SSI         && subdevice == PCI_DEVICE_ID_LMC_SSI) ||	/* detect LMC1000 */        (AdapModelNum == LMC_ADAP_DS3         && subdevice == PCI_DEVICE_ID_LMC_DS3) ||	/* detect LMC5245 */        (AdapModelNum == LMC_ADAP_HSSI         && subdevice == PCI_DEVICE_ID_LMC_HSSI))    {				/* detect LMC5200 */    }    else {        printk ("%s: Model number (%d) miscompare for PCI Subsystem ID = 0x%04x\n",                dev->name, AdapModelNum, subdevice);//        return (NULL);    }    /*     * reset clock     */    LMC_CSR_WRITE (sc, csr_gp_timer, 0xFFFFFFFFUL);    sc->board_idx = cards_found++;    sc->stats.check = STATCHECK;    sc->stats.version_size = (DRIVER_VERSION << 16) +        sizeof (struct lmc_statistics);    sc->stats.lmc_cardtype = sc->lmc_cardtype;    sc->lmc_ok = 0;    sc->last_link_status = 0;    lmc_trace(dev, "lmc_init_one out");    return 0; out4:    lmc_proto_detach(sc); out3:    if (pdev) {	    pci_release_regions(pdev);	    pci_set_drvdata(pdev, NULL);    } out2:    free_netdev(dev); out1:    return err;}/* * Called from pci when removing module. */static void __devexit lmc_remove_one (struct pci_dev *pdev){    struct net_device *dev = pci_get_drvdata(pdev);        if (dev) {	    lmc_softc_t *sc = dev->priv;	    	    printk("%s: removing...\n", dev->name);	    lmc_proto_detach(sc);	    unregister_netdev(dev);	    free_netdev(dev);	    pci_release_regions(pdev);	    pci_disable_device(pdev);	    pci_set_drvdata(pdev, NULL);    }}/* After this is called, packets can be sent. * Does not initialize the addresses */static int lmc_open (struct net_device *dev) /*fold00*/{    lmc_softc_t *sc = dev->priv;    lmc_trace(dev, "lmc_open in");    lmc_led_on(sc, LMC_DS3_LED0);    lmc_dec_reset (sc);    lmc_reset (sc);    LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0);    LMC_EVENT_LOG(LMC_EVENT_RESET2,                  lmc_mii_readreg (sc, 0, 16),                  lmc_mii_readreg (sc, 0, 17));    if (sc->lmc_ok){        lmc_trace(dev, "lmc_open lmc_ok out");        return (0);    }    lmc_softreset (sc);    /* Since we have to use PCI bus, this should work on x86,alpha,ppc */    if (request_irq (dev->irq, &lmc_interrupt, SA_SHIRQ, dev->name, dev)){        printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq);        lmc_trace(dev, "lmc_open irq failed out");        return -EAGAIN;    }    sc->got_irq = 1;    /* Assert Terminal Active */    sc->lmc_miireg16 |= LMC_MII16_LED_ALL;    sc->lmc_media->set_link_status (sc, LMC_LINK_UP);    /*     * reset to last state.     */    sc->lmc_media->set_status (sc, NULL);    /* setup default bits to be used in tulip_desc_t transmit descriptor     * -baz */    sc->TxDescriptControlInit = (                                 LMC_TDES_INTERRUPT_ON_COMPLETION                                 | LMC_TDES_FIRST_SEGMENT                                 | LMC_TDES_LAST_SEGMENT                                 | LMC_TDES_SECOND_ADDR_CHAINED                                 | LMC_TDES_DISABLE_PADDING                                );    if (sc->ictl.crc_length == LMC_CTL_CRC_LENGTH_16) {        /* disable 32 bit CRC generated by ASIC */        sc->TxDescriptControlInit |= LMC_TDES_ADD_CRC_DISABLE;    }    sc->lmc_media->set_crc_length(sc, sc->ictl.crc_length);    /* Acknoledge the Terminal Active and light LEDs */    /* dev->flags |= IFF_UP; */    lmc_proto_open(sc);    dev->do_ioctl = lmc_ioctl;    netif_start_queue(dev);        sc->stats.tx_tbusy0++ ;    /*     * select what interrupts we want to get     */    sc->lmc_intrmask = 0;    /* Should be using the default interrupt mask defined in the .h file. */    sc->lmc_intrmask |= (TULIP_STS_NORMALINTR                         | TULIP_STS_RXINTR                         | TULIP_STS_TXINTR                         | TULIP_STS_ABNRMLINTR                         | TULIP_STS_SYSERROR                         | TULIP_STS_TXSTOPPED                         | TULIP_STS_TXUNDERFLOW                         | TULIP_STS_RXSTOPPED		         | TULIP_STS_RXNOBUF                        );    LMC_CSR_WRITE (sc, csr_intr, sc->lmc_intrmask);    sc->lmc_cmdmode |= TULIP_CMD_TXRUN;    sc->lmc_cmdmode |= TULIP_CMD_RXRUN;    LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);    sc->lmc_ok = 1; /* Run watchdog */    /*     * Set the if up now - pfb     */    sc->last_link_status = 1;    /*     * Setup a timer for the watchdog on probe, and start it running.     * Since lmc_ok == 0, it will be a NOP for now.     */    init_timer (&sc->timer);    sc->timer.expires = jiffies + HZ;    sc->timer.data = (unsigned long) dev;    sc->timer.function = &lmc_watchdog;    add_timer (&sc->timer);    lmc_trace(dev, "lmc_open out");    return (0);}/* Total reset to compensate for the AdTran DSU doing bad things *  under heavy load */static void lmc_running_reset (struct net_device *dev) /*fold00*/{    lmc_softc_t *sc = (lmc_softc_t *) dev->priv;    lmc_trace(dev, "lmc_runnig_reset in");    /* stop interrupts */    /* Clear the interrupt mask */    LMC_CSR_WRITE (sc, csr_intr, 0x00000000);    lmc_dec_reset (sc);    lmc_reset (sc);    lmc_softreset (sc);    /* sc->lmc_miireg16 |= LMC_MII16_LED_ALL; */    sc->lmc_media->set_link_status (sc, 1);    sc->lmc_media->set_status (sc, NULL);    netif_wake_queue(dev);    sc->lmc_txfull = 0;    sc->stats.tx_tbusy0++ ;    sc->lmc_intrmask = TULIP_DEFAULT_INTR_MASK;    LMC_CSR_WRITE (sc, csr_intr, sc->lmc_intrmask);    sc->lmc_cmdmode |= (TULIP_CMD_TXRUN | TULIP_CMD_RXRUN);    LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);    lmc_trace(dev, "lmc_runnin_reset_out");}/* This is what is called when you ifconfig down a device. * This disables the timer for the watchdog and keepalives, * and disables the irq for dev. */static int lmc_close (struct net_device *dev) /*fold00*/{    /* not calling release_region() as we should */    lmc_softc_t *sc;    lmc_trace(dev, "lmc_close in");        sc = dev->priv;    sc->lmc_ok = 0;    sc->lmc_media->set_link_status (sc, 0);    del_timer (&sc->timer);    lmc_proto_close(sc);    lmc_ifdown (dev);    lmc_trace(dev, "lmc_close out");        return 0;}/* Ends the transfer of packets *//* When the interface goes down, this is called */static int lmc_ifdown (struct net_device *dev) /*fold00*/{    lmc_softc_t *sc = dev->priv;    u32 csr6;    int i;    lmc_trace(dev, "lmc_ifdown in");        /* Don't let anything else go on right now */    //    dev->start = 0;    netif_stop_queue(dev);    sc->stats.tx_tbusy1++ ;    /* stop interrupts */    /* Clear the interrupt mask */    LMC_CSR_WRITE (sc, csr_intr, 0x00000000);    /* Stop Tx and Rx on the chip */    csr6 = LMC_CSR_READ (sc, csr_command);    csr6 &= ~LMC_DEC_ST;		/* Turn off the Transmission bit */    csr6 &= ~LMC_DEC_SR;		/* Turn off the Receive bit */    LMC_CSR_WRITE (sc, csr_command, csr6);    sc->stats.rx_missed_errors +=        LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;    /* release the interrupt */    if(sc->got_irq == 1){        free_irq (dev->irq, dev);        sc->got_irq = 0;    }    /* free skbuffs in the Rx queue */    for (i = 0; i < LMC_RXDESCS; i++)    {        struct sk_buff *skb = sc->lmc_rxq[i];        sc->lmc_rxq[i] = NULL;        sc->lmc_rxring[i].status = 0;        sc->lmc_rxring[i].length = 0;        sc->lmc_rxring[i].buffer1 = 0xDEADBEEF;        if (skb != NULL)            dev_kfree_skb(skb);        sc->lmc_rxq[i] = NULL;    }    for (i = 0; i < LMC_TXDESCS; i++)    {        if (sc->lmc_txq[i] != NULL)            dev_kfree_skb(sc->lmc_txq[i]);        sc->lmc_txq[i] = NULL;    }    lmc_led_off (sc, LMC_MII16_LED_ALL);    netif_wake_queue(dev);    sc->stats.tx_tbusy0++ ;    lmc_trace(dev, "lmc_ifdown out");    return 0;}/* Interrupt handling routine.  This will take an incoming packet, or clean * up after a trasmit. */static irqreturn_t lmc_interrupt (int irq, void *dev_instance, struct pt_regs *regs) /*fold00*/{    struct net_device *dev = (struct net_device *) dev_instance;    lmc_softc_t *sc;    u32 csr;    int i;    s32 stat;    unsigned int badtx;    u32 firstcsr;    int max_work = LMC_RXDESCS;    int handled = 0;    lmc_trace(dev, "lmc_interrupt in");    sc = dev->priv;        spin_lock(&sc->lmc_lock);    /*     * Read the csr to find what interrupts we have (if any)     */    csr = LMC_CSR_READ (sc, csr_status);    /*     * Make sure this is our interrupt     */    if ( ! (csr & sc->lmc_intrmask)) {        goto lmc_int_fail_out;    }    firstcsr = csr;    /* always go through this loop at least once */    while (csr & sc->lmc_intrmask) {	handled = 1;        /*         * Clear interrupt bits, we handle all case below         */        LMC_CSR_WRITE (sc, csr_status, csr);        /*         * One of         *  - Transmit process timed out CSR5<1>         *  - Transmit jabber timeout    CSR5<3>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -