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

📄 uec.c

📁 from wangkj@yahoo.com 电路原理图和详细说明: amd.9966.org或者 arm.9966.org 都是原创,包括boot, loader,u-boot,linu
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2006 Freescale Semiconductor, Inc. * * Dave Liu <daveliu@freescale.com> * * 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 "net.h"#include "malloc.h"#include "asm/errno.h"#include "asm/io.h"#include "asm/immap_qe.h"#include "qe.h"#include "uccf.h"#include "uec.h"#include "uec_phy.h"#if defined(CONFIG_QE)#ifdef CONFIG_UEC_ETH1static uec_info_t eth1_uec_info = {	.uf_info		= {		.ucc_num	= CFG_UEC1_UCC_NUM,		.rx_clock	= CFG_UEC1_RX_CLK,		.tx_clock	= CFG_UEC1_TX_CLK,		.eth_type	= CFG_UEC1_ETH_TYPE,	},	.num_threads_tx		= UEC_NUM_OF_THREADS_4,	.num_threads_rx		= UEC_NUM_OF_THREADS_4,	.riscTx			= QE_RISC_ALLOCATION_RISC1_AND_RISC2,	.riscRx			= QE_RISC_ALLOCATION_RISC1_AND_RISC2,	.tx_bd_ring_len		= 16,	.rx_bd_ring_len		= 16,	.phy_address		= CFG_UEC1_PHY_ADDR,	.enet_interface		= CFG_UEC1_INTERFACE_MODE,};#endif#ifdef CONFIG_UEC_ETH2static uec_info_t eth2_uec_info = {	.uf_info		= {		.ucc_num	= CFG_UEC2_UCC_NUM,		.rx_clock	= CFG_UEC2_RX_CLK,		.tx_clock	= CFG_UEC2_TX_CLK,		.eth_type	= CFG_UEC2_ETH_TYPE,	},	.num_threads_tx		= UEC_NUM_OF_THREADS_4,	.num_threads_rx		= UEC_NUM_OF_THREADS_4,	.riscTx			= QE_RISC_ALLOCATION_RISC1_AND_RISC2,	.riscRx			= QE_RISC_ALLOCATION_RISC1_AND_RISC2,	.tx_bd_ring_len		= 16,	.rx_bd_ring_len		= 16,	.phy_address		= CFG_UEC2_PHY_ADDR,	.enet_interface		= CFG_UEC2_INTERFACE_MODE,};#endifstatic int uec_mac_enable(uec_private_t *uec, comm_dir_e mode){	uec_t		*uec_regs;	u32		maccfg1;	if (!uec) {		printf("%s: uec not initial\n", __FUNCTION__);		return -EINVAL;	}	uec_regs = uec->uec_regs;	maccfg1 = in_be32(&uec_regs->maccfg1);	if (mode & COMM_DIR_TX)	{		maccfg1 |= MACCFG1_ENABLE_TX;		out_be32(&uec_regs->maccfg1, maccfg1);		uec->mac_tx_enabled = 1;	}	if (mode & COMM_DIR_RX)	{		maccfg1 |= MACCFG1_ENABLE_RX;		out_be32(&uec_regs->maccfg1, maccfg1);		uec->mac_rx_enabled = 1;	}	return 0;}static int uec_mac_disable(uec_private_t *uec, comm_dir_e mode){	uec_t		*uec_regs;	u32		maccfg1;	if (!uec) {		printf("%s: uec not initial\n", __FUNCTION__);		return -EINVAL;	}	uec_regs = uec->uec_regs;	maccfg1 = in_be32(&uec_regs->maccfg1);	if (mode & COMM_DIR_TX)	{		maccfg1 &= ~MACCFG1_ENABLE_TX;		out_be32(&uec_regs->maccfg1, maccfg1);		uec->mac_tx_enabled = 0;	}	if (mode & COMM_DIR_RX)	{		maccfg1 &= ~MACCFG1_ENABLE_RX;		out_be32(&uec_regs->maccfg1, maccfg1);		uec->mac_rx_enabled = 0;	}	return 0;}static int uec_graceful_stop_tx(uec_private_t *uec){	ucc_fast_t		*uf_regs;	u32			cecr_subblock;	u32			ucce;	if (!uec || !uec->uccf) {		printf("%s: No handle passed.\n", __FUNCTION__);		return -EINVAL;	}	uf_regs = uec->uccf->uf_regs;	/* Clear the grace stop event */	out_be32(&uf_regs->ucce, UCCE_GRA);	/* Issue host command */	cecr_subblock =		 ucc_fast_get_qe_cr_subblock(uec->uec_info->uf_info.ucc_num);	qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock,			 (u8)QE_CR_PROTOCOL_ETHERNET, 0);	/* Wait for command to complete */	do {		ucce = in_be32(&uf_regs->ucce);	} while (! (ucce & UCCE_GRA));	uec->grace_stopped_tx = 1;	return 0;}static int uec_graceful_stop_rx(uec_private_t *uec){	u32		cecr_subblock;	u8		ack;	if (!uec) {		printf("%s: No handle passed.\n", __FUNCTION__);		return -EINVAL;	}	if (!uec->p_rx_glbl_pram) {		printf("%s: No init rx global parameter\n", __FUNCTION__);		return -EINVAL;	}	/* Clear acknowledge bit */	ack = uec->p_rx_glbl_pram->rxgstpack;	ack &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX;	uec->p_rx_glbl_pram->rxgstpack = ack;	/* Keep issuing cmd and checking ack bit until it is asserted */	do {		/* Issue host command */		cecr_subblock =		 ucc_fast_get_qe_cr_subblock(uec->uec_info->uf_info.ucc_num);		qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,				 (u8)QE_CR_PROTOCOL_ETHERNET, 0);		ack = uec->p_rx_glbl_pram->rxgstpack;	} while (! (ack & GRACEFUL_STOP_ACKNOWLEDGE_RX ));	uec->grace_stopped_rx = 1;	return 0;}static int uec_restart_tx(uec_private_t *uec){	u32		cecr_subblock;	if (!uec || !uec->uec_info) {		printf("%s: No handle passed.\n", __FUNCTION__);		return -EINVAL;	}	cecr_subblock =	 ucc_fast_get_qe_cr_subblock(uec->uec_info->uf_info.ucc_num);	qe_issue_cmd(QE_RESTART_TX, cecr_subblock,			 (u8)QE_CR_PROTOCOL_ETHERNET, 0);	uec->grace_stopped_tx = 0;	return 0;}static int uec_restart_rx(uec_private_t *uec){	u32		cecr_subblock;	if (!uec || !uec->uec_info) {		printf("%s: No handle passed.\n", __FUNCTION__);		return -EINVAL;	}	cecr_subblock =	 ucc_fast_get_qe_cr_subblock(uec->uec_info->uf_info.ucc_num);	qe_issue_cmd(QE_RESTART_RX, cecr_subblock,			 (u8)QE_CR_PROTOCOL_ETHERNET, 0);	uec->grace_stopped_rx = 0;	return 0;}static int uec_open(uec_private_t *uec, comm_dir_e mode){	ucc_fast_private_t	*uccf;	if (!uec || !uec->uccf) {		printf("%s: No handle passed.\n", __FUNCTION__);		return -EINVAL;	}	uccf = uec->uccf;	/* check if the UCC number is in range. */	if (uec->uec_info->uf_info.ucc_num >= UCC_MAX_NUM) {		printf("%s: ucc_num out of range.\n", __FUNCTION__);		return -EINVAL;	}	/* Enable MAC */	uec_mac_enable(uec, mode);	/* Enable UCC fast */	ucc_fast_enable(uccf, mode);	/* RISC microcode start */	if ((mode & COMM_DIR_TX) && uec->grace_stopped_tx) {		uec_restart_tx(uec);	}	if ((mode & COMM_DIR_RX) && uec->grace_stopped_rx) {		uec_restart_rx(uec);	}	return 0;}static int uec_stop(uec_private_t *uec, comm_dir_e mode){	ucc_fast_private_t	*uccf;	if (!uec || !uec->uccf) {		printf("%s: No handle passed.\n", __FUNCTION__);		return -EINVAL;	}	uccf = uec->uccf;	/* check if the UCC number is in range. */	if (uec->uec_info->uf_info.ucc_num >= UCC_MAX_NUM) {		printf("%s: ucc_num out of range.\n", __FUNCTION__);		return -EINVAL;	}	/* Stop any transmissions */	if ((mode & COMM_DIR_TX) && !uec->grace_stopped_tx) {		uec_graceful_stop_tx(uec);	}	/* Stop any receptions */	if ((mode & COMM_DIR_RX) && !uec->grace_stopped_rx) {		uec_graceful_stop_rx(uec);	}	/* Disable the UCC fast */	ucc_fast_disable(uec->uccf, mode);	/* Disable the MAC */	uec_mac_disable(uec, mode);	return 0;}static int uec_set_mac_duplex(uec_private_t *uec, int duplex){	uec_t		*uec_regs;	u32		maccfg2;	if (!uec) {		printf("%s: uec not initial\n", __FUNCTION__);		return -EINVAL;	}	uec_regs = uec->uec_regs;	if (duplex == DUPLEX_HALF) {		maccfg2 = in_be32(&uec_regs->maccfg2);		maccfg2 &= ~MACCFG2_FDX;		out_be32(&uec_regs->maccfg2, maccfg2);	}	if (duplex == DUPLEX_FULL) {		maccfg2 = in_be32(&uec_regs->maccfg2);		maccfg2 |= MACCFG2_FDX;		out_be32(&uec_regs->maccfg2, maccfg2);	}	return 0;}static int uec_set_mac_if_mode(uec_private_t *uec, enet_interface_e if_mode){	enet_interface_e	enet_if_mode;	uec_info_t 		*uec_info;	uec_t			*uec_regs;	u32			upsmr;	u32			maccfg2;	if (!uec) {		printf("%s: uec not initial\n", __FUNCTION__);		return -EINVAL;	}	uec_info = uec->uec_info;	uec_regs = uec->uec_regs;	enet_if_mode = if_mode;	maccfg2 = in_be32(&uec_regs->maccfg2);	maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK;	upsmr = in_be32(&uec->uccf->uf_regs->upsmr);	upsmr &= ~(UPSMR_RPM | UPSMR_TBIM | UPSMR_R10M | UPSMR_RMM);	switch (enet_if_mode) {		case ENET_100_MII:		case ENET_10_MII:			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;			break;		case ENET_1000_GMII:			maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;			break;		case ENET_1000_TBI:			maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;			upsmr |= UPSMR_TBIM;			break;		case ENET_1000_RTBI:			maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;			upsmr |= (UPSMR_RPM | UPSMR_TBIM);			break;		case ENET_1000_RGMII:			maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;			upsmr |= UPSMR_RPM;			break;		case ENET_100_RGMII:			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;			upsmr |= UPSMR_RPM;			break;		case ENET_10_RGMII:			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;			upsmr |= (UPSMR_RPM | UPSMR_R10M);			break;		case ENET_100_RMII:			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;			upsmr |= UPSMR_RMM;			break;		case ENET_10_RMII:			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;			upsmr |= (UPSMR_R10M | UPSMR_RMM);			break;		default:			return -EINVAL;			break;	}	out_be32(&uec_regs->maccfg2, maccfg2);	out_be32(&uec->uccf->uf_regs->upsmr, upsmr);	return 0;}static int init_mii_management_configuration(uec_t *uec_regs){	uint		timeout = 0x1000;	u32		miimcfg = 0;	miimcfg = in_be32(&uec_regs->miimcfg);	miimcfg |= MIIMCFG_MNGMNT_CLC_DIV_INIT_VALUE;	out_be32(&uec_regs->miimcfg, miimcfg);	/* Wait until the bus is free */	while ((in_be32(&uec_regs->miimcfg) & MIIMIND_BUSY) && timeout--);	if (timeout <= 0) {		printf("%s: The MII Bus is stuck!", __FUNCTION__);		return -ETIMEDOUT;	}	return 0;}static int init_phy(struct eth_device *dev){	uec_private_t		*uec;	uec_t			*uec_regs;	struct uec_mii_info	*mii_info;	struct phy_info		*curphy;	int			err;	uec = (uec_private_t *)dev->priv;	uec_regs = uec->uec_regs;

⌨️ 快捷键说明

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