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

📄 uec.c

📁 U-boot源码 ARM7启动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (i==0) {			init_enet_offset = 0;		} else {			init_enet_offset = qe_muram_alloc(					sizeof(uec_thread_rx_pram_t),					 UEC_THREAD_RX_PRAM_ALIGNMENT);		}		entry_val = ((u32)snum << ENET_INIT_PARAM_SNUM_SHIFT) |				 init_enet_offset | (u32)uec_info->riscRx;		p_init_enet_param->rxthread[i] = entry_val;	}	/* Init Tx global parameter pointer */	p_init_enet_param->txglobal = uec->tx_glbl_pram_offset |					 (u32)uec_info->riscTx;	/* Init Tx threads */	for (i = 0; i < thread_tx; i++) {		if ((snum = qe_get_snum()) < 0)	{			printf("%s can not get snum\n", __FUNCTION__);			return -ENOMEM;		}		init_enet_offset = qe_muram_alloc(sizeof(uec_thread_tx_pram_t),						 UEC_THREAD_TX_PRAM_ALIGNMENT);		entry_val = ((u32)snum << ENET_INIT_PARAM_SNUM_SHIFT) |				 init_enet_offset | (u32)uec_info->riscTx;		p_init_enet_param->txthread[i] = entry_val;	}	__asm__ __volatile__("sync");	/* Issue QE command */	command = QE_INIT_TX_RX;	cecr_subblock =	ucc_fast_get_qe_cr_subblock(				uec->uec_info->uf_info.ucc_num);	qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,						 init_enet_param_offset);	return 0;}static int uec_startup(uec_private_t *uec){	uec_info_t			*uec_info;	ucc_fast_info_t			*uf_info;	ucc_fast_private_t		*uccf;	ucc_fast_t			*uf_regs;	uec_t				*uec_regs;	int				num_threads_tx;	int				num_threads_rx;	u32				utbipar;	enet_interface_e		enet_interface;	u32				length;	u32				align;	qe_bd_t				*bd;	u8				*buf;	int				i;	if (!uec || !uec->uec_info) {		printf("%s: uec or uec_info not initial\n", __FUNCTION__);		return -EINVAL;	}	uec_info = uec->uec_info;	uf_info = &(uec_info->uf_info);	/* Check if Rx BD ring len is illegal */	if ((uec_info->rx_bd_ring_len < UEC_RX_BD_RING_SIZE_MIN) || \		(uec_info->rx_bd_ring_len % UEC_RX_BD_RING_SIZE_ALIGNMENT)) {		printf("%s: Rx BD ring len must be multiple of 4, and > 8.\n",			 __FUNCTION__);		return -EINVAL;	}	/* Check if Tx BD ring len is illegal */	if (uec_info->tx_bd_ring_len < UEC_TX_BD_RING_SIZE_MIN) {		printf("%s: Tx BD ring length must not be smaller than 2.\n",			 __FUNCTION__);		return -EINVAL;	}	/* Check if MRBLR is illegal */	if ((MAX_RXBUF_LEN == 0) || (MAX_RXBUF_LEN  % UEC_MRBLR_ALIGNMENT)) {		printf("%s: max rx buffer length must be mutliple of 128.\n",			 __FUNCTION__);		return -EINVAL;	}	/* Both Rx and Tx are stopped */	uec->grace_stopped_rx = 1;	uec->grace_stopped_tx = 1;	/* Init UCC fast */	if (ucc_fast_init(uf_info, &uccf)) {		printf("%s: failed to init ucc fast\n", __FUNCTION__);		return -ENOMEM;	}	/* Save uccf */	uec->uccf = uccf;	/* Convert the Tx threads number */	if (uec_convert_threads_num(uec_info->num_threads_tx,					 &num_threads_tx)) {		return -EINVAL;	}	/* Convert the Rx threads number */	if (uec_convert_threads_num(uec_info->num_threads_rx,					 &num_threads_rx)) {		return -EINVAL;	}	uf_regs = uccf->uf_regs;	/* UEC register is following UCC fast registers */	uec_regs = (uec_t *)(&uf_regs->ucc_eth);	/* Save the UEC register pointer to UEC private struct */	uec->uec_regs = uec_regs;	/* Init UPSMR, enable hardware statistics (UCC) */	out_be32(&uec->uccf->uf_regs->upsmr, UPSMR_INIT_VALUE);	/* Init MACCFG1, flow control disable, disable Tx and Rx */	out_be32(&uec_regs->maccfg1, MACCFG1_INIT_VALUE);	/* Init MACCFG2, length check, MAC PAD and CRC enable */	out_be32(&uec_regs->maccfg2, MACCFG2_INIT_VALUE);	/* Setup MAC interface mode */	uec_set_mac_if_mode(uec, uec_info->enet_interface);	/* Setup MII management base */#ifndef CONFIG_eTSEC_MDIO_BUS	uec->uec_mii_regs = (uec_mii_t *)(&uec_regs->miimcfg);#else	uec->uec_mii_regs = (uec_mii_t *) CONFIG_MIIM_ADDRESS;#endif	/* Setup MII master clock source */	qe_set_mii_clk_src(uec_info->uf_info.ucc_num);	/* Setup UTBIPAR */	utbipar = in_be32(&uec_regs->utbipar);	utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK;	enet_interface = uec->uec_info->enet_interface;	if (enet_interface == ENET_1000_TBI ||		 enet_interface == ENET_1000_RTBI) {		utbipar |=  (uec_info->phy_address + uec_info->uf_info.ucc_num)						 << UTBIPAR_PHY_ADDRESS_SHIFT;	} else {		utbipar |=  (0x10 + uec_info->uf_info.ucc_num)						 << UTBIPAR_PHY_ADDRESS_SHIFT;	}	out_be32(&uec_regs->utbipar, utbipar);	/* Allocate Tx BDs */	length = ((uec_info->tx_bd_ring_len * SIZEOFBD) /		 UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) *		 UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;	if ((uec_info->tx_bd_ring_len * SIZEOFBD) %		 UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) {		length += UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;	}	align = UEC_TX_BD_RING_ALIGNMENT;	uec->tx_bd_ring_offset = (u32)malloc((u32)(length + align));	if (uec->tx_bd_ring_offset != 0) {		uec->p_tx_bd_ring = (u8 *)((uec->tx_bd_ring_offset + align)						 & ~(align - 1));	}	/* Zero all of Tx BDs */	memset((void *)(uec->tx_bd_ring_offset), 0, length + align);	/* Allocate Rx BDs */	length = uec_info->rx_bd_ring_len * SIZEOFBD;	align = UEC_RX_BD_RING_ALIGNMENT;	uec->rx_bd_ring_offset = (u32)(malloc((u32)(length + align)));	if (uec->rx_bd_ring_offset != 0) {		uec->p_rx_bd_ring = (u8 *)((uec->rx_bd_ring_offset + align)							 & ~(align - 1));	}	/* Zero all of Rx BDs */	memset((void *)(uec->rx_bd_ring_offset), 0, length + align);	/* Allocate Rx buffer */	length = uec_info->rx_bd_ring_len * MAX_RXBUF_LEN;	align = UEC_RX_DATA_BUF_ALIGNMENT;	uec->rx_buf_offset = (u32)malloc(length + align);	if (uec->rx_buf_offset != 0) {		uec->p_rx_buf = (u8 *)((uec->rx_buf_offset + align)						 & ~(align - 1));	}	/* Zero all of the Rx buffer */	memset((void *)(uec->rx_buf_offset), 0, length + align);	/* Init TxBD ring */	bd = (qe_bd_t *)uec->p_tx_bd_ring;	uec->txBd = bd;	for (i = 0; i < uec_info->tx_bd_ring_len; i++) {		BD_DATA_CLEAR(bd);		BD_STATUS_SET(bd, 0);		BD_LENGTH_SET(bd, 0);		bd ++;	}	BD_STATUS_SET((--bd), TxBD_WRAP);	/* Init RxBD ring */	bd = (qe_bd_t *)uec->p_rx_bd_ring;	uec->rxBd = bd;	buf = uec->p_rx_buf;	for (i = 0; i < uec_info->rx_bd_ring_len; i++) {		BD_DATA_SET(bd, buf);		BD_LENGTH_SET(bd, 0);		BD_STATUS_SET(bd, RxBD_EMPTY);		buf += MAX_RXBUF_LEN;		bd ++;	}	BD_STATUS_SET((--bd), RxBD_WRAP | RxBD_EMPTY);	/* Init global Tx parameter RAM */	uec_init_tx_parameter(uec, num_threads_tx);	/* Init global Rx parameter RAM */	uec_init_rx_parameter(uec, num_threads_rx);	/* Init ethernet Tx and Rx parameter command */	if (uec_issue_init_enet_rxtx_cmd(uec, num_threads_tx,					 num_threads_rx)) {		printf("%s issue init enet cmd failed\n", __FUNCTION__);		return -ENOMEM;	}	return 0;}static int uec_init(struct eth_device* dev, bd_t *bd){	uec_private_t		*uec;	int			err;	uec = (uec_private_t *)dev->priv;	if (uec->the_first_run == 0) {		/* Set up the MAC address */		if (dev->enetaddr[0] & 0x01) {			printf("%s: MacAddress is multcast address\n",				 __FUNCTION__);			return 0;		}		uec_set_mac_address(uec, dev->enetaddr);		uec->the_first_run = 1;	}	err = uec_open(uec, COMM_DIR_RX_AND_TX);	if (err) {		printf("%s: cannot enable UEC device\n", dev->name);		return 0;	}	return uec->mii_info->link;}static void uec_halt(struct eth_device* dev){	uec_private_t	*uec = (uec_private_t *)dev->priv;	uec_stop(uec, COMM_DIR_RX_AND_TX);}static int uec_send(struct eth_device* dev, volatile void *buf, int len){	uec_private_t		*uec;	ucc_fast_private_t	*uccf;	volatile qe_bd_t	*bd;	u16			status;	int			i;	int			result = 0;	uec = (uec_private_t *)dev->priv;	uccf = uec->uccf;	bd = uec->txBd;	/* Find an empty TxBD */	for (i = 0; bd->status & TxBD_READY; i++) {		if (i > 0x100000) {			printf("%s: tx buffer not ready\n", dev->name);			return result;		}	}	/* Init TxBD */	BD_DATA_SET(bd, buf);	BD_LENGTH_SET(bd, len);	status = bd->status;	status &= BD_WRAP;	status |= (TxBD_READY | TxBD_LAST);	BD_STATUS_SET(bd, status);	/* Tell UCC to transmit the buffer */	ucc_fast_transmit_on_demand(uccf);	/* Wait for buffer to be transmitted */	for (i = 0; bd->status & TxBD_READY; i++) {		if (i > 0x100000) {			printf("%s: tx error\n", dev->name);			return result;		}	}	/* Ok, the buffer be transimitted */	BD_ADVANCE(bd, status, uec->p_tx_bd_ring);	uec->txBd = bd;	result = 1;	return result;}static int uec_recv(struct eth_device* dev){	uec_private_t		*uec = dev->priv;	volatile qe_bd_t	*bd;	u16			status;	u16			len;	u8			*data;	bd = uec->rxBd;	status = bd->status;	while (!(status & RxBD_EMPTY)) {		if (!(status & RxBD_ERROR)) {			data = BD_DATA(bd);			len = BD_LENGTH(bd);			NetReceive(data, len);		} else {			printf("%s: Rx error\n", dev->name);		}		status &= BD_CLEAN;		BD_LENGTH_SET(bd, 0);		BD_STATUS_SET(bd, status | RxBD_EMPTY);		BD_ADVANCE(bd, status, uec->p_rx_bd_ring);		status = bd->status;	}	uec->rxBd = bd;	return 1;}int uec_initialize(int index){	struct eth_device	*dev;	int			i;	uec_private_t		*uec;	uec_info_t		*uec_info;	int			err;	dev = (struct eth_device *)malloc(sizeof(struct eth_device));	if (!dev)		return 0;	memset(dev, 0, sizeof(struct eth_device));	/* Allocate the UEC private struct */	uec = (uec_private_t *)malloc(sizeof(uec_private_t));	if (!uec) {		return -ENOMEM;	}	memset(uec, 0, sizeof(uec_private_t));	/* Init UEC private struct, they come from board.h */	if (index == 0) {#ifdef CONFIG_UEC_ETH1		uec_info = &eth1_uec_info;#endif	} else if (index == 1) {#ifdef CONFIG_UEC_ETH2		uec_info = &eth2_uec_info;#endif	} else {		printf("%s: index is illegal.\n", __FUNCTION__);		return -EINVAL;	}	uec->uec_info = uec_info;	sprintf(dev->name, "FSL UEC%d", index);	dev->iobase = 0;	dev->priv = (void *)uec;	dev->init = uec_init;	dev->halt = uec_halt;	dev->send = uec_send;	dev->recv = uec_recv;	/* Clear the ethnet address */	for (i = 0; i < 6; i++)		dev->enetaddr[i] = 0;	eth_register(dev);	err = uec_startup(uec);	if (err) {		printf("%s: Cannot configure net device, aborting.",dev->name);		return err;	}	err = init_phy(dev);	if (err) {		printf("%s: Cannot initialize PHY, aborting.\n", dev->name);		return err;	}	phy_change(dev);	return 1;}#endif /* CONFIG_QE */

⌨️ 快捷键说明

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