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

📄 mpc85xx.c

📁 qnx powerpc MPC8245的 BSP源文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	if ((ext->tx_addr_table = malloc (ext->num_tx_descriptors * sizeof(uint32_t))) == NULL) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "malloc at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		return (errno);	}#endif	return (EOK);}/****************************************************************************//*                                                                          *//****************************************************************************/static int	mpc_init_list (mpc85xx_t *ext){	mpc_bd_t		*bd;	int 			i;	net_iov_t		*iov;	npkt_t          *npkt;	/* initialize the receive ring */	if ((npkt = mpc_alloc_npkt(ext, MPC_MTU_SIZE, ext->num_rx_descriptors)) == NULL) {		errno = ENOBUFS;		return -1;	}		for (i = 0, bd = (mpc_bd_t *) ext->rx_bd; i < ext->num_rx_descriptors; i++, bd++) {		if (i == ext->num_rx_descriptors - 1) {			bd->status = (RXBD_W | RXBD_E | RXBD_I);	/* Wrap indicator */		} else {			bd->status = (RXBD_E | RXBD_I);		}		ext->rx_pktq[i] = npkt;		npkt = npkt->next;		ext->rx_pktq[i]->next = NULL;		//		ext->rx_pktq[i]->flags = (_NPKT_UP | MPC_KEEP_PACKET);		iov = TAILQ_FIRST(&(ext->rx_pktq[i]->buffers))->net_iov;				bd->buffer = iov->iov_phys;		bd->length = 0;	}	ext->rx_cidx = 0;                	#if 0	/* let's also initialize the freeq */	if ((npkt = mpc_alloc_npkt(ext, MPC_MTU_SIZE, ext->num_rx_descriptors)) == NULL) {		errno = ENOBUFS;		return -1;	}	_mutex_lock (&ext->rx_free_pkt_q_mutex);	ext->rx_free_pkt_q = npkt;	ext->num_rx_free = ext->num_rx_descriptors;	_mutex_unlock (&ext->rx_free_pkt_q_mutex);#endif	/* setup the tx_addr_table */	for (i = 0; i < ext->num_tx_descriptors; i++) {		ext->tx_bd[i].status = 0;#if 0		if (i == ext->num_tx_descriptors - 1) {		  ext->tx_bd [i].status = TXBD_W;	/* Wrap */		}		if ((ext->tx_addr_table[i] = vtophys ((void *) &ext->tx_bd[i])) == -1) {			errno = ENOBUFS;			return (-1);		}#endif	}	ext->tx_bd[ext->num_tx_descriptors - 1].status = TXBD_W;		ext->tx_pidx = ext->tx_cidx = 0;	return (EOK);}/****************************************************************************//*                                                                          *//****************************************************************************/static	void	read_phys_addr (mpc85xx_t *ext){	uint32_t	*base = ext->reg;	uint32_t	addr [2];	addr [0] = *(base + MPC_MACSTNADDR1);	addr [1] = *(base + MPC_MACSTNADDR2);	if (ext->cfg.verbose) {		nic_slogf (_SLOGC_NETWORK, _SLOG_INFO, "MAC addr1 %08x - addr2 %08x", addr [0], addr [1]);	}}/****************************************************************************//*                                                                          *//****************************************************************************/static	void	set_phys_addr (mpc85xx_t *ext){	uint32_t	*base = ext->reg;	union {		uint32_t	addr [2];		uint8_t		caddr [8];		} tab;	int			i, j;	memset ((char *) tab.caddr, 0, 8);	for (i = 0, j = 5; i < 6; i++, j--) {		tab.caddr [i] = ext->cfg.current_address [j];	}	*(base + MPC_MACSTNADDR1) = tab.addr [0];	*(base + MPC_MACSTNADDR2) = tab.addr [1];}/****************************************************************************//*                                                                          *//****************************************************************************/void	mpc_reset (mpc85xx_t *ext){	uint32_t	*base = ext->reg;	uint32_t	status;	int			timeout = MPC_TIMEOUT;	/* Graceful transmit stop and wait for completion. */	*(base + MPC_DMACTRL) |= DMACTRL_GTS;	timeout = MPC_TIMEOUT;	do {		nanospin_ns (10);		if (! --timeout)			break;		status = *(base + MPC_IEVENT);	} while ((status & IEVENT_GTSC) != IEVENT_GTSC);		if (! timeout) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "DMA GTS stop failed");	}		/* Disable Rx and Tx */	*(base + MPC_MACCFG1) &= ~(MACCFG1_TXEN | MACCFG1_RXEN);		/* Wait for 9.6KBytes worth of data (worst case ~ 8ms) */	delay (9);		/* Graceful receive stop and wait for completion. */	*(base + MPC_DMACTRL) |= DMACTRL_GRS;	timeout = MPC_TIMEOUT;	do {		nanospin_ns (10);		if (! --timeout)			break;		status = *(base + MPC_IEVENT);	} while ((status & IEVENT_GRSC) != IEVENT_GRSC);		if (!timeout) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "DMA GRS stop failed");	}		*(base + MPC_IEVENT) = (IEVENT_GTSC | IEVENT_GRSC);	*(base + MPC_MACCFG1) = MACCFG1_SFT_RESET;	nanospin_ns (1000);	*(base + MPC_MACCFG1) &= ~MACCFG1_SFT_RESET;}/****************************************************************************//*                                                                          *//****************************************************************************/static int	mpc_config (mpc85xx_t *ext){	nic_config_t			*cfg = &ext->cfg;	nic_ethernet_stats_t	*estats = &ext->stats.un.estats;	nic_stats_t				*gstats = &ext->stats;	uint32_t				*base = ext->reg;	/* nic ethernet default params */	cfg->media = NIC_MEDIA_802_3;	cfg->mac_length = ETH_MAC_LEN;	if (cfg->mtu == 0 || cfg->mtu > ETH_MAX_PKT_LEN ) {		cfg->mtu = ETH_MAX_PKT_LEN;	}	cfg->mru = cfg->mtu;	gstats->media = cfg->media;	estats->valid_stats =		NIC_ETHER_STAT_INTERNAL_TX_ERRORS |		NIC_ETHER_STAT_INTERNAL_RX_ERRORS |		NIC_ETHER_STAT_TX_DEFERRED |		NIC_ETHER_STAT_XCOLL_ABORTED |		NIC_ETHER_STAT_LATE_COLLISIONS |		NIC_ETHER_STAT_SINGLE_COLLISIONS |		NIC_ETHER_STAT_MULTI_COLLISIONS |		NIC_ETHER_STAT_TOTAL_COLLISION_FRAMES |		NIC_ETHER_STAT_ALIGN_ERRORS |		NIC_ETHER_STAT_FCS_ERRORS |		NIC_ETHER_STAT_JABBER_DETECTED |		NIC_ETHER_STAT_OVERSIZED_PACKETS |		NIC_ETHER_STAT_SHORT_PACKETS |		NIC_ETHER_STAT_LENGTH_FIELD_OUTRANGE |		NIC_ETHER_STAT_LENGTH_FIELD_MISMATCH |		NIC_ETHER_STAT_EXCESSIVE_DEFERRALS;	if (ext->num_rx_descriptors <= 0) {		ext->num_rx_descriptors = DEFAULT_NUM_RX_DESCRIPTORS;	}		if (ext->num_tx_descriptors <= 0) {		ext->num_tx_descriptors = DEFAULT_NUM_TX_DESCRIPTORS;	}	if (cfg->media_rate != -1) {		ext->data_rate = (cfg->media_rate / 1000);	} else {		ext->data_rate = 0;	}	if (mpc_init_memory (ext) != EOK) {		return (-1);	}	if (mpc_init_list (ext) != EOK) {		return (-1);	}	mpc_reset (ext);	/* get out physical address */	if (nic_get_syspage_mac (cfg->permanent_address) == -1) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "devn-mpc85xx: MAC address not found in system page");//		read_phys_addr (ext);	}	/* set up our address */	/* check for command line override */	if (memcmp (cfg->current_address, "\0\0\0\0\0\0", 6) == 0) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "You must specify a MAC address");		return (-1);	}	set_phys_addr (ext);	read_phys_addr (ext);	*(base + MPC_TBASE)  = vtophys ((void *) ext->tx_bd);	*(base + MPC_RBASE)  = vtophys ((void *) ext->rx_bd);	*(base + MPC_MACCFG2) = (MACCFG2_IF_MODE_BYT | MACCFG2_PAD_CRC |		(cfg->duplex ? MACCFG2_FDX : 0) | MACCFG2_PRE_LEN(7));	*(base + MPC_ECNTRL) = (ECNTRL_CLRCNT | ECNTRL_STEN | ECNTRL_AUTOZ);	*(base + MPC_MRBLR) = MPC_MTU_SIZE;		*(base + MPC_DMACTRL) |= (DMACTRL_WWR | DMACTRL_TBDSEN | DMACTRL_TDSEN /*| DMACTRL_WOP*/);	/* Suprisingly enough, when performing loopback tests, the polled mode is FASTER than the	 * wait mode for smaller packets */	*(base + MPC_DMACTRL) &= ~(DMACTRL_WOP);			*(base + MPC_FIFO_TX_THR) = ext->fifo;	*(base + MPC_FIFO_TX_STARVE) = ext->fifo_starve;	*(base + MPC_FIFO_TX_STARVE_SHUTOFF) = ext->fifo_starve_shutoff;#if 1	/* ask chip put 64bytes in L2 cache */	*(base + MPC_ATTR) = 0x40c0;	*(base + MPC_ATTRELI) = 0x00400000;#else	*(base + MPC_ATTR)   = 0x000000c0;#endif	*(base + MPC_IADDR0) = 0x0;	*(base + MPC_IADDR1) = 0x0;	*(base + MPC_IADDR2) = 0x0;	*(base + MPC_IADDR3) = 0x0;	*(base + MPC_IADDR4) = 0x0;	*(base + MPC_IADDR5) = 0x0;	*(base + MPC_IADDR6) = 0x0;	*(base + MPC_IADDR7) = 0x0;	*(base + MPC_GADDR0) = 0x0;	*(base + MPC_GADDR1) = 0x0;	*(base + MPC_GADDR2) = 0x0;	*(base + MPC_GADDR3) = 0x0;	*(base + MPC_GADDR4) = 0x0;	*(base + MPC_GADDR5) = 0x0;	*(base + MPC_GADDR6) = 0x0;	*(base + MPC_GADDR7) = 0x0;	*(base + MPC_CAR1) = 0xffffffff;	*(base + MPC_CAR2) = 0xffffffff;	*(base + MPC_CAM1) = 0x0;	*(base + MPC_CAM2) = 0x0;	if (cfg->flags & NIC_FLAG_PROMISCUOUS) {		*(base + MPC_RCTRL) = RCTRL_PROM;	}		*(base + MPC_IMASK) = (IMASK_TXE | IMASK_TXB | IMASK_TXF | IMASK_RXBO | IMASK_RXFO | IMASK_BABR | IMASK_BSY | IMASK_EBERR);		*(base + MPC_TSTAT) = TSTAT_THLT;		*(base + MPC_RSTAT) = RSTAT_QHLT;	*(base + MPC_DMACTRL) &= ~(DMACTRL_GRS | DMACTRL_GTS);	*(base + MPC_MACCFG1) = (MACCFG1_RXEN | MACCFG1_TXEN | ext->flowctl_flag | ext->loopback);	mpc_init_phy (ext, (cfg->media_rate == - 1) ? 0 : cfg->media_rate);	return (EOK);}/****************************************************************************//*                                                                          *//****************************************************************************/int 	mpc_register_device (mpc85xx_t *ext, io_net_self_t *ion, void *dll_hdl){	nic_config_t			*cfg = &ext->cfg;	pthread_attr_t			pattr;	pthread_mutexattr_t		mattr;	struct sched_param		param;	struct sigevent			event;	uint16_t				lan;	int						ret, err = 0;	ext->ion = ion;	ext->dll_hdl = dll_hdl;	if ((ext->chid = ChannelCreate (_NTO_CHF_DISCONNECT | _NTO_CHF_UNBLOCK)) < 0) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "ChannelCreate at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		goto error;	}	err++;	if ((ext->coid = ConnectAttach (0, 0, ext->chid, _NTO_SIDE_CHANNEL, 0)) < 0) {		nic_slogf( _SLOGC_NETWORK, _SLOG_ERROR, "devn-mpc85xx:  Unable to ConnectAtttach" );		goto error;	}	err++;#if	0	if (cache_init(0, &ext->cachectl, NULL) == -1) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR,		    "devn-mpc85xx: cache_init() failed");		goto error;	}	err++;#endif	/* we need a valid connection id before calling mpc_config */	if (mpc_config (ext) != EOK) {		nic_slogf ( _SLOGC_NETWORK, _SLOG_ERROR, "devn-mpc85xx:  mpc_config error" );		goto error;	}	pthread_mutexattr_init (&mattr);	if (pthread_mutex_init (&ext->tx_mutex, &mattr) != EOK) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "devn-mpc85xx:  Unable to initialize TX mutex");		goto error;	}	err++;	if (pthread_mutex_init (&ext->rx_free_pkt_q_mutex, &mattr) != EOK) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "devn-mpc85xx:  Unable to initialize RX Free Queue mutex");		goto error;	}	err++;	mpc_entry.func_hdl = (void *) ext;	mpc_entry.top_type = cfg->uptype;	if (cfg->lan != -1) {		mpc_entry.flags |= _REG_ENDPOINT_ARG;		lan = cfg->lan;	}	if (ion_register (dll_hdl, &mpc_entry, &ext->reg_hdl, &ext->cell, &lan) < 0) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "ion_register at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		goto error;	}	cfg->lan = lan;	if (ext->ion->devctl (ext->reg_hdl, DCMD_IO_NET_VERSION, &ext->version, sizeof (ext->version), NULL)) {		ext->version = 0;	}	if (ext->ion->devctl (ext->reg_hdl, DCMD_IO_NET_STATIC, &ext->io_static,		sizeof(ext->io_static), NULL)) {		ext->io_static = 0;	}	if (!ext->max_pkts) {		ext->max_pkts = MPC_DEFAULT_MAX_PACKETS;	}	pthread_attr_init (&pattr);	pthread_attr_setschedpolicy (&pattr, SCHED_RR);

⌨️ 快捷键说明

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