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

📄 mgcoge_hdlc_enet.c

📁 uboot200903最新版本的通用uboot
💻 C
字号:
/* * (C) Copyright 2008 * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. * * Based in part on cpu/mpc8260/ether_scc.c. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include <common.h>#include <malloc.h>#include <net.h>#ifdef CONFIG_KEYMILE_HDLC_ENET#include "../common/keymile_hdlc_enet.h"char keymile_slot;	/* our slot number in the backplane *//* * Since, except during initialization, ethact is always HDLC ETHERNET * while we're in the driver, just use serial_printf() everywhere for * output.  This avoids possible conflicts when netconsole is being * used. */#define dprintf(fmt, args...)	serial_printf(fmt, ##args)static int already_inited;/*  * SCC Ethernet Tx and Rx buffer descriptors allocated at the  *  immr->udata_bd address on Dual-Port RAM  * Provide for Double Buffering  */typedef volatile struct CommonBufferDescriptor {    cbd_t txbd;			/* Tx BD */    cbd_t rxbd[HDLC_PKTBUFSRX];	/* Rx BD */} RTXBD;static RTXBD *rtx;int keymile_hdlc_enet_init(struct eth_device *, bd_t *);void keymile_hdlc_enet_halt(struct eth_device *);extern void keymile_hdlc_enet_init_bds(RTXBD *);extern void initCachedNumbers(int);/* Use SCC1 */#define CPM_CR_SCC_PAGE		CPM_CR_SCC1_PAGE#define CPM_CR_SCC_SBLOCK	CPM_CR_SCC1_SBLOCK#define CMXSCR_MASK		(CMXSCR_GR1|CMXSCR_SC1|\					CMXSCR_RS1CS_MSK|CMXSCR_TS1CS_MSK)#define CMXSCR_VALUE		(CMXSCR_RS1CS_CLK11|CMXSCR_TS1CS_CLK11)#define MGC_PROFF_HDLC	PROFF_SCC1#define MGC_SCC_HDLC	0	/* Index, not number! */int keymile_hdlc_enet_init(struct eth_device *dev, bd_t *bis){	/* int i; */	uint dpr;	/* volatile cbd_t *bdp; */	volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;	volatile cpm8260_t *cp = &(im->im_cpm);	volatile scc_t *sccp;	volatile scc_hdlc_t *hpr;	volatile iop8260_t *iop;	if (already_inited)		return 0;	hpr = (scc_hdlc_t *)(&im->im_dprambase[MGC_PROFF_HDLC]);	sccp = (scc_t *)(&im->im_scc[MGC_SCC_HDLC]);	iop = &im->im_ioport;	/*	 * Disable receive and transmit just in case.	 */	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);	/*	 * Avoid exhausting DPRAM, which would cause a panic.	 */	if (rtx == NULL) {		/* dpr is an offset into dpram */		dpr = m8260_cpm_dpalloc(sizeof(RTXBD), 8);		rtx = (RTXBD *)&im->im_dprambase[dpr];	}	/* We need the slot number for addressing. */	keymile_slot = *(char *)(CONFIG_SYS_SLOT_ID_BASE +		CONFIG_SYS_SLOT_ID_OFF) & CONFIG_SYS_SLOT_ID_MASK;	/*	 * Be consistent with the Linux driver and set	 * only enetaddr[0].	 *	 * Always add 1 to the slot number so that	 * there are no problems with an ethaddr which	 * is all 0s.  This should be acceptable because	 * a board should never have a slot number of 255,	 * which is the broadcast address.  The HDLC addressing	 * uses only the slot number.	 */	dev->enetaddr[0] = keymile_slot + 1;#ifdef TEST_IT	dprintf("slot %d\n", keymile_slot);#endif	/* use pd30, pd31 pins for TXD1, RXD1 respectively */	iop->iop_ppard |= (0x80000000 >> 30) | (0x80000000 >> 31);	iop->iop_pdird |= (0x80000000 >> 30);	iop->iop_psord |= (0x80000000 >> 30);	/* use pc21 as CLK11 */	iop->iop_pparc |= (0x80000000 >> 21);	iop->iop_pdirc &= ~(0x80000000 >> 21);	iop->iop_psorc &= ~(0x80000000 >> 21);	/* use pc15 as CTS1 */	iop->iop_pparc |= (0x80000000 >> 15);	iop->iop_pdirc &= ~(0x80000000 >> 15);	iop->iop_psorc &= ~(0x80000000 >> 15);	/*	 * SI clock routing	 * use CLK11	 * this also connects SCC1 to NMSI	 */	im->im_cpmux.cmx_scr = (im->im_cpmux.cmx_scr & ~CMXSCR_MASK) |		CMXSCR_VALUE;	/* keymile_rxIdx = 0; */	/*	 * Initialize function code registers for big-endian.	 */	hpr->sh_genscc.scc_rfcr = CPMFCR_EB;	hpr->sh_genscc.scc_tfcr = CPMFCR_EB;	/*	 * Set maximum bytes per receive buffer.	 */	hpr->sh_genscc.scc_mrblr = MAX_FRAME_LENGTH;	/* Setup CRC generator values for HDLC */	hpr->sh_cmask = 0x0000F0B8;	hpr->sh_cpres = 0x0000FFFF;	/* Initialize all error counters to 0 */	hpr->sh_disfc = 0;	hpr->sh_crcec = 0;	hpr->sh_abtsc = 0;	hpr->sh_nmarc = 0;	hpr->sh_retrc = 0;	/* Set maximum frame length size */	hpr->sh_mflr = MAX_FRAME_LENGTH;	/* set to 1 for per frame processing change later if needed */	hpr->sh_rfthr = 1;	hpr->sh_hmask = 0xff;	hpr->sh_haddr2 = SET_HDLC_UUA(keymile_slot);	hpr->sh_haddr3 = hpr->sh_haddr2;	hpr->sh_haddr4 = hpr->sh_haddr2;	/* broadcast */	hpr->sh_haddr1 = HDLC_BCAST;	hpr->sh_genscc.scc_rbase = (unsigned int) &rtx->rxbd[0];	hpr->sh_genscc.scc_tbase = (unsigned int) &rtx->txbd;#if 0	/*	 * Initialize the buffer descriptors.	 */	bdp = &rtx->txbd;	bdp->cbd_sc = 0;	bdp->cbd_bufaddr = 0;	bdp->cbd_sc = BD_SC_WRAP;	/*	 *	Setup RX packet buffers, aligned correctly.	 *	Borrowed from net/net.c.	 */	MyRxPackets[0] = &MyPktBuf[0] + (PKTALIGN - 1);	MyRxPackets[0] -= (ulong)MyRxPackets[0] % PKTALIGN;	for (i = 1; i < HDLC_PKTBUFSRX; i++)		MyRxPackets[i] = MyRxPackets[0] + i * PKT_MAXBLR_SIZE;	bdp = &rtx->rxbd[0];	for (i = 0; i < HDLC_PKTBUFSRX; i++) {		bdp->cbd_sc = BD_SC_EMPTY;		/* Leave space at the start for INET header. */		bdp->cbd_bufaddr = (unsigned int)(MyRxPackets[i] +			INET_HDR_ALIGN);		bdp++;	}	bdp--;	bdp->cbd_sc |= BD_SC_WRAP;#else	keymile_hdlc_enet_init_bds(rtx);#endif	/* 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(CPM_CR_SCC_PAGE, CPM_CR_SCC_SBLOCK,					0, CPM_CR_INIT_TRX) | CPM_CR_FLG;	while (cp->cp_cpcr & CPM_CR_FLG);	sccp->scc_gsmrl = SCC_GSMRL_MODE_HDLC;	/* CTSS=1 */	sccp->scc_gsmrh = SCC_GSMRH_CTSS;	/* NOF=0, RTE=1, DRT=0, BUS=1 */	sccp->scc_psmr = ((0x8000 >> 6) | (0x8000 >> 10));/* loopback for local testing */#ifdef GJTEST	dprintf("LOOPBACK!\n");	sccp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP;#endif	/*	 * Disable all interrupts and clear all pending	 * events.	 */	sccp->scc_sccm = 0;	sccp->scc_scce = 0xffff;	/*	 * And last, enable the transmit and receive processing.	 */	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);	dprintf("%s: HDLC ENET Version 0.3 on SCC%d\n", dev->name,		MGC_SCC_HDLC + 1);	/*	 * We may not get an ARP packet because ARP was already done on	 * a different interface, so initialize the cached values now.	 */	initCachedNumbers(1);	already_inited = 1;	return 0;}void keymile_hdlc_enet_halt(struct eth_device *dev){#if 0 /* just return, but keep this for reference */	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;	/* maybe should do a graceful stop here? */	immr->im_scc[MGC_SCC_HDLC].scc_gsmrl &=		~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);#endif}#endif /* CONFIG_MGCOGE_HDLC_ENET */

⌨️ 快捷键说明

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