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

📄 cs8900.c

📁 QNX ADS BSP code for i.MX27 chips
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $QNXLicenseC:  * Copyright 2007, QNX Software Systems.   *   * Licensed under the Apache License, Version 2.0 (the "License"). You   * may not reproduce, modify or distribute this software except in   * compliance with the License. You may obtain a copy of the License   * at: http://www.apache.org/licenses/LICENSE-2.0   *   * Unless required by applicable law or agreed to in writing, software   * distributed under the License is distributed on an "AS IS" basis,   * WITHOUT WARRANTIES OF ANY KIND, either express or implied.  *  * This file may contain contributions from others, either as   * contributors under the License or as licensors under other terms.    * Please review this entire file for other proprietary rights or license   * notices, as well as the QNX Development Suite License Guide at   * http://licensing.qnx.com/license-guide/ for other information.  * $ *//* * Todo: * finish promiscious/multicast * test shared memory mode */#include <crys8900.h>#define NIC_INTERRUPT_EVENT		0#define NIC_TIMER_EVENT			1#define NIC_PRIORITY			21extern int variant_irq_init(void *handle);extern int cs8900_variant_load(void *handle);io_net_dll_entry_t io_net_dll_entry = {		2, 		cs8900_init, 		NULL };io_net_registrant_funcs_t cs8900_funcs = {		8, 		NULL,		cs8900_send_packets, 		cs8900_receive_complete,		cs8900_shutdown1,		cs8900_shutdown2,		cs8900_advertise,		cs8900_devctl, 		cs8900_flush, 		NULL		};io_net_registrant_t cs8900_entry = {        _REG_PRODUCER_UP | _REG_TRACK_MCAST,        "devn-cs8900",        "en",        NULL,        NULL,        &cs8900_funcs,        0	};int cs8900_init( void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char *options){	int ret;	dpp = dpp;	if (ret = crys8900_detect(dll_hdl, ion, options)) {		errno = ret;		return -1;	}	return 0;}int cs8900_reset( void *handle ){	cs8900_dev_t	*cs8900 = (cs8900_dev_t *)handle;	int					iobase;	int					cnt;	iobase = cs8900->iobase;	cs8900_wpktpage( iobase, CS8900_SELFCTL, cs8900_rpktpage( iobase, CS8900_SELFCTL ) | SELFCTL_RESET );	delay( 30 );#ifdef __X86__	if( cs8900->chip_id != CS8900 ) {		/* Hardware problem requires PNP registers to be reconfigured after a reset */		outle16( iobase + CS8900_PORT_PKTPG, CS8920_ISAINT );		out8( iobase + CS8900_PORT_PKTPG_DATA, cs8900->cfg.irq[0] );		out8( iobase + CS8900_PORT_PKTPG_DATA + 1, 0 );		outle16( iobase + CS8900_PORT_PKTPG, CS8920_MEM_BASE );		out8( iobase + CS8900_PORT_PKTPG_DATA, (cs8900->smem_addr >> 8) & 0xff );		out8( iobase + CS8900_PORT_PKTPG_DATA + 1, ( cs8900->smem_addr >> 24 ) & 0xff );	}#endif	/* Wait until the chip is reset */	for (cnt = 1000; cnt && !( cs8900_rpktpage( iobase, CS8900_SELFST ) & SELFST_INIT_DONE ); cnt--)		nsec_delay(10);	return( 0 );}int cs8900_init_memory( void *handle ){	cs8900_dev_t	*cs8900	= (cs8900_dev_t *) handle;	int i,j;	cs8900->num_rx_pkts = 16;	cs8900->rx_pktq = calloc(cs8900->num_rx_pkts, sizeof(npkt_t *));	if (cs8900->rx_pktq == NULL) {		perror("calloc");		return (-1);	}	cs8900->rx_max = cs8900->num_rx_pkts * 2;	cs8900->rx_active = cs8900->num_rx_pkts;	cs8900->rx_cidx = cs8900->rx_pidx = 0;		for (i = 0; i < cs8900->num_rx_pkts; i++) {		cs8900->rx_pktq[i] = cs8900_alloc_npkt(cs8900, 1518);		if (cs8900->rx_pktq[i] == NULL) {			for (j = 0; j < i; j++) {				if (cs8900->rx_pktq[i]) {					ion_free(cs8900->rx_pktq[i]->org_data);					ion_free(cs8900->rx_pktq[i]);				}			}		}	}#ifdef __X86__	if( cs8900->mode & CS8900_DMA ) {		cs8900->dmem_size = ( cs8900->isa_cnf & I_CNF_ISA_DMA_64K ) ? 0x10000 : 0x4000;		/* receive DMA buffer memory */		if( ( cs8900->dmem = mmap( NULL, cs8900->dmem_size, PROT_READ | PROT_WRITE | PROT_NOCACHE, MAP_ANON | MAP_PHYS | MAP_BELOW16M, NOFD, 0 ) ) == MAP_FAILED ) {			return( 1 );		}		cs8900->dmem_cptr = cs8900->dmem;	}	if( cs8900->mode & CS8900_SHARED ) {			/* map in shared memory */		if( !cs8900->smem_size ) {			cs8900->smem_size = 4096;		}		if( ( cs8900->smem = mmap( NULL, cs8900->smem_size, PROT_READ | PROT_WRITE | PROT_NOCACHE, MAP_SHARED | MAP_PHYS, NOFD, cs8900->smem_addr ) ) == MAP_FAILED ) {			return( 1 );		}	}#endif	return( 0 );}int cs8900_read_eeprom( int iobase, int off, int len, int *buffer ){	int		i;	int		cnt;	for( i = 0; i < len; i++ ) {		for(cnt = 1000; cnt && (cs8900_rpktpage(iobase, CS8900_SELFST) & SELFST_SI_BUSY); cnt--)			nsec_delay (10);		/* send read command and location */		cs8900_wpktpage( iobase, CS8900_EEPROM_CMD, (off + i) | EEPROM_READ_CMD );		for(cnt = 1000; cnt && (cs8900_rpktpage(iobase, CS8900_SELFST) & SELFST_SI_BUSY); cnt--)			nsec_delay (10);		buffer[i] = cs8900_rpktpage( iobase, CS8900_EEPROM_DATA );	}	return( 0 );}int cs8900_eeprom_config( void *handle ){	int					i;	cs8900_dev_t		*cs8900	= (cs8900_dev_t *)handle;	int					cksum;	int					iobase;	int					rom[CHKSUM_LEN];	iobase	= cs8900->iobase;	/* check for EEPROM */	if( !( cs8900_rpktpage( iobase, CS8900_SELFST ) & SELFST_EEPROM_PRESENT ) ) {		return( 1 );	}	if( cs8900_read_eeprom( iobase, START_EEPROM_DATA, CHKSUM_LEN, rom ) ) {		return( 1 );	}	/* verify cksum */	for( i = 0, cksum = 0; i < CHKSUM_LEN; i++ ) {		cksum += rom[i];	}	if( cksum & 0xffff ) {		return( 1 );	}	if( !cs8900->auto_neg_cnf ) {		/* get transmission control */		cs8900->auto_neg_cnf = rom[AUTO_NEG_CNF_OFFSET/2];	}	if( !cs8900->adapter_cnf ) {		/* get adapter configuration */		cs8900->adapter_cnf = rom[ADAPTER_CNF_OFFSET/2];	}#ifdef __X86__	/* get ISA config */	if( !cs8900->isa_cnf ) {		cs8900->isa_cnf = rom[ISA_CNF_OFFSET/2];	}	/* get shared memory address */	if( !cs8900->smem_addr ) {		cs8900->smem_addr = rom[PACKET_PAGE_OFFSET/2] << 8;	}#endif	/* read MAC */	for( i = 0; i < ETH_MAC_LEN / 2; i++ ) {		cs8900->cfg.permanent_address[i*2]		= rom[i];		cs8900->cfg.permanent_address[i*2+1]	= rom[i] >> 8;	}	/* Override with MAC address from syspage, if available */	nic_get_syspage_mac(cs8900->cfg.permanent_address);	return( 0 );}int cs8900_config( void *handle ){	cs8900_dev_t	*cs8900	= (cs8900_dev_t	*)handle;	int					iobase;	iobase			= cs8900->iobase;	strcpy( cs8900->cfg.device_description, "Crystal 89xx" );	cs8900->cfg.media			= NIC_MEDIA_802_3;	cs8900->cfg.media_rate		= 10000; /* in kbits/sec */	cs8900->cfg.mac_length		= ETH_MAC_LEN;    if (cs8900->cfg.mtu == 0 || cs8900->cfg.mtu > ETH_MAX_PKT_LEN)        cs8900->cfg.mtu = ETH_MAX_PKT_LEN;	cs8900->chip_id = cs8900_rpktpage( iobase, CS8900_DEVICE_ID ) & ~REVISION_BITS;	cs8900_reset( cs8900 );	if( cs8900_eeprom_config( cs8900 ) ) {		if( !cs8900->auto_neg_cnf ) {			cs8900->auto_neg_cnf = N_CNF_ALLOW_FDX | N_CNF_NEG_ENABLE;		}		if( !cs8900->adapter_cnf ) {			cs8900->adapter_cnf = A_CNF_10B_T;		}		if( !cs8900->isa_cnf ) {/*			cs8900->isa_cnf = I_CNF_ISA_DMA_64K | I_CNF_ISA_RXDMA | I_CNF_STREAM_TRANSFER; */		}	}	/* check for MAC command line override */	if( memcmp( cs8900->cfg.current_address, "\0\0\0\0\0\0", 6 ) == 0 ) {		memcpy( cs8900->cfg.current_address, cs8900->cfg.permanent_address, ETH_MAC_LEN );    }#ifdef __X86__{	int		irq;	/* If this is a CS8900 then no pnp soft */	irq = cs8900_rpktpage( iobase, CS8920_ISAINT );	if( cs8900->chip_id != CS8900 && irq && irq < CS8920_NO_INTS ) {		if( !cs8900->cfg.irq[0] ) {			cs8900->cfg.irq[0] = irq;       		cs8900->cfg.num_irqs = 1;		}	}	else {		irq = cs8900->isa_cnf & I_CNF_INT_NO_MASK;		if (cs8900->chip_id == CS8900) {			/* mung irq using eval board mapping table */			switch (irq) {				case 0: irq = 10; break;				case 1: irq = 11; break;				case 2: irq = 12; break;				case 3: irq =  5; break;			}		}		if (!cs8900->cfg.irq[0]) {			cs8900->cfg.irq[0] = irq;       		cs8900->cfg.num_irqs = 1;		}	}}#endif	if( cs8900_init_memory( cs8900 ) ) {		return( 1 );	}	if( cs8900->cfg.verbose ) {		nic_dump_config( &cs8900->cfg );	}	return( 0 );}int cs8900_initialize( void *handle ){	int					i;	int					irq,temp_irq;	int					iobase;	int					i_cnf;	cs8900_dev_t		*cs8900 = (cs8900_dev_t *)handle;	nic_config_t		*cfg;    int                 reg;	cfg		= &cs8900->cfg;	iobase	= cs8900->iobase;	i_cnf	= cs8900->isa_cnf;	/* set ioport */	cs8900_wpktpage( iobase, CS8900_ISAIOB, (int)cfg->io_window_base[0]);/*	cs8900_wpktpage( iobase, CS8900_ISAIOB, 0x300 ); */	/* set interrupt */	irq = cfg->irq[0];	if (cs8900->chip_id == CS8900) {#ifdef __X86__		switch (irq) {			case 10: irq = 0; break;			case 11: irq = 1; break;			case 12: irq = 2; break;			case 5:  irq = 3; break;			default: irq = 3; break;		}#endif        temp_irq = variant_irq_init(cs8900);        if (temp_irq != -1)            irq = temp_irq;				cs8900_wpktpage( iobase, CS8900_ISAINT, irq );	}	else		cs8900_wpktpage( iobase, CS8920_ISAINT, irq );	/* set the MAC address */	for( i = 0; i < ETH_MAC_LEN / 2; i++ ) {		cs8900_wpktpage( iobase, CS8900_IA + i * 2, cs8900->cfg.current_address[i*2] | (cs8900->cfg.current_address[i*2+1] << 8 ) );	}#ifdef __X86__	if( cs8900->mode & CS8900_DMA ) {		cs8900_wpktpage( iobase, CS8900_ISADMA, cfg->dma_channel[0] - 5 );	}	if( cs8900->mode & CS8900_SHARED ) {		outle16( iobase + CS8900_PORT_PKTPG, CS8920_MEM_BASE );		out8( iobase + CS8900_PORT_PKTPG_DATA, (cs8900->smem_addr >> 8) & 0xff );		out8( iobase + CS8900_PORT_PKTPG_DATA + 1, ( cs8900->smem_addr >> 24 ) & 0xff );/*		cs8900_wpktpage( iobase, CS8900_MEM_BASE, cs8900->smem_addr ); */	}#endif	/* configure line settings */	cs8900_wpktpage( iobase, CS8900_LINECTL, LINECTL_RXON | LINECTL_TXON );	/* configure rx acceptance parameters */	reg = RXCTL_BRDCAST_OK | RXCTL_IA_OK | RXCTL_RX_OK;    if( cs8900->cfg.flags & NIC_FLAG_PROMISCUOUS )    {        reg |= RXCTL_PROM_OK;    }    if( cs8900->cfg.flags & NIC_FLAG_MULTICAST )    {        reg |= RXCTL_MULTI_OK;    }	cs8900_wpktpage( iobase, CS8900_RXCTL, reg );	/* configure rx interrupt generation parameters */	cs8900_wpktpage( iobase, CS8900_RXCFG,										( ( i_cnf & I_CNF_ANY_ISA_DMA ) ? 0 : RXCFG_RXOK_IRQ ) |										RXCFG_EXTRADATA_IRQ |										RXCFG_CRCERR_IRQ |										( ( i_cnf & I_CNF_ANY_ISA_DMA ) ? RXCFG_DMA_ONLY : 0 ) |										( ( i_cnf & I_CNF_STREAM_TRANSFER ) ? RXCFG_STREAM_TXFR : 0 ) );	cs8900_wpktpage( iobase, CS8900_TXCFG,										TXCFG_TXOK_IRQ |										TXCFG_MAXCOL_IRQ |										TXCFG_JABBER_IRQ |										TXCFG_OOWCOL_IRQ |										TXCFG_SQEERR_IRQ |										TXCFG_NOCAR_IRQ );	cs8900_wpktpage( iobase, CS8900_BUFCFG,										BUFCFG_TXRDY_IRQ |										BUFCFG_TXUNDER_IRQ | 										BUFCFG_RXMISS_IRQ |										( ( i_cnf & I_CNF_ANY_ISA_DMA ) ? BUFCFG_RXDMA_IRQ: 0 ) );#ifdef __X86__	if( i_cnf & I_CNF_ANY_ISA_DMA ) {		paddr_t	paddr;		mem_offset( (void *)cs8900->dmem, NOFD, 1, (off_t *)&paddr, NULL );		setup_8237( 0x14, cs8900->cfg.dma_channel[0], paddr, cs8900->dmem_size );	}#endif	if( cs8900->chip_id != CS8900 ) {		cs8900_wpktpage( iobase, CS8900_AUTONEGCTL, AUTONEGCTL_NLP );	}	/* enable interrupts, and memory */	cs8900_wpktpage( iobase, CS8900_BUSCTL,

⌨️ 快捷键说明

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