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

📄 ether_fcc.c.svn-base

📁 u-boot for S3c2443 processor
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
		n--;	}	lp = (ulong *)bp;	nl = n / sizeof (ulong);	n -= nl * sizeof (ulong);	while (nl > 0) {		ulong diff;		diff = *lp++ ^ pat;		if (diff)			cnt += nbs (diff, 32);		nl--;	}	bp = (uchar *)lp;	while (n > 0) {		uchar diff;		diff = *bp++ ^ (uchar)pat;		if (diff)			cnt += nbs ((ulong)diff, 8);		n--;	}	return (cnt);}static inline unsigned shortswap16 (unsigned short x){	return (((x & 0xff) << 8) | ((x & 0xff00) >> 8));}voideth_loopback_test (void){	DECLARE_GLOBAL_DATA_PTR;	volatile immap_t *immr = (immap_t *)CFG_IMMR;	volatile cpm8260_t *cp = &(immr->im_cpm);	int c, nclosed;	ulong runtime, nmsec;	uchar *bases[3];	puts ("FCC Ethernet External loopback test\n");	memcpy (NetOurEther, gd->bd->bi_enetaddr, 6);	/*	 * global initialisations for all FCC channels	 */	/* 28.9 - (1-2): ioports have been set up already */#if defined(CONFIG_HYMOD)	/*	 * Attention: this is board-specific	 * 0, FCC1	 * 1, FCC2	 * 2, FCC3	 */#       define FCC_START_LOOP 0#       define FCC_END_LOOP   2	/*	 * Attention: this is board-specific	 * - FCC1 Rx-CLK is CLK10	 * - FCC1 Tx-CLK is CLK11	 * - FCC2 Rx-CLK is CLK13	 * - FCC2 Tx-CLK is CLK14	 * - FCC3 Rx-CLK is CLK15	 * - FCC3 Tx-CLK is CLK16	 */	/* 28.9 - (3): connect FCC's tx and rx clocks */	immr->im_cpmux.cmx_uar = 0;	immr->im_cpmux.cmx_fcr = CMXFCR_RF1CS_CLK10|CMXFCR_TF1CS_CLK11|\	    CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14|\	    CMXFCR_RF3CS_CLK15|CMXFCR_TF3CS_CLK16;#elif defined(CONFIG_SBC8260) || defined(CONFIG_SACSng)	/*	 * Attention: this is board-specific	 * 1, FCC2	 */#       define FCC_START_LOOP 1#       define FCC_END_LOOP   1	/*	 * Attention: this is board-specific	 * - FCC2 Rx-CLK is CLK13	 * - FCC2 Tx-CLK is CLK14	 */	/* 28.9 - (3): connect FCC's tx and rx clocks */	immr->im_cpmux.cmx_uar = 0;	immr->im_cpmux.cmx_fcr = CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14;#else#error "eth_loopback_test not supported on your board"#endif	puts ("Initialise FCC channels:");	for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++) {		elbt_chan *ecp = &elbt_chans[c];		volatile fcc_t *fcp = &immr->im_fcc[c];		volatile fcc_enet_t *fpp;		int i;		ulong addr;		/*		 * initialise channel data		 */		printf (" %d", c);		memset ((void *)ecp, 0, sizeof (*ecp));		ecp->state = Idle;		switch (c) {		case 0: /* FCC1 */			ecp->proff = PROFF_FCC1;			ecp->page = CPM_CR_FCC1_PAGE;			ecp->sblock = CPM_CR_FCC1_SBLOCK;			break;		case 1: /* FCC2 */			ecp->proff = PROFF_FCC2;			ecp->page = CPM_CR_FCC2_PAGE;			ecp->sblock = CPM_CR_FCC2_SBLOCK;			break;		case 2: /* FCC3 */			ecp->proff = PROFF_FCC3;			ecp->page = CPM_CR_FCC3_PAGE;			ecp->sblock = CPM_CR_FCC3_SBLOCK;			break;		}		/*		 * set up tx buffers and bds		 */		for (i = 0; i < ELBT_NTXBD; i++) {			cbd_t *bdp = &ecp->txbd[i];			uchar *bp = &ecp->txbufs[i][0];			bdp->cbd_bufaddr = (uint)bp;			/* room for crc */			bdp->cbd_datlen = ELBT_BUFSZ - ELBT_CRCSZ;			bdp->cbd_sc = BD_ENET_TX_READY | BD_ENET_TX_PAD | \				BD_ENET_TX_LAST | BD_ENET_TX_TC;			memset ((void *)bp, patbytes[i], ELBT_BUFSZ);			NetSetEther (bp, NetBcastAddr, 0x8000);		}		ecp->txbd[ELBT_NTXBD - 1].cbd_sc |= BD_ENET_TX_WRAP;		/*		 * set up rx buffers and bds		 */		for (i = 0; i < ELBT_NRXBD; i++) {		    cbd_t *bdp = &ecp->rxbd[i];		    uchar *bp = &ecp->rxbufs[i][0];		    bdp->cbd_bufaddr = (uint)bp;		    bdp->cbd_datlen = 0;		    bdp->cbd_sc = BD_ENET_RX_EMPTY;		    memset ((void *)bp, 0, ELBT_BUFSZ);		}		ecp->rxbd[ELBT_NRXBD - 1].cbd_sc |= BD_ENET_RX_WRAP;		/*		 * set up the FCC channel hardware		 */		/* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, Mode Ethernet */		fcp->fcc_gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;		/* 28.9 - (5): FPSMR: fd, enet CRC, Promis, RMON, Rx SHort */		fcp->fcc_fpsmr = FCC_PSMR_FDE | FCC_PSMR_LPB | \			FCC_PSMR_ENCRC | FCC_PSMR_PRO | \			FCC_PSMR_MON | FCC_PSMR_RSH;		/* 28.9 - (6): FDSR: Ethernet Syn */		fcp->fcc_fdsr = 0xD555;		/* 29.9 - (7): initialise parameter ram */		fpp = (fcc_enet_t *)&(immr->im_dprambase[ecp->proff]);		/* clear whole struct to make sure all resv fields are zero */		memset ((void *)fpp, 0, sizeof (fcc_enet_t));		/*		 * common Parameter RAM area		 *		 * Allocate space in the reserved FCC area of DPRAM for the		 * internal buffers.  No one uses this space (yet), so we		 * can do this.  Later, we will add resource management for		 * this area.		 */		addr = CPM_FCC_SPECIAL_BASE + (c * 64);		fpp->fen_genfcc.fcc_riptr = addr;		fpp->fen_genfcc.fcc_tiptr = addr + 32;		/*		 * Set maximum bytes per receive buffer.		 * It must be a multiple of 32.		 * buffers are in 60x bus memory.		 */		fpp->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE;		fpp->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB) << 24;		fpp->fen_genfcc.fcc_rbase = (unsigned int)(&ecp->rxbd[0]);		fpp->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB) << 24;		fpp->fen_genfcc.fcc_tbase = (unsigned int)(&ecp->txbd[0]);		/* protocol-specific area */		fpp->fen_cmask = 0xdebb20e3;	/* CRC mask */		fpp->fen_cpres = 0xffffffff;	/* CRC preset */		fpp->fen_retlim = 15;		/* Retry limit threshold */		fpp->fen_mflr = PKT_MAXBUF_SIZE;/* max frame length register */		/*		 * Set Ethernet station address.		 *		 * This is supplied in the board information structure, so we		 * copy that into the controller.		 * So, far we have only been given one Ethernet address. We use		 * the same address for all channels		 */#define ea gd->bd->bi_enetaddr		fpp->fen_paddrh = (ea[5] << 8) + ea[4];		fpp->fen_paddrm = (ea[3] << 8) + ea[2];		fpp->fen_paddrl = (ea[1] << 8) + ea[0];#undef ea		fpp->fen_minflr = PKT_MINBUF_SIZE; /* min frame len register */		/*		 * pad pointer. use tiptr since we don't need		 * a specific padding char		 */		fpp->fen_padptr = fpp->fen_genfcc.fcc_tiptr;		fpp->fen_maxd1 = PKT_MAXDMA_SIZE;	/* max DMA1 length */		fpp->fen_maxd2 = PKT_MAXDMA_SIZE;	/* max DMA2 length */		fpp->fen_rfthr = 1;		fpp->fen_rfcnt = 1;		/* 28.9 - (8): clear out events in FCCE */		fcp->fcc_fcce = ~0x0;		/* 28.9 - (9): FCCM: mask all events */		fcp->fcc_fccm = 0;		/* 28.9 - (10-12): we don't use ethernet interrupts */		/* 28.9 - (13)		 *		 * Let's re-initialize the channel now.  We have to do it later		 * than the manual describes because we have just now finished		 * the BD initialization.		 */		cp->cp_cpcr = mk_cr_cmd (ecp->page, ecp->sblock, \			0x0c, CPM_CR_INIT_TRX) | CPM_CR_FLG;		do {			__asm__ __volatile__ ("eieio");		} while (cp->cp_cpcr & CPM_CR_FLG);	}	puts (" done\nStarting test... (Ctrl-C to Finish)\n");	/*	 * Note: don't want serial output from here until the end of the	 * test - the delays would probably stuff things up.	 */	clear_ctrlc ();	runtime = get_timer (0);	do {		nclosed = 0;		for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++) {			volatile fcc_t *fcp = &immr->im_fcc[c];			elbt_chan *ecp = &elbt_chans[c];			int i;			switch (ecp->state) {			case Idle:				/*				 * set the channel Running ...				 */				/* 28.9 - (14): enable tx/rx in gfmr */				fcp->fcc_gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;				ecp->state = Running;				break;			case Running:				/*				 * (while Running only) check for				 * termination of the test				 */				(void)ctrlc ();				if (had_ctrlc ()) {					/*					 * initiate a "graceful stop transmit"					 * on the channel					 */					cp->cp_cpcr = mk_cr_cmd (ecp->page, \						ecp->sblock, 0x0c, \						CPM_CR_GRACEFUL_STOP_TX) | \						CPM_CR_FLG;					do {						__asm__ __volatile__ ("eieio");					} while (cp->cp_cpcr & CPM_CR_FLG);					ecp->clstime = get_timer (0);					ecp->state = Closing;				}				/* fall through ... */			case Closing:				/*				 * (while Running or Closing) poll the channel:				 * - check for any non-READY tx buffers and				 *   make them ready				 * - check for any non-EMPTY rx buffers and				 *   check that they were received correctly,				 *   adjust counters etc, then make empty				 */				for (i = 0; i < ELBT_NTXBD; i++) {					cbd_t *bdp = &ecp->txbd[i];					ushort sc = bdp->cbd_sc;					if ((sc & BD_ENET_TX_READY) != 0)						continue;					/*					 * this frame has finished					 * transmitting					 */					ecp->nsent++;					if (sc & BD_ENET_TX_STATS) {						ulong n;						/*						 * we had an error on						 * the transmission						 */						n = ecp->ntxerr++;						if (n < ELBT_MAXTXERR)							ecp->txerrs[n] = sc;						if (sc & BD_ENET_TX_DEF)							ecp->txeacc.def++;						if (sc & BD_ENET_TX_HB)							ecp->txeacc.hb++;						if (sc & BD_ENET_TX_LC)							ecp->txeacc.lc++;						if (sc & BD_ENET_TX_RL)							ecp->txeacc.rl++;						if (sc & BD_ENET_TX_RCMASK)							ecp->txeacc.rc++;						if (sc & BD_ENET_TX_UN)							ecp->txeacc.un++;						if (sc & BD_ENET_TX_CSL)							ecp->txeacc.csl++;						bdp->cbd_sc &= \							~BD_ENET_TX_STATS;					}					if (ecp->state == Closing)						ecp->clstime = get_timer (0);					/* make it ready again */					bdp->cbd_sc |= BD_ENET_TX_READY;				}				for (i = 0; i < ELBT_NRXBD; i++) {					cbd_t *bdp = &ecp->rxbd[i];					ushort sc = bdp->cbd_sc, mask;					if ((sc & BD_ENET_RX_EMPTY) != 0)						continue;					/* we have a new frame in this buffer */					ecp->nrcvd++;					mask = BD_ENET_RX_LAST|BD_ENET_RX_FIRST;					if ((sc & mask) != mask) {						/* somethings wrong here ... */						if (!(sc & BD_ENET_RX_LAST))							ecp->rxeacc._l++;						if (!(sc & BD_ENET_RX_FIRST))							ecp->rxeacc._f++;					}					if (sc & BD_ENET_RX_STATS) {						ulong n;						/*						 * we had some sort of error						 * on the frame						 */						n = ecp->nrxerr++;						if (n < ELBT_MAXRXERR)							ecp->rxerrs[n] = sc;						if (sc & BD_ENET_RX_MISS)							ecp->rxeacc.m++;						if (sc & BD_ENET_RX_BC)							ecp->rxeacc.bc++;						if (sc & BD_ENET_RX_MC)							ecp->rxeacc.mc++;						if (sc & BD_ENET_RX_LG)							ecp->rxeacc.lg++;						if (sc & BD_ENET_RX_NO)							ecp->rxeacc.no++;						if (sc & BD_ENET_RX_SH)							ecp->rxeacc.sh++;						if (sc & BD_ENET_RX_CR)							ecp->rxeacc.cr++;						if (sc & BD_ENET_RX_OV)							ecp->rxeacc.ov++;						if (sc & BD_ENET_RX_CL)							ecp->rxeacc.cl++;						bdp->cbd_sc &= \							~BD_ENET_RX_STATS;					}					else {						ushort datlen = bdp->cbd_datlen;						Ethernet_t *ehp;						ushort prot;						int ours, tb, n, nbytes;						ehp = (Ethernet_t *) \							&ecp->rxbufs[i][0];						ours = memcmp (ehp->et_src, \							NetOurEther, 6);						prot = swap16 (ehp->et_protlen);						tb = prot & 0x8000;						n = prot & 0x7fff;						nbytes = ELBT_BUFSZ - \							offsetof (Ethernet_t, \								et_dsap) - \							ELBT_CRCSZ;						/* check the frame is correct */						if (datlen != ELBT_BUFSZ)							ecp->rxeacc.badlen++;						else if (!ours)							ecp->rxeacc.badsrc++;						else if (!tb || n >= ELBT_NTXBD)							ecp->rxeacc.badtyp++;						else {							ulong patword = \								patwords[n];							uint nbb;							nbb = badbits ( \								&ehp->et_dsap, \								nbytes, \								patword);							ecp->rxeacc.badbit += \								nbb;						}					}					if (ecp->state == Closing)					    ecp->clstime = get_timer (0);					/* make it empty again */					bdp->cbd_sc |= BD_ENET_RX_EMPTY;				}				if (ecp->state != Closing)					break;				/*				 * (while Closing) check to see if				 * waited long enough				 */				if (get_timer (ecp->clstime) >= ELBT_CLSWAIT) {					/* write GFMR: disable tx/rx */					fcp->fcc_gfmr &= \						~(FCC_GFMR_ENT | FCC_GFMR_ENR);					ecp->state = Closed;				}				break;			case Closed:				nclosed++;				break;			}		}	} while (nclosed < (FCC_END_LOOP - FCC_START_LOOP + 1));	runtime = get_timer (runtime);	if (runtime <= ELBT_CLSWAIT) {		printf ("Whoops! somehow elapsed time (%ld) is wrong (<= %d)\n",			runtime, ELBT_CLSWAIT);		return;	}	nmsec = runtime - ELBT_CLSWAIT;	printf ("Test Finished in %ldms (plus %dms close wait period)!\n\n",		nmsec, ELBT_CLSWAIT);	/*	 * now print stats	 */	for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++) {		elbt_chan *ecp = &elbt_chans[c];		uint rxpps, txpps, nerr;		rxpps = (ecp->nrcvd * 1000) / nmsec;		txpps = (ecp->nsent * 1000) / nmsec;		printf ("Channel %d: %d rcvd (%d pps, %d rxerrs), "			"%d sent (%d pps, %d txerrs)\n\n", c,			ecp->nrcvd, rxpps, ecp->nrxerr,			ecp->nsent, txpps, ecp->ntxerr);		if ((nerr = ecp->nrxerr) > 0) {			ulong i;			printf ("\tFirst %d rx errs:", nerr);			for (i = 0; i < nerr; i++)				printf (" %04x", ecp->rxerrs[i]);			putc ('\n');		}		if ((nerr = ecp->ntxerr) > 0) {			ulong i;			printf ("\tFirst %d tx errs:", nerr);			for (i = 0; i < nerr; i++)				printf (" %04x", ecp->txerrs[i]);			putc ('\n');		}	}	puts ("Receive Error Counts:\n");	for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++)		bases[c] = (uchar *)&elbt_chans[c].rxeacc;	print_desc (rxeacc_descs, rxeacc_ndesc, bases, 3);	puts ("\nTransmit Error Counts:\n");	for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++)		bases[c] = (uchar *)&elbt_chans[c].txeacc;	print_desc (txeacc_descs, txeacc_ndesc, bases, 3);	puts ("\nRMON(-like) Counters:\n");	for (c = FCC_START_LOOP; c <= FCC_END_LOOP; c++)		bases[c] = (uchar *)&immr->im_dprambase[elbt_chans[c].proff];	print_desc (epram_descs, epram_ndesc, bases, 3);}#endif /* CONFIG_ETHER_LOOPBACK_TEST */#endif	/* CONFIG_ETHER_ON_FCC && CFG_CMD_NET && CONFIG_NET_MULTI */

⌨️ 快捷键说明

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