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

📄 mpc85xx.c

📁 qnx powerpc MPC8245的 BSP源文件
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * $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.  * $  */#include "mpc85xx.h"#include <net/if_ether.h>io_net_dll_entry_t io_net_dll_entry = {					2, 					mpc_init, 					NULL 					};io_net_registrant_funcs_t mpc_funcs = {							8, 							NULL, 							mpc_send_packets,							mpc_receive_complete, 							mpc_shutdown1,							mpc_shutdown2,							mpc_advertise,							mpc_devctl, 							mpc_flush, 							NULL							};io_net_registrant_t mpc_entry = {					_REG_PRODUCER_UP | _REG_TRACK_MCAST,					"devn-mpc85xx",					"en",					NULL,					NULL,					&mpc_funcs,					0					};/****************************************************************************//*                                                                          *//****************************************************************************//*  * mpc_init * * Initial entry point for io-net into driver.  Initiates a search * for nic. * * return  0 on success *        -1 and set errno on error */int		mpc_init (void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char *opts){int		rval;	dpp = dpp;                     	if (rval = mpc_detect (dll_hdl, ion, opts)) {		errno = rval;		return -1;	}	return (0);}/****************************************************************************//*                                                                          *//****************************************************************************/#define MPC_ROUNDUP(_ptr, _align) ((((unsigned)_ptr) + (_align - 1)) & ~(_align - 1))npkt_t *mpc_alloc_npkt (mpc85xx_t *ext, size_t size, int num) {	npkt_t			*npkt, *nph, **npt;	net_buf_t		*nb;	net_iov_t		*iov;	char			*ptr;	int			    linesize = 64, psize;	mpc85xx_pool_t  *poolp;	if (size < MPC_MTU_SIZE) {		size = MPC_MTU_SIZE;	}		/* allocate enough space for packet data.  "linesize" extra bytes must	be allocated to ensure that the packet data area doesn't collide with the	pool information area when the packet area is re-aligned to a cache line	boundary. */	psize = (MPC_ROUNDUP(size, linesize) * num + linesize) + sizeof(*poolp);		if ((ptr = ion_alloc (psize, 0)) == NULL) {		return (NULL);	}		/* the pool head is at the end of the space, to allow packet data 	 * properly aligned */	poolp = (mpc85xx_pool_t *)(ptr + psize - sizeof(*poolp));	poolp->buf_head = ptr;	poolp->ref = num;	/* get all packets */	for (nph = NULL, npt = &nph; num; num--) {		if ((npkt = ion_alloc_npkt (sizeof (net_buf_t) + sizeof (net_iov_t),									(void **) (void *)&nb)) == NULL) {			goto failed;		}		npkt->org_data = poolp;		/* Pad buffer to begin on a cache line boundary */		if (linesize != 0) {		  ptr = (char *)MPC_ROUNDUP(ptr, linesize);		}				TAILQ_INSERT_HEAD (&npkt->buffers, nb, ptrs);			iov = (net_iov_t *)(nb + 1);			nb->niov = 1;		nb->net_iov = iov;		iov->iov_base = (void *) ptr;		iov->iov_len = size;		iov->iov_phys = (paddr_t)(ion_mphys (iov->iov_base));		npkt->next = NULL;		npkt->tot_iov = 1;				ptr += size;				*npt = npkt;		npt = &npkt->next;	}	return (nph);failed:	while (npkt = nph) {		nph = npkt->next;		ion_free(npkt);	}	ion_free(poolp->buf_head);	return NULL;}/****************************************************************************//*                                                                          *//****************************************************************************/void	mpc_update_stats (mpc85xx_t *ext){	uint32_t				tmp, *base = ext->reg;	nic_ethernet_stats_t	*estats = &ext->stats.un.estats;	uint32_t				car1, car2;	car1 = *(base + MPC_CAR1);	car2 = *(base + MPC_CAR2);	ext->stats.octets_rxed_ok += *(base + MPC_RBYT);	ext->stats.rxed_ok += *(base + MPC_RPKT);	estats->fcs_errors += *(base + MPC_RFCS);	ext->stats.rxed_multicast += *(base + MPC_RMCA);	ext->stats.rxed_broadcast += *(base + MPC_RBCA);	estats->align_errors += *(base + MPC_RALN);	estats->length_field_mismatch += *(base + MPC_RFLR);	estats->no_carrier += *(base + MPC_RCSE);	estats->short_packets += *(base + MPC_RUND);	estats->oversized_packets += *(base + MPC_ROVR);	estats->internal_rx_errors += *(base + MPC_RFRG);	estats->jabber_detected += *(base + MPC_RJBR);	estats->internal_rx_errors += *(base + MPC_RDRP);	ext->stats.octets_txed_ok += *(base + MPC_TBYT);	ext->stats.txed_ok += *(base + MPC_TPKT);	ext->stats.txed_multicast += *(base + MPC_TMCA);	ext->stats.txed_broadcast += *(base + MPC_TBCA);	estats->excessive_deferrals += *(base + MPC_TDFR);	estats->single_collisions += *(base + MPC_TSCL);	estats->multi_collisions += *(base + MPC_TMCL);	estats->late_collisions += *(base + MPC_TLCL);	estats->xcoll_aborted += *(base + MPC_TXCL);	estats->total_collision_frames += *(base + MPC_TNCL);	estats->jabber_detected += *(base + MPC_TJBR);	tmp = *(base + MPC_TR64);	tmp = *(base + MPC_TR127);	tmp = *(base + MPC_TR255);	tmp = *(base + MPC_TR511);	tmp = *(base + MPC_TR1K);	tmp = *(base + MPC_TRMAX);	tmp = *(base + MPC_TRMGV);	tmp = *(base + MPC_TFRG);	tmp = *(base + MPC_RXCF);	tmp = *(base + MPC_RXPF);	tmp = *(base + MPC_RXUO);	tmp = *(base + MPC_RCDE);	tmp = *(base + MPC_TXPF);	tmp = *(base + MPC_TEDF);	tmp = *(base + MPC_TDRP);	if (car1) {		*(base + MPC_CAR1) = car1;	}	if (car2) {		*(base + MPC_CAR2) = car2;	}}/****************************************************************************//*                                                                          *//****************************************************************************/static int	mpc_process_tx_interrupt (mpc85xx_t *ext){	mpc_download_complete(ext);	return (0);}/****************************************************************************//*                                                                          *//****************************************************************************/static int	mpc_process_rx_interrupt (mpc85xx_t *ext){	mpc_receive (ext);	return (0);}static int	mpc_process_interrupt (mpc85xx_t *ext, int id) {	uint32_t	*base = ext->reg;	uint32_t	ievent;		for (;;) {		ievent = *(base + MPC_IEVENT);				if (!ievent) {			break;		}		if (ievent & IEVENT_MSRO) {			mpc_update_stats(ext);		}				*(base + MPC_IEVENT) = ievent;		if ((ievent & (IEVENT_RXC | IEVENT_RXBO | IEVENT_RXFO | IEVENT_BSY)) != 0) {			mpc_process_rx_interrupt(ext);			if (ievent & IEVENT_BSY)			  *(base + MPC_RSTAT) = RSTAT_QHLT;		}				if ((ievent & (IEVENT_TXC | IEVENT_TXB | IEVENT_TXF)) != 0) {			mpc_process_tx_interrupt(ext);		}		if (ievent & IEVENT_TXE) {			*(base + MPC_TSTAT) = TSTAT_THLT;		}		}	InterruptUnmask (ext->cfg.irq [id], ext->iid [id]);	return 0;}/****************************************************************************//*                                                                          *//****************************************************************************/static void mpc_event_handler (mpc85xx_t *ext){	struct _pulse	pulse;	iov_t			iov;	int				rcvid;	SETIOV (&iov, &pulse, sizeof(pulse));	while (1) {		rcvid = MsgReceivev (ext->chid, &iov, 1, NULL);				if (rcvid < 0) {			if (errno == ESRCH) {				pthread_exit (NULL);			}			continue;		}				switch (pulse.code) {		  case MDI_TIMER:			if (ext->probe_phy || 					(ext->cfg.flags & NIC_FLAG_LINK_DOWN) || 					!ext->rcvpkts) {				MDI_MonitorPhy (ext->mdi);			}			mpc_download_complete(ext);			ext->rcvpkts = 0;			break;		  case NIC_INTR_EVENT_TX:			mpc_process_interrupt (ext, 0);			break;		  case NIC_INTR_EVENT_RX:			mpc_process_interrupt (ext, 1);			break;		  case NIC_INTR_EVENT_ERR:			mpc_process_interrupt (ext, 2);			break;		  default:			if (rcvid) {				MsgReplyv (rcvid, ENOTSUP, &iov, 1);			}			break;		}	}}/****************************************************************************//*                                                                          *//****************************************************************************/static void *mpc_driver_thread (void *data){	mpc_event_handler ((mpc85xx_t *) data);	return (NULL);}/****************************************************************************//*                                                                          *//****************************************************************************/static paddr_t vtophys (void *addr){	off64_t                 offset;	if (mem_offset64 (addr, NOFD, 1, &offset, 0) == -1) {		return (-1);	}	return (offset);}/****************************************************************************//*                                                                          *//****************************************************************************/static int	mpc_init_memory (mpc85xx_t *ext){	/* set up the descriptors and packet pools/lists */		if ((ext->rx_bd = mmap (NULL, sizeof (mpc_bd_t) * ext->num_rx_descriptors, 	    PROT_READ | PROT_WRITE /*| PROT_NOCACHE */, MAP_ANON | MAP_PHYS, NOFD, 0)) == MAP_FAILED) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "mmap at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		return (errno);	}	if ((ext->rx_pktq = calloc (ext->num_rx_descriptors, sizeof(npkt_t *))) == NULL) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "calloc at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		return (errno);	}	if ((ext->tx_bd = mmap (NULL, sizeof (mpc_bd_t) * ext->num_tx_descriptors, 	    PROT_READ | PROT_WRITE /*| PROT_NOCACHE */, MAP_ANON | MAP_PHYS, NOFD, 0)) == MAP_FAILED) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "mmap at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		return (errno);	}	if ((ext->tx_pktq = calloc (ext->num_tx_descriptors, sizeof(npkt_t *))) == NULL) {		nic_slogf (_SLOGC_NETWORK, _SLOG_ERROR, "calloc at \"%s\":%d: %s\n",			__FILE__, __LINE__, strerror(errno));		return (errno);	}#if 0

⌨️ 快捷键说明

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