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

📄 lmc_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
    return 0;}static struct net_device_stats *lmc_get_stats (struct net_device *dev) /*fold00*/{    lmc_softc_t *sc = dev->priv;    unsigned long flags;    lmc_trace(dev, "lmc_get_stats in");    spin_lock_irqsave(&sc->lmc_lock, flags);    sc->stats.rx_missed_errors += LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;    spin_unlock_irqrestore(&sc->lmc_lock, flags);    lmc_trace(dev, "lmc_get_stats out");    return (struct net_device_stats *) &sc->stats;}static struct pci_driver lmc_driver = {	.name		= "lmc",	.id_table	= lmc_pci_tbl,	.probe		= lmc_init_one,	.remove		= __devexit_p(lmc_remove_one),};static int __init init_lmc(void){    return pci_module_init(&lmc_driver);}static void __exit exit_lmc(void){    pci_unregister_driver(&lmc_driver);}module_init(init_lmc);module_exit(exit_lmc);unsigned lmc_mii_readreg (lmc_softc_t * const sc, unsigned devaddr, unsigned regno) /*fold00*/{    int i;    int command = (0xf6 << 10) | (devaddr << 5) | regno;    int retval = 0;    lmc_trace(sc->lmc_device, "lmc_mii_readreg in");    LMC_MII_SYNC (sc);    lmc_trace(sc->lmc_device, "lmc_mii_readreg: done sync");    for (i = 15; i >= 0; i--)    {        int dataval = (command & (1 << i)) ? 0x20000 : 0;        LMC_CSR_WRITE (sc, csr_9, dataval);        lmc_delay ();        /* __SLOW_DOWN_IO; */        LMC_CSR_WRITE (sc, csr_9, dataval | 0x10000);        lmc_delay ();        /* __SLOW_DOWN_IO; */    }    lmc_trace(sc->lmc_device, "lmc_mii_readreg: done1");    for (i = 19; i > 0; i--)    {        LMC_CSR_WRITE (sc, csr_9, 0x40000);        lmc_delay ();        /* __SLOW_DOWN_IO; */        retval = (retval << 1) | ((LMC_CSR_READ (sc, csr_9) & 0x80000) ? 1 : 0);        LMC_CSR_WRITE (sc, csr_9, 0x40000 | 0x10000);        lmc_delay ();        /* __SLOW_DOWN_IO; */    }    lmc_trace(sc->lmc_device, "lmc_mii_readreg out");    return (retval >> 1) & 0xffff;}void lmc_mii_writereg (lmc_softc_t * const sc, unsigned devaddr, unsigned regno, unsigned data) /*fold00*/{    int i = 32;    int command = (0x5002 << 16) | (devaddr << 23) | (regno << 18) | data;    lmc_trace(sc->lmc_device, "lmc_mii_writereg in");    LMC_MII_SYNC (sc);    i = 31;    while (i >= 0)    {        int datav;        if (command & (1 << i))            datav = 0x20000;        else            datav = 0x00000;        LMC_CSR_WRITE (sc, csr_9, datav);        lmc_delay ();        /* __SLOW_DOWN_IO; */        LMC_CSR_WRITE (sc, csr_9, (datav | 0x10000));        lmc_delay ();        /* __SLOW_DOWN_IO; */        i--;    }    i = 2;    while (i > 0)    {        LMC_CSR_WRITE (sc, csr_9, 0x40000);        lmc_delay ();        /* __SLOW_DOWN_IO; */        LMC_CSR_WRITE (sc, csr_9, 0x50000);        lmc_delay ();        /* __SLOW_DOWN_IO; */        i--;    }    lmc_trace(sc->lmc_device, "lmc_mii_writereg out");}static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/{    int i;    lmc_trace(sc->lmc_device, "lmc_softreset in");    /* Initialize the receive rings and buffers. */    sc->lmc_txfull = 0;    sc->lmc_next_rx = 0;    sc->lmc_next_tx = 0;    sc->lmc_taint_rx = 0;    sc->lmc_taint_tx = 0;    /*     * Setup each one of the receiver buffers     * allocate an skbuff for each one, setup the descriptor table     * and point each buffer at the next one     */    for (i = 0; i < LMC_RXDESCS; i++)    {        struct sk_buff *skb;        if (sc->lmc_rxq[i] == NULL)        {            skb = dev_alloc_skb (LMC_PKT_BUF_SZ + 2);            if(skb == NULL){                printk(KERN_WARNING "%s: Failed to allocate receiver ring, will try again\n", sc->name);                sc->failed_ring = 1;                break;            }            else{                sc->lmc_rxq[i] = skb;            }        }        else        {            skb = sc->lmc_rxq[i];        }        skb->dev = sc->lmc_device;        /* owned by 21140 */        sc->lmc_rxring[i].status = 0x80000000;        /* used to be PKT_BUF_SZ now uses skb since we lose some to head room */        sc->lmc_rxring[i].length = skb->end - skb->data;        /* use to be tail which is dumb since you're thinking why write         * to the end of the packj,et but since there's nothing there tail == data         */        sc->lmc_rxring[i].buffer1 = virt_to_bus (skb->data);        /* This is fair since the structure is static and we have the next address */        sc->lmc_rxring[i].buffer2 = virt_to_bus (&sc->lmc_rxring[i + 1]);    }    /*     * Sets end of ring     */    sc->lmc_rxring[i - 1].length |= 0x02000000; /* Set end of buffers flag */    sc->lmc_rxring[i - 1].buffer2 = virt_to_bus (&sc->lmc_rxring[0]); /* Point back to the start */    LMC_CSR_WRITE (sc, csr_rxlist, virt_to_bus (sc->lmc_rxring)); /* write base address */    /* Initialize the transmit rings and buffers */    for (i = 0; i < LMC_TXDESCS; i++)    {        if (sc->lmc_txq[i] != NULL){		/* have buffer */            dev_kfree_skb(sc->lmc_txq[i]);	/* free it */            sc->stats.tx_dropped++;      /* We just dropped a packet */        }        sc->lmc_txq[i] = NULL;        sc->lmc_txring[i].status = 0x00000000;        sc->lmc_txring[i].buffer2 = virt_to_bus (&sc->lmc_txring[i + 1]);    }    sc->lmc_txring[i - 1].buffer2 = virt_to_bus (&sc->lmc_txring[0]);    LMC_CSR_WRITE (sc, csr_txlist, virt_to_bus (sc->lmc_txring));    lmc_trace(sc->lmc_device, "lmc_softreset out");}void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/{    lmc_trace(sc->lmc_device, "lmc_gpio_mkinput in");    sc->lmc_gpio_io &= ~bits;    LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));    lmc_trace(sc->lmc_device, "lmc_gpio_mkinput out");}void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/{    lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput in");    sc->lmc_gpio_io |= bits;    LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));    lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput out");}void lmc_led_on(lmc_softc_t * const sc, u_int32_t led) /*fold00*/{    lmc_trace(sc->lmc_device, "lmc_led_on in");    if((~sc->lmc_miireg16) & led){ /* Already on! */        lmc_trace(sc->lmc_device, "lmc_led_on aon out");        return;    }        sc->lmc_miireg16 &= ~led;    lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);    lmc_trace(sc->lmc_device, "lmc_led_on out");}void lmc_led_off(lmc_softc_t * const sc, u_int32_t led) /*fold00*/{    lmc_trace(sc->lmc_device, "lmc_led_off in");    if(sc->lmc_miireg16 & led){ /* Already set don't do anything */        lmc_trace(sc->lmc_device, "lmc_led_off aoff out");        return;    }        sc->lmc_miireg16 |= led;    lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);    lmc_trace(sc->lmc_device, "lmc_led_off out");}static void lmc_reset(lmc_softc_t * const sc) /*fold00*/{    lmc_trace(sc->lmc_device, "lmc_reset in");    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);    /*     * make some of the GPIO pins be outputs     */    lmc_gpio_mkoutput(sc, LMC_GEP_RESET);    /*     * RESET low to force state reset.  This also forces     * the transmitter clock to be internal, but we expect to reset     * that later anyway.     */    sc->lmc_gpio &= ~(LMC_GEP_RESET);    LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);    /*     * hold for more than 10 microseconds     */    udelay(50);    /*     * stop driving Xilinx-related signals     */    lmc_gpio_mkinput(sc, LMC_GEP_RESET);    /*     * Call media specific init routine     */    sc->lmc_media->init(sc);    sc->stats.resetCount++;    lmc_trace(sc->lmc_device, "lmc_reset out");}static void lmc_dec_reset(lmc_softc_t * const sc) /*fold00*/{    u_int32_t val;    lmc_trace(sc->lmc_device, "lmc_dec_reset in");    /*     * disable all interrupts     */    sc->lmc_intrmask = 0;    LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask);    /*     * Reset the chip with a software reset command.     * Wait 10 microseconds (actually 50 PCI cycles but at     * 33MHz that comes to two microseconds but wait a     * bit longer anyways)     */    LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);    udelay(25);#ifdef __sparc__    sc->lmc_busmode = LMC_CSR_READ(sc, csr_busmode);    sc->lmc_busmode = 0x00100000;    sc->lmc_busmode &= ~TULIP_BUSMODE_SWRESET;    LMC_CSR_WRITE(sc, csr_busmode, sc->lmc_busmode);#endif    sc->lmc_cmdmode = LMC_CSR_READ(sc, csr_command);    /*     * We want:     *   no ethernet address in frames we write     *   disable padding (txdesc, padding disable)     *   ignore runt frames (rdes0 bit 15)     *   no receiver watchdog or transmitter jabber timer     *       (csr15 bit 0,14 == 1)     *   if using 16-bit CRC, turn off CRC (trans desc, crc disable)     */    sc->lmc_cmdmode |= ( TULIP_CMD_PROMISCUOUS                         | TULIP_CMD_FULLDUPLEX                         | TULIP_CMD_PASSBADPKT                         | TULIP_CMD_NOHEARTBEAT                         | TULIP_CMD_PORTSELECT                         | TULIP_CMD_RECEIVEALL                         | TULIP_CMD_MUSTBEONE                       );    sc->lmc_cmdmode &= ~( TULIP_CMD_OPERMODE                          | TULIP_CMD_THRESHOLDCTL                          | TULIP_CMD_STOREFWD                          | TULIP_CMD_TXTHRSHLDCTL                        );    LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);    /*     * disable receiver watchdog and transmit jabber     */    val = LMC_CSR_READ(sc, csr_sia_general);    val |= (TULIP_WATCHDOG_TXDISABLE | TULIP_WATCHDOG_RXDISABLE);    LMC_CSR_WRITE(sc, csr_sia_general, val);    lmc_trace(sc->lmc_device, "lmc_dec_reset out");}static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, /*fold00*/                         size_t csr_size){    lmc_trace(sc->lmc_device, "lmc_initcsrs in");    sc->lmc_csrs.csr_busmode	        = csr_base +  0 * csr_size;    sc->lmc_csrs.csr_txpoll		= csr_base +  1 * csr_size;    sc->lmc_csrs.csr_rxpoll		= csr_base +  2 * csr_size;    sc->lmc_csrs.csr_rxlist		= csr_base +  3 * csr_size;    sc->lmc_csrs.csr_txlist		= csr_base +  4 * csr_size;    sc->lmc_csrs.csr_status		= csr_base +  5 * csr_size;    sc->lmc_csrs.csr_command	        = csr_base +  6 * csr_size;    sc->lmc_csrs.csr_intr		= csr_base +  7 * csr_size;    sc->lmc_csrs.csr_missed_frames	= csr_base +  8 * csr_size;    sc->lmc_csrs.csr_9		        = csr_base +  9 * csr_size;    sc->lmc_csrs.csr_10		        = csr_base + 10 * csr_size;    sc->lmc_csrs.csr_11		        = csr_base + 11 * csr_size;    sc->lmc_csrs.csr_12		        = csr_base + 12 * csr_size;    sc->lmc_csrs.csr_13		        = csr_base + 13 * csr_size;    sc->lmc_csrs.csr_14		        = csr_base + 14 * csr_size;    sc->lmc_csrs.csr_15		        = csr_base + 15 * csr_size;    lmc_trace(sc->lmc_device, "lmc_initcsrs out");}static void lmc_driver_timeout(struct net_device *dev) { /*fold00*/    lmc_softc_t *sc;    u32 csr6;    unsigned long flags;    lmc_trace(dev, "lmc_driver_timeout in");    sc = dev->priv;    spin_lock_irqsave(&sc->lmc_lock, flags);    printk("%s: Xmitter busy|\n", dev->name);    sc->stats.tx_tbusy_calls++ ;    if (jiffies - dev->trans_start < TX_TIMEOUT) {        goto bug_out;    }    /*     * Chip seems to have locked up     * Reset it     * This whips out all our decriptor     * table and starts from scartch     */    LMC_EVENT_LOG(LMC_EVENT_XMTPRCTMO,                  LMC_CSR_READ (sc, csr_status),                  sc->stats.tx_ProcTimeout);    lmc_running_reset (dev);    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));    /* restart the tx processes */    csr6 = LMC_CSR_READ (sc, csr_command);    LMC_CSR_WRITE (sc, csr_command, csr6 | 0x0002);    LMC_CSR_WRITE (sc, csr_command, csr6 | 0x2002);    /* immediate transmit */    LMC_CSR_WRITE (sc, csr_txpoll, 0);    sc->stats.tx_errors++;    sc->stats.tx_ProcTimeout++;	/* -baz */    dev->trans_start = jiffies;bug_out:    spin_unlock_irqrestore(&sc->lmc_lock, flags);    lmc_trace(dev, "lmc_driver_timout out");}

⌨️ 快捷键说明

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