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

📄 lmc_main.c

📁 移植到2410开发板上的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /*     * 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);    /* Just fill in the entries for the device */    dev->init = lmc_init;    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->set_config = lmc_set_config;#if LINUX_VERSION_CODE >= 0x20363    dev->tx_timeout = lmc_driver_timeout;    dev->watchdog_timeo = (HZ); /* 1 second */#endif        /*     * 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);    LMC_SETUP_20_DEV;    printk ("%s: detected at %lx, irq %d\n", dev->name, ioaddr, dev->irq);    if (register_netdev (dev) != 0) {        printk (KERN_ERR "%s: register_netdev failed.\n", dev->name);        lmc_proto_detach(sc);        kfree (dev->priv);        kfree (dev);        return NULL;    }    /*     * Request the region of registers we need, so that     * later on, no one else will take our card away from     * us.     */    request_region (ioaddr, LMC_REG_RANGE, dev->name);    sc->lmc_cardtype = LMC_CARDTYPE_UNKNOWN;    sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;    switch (subdevice) {    case PCI_PRODUCT_LMC_HSSI:        printk ("%s: LMC HSSI\n", dev->name);        sc->lmc_cardtype = LMC_CARDTYPE_HSSI;        sc->lmc_media = &lmc_hssi_media;        break;    case PCI_PRODUCT_LMC_DS3:        printk ("%s: LMC DS3\n", dev->name);        sc->lmc_cardtype = LMC_CARDTYPE_DS3;        sc->lmc_media = &lmc_ds3_media;        break;    case PCI_PRODUCT_LMC_SSI:        printk ("%s: LMC SSI\n", dev->name);        sc->lmc_cardtype = LMC_CARDTYPE_SSI;        sc->lmc_media = &lmc_ssi_media;        break;    case PCI_PRODUCT_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_PRODUCT_LMC_T1) ||		/* detect LMC1200 */        (AdapModelNum == LMC_ADAP_SSI         && subdevice == PCI_PRODUCT_LMC_SSI) ||	/* detect LMC1000 */        (AdapModelNum == LMC_ADAP_DS3         && subdevice == PCI_PRODUCT_LMC_DS3) ||	/* detect LMC5245 */        (AdapModelNum == LMC_ADAP_HSSI         && subdevice == PCI_PRODUCT_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 = board_idx;    memset (&sc->stats, 0, sizeof (struct lmc_statistics));    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_probe1 out");    return dev;}/* This is the entry point.  This is what is called immediatly. *//* This goes out and finds the card */int lmc_probe_fake(struct net_device *dev) /*fold00*/{    lmc_probe(NULL);    /* Return 1 to unloaded bogus device */    return 1;}int lmc_probe (struct net_device *dev) /*fold00*/{    int pci_index = 0;    unsigned long pci_ioaddr;    unsigned int pci_irq_line;    u16 vendor, subvendor, device, subdevice;    u32 foundaddr = 0;    unsigned char pci_bus, pci_device_fn;    u8 intcf = 0;    /* The card is only available on PCI, so if we don't have a     * PCI bus, we are in trouble.     */    if (!LMC_PCI_PRESENT()) {/*        printk ("%s: We really want a pci bios!\n", dev->name);*/        return -1;    }    /* Loop basically until we don't find anymore. */    while (pci_index < 0xff){    	struct pci_dev *pdev;        /* The tulip is considered an ethernet class of card... */        if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,                                pci_index, &pci_bus,                                &pci_device_fn) != PCIBIOS_SUCCESSFUL) {            /* No card found on this pass */            break;        }        /* Read the info we need to determine if this is         * our card or not         */	pdev = pci_find_slot (pci_bus, pci_device_fn);	if (!pdev) break;	if (pci_enable_device(pdev))		break;        vendor = pdev->vendor;        device = pdev->device;        pci_irq_line = pdev->irq;        pci_ioaddr = pci_resource_start (pdev, 0);	subvendor = pdev->subsystem_vendor;	subdevice = pdev->subsystem_device;	pci_set_master (pdev);        /*         * Make sure it's the correct card.  CHECK SUBVENDOR ID!         * There are lots of tulip's out there.         * Also check the region of registers we will soon be         * poking, to make sure no one else has reserved them.         * This prevents taking someone else's device.         *         * Check either the subvendor or the subdevice, some systems reverse         * the setting in the bois, seems to be version and arch dependant?         * Fix the two variables         *         */        if (!(check_region (pci_ioaddr, LMC_REG_RANGE)) &&            (vendor == CORRECT_VENDOR_ID) &&            (device == CORRECT_DEV_ID) &&            ((subvendor == PCI_VENDOR_LMC)  || (subdevice == PCI_VENDOR_LMC))){            struct net_device *cur, *prev = NULL;            /* Fix the error, exchange the two values */            if(subdevice == PCI_VENDOR_LMC){                subdevice = subvendor;                subvendor = PCI_VENDOR_LMC ;            }            /* Make the call to actually setup this card */            dev = lmc_probe1 (dev, pci_ioaddr, pci_irq_line,                              device, subdevice, cards_found);            if (dev == NULL) {                printk ("lmc_probe: lmc_probe1 failed\n");                goto lmc_probe_next_card;            }            /* insert the device into the chain of lmc devices */            for (cur = Lmc_root_dev;                 cur != NULL;                 cur = ((lmc_softc_t *) cur->priv)->next_module) {                prev = cur;            }            if (prev == NULL)                Lmc_root_dev = dev;            else                ((lmc_softc_t *) prev->priv)->next_module = dev;            ((lmc_softc_t *) dev->priv)->next_module = NULL;            /* end insert */            foundaddr = dev->base_addr;            cards_found++;            intcf++;        }    lmc_probe_next_card:        pci_index++;    }    if (cards_found < 1)        return -1;#if LINUX_VERSION_CODE >= 0x20200    return foundaddr;#else    return 0;#endif}/* 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;    LMC_XMITTER_INIT(dev);    #if LINUX_VERSION_CODE < 0x20363    dev->start = 1;#endif        sc->stats.tx_tbusy0++ ;    MOD_INC_USE_COUNT;    /*     * 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);    //dev->flags |= IFF_RUNNING;        LMC_XMITTER_FREE(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 */

⌨️ 快捷键说明

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