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

📄 if_lancepci.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        }        else {            cpd->found = 0;            cpd->active = 0;#if DEBUG & 8            db_printf("eth%d not found\n", device_index);#endif        }    }    if (0 == found_devices)        return 0;    return 1;}static boolamd_lancepci_init(struct cyg_netdevtab_entry *tab){    static int initialized = 0; // only probe PCI et al *once*    struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;    struct lancepci_priv_data *cpd =        (struct lancepci_priv_data *)sc->driver_private;    cyg_uint16 val;    cyg_uint32 b;    cyg_uint8* p;    cyg_uint8* d;    int i;    DEBUG_FUNCTION();    if ( 0 == initialized++ ) {        // then this is the first time ever:        if ( ! pci_init_find_lancepci() ) {#if DEBUG & 8            db_printf( "pci_init_find_lancepci failed" );#endif            return false;        }    }    // If this device is not present, exit    if (0 == cpd->found)        return 0;#if DEBUG & 8    db_printf("lancepci at base 0x%08x, EEPROM key 0x%04x\n",                cpd->base, _SU16(cpd->base, LANCE_IO_ID));#endif#if 0    // FIXME: Doesn't work with non-conforming EEPROMS    if (LANCE_IO_ID_KEY != _SU16(cpd->base, LANCE_IO_ID) ) {        db_printf("Lance EPROM key not found\n");        return false;    }#endif#if DEBUG & 9    db_printf("pcimem : %08x size: %08x\n", lancepci_heap_base, lancepci_heap_size);#endif    // Prepare ESA    if (!cpd->hardwired_esa) {        // Don't use the address from the EEPROM for VMware        // Use the address that VMware prepares in CSR_PAR registers        // if You want to be able to use NAT networking. (iz@elsis.si Feb 27 04)        //        // p = cpd->base + LANCE_IO_EEPROM;        // for (i = 0; i < 6; i++)        // cpd->esa[i] = *p++;        put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);        for (i = 0;  i < sizeof(cpd->esa);  i += 2) {            cyg_uint16 z = get_reg(sc, LANCE_CSR_PAR0+i/2 );            cpd->esa[i] =   (cyg_uint8)(0xff & z);            cpd->esa[i+1] = (cyg_uint8)(0xff & (z >> 8));      }    }#if DEBUG & 9    db_printf("Lance - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",                (cpd->hardwired_esa) ? "static" : "eeprom",                cpd->esa[0], cpd->esa[1], cpd->esa[2],                cpd->esa[3], cpd->esa[4], cpd->esa[5] );#endif    // Prepare RX and TX rings    p = cpd->rx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->rx_ring_log_cnt)*LANCE_RD_SIZE));    memset(cpd->rx_ring,0,(1<<cpd->rx_ring_log_cnt)*LANCE_RD_SIZE);    d = cpd->rx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->rx_ring_cnt));    memset(cpd->rx_buffers,0,_BUF_SIZE*cpd->rx_ring_cnt);    for (i = 0; i < cpd->rx_ring_cnt; i++) {        HAL_PCI_CPU_TO_BUS(d, (cyg_uint8 *)b);        _SU32(p, LANCE_RD_PTR) = (b & LANCE_RD_PTR_MASK) | LANCE_RD_PTR_OWN;        _SU16(p, LANCE_RD_BLEN) = (-_BUF_SIZE);        p += LANCE_RD_SIZE;        d += _BUF_SIZE;    }    cpd->rx_ring_next = 0;    p = cpd->tx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->tx_ring_log_cnt)*LANCE_TD_SIZE));    memset(cpd->tx_ring,0,(1<<cpd->tx_ring_log_cnt)*LANCE_TD_SIZE);    d = cpd->tx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->tx_ring_cnt));    for (i = 0; i < cpd->tx_ring_cnt; i++) {        HAL_PCI_CPU_TO_BUS(d, (cyg_uint8 *)b);        _SU32(p, LANCE_RD_PTR) = b & LANCE_TD_PTR_MASK;        p += LANCE_TD_SIZE;        d += _BUF_SIZE;    }    cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;    // Initialization table    cpd->init_table = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(LANCE_IB_SIZE));    _SU16(cpd->init_table, LANCE_IB_MODE) = 0x0000;    for (i = 0; i < 6; i++)        _SU8(cpd->init_table, LANCE_IB_PADR0+i) = cpd->esa[i];    for (i = 0; i < 8; i++)        _SU8(cpd->init_table, LANCE_IB_LADRF0+i) = 0;    HAL_PCI_CPU_TO_BUS(cpd->rx_ring, (cyg_uint8 *)b);    _SU32(cpd->init_table, LANCE_IB_RDRA) = ((b & LANCE_IB_RDRA_PTR_mask)                                        | (cpd->rx_ring_log_cnt << LANCE_IB_RDRA_CNT_shift));    HAL_PCI_CPU_TO_BUS(cpd->tx_ring, (cyg_uint8 *)b);    _SU32(cpd->init_table, LANCE_IB_TDRA) = ((b & LANCE_IB_TDRA_PTR_mask)                                        | (cpd->tx_ring_log_cnt << LANCE_IB_TDRA_CNT_shift));#if DEBUG & 9    db_printf("Loading up lance controller from table at 0x%08x\n", cpd->init_table);    db_printf(" Mode 0x%04x\n", _SU16(cpd->init_table, LANCE_IB_MODE));    db_printf(" PADR %02x:%02x:%02x:%02x:%02x:%02x ",                _SU8(cpd->init_table, LANCE_IB_PADR0+0), _SU8(cpd->init_table, LANCE_IB_PADR0+1),                _SU8(cpd->init_table, LANCE_IB_PADR0+2), _SU8(cpd->init_table, LANCE_IB_PADR0+3),                _SU8(cpd->init_table, LANCE_IB_PADR0+4), _SU8(cpd->init_table, LANCE_IB_PADR0+5));    db_printf("LADR %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",                _SU8(cpd->init_table, LANCE_IB_LADRF0+0), _SU8(cpd->init_table, LANCE_IB_LADRF0+1),                _SU8(cpd->init_table, LANCE_IB_LADRF0+2), _SU8(cpd->init_table, LANCE_IB_LADRF0+3),                _SU8(cpd->init_table, LANCE_IB_LADRF0+4), _SU8(cpd->init_table, LANCE_IB_LADRF0+5),                _SU8(cpd->init_table, LANCE_IB_LADRF0+5), _SU8(cpd->init_table, LANCE_IB_LADRF0+7));    db_printf(" RX 0x%08x (len %d) TX 0x%08x (len %d)\n",                _SU32(cpd->init_table, LANCE_IB_RDRA) & 0x1fffffff,                (_SU32(cpd->init_table, LANCE_IB_RDRA) >> LANCE_IB_RDRA_CNT_shift) & 7,                _SU32(cpd->init_table, LANCE_IB_TDRA) & 0x1fffffff,                (_SU32(cpd->init_table, LANCE_IB_TDRA) >> LANCE_IB_TDRA_CNT_shift) & 7);#endif    // Reset chip    HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_RESET, val);    // Load up chip with buffers.    // Note: There is a 16M limit on the addresses used by the driver    // since the top 8 bits of the init_table address is appended to    // all other addresses used by the controller.    HAL_PCI_CPU_TO_BUS(cpd->init_table, (cyg_uint8 *)b);    put_reg(sc, LANCE_CSR_IBA0, (b >>  0) & 0xffff);    put_reg(sc, LANCE_CSR_IBA1, (b >> 16) & 0xffff);    // Disable automatic TX polling (_send will force a poll), pad    // XT frames to legal length, mask status interrupts.    put_reg(sc, LANCE_CSR_TFC, (LANCE_CSR_TFC_TXDPOLL | LANCE_CSR_TFC_APAD_XMT                                | LANCE_CSR_TFC_MFCOM | LANCE_CSR_TFC_RCVCCOM                                | LANCE_CSR_TFC_TXSTRTM));    // Recover after TX FIFO underflow    put_reg(sc, LANCE_CSR_IM, LANCE_CSR_IM_DXSUFLO);    // Initialize controller - load up init_table    put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_INIT);    while (0 == (get_reg(sc, LANCE_CSR_CSCR) & LANCE_CSR_CSCR_IDON));    // Stop controller    put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);#if DEBUG & 9    db_printf("lancepci controller state is now:\n");    db_printf(" Mode 0x%04x  TFC 0x%04x\n", _SU16(cpd->init_table, LANCE_IB_MODE), get_reg(sc, LANCE_CSR_TFC));    db_printf(" PADR %04x:%04x:%04x ",                get_reg(sc, LANCE_CSR_PAR0),                get_reg(sc, LANCE_CSR_PAR1),                get_reg(sc, LANCE_CSR_PAR2));    db_printf("LADR %04x:%04x:%04x:%04x\n",                get_reg(sc, LANCE_CSR_LAR0),                get_reg(sc, LANCE_CSR_LAR1),                get_reg(sc, LANCE_CSR_LAR2),                get_reg(sc, LANCE_CSR_LAR3));    db_printf(" RX 0x%04x%04x (len 0x%04x) TX 0x%04x%04x (len 0x%04x)\n",                get_reg(sc, LANCE_CSR_BARRU), get_reg(sc, LANCE_CSR_BARRL),                get_reg(sc, LANCE_CSR_RRLEN),                get_reg(sc, LANCE_CSR_BATRU), get_reg(sc, LANCE_CSR_BATRL),                get_reg(sc, LANCE_CSR_TRLEN));    val = get_reg(sc, LANCE_CSR_ID_LO);    db_printf("lancepci ID 0x%04x (%s) ",                val,                (0x5003 == val) ? "Am79C973" : (0x7003 == val) ? "Am79C975" :		        (0x1003 == val) ? "Am79C900 or wmWare VLANCE" : "Unknown");    val = get_reg(sc, LANCE_CSR_ID_HI);    db_printf("Part IDU 0x%03x Silicon rev %d\n",                val & 0x0fff, (val >> 12) & 0xf);#endif    // and record the net dev pointer    cpd->ndp = (void *)tab;    cpd->active = 0;    oursc=sc;    // Initialize upper level driver    (sc->funs->eth_drv->init)(sc, cpd->esa);    cpd->txbusyh=cpd->txbusy=0;    cpd->event=0;    db_printf("Lancepci driver loaded and Init Done\n");    return true;}static voidlancepci_stop(struct eth_drv_sc *sc){    cyg_uint32 b;    struct lancepci_priv_data *cpd =        (struct lancepci_priv_data *)sc->driver_private;    DEBUG_FUNCTION();    if (!cpd->active)        return;    if (cpd->txbusyh) {#if DEBUG & 9        db_printf("Lancepci-stop:waiting for tx empty\n");#endif        b=100;        while (cpd->txbusyh && b) {	    CYGACC_CALL_IF_DELAY_US(200);	    b--;	 }    }    put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);    cpd->active = 0;#if DEBUG & 9    db_printf("Lancepci-stop:done\n");#endif}//// This function is called to "start up" the interface.  It may be called// multiple times, even when the hardware is already running.  It will be// called whenever something "hardware oriented" changes and should leave// the hardware ready to send/receive packets.//static voidlancepci_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags){    cyg_uint16 reg;    cyg_uint32 b;    struct lancepci_priv_data *cpd =        (struct lancepci_priv_data *)sc->driver_private;#ifdef CYGPKG_NET    struct ifnet *ifp = &sc->sc_arpcom.ac_if;#endif    DEBUG_FUNCTION();    // If device is already active, stop it#if DEBUG & 9	db_printf("Lancepci-start:entered\n");#endif    if (cpd->active)     {        if (cpd->txbusyh) {#if DEBUG & 9	    db_printf("Lancepci-start:waiting for tx empty\n");#endif	    b=100;     	    while (cpd->txbusyh && b) {	        CYGACC_CALL_IF_DELAY_US(200);		b--;	    }	}    	put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);    	cpd->active = 0;#if DEBUG & 9    	db_printf("Lancepci-start:stopped\n");#endif    }    CYGACC_CALL_IF_DELAY_US(200);#ifdef CYGPKG_NET    if (( 0#ifdef ETH_DRV_FLAGS_PROMISC_MODE         != (flags & ETH_DRV_FLAGS_PROMISC_MODE)#endif        ) || (ifp->if_flags & IFF_PROMISC)        ) {        // Then we select promiscuous mode.    	_SU16(cpd->init_table, LANCE_IB_MODE) = 0x0000|LANCE_CSR_MODE_PROM;#if DEBUG & 9	db_printf("Promisc MODE!");#endif    }    else _SU16(cpd->init_table, LANCE_IB_MODE) = 0x0000;#endif    cpd->rx_ring_next = 0;    cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;    // Init the chip again    HAL_PCI_CPU_TO_BUS(cpd->init_table, (cyg_uint8 *)b);    put_reg(sc, LANCE_CSR_IBA0, (b >>  0) & 0xffff);    put_reg(sc, LANCE_CSR_IBA1, (b >> 16) & 0xffff);    // Disable automatic TX polling (_send will force a poll), pad    // XT frames to legal length, mask status interrupts.    put_reg(sc, LANCE_CSR_TFC, (LANCE_CSR_TFC_TXDPOLL | LANCE_CSR_TFC_APAD_XMT                                | LANCE_CSR_TFC_MFCOM | LANCE_CSR_TFC_RCVCCOM                                | LANCE_CSR_TFC_TXSTRTM));    // Recover after TX FIFO underflow    put_reg(sc, LANCE_CSR_IM, LANCE_CSR_IM_DXSUFLO);    // Initialize controller - load up init_table    put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_INIT);    while (0 == (get_reg(sc, LANCE_CSR_CSCR) & LANCE_CSR_CSCR_IDON));	reg=get_reg(sc,LANCE_CSR_CSCR);    put_reg(sc, LANCE_CSR_CSCR, (reg|(LANCE_CSR_CSCR_IENA | LANCE_CSR_CSCR_STRT))&~LANCE_CSR_CSCR_INIT);#if DEBUG & 9	reg=get_reg(sc,LANCE_CSR_CSCR);	db_printf("CSR after start = %4x\n",reg);#endif    cpd->active = 1; cpd->txbusy=0; cpd->txbusyh=0;    // delay is necessary for Vmware to get a tick !!!    CYGACC_CALL_IF_DELAY_US(50000);}//// This routine is called to perform special "control" opertions//static intlancepci_control(struct eth_drv_sc *sc, unsigned long key,               void *data, int data_length){    cyg_uint8 *esa = (cyg_uint8 *)data;    int i, res;    cyg_uint16 reg;    struct lancepci_priv_data *cpd =        (struct lancepci_priv_data *)sc->driver_private;    DEBUG_FUNCTION();#if DEBUG & 9	db_printf("Lancepci-control:entered\n");#endif    res = 0;                            // expect success    switch (key) {        case ETH_DRV_SET_MAC_ADDRESS:#if 9 & DEBUG            db_printf("PCNET - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",                esa[0], esa[1], esa[2], esa[3], esa[4], esa[5] );#endif // DEBUG            for ( i = 0; i < sizeof(cpd->esa);  i++ )                cpd->esa[i] = esa[i];            for (i = 0;  i < sizeof(cpd->esa);  i += 2) {                reg = cpd->esa[i] | (cpd->esa[i+1] << 8);                put_reg(sc, LANCE_CSR_PAR0+i/2, reg );            }            for (i = 0; i < 6; i++)	// in case of later restart                _SU8(cpd->init_table, LANCE_IB_PADR0+i) = cpd->esa[i];            break;#ifdef ETH_DRV_GET_MAC_ADDRESS        case ETH_DRV_GET_MAC_ADDRESS:            // Extract the MAC address that is in the chip, and tell the            // system about it.            for (i = 0;  i < sizeof(cpd->esa);  i += 2) {                cyg_uint16 z = get_reg(sc, LANCE_CSR_PAR0+i/2 );                esa[i] =   (cyg_uint8)(0xff & z);                esa[i+1] = (cyg_uint8)(0xff & (z >> 8));            }            break;#endif#ifdef ETH_DRV_GET_IF_STATS_UD        case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE#endif        // drop through#ifdef ETH_DRV_GET_IF_STATS        case ETH_DRV_GET_IF_STATS:#endif#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)        {            struct ether_drv_stats *p = (struct ether_drv_stats *)data;            // Chipset entry is no longer supported; RFC1573.            for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )                p->snmp_chipset[i] = 0;            // This perhaps should be a config opt, so you can make up your own            // description, or supply it from the instantiation.            strcpy( p->description, "AMD LancePCI" );            // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );            p->operational = 3;         // LINK UP            p->duplex = 2;              // 2 = SIMPLEX            p->speed = 10 * 1000000;#if FIXME#ifdef KEEP_STATISTICS            {                struct amd_lancepci_stats *ps = &(cpd->stats);                // Admit to it...                p->supports_dot3        = true;                p->tx_good              = ps->tx_good             ;                p->tx_max_collisions    = ps->tx_max_collisions   ;                p->tx_late_collisions   = ps->tx_late_collisions  ;                p->tx_underrun          = ps->tx_underrun         ;                p->tx_carrier_loss      = ps->tx_carrier_loss     ;                p->tx_deferred          = ps->tx_deferred         ;                p->tx_sqetesterrors     = ps->tx_sqetesterrors    ;                p->tx_single_collisions = ps->tx_single_collisions;                p->tx_mult_collisions   = ps->tx_mult_collisions  ;                p->tx_total_collisions  = ps->tx_total_collisions ;                p->rx_good              = ps->rx_good             ;                p->rx_crc_errors        = ps->rx_crc_errors       ;                p->rx_align_errors      = ps->rx_align_errors     ;                p->rx_resource_errors   = ps->rx_resource_errors  ;                p->rx_overrun_errors    = ps->rx_overrun_errors   ;                p->rx_collisions        = ps->rx_collisions       ;                p->rx_short_frames      = ps->rx_short_frames     ;                p->rx_too_long_frames   = ps->rx_too_long_frames  ;                p->rx_symbol_errors     = ps->rx_symbol_errors    ;                p->interrupts           = ps->interrupts          ;                p->rx_count             = ps->rx_count            ;                p->rx_deliver           = ps->rx_deliver          ;                p->rx_resource          = ps->rx_resource         ;                p->rx_restart           = ps->rx_restart          ;                p->tx_count             = ps->tx_count            ;                p->tx_complete          = ps->tx_complete         ;                p->tx_dropped           = ps->tx_dropped          ;            }#endif // KEEP_STATISTICS#endif // FIXME            p->tx_queue_len = 1;            break;        }#endif        default:            res = 1;            break;    }

⌨️ 快捷键说明

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