[U-Boot] [PATCH 2/3] Add support W90P710 EMC interface

Ben Warren biggerbadderben at gmail.com
Tue Feb 10 07:35:56 CET 2009


Hi Konstantin,

Vovk Konstantin wrote:
> This will add Ethernet interfacse to uBoot
> W90P710 ARM SoC port. If you want reset
> and initialize PHY KSZ8001 after MAC init,
> simply add CONFIG_RESET_PHY_R define in your
> board configuration file. In most cases this is
> not necessarily.
> ---
>   drivers/net/Makefile      |    5 +-
>   drivers/net/w90p710_eth.c |  482 +++++++++++++++++++++++++++++++++++++++++++++
>   drivers/net/w90p710_eth.h |  277 ++++++++++++++++++++++++++
>   include/netdev.h          |    3 +-
>   4 files changed, 763 insertions(+), 4 deletions(-)
>   create mode 100644 drivers/net/w90p710_eth.c
>   create mode 100644 drivers/net/w90p710_eth.h
>
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 128dc11..2dff5a5 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -26,7 +26,6 @@ include $(TOPDIR)/config.mk
>   LIB	:= $(obj)libnet.a
>
>   COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
> -COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
>   COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
>   COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o
>   COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o
> @@ -55,11 +54,11 @@ COBJS-$(CONFIG_NS8382X) += ns8382x.o
>   COBJS-$(CONFIG_DRIVER_NS9750_ETHERNET) += ns9750_eth.o
>   COBJS-$(CONFIG_PCNET) += pcnet.o
>   COBJS-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o
> +COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
>   COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o
>   COBJS-$(CONFIG_RTL8139) += rtl8139.o
>   COBJS-$(CONFIG_RTL8169) += rtl8169.o
>   COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o
> -COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
>   COBJS-$(CONFIG_DRIVER_SMC91111) += smc91111.o
>   COBJS-$(CONFIG_DRIVER_SMC911X) += smc911x.o
>   COBJS-$(CONFIG_TIGON3) += tigon3.o bcm570x_autoneg.o 5701rls.o
> @@ -69,6 +68,8 @@ COBJS-$(CONFIG_ULI526X) += uli526x.o
>   COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o
>   COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o
>   COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
> +COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
> +COBJS-$(CONFIG_DRIVER_W90P710_ETH) += w90p710_eth.o
>
>   
Looks like you mangled this file. Please be more careful in merging
>   COBJS	:= $(COBJS-y)
>   SRCS	:= $(COBJS:.o=.c)
> diff --git a/drivers/net/w90p710_eth.c b/drivers/net/w90p710_eth.c
> new file mode 100644
> index 0000000..654df08
> --- /dev/null
> +++ b/drivers/net/w90p710_eth.c
> @@ -0,0 +1,482 @@
> +/***********************************************************************
> + *
> + * (C) Copyright 2008
> + * KSL Embedded Development Team <www.kslemb.com>
> + * Konstantin Vovk <ksl at kslemb.com>
> + *
> + * 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
> + *
> + * Description:   Ethernet interface for Winbond W90P710 SoC
> + */
> +
> +#include <common.h>
> +#ifdef CONFIG_DRIVER_W90P710_ETH
>   
Please remove. The Makefile takes care of this
> +
> +#include <command.h>
> +#include <net.h>
> +#include <malloc.h>
> +#include <asm/hardware.h>
> +#include "w90p710_eth.h"
> +
> +#ifdef CONFIG_STATUS_LED
> +#include <status_led.h>
> +#endif
> +
> +#if 0
> +#define DEBUG
> +#endif
> +
> +#if 1
> +#define DEBUG_PHY_RESET
> +#endif
> +
> +#ifdef	DEBUG
> +#define printk(fmt, args...)	printf(fmt, ##args)
> +#else
> +#define printk(fmt, args...)
> +#endif
> +
>   
Please use debug() instead of this. No dead code.
> +#ifdef DEBUG_PHY_RESET
> +#define print_phy(fmt, args...)	printf(fmt, ##args)
> +#else
> +#define print_phy(fmt, args...)
> +#endif
> +
> +static TX_FrameDescriptor	txFDbase[ETH_MaxTxFrames];
> +static MACFrame			txFrameBase[ETH_MaxTxFrames];
> +static RX_FrameDescriptor	rxFDbase[PKTBUFSRX];
> +static ETH			m_eth;
> +
> +static s32 TxFDinit (ETH *eth)
> +{
>   
Typedefs are frowned upon. Especially non-descriptive ones like "ETH"
> +	s32 i;
> +	MACFrame *txFrmBase;
> +
> +	/* use non-cacheble space for access to the TX buffers */
> +	txFrmBase = (MACFrame *)( (u32)txFrameBase | 0x80000000);
> +
> +	/* store start of Tx descriptors and set current */
> +	eth->m_curTX_FD  =  (TX_FrameDescriptor *) ((u32)txFDbase | 0x80000000);
> +	eth->m_baseTX_FD = eth->m_curTX_FD;
> +
> +	for ( i = 0; i < ETH_MaxTxFrames; i++) {
> +		eth->m_baseTX_FD[i].m_frameDataPtr.ui = (u32)&txFrmBase[i];
> +		/* Clear Owner and IntEn bits - Oner now is CPU*/
>   
s/Oner/Owner/

> +		eth->m_baseTX_FD[i].m_opt.ui = 0;
> +		/* Enable Padding Automaticaly */
> +		eth->m_baseTX_FD[i].m_opt.bf.padding = 1;
> +		/* Enable CRC Append */
> +		eth->m_baseTX_FD[i].m_opt.bf.crc_en = 1;
> +		/* Clear status and transmit count*/
> +		eth->m_baseTX_FD[i].m_status.ui = 0;
> +		/* Point to the next descriptor */
> +		eth->m_baseTX_FD[i].m_nextFD = &eth->m_baseTX_FD[i+1];
> +	}
> +
> +	/* make the list circular */
> +	eth->m_baseTX_FD[i-1].m_nextFD = &eth->m_baseTX_FD[0];
> +	/* Write Current TX Descriptor Buffer Start Address */
> +	PUT_REG (REG_TXDLSA, (u32)eth->m_curTX_FD);
> +	return 0;
> +}
> +
> +static s32 RxFDinit( ETH *eth)
> +{
> + s32 i;
> +	/* store start of Rx descriptors and set current */
> +	eth->m_curRX_FD = (RX_FrameDescriptor *)((u32)rxFDbase | 0x80000000);
> +	eth->m_baseRX_FD = eth->m_curRX_FD;
> +
> +	for ( i = 0; i < PKTBUFSRX; i++) {
> +		eth->m_baseRX_FD[i].m_frameDataPtr.ui =
> +				(u32)NetRxPackets[i] | 0x80000000;
> +		eth->m_baseRX_FD[i].m_status.ui = 0x0;
> +		eth->m_baseRX_FD[i].m_status.bf.owner = 0x02;/* Owner is EMC */
> +		eth->m_baseRX_FD[i].m_reserved = 0x0;
> +		eth->m_baseRX_FD[i].m_nextFD = &eth->m_baseRX_FD[i+1];
> +	}
> +	/* make the list circular */
> +	eth->m_baseRX_FD[i-1].m_nextFD = &eth->m_baseRX_FD[0];
> +	/* Write Current RX Descriptor Buffer Start Address */
> +	PUT_REG (REG_RXDLSA, (u32)eth->m_curRX_FD);
> +	return 0;
> +}
> +
> +#ifdef CONFIG_RESET_PHY_R
> +/* Write External PHY Register */
> +void PHY_Write (unsigned int PHY_Reg_Addr, unsigned int PHY_Number,
> +	 	unsigned int Data)
> +{
> +	volatile unsigned int Check;
> +
> +	PUT_REG (REG_MIID, Data);
> +	PUT_REG (REG_MIIDA,
> +		PHY_Reg_Addr | PHY_Number | PHYBUSY | PHYWR | MDCCR);
> +	do {
> +		Check = GET_REG (REG_MIIDA);
> +	}
> +	while (Check & PHYBUSY);
> +	PUT_REG (REG_MIID, 0x0);
> +}
> +
> +/* Read External PHY Register */
> +unsigned int PHY_Read (unsigned int PHY_Reg_Addr, unsigned int PHY_Number)
> +{
> +	unsigned int PHY_Data;
> +	volatile unsigned int Check;
> +
> +	PUT_REG (REG_MIIDA, PHY_Reg_Addr | PHY_Number | PHYBUSY | MDCCR);
> +	do {
> +		Check = GET_REG (REG_MIIDA);
> +	}
> +	while (Check & PHYBUSY);
> +	PHY_Data = GET_REG (REG_MIID);
> +	return PHY_Data;
> +}
> +
> +/* Reset external PHY Chip */
> +void PHY_Reset(void)
> +{
> +	unsigned int Read_Value;
> +	unsigned int wait;
> +	int i;
> +	unsigned char Status = 0;
> +
> +	/* Configure GPIO2 function as MAC pins */
> +	PUT_REG (REG_GPIO_CFG2, 0x00055555);
> +	/*
> +	 * Configure MAC Command Register:
> +	 * 100M, Full Duplex, strip CRC,
> +	 * MDC clock generation, accept control frame
> +	 */
> +	PUT_REG (REG_MCMDR,
> +		MCMDR_OPMOD | MCMDR_FDUP | MCMDR_SPCRC | MCMDR_EnMDC);
> +	print_phy ("Reset KSZ8001 PHY...");
> +	PHY_Write (PHY_CNTL_REG, PHYAD, RESET_PHY);
> +
> +	wait = 1000000;
> +	while (1) {	/* wait for auto-negotiation complete */
>   
Instead of while(1), consider restructuring so it's while(--wait). The 
functionality is really a timeout, not an infinite loop. Apply globally.
> +		Read_Value = PHY_Read (PHY_STATUS_REG, PHYAD);
> +
> +		if ((Read_Value & AN_COMPLETE) != 0) {
> +			print_phy ("OK\n");
> +		break;
> +		}
> +
> +		if (!(wait--)) {
> +			print_phy ("FAILED!\n");
> +			break;
> +		}
> +	}
> +
> +	PHY_Write (PHY_ANA_REG,
> +		PHYAD, DR100_TX_FULL | DR100_TX_HALF | DR10_TX_FULL  |
> +		DR10_TX_HALF | IEEE_802_3_CSMA_CD);
> +
> +	Read_Value = PHY_Read (PHY_CNTL_REG, PHYAD);
> +	Read_Value |= (RESTART_AN + ENABLE_AN);
> +	PHY_Write (PHY_CNTL_REG, PHYAD, Read_Value);
> +
> +	print_phy ("Wait for auto-negotiation complete...");
> +	wait = 1000000; i = 0;
> +	/* wait for auto-negotiation complete */
> +	while (1) {
> +		Read_Value = PHY_Read (PHY_STATUS_REG, PHYAD) ;
> +
> +		if ((Read_Value & AN_COMPLETE) != 0) {
> +			print_phy ("OK\n");
> +			Status = 1;
> +			break;
> +		}
> +
> +		if (!(wait--)) {
> +			print_phy ("FAILED!!\n");
> +			break;
> +		}
> +	
> +		if(i==10000) {
> +			i=0;
> +			print_phy (".");
> +		}
> +		else
> +			i++;
> +	}/* end while */
> +
> +	if ( Status == 0 ) {
> +		print_phy ("Set default: 100M Full Duplex\n");
> +		/*
> +		 * Configure MAC Command Register: 100M, Full Duplex, strip CRC,
> +		 * MDC clock generation, accept control frame
> +		 */
> +		PUT_REG (REG_MCMDR,
> +			MCMDR_OPMOD | MCMDR_FDUP | MCMDR_SPCRC | MCMDR_EnMDC);
> +	}
> +	else {
>   
Join these two lines ( } else { )
> +		/* See KSZ8001 Data Sheet for details */
> +		Read_Value = PHY_Read (0x1F, PHYAD);
> +		Read_Value &= 0x1C;
>   
What do all these magic numbers mean? For standard 802.3 PHY registers, 
please use defines from linux/mii.h instead of your own.
> +		if ((Read_Value == 8) || (Read_Value == 0x18)) {/* 100MB */
> +			print_phy ("100Mb - ");
> +			PUT_REG (REG_MCMDR, GET_REG (REG_MCMDR) | MCMDR_OPMOD);
> +		}
> +		else if ((Read_Value == 4) || (Read_Value == 0x14)) {/* 10 MB */
> +			print_phy ("10MB - ");
> +			PUT_REG (REG_MCMDR, GET_REG (REG_MCMDR) &
> +				(~MCMDR_OPMOD));
> +		}
> +		else
> +			print_phy ("Still in auto-negotiation or PHY/MII isolate
> +mode\n");
>   
line wrapped
> +		/* Full Duplex */
> + 		if ((Read_Value == 0x18) || (Read_Value == 0x14)) {
> +			print_phy ("Full Duplex\n");
> +			PUT_REG (REG_MCMDR, GET_REG (REG_MCMDR) | MCMDR_FDUP);
> +		}
> +		/* Half Duplex */
> +		else if ((Read_Value == 8) || (Read_Value == 4)) {
> +			print_phy ("Half Duplex\n");
> +			PUT_REG (REG_MCMDR,
> +				GET_REG (REG_MCMDR) &
> +				(~MCMDR_FDUP));
> +		}
> +	}
> +}
> +#endif
> +
> +/* Public u-boot interface functions below */
> +
> +/* Init W90P710 Ethernet controller */
> +int W90P710_eth_init (struct eth_device *dev, bd_t *bis)
>   
This and all functions below (except initialize()) should be static
> +{
> +	volatile unsigned int Check;
> +	unsigned int cnt = 0;
> +	ETH *eth = &m_eth;
> +
> +	printk ("\nInit W90P710 EMC...\n");
> +	/* Configure GPIO2 function as MAC pins */
> +	PUT_REG (REG_GPIO_CFG2, 0x00055555);
> +
> +	/* Store our MAC address */
> +	eth->m_mac = bis->bi_enetaddr;
> +	/* Issue Software Reset to the MAC  */
> +	PUT_REG (REG_MCMDR, MCMDR_SWR);
> +	/* Wait for MAC come out from Reset */
> +	do {
> +		Check = GET_REG (REG_MCMDR);
> +		cnt++;
> +		if (cnt == 10000)
> +			printk ("Error reseting MAC\n");
> +	}
> +	while (Check & MCMDR_SWR);
> +
> +	 /* Set the Max RX Frame Length */
> +	PUT_REG (REG_DMARFC, sizeof (MACFrame));
> +	/* Set thresholds: TX low to 96, RX low to 96 and DMA burst to 8 words */
> +	PUT_REG (REG_FFTCR, 0x100303);
> +
> +	/* Init frame descriptors */
> +	TxFDinit (eth);
> +	RxFDinit (eth);
> +
> +	/* Init the CAM with our MAC address */
> +	PUT_REG (REG_CAM0M_Base,
> +				(eth->m_mac[0] << 24) | (eth->m_mac[1] << 16) |
> +				(eth->m_mac[2] <<  8) | (eth->m_mac[3]));
> +	PUT_REG (REG_CAM0L_Base, (eth->m_mac[4] << 24) | (eth->m_mac[5] << 16));
> +
> +	/* Enable CAM address 0 -- the MAC we just loaded */
> +	PUT_REG (REG_CAMEN, 0x1);
> +	/* Accept broadcast packetes, enable compare mode */
> +	PUT_REG (REG_CAMCMR, CAM_ABP | CAM_ECMP);
> +
> +	/*
> +	 * Configure MAC Command Register: 100M, Full Duplex,
> +	 * strip CRC, MDC clock generation, accept control frame
> +	 */
> +	//#ifndef CONFIG_RESET_PHY_R /* We do this operation in the phy_reset */
>   
No C++ comments, and no dead code.
> +	PUT_REG (REG_MCMDR,
> +			MCMDR_OPMOD | MCMDR_FDUP | MCMDR_SPCRC | MCMDR_EnMDC);
> +	//#endif
> +	/* Start reception process */
> +	PUT_REG (REG_MCMDR, GET_REG (REG_MCMDR) | MCMDR_RXON);
> +
> +	/* Enable interrupts on TX and RX*/
> +	PUT_REG (REG_MIEN,
> +			EnRXINTR | EnTXINTR | EnTXCP | EnRXGD |
> +			MISTA_RDU | MISTA_RxBErr | MISTA_TxBErr);
> +
> +	return 0;
> +}
> +
> +/* Send a packet */
> +s32 W90P710_eth_send (struct eth_device *dev, volatile void *packet, s32 length)
> +{
> + 	u32 Check;
> +	ETH *eth = &m_eth;
> +#ifdef CONFIG_STATUS_LED
>   
This is a pretty generic-looking CONFIG. If it's only used by this 
driver, please give it a more specific name.
> +	status_led_set (STATUS_LED_BOOT, STATUS_LED_ON);
> +#endif
> +
> +	printk("EMC TX...");
> +	if( eth->m_curTX_FD->m_opt.bf.owner) {
> +		printk("eth_send(): TX Frame.  CPU not owner.\n");
> +#ifdef CONFIG_STATUS_LED
> +		status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);
> +#endif
> +		return -1;
> +	}
> +
> +	/* copy user data into frame data pointer */
> +	memcpy ((void *)((u32)(eth->m_curTX_FD->m_frameDataPtr.ui)),
> +			(void *)packet, length);
> +
> +	/* Set TX Frame flags */
> +	/* Tx Interrupt Enable */
> +	eth->m_curTX_FD->m_opt.bf.macTxIrqEnbl = 1;
> +	/* CRC Append Enable   */
> +	eth->m_curTX_FD->m_opt.bf.crc_en = 1;
> +	/* Padding Enable */
> +	eth->m_curTX_FD->m_opt.bf.padding = 1;
> +
> +	/* Set TX Frame length */
> +	eth->m_curTX_FD->m_status.bf.len = length;
> +
> +	/* Change ownership to EMC */
> +	eth->m_curTX_FD->m_opt.bf.owner = 1;
> +
> +	/* Enable MAC TXON if need and remove halt state writing TXDR control register */
> +	Check = GET_REG (REG_MCMDR);
> +	if (!(Check & MCMDR_TXON))
> +	PUT_REG (REG_MCMDR, Check | MCMDR_TXON);
> +	PUT_REG (REG_TSDR, 0);
> +	do {
> +		Check = GET_REG (REG_MISTA);
> +		/* printk("MISTA=%x\n", Check); */
> +	}
> +	while (!(Check & MISTA_TXINTR));
> +
> +	/* Clear all TX Bits in MISTA Register */
> +	PUT_REG (REG_MISTA, Check & 0xFFFF0000);
> +	/* If transmission comlete correctly */
> +	if (eth->m_curTX_FD->m_status.bf.complete) {
> +		/* Change the Tx frame descriptor for next use */
> +		eth->m_curTX_FD = eth->m_curTX_FD->m_nextFD;
> +		printk ("Ok\n");
> +#ifdef CONFIG_STATUS_LED
> +		status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);
> +#endif
> +	return 0;
> +}
> +	/* There was an error */
> +	else {
> +		printk ("EMC Transmission error. MISTA=%x\n", Check);
> +#ifdef CONFIG_STATUS_LED
> +		status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);
> +#endif
> +		return -1;
> +	}
> +}
> +
> +/* Check for received packets */
> +s32 W90P710_eth_rx (struct eth_device *dev)
> +{
> +	s32 nLen = 0;
> +	ETH *eth = &m_eth;
> +	u32 Check, i = 0;
> +
> +#ifdef CONFIG_STATUS_LED
> +	status_led_set (STATUS_LED_BOOT, STATUS_LED_ON);
> +#endif
> +	printk("EMC RX...");
> +	/* Get RX Interrupt status */
> +	do {
> +		Check = GET_REG (REG_MISTA);
> +		i++;
> +		if (i > 500000) {
> +			printk ("RX Interrupt wait timeout elapsed\n");
> +			break;
> +		}
> +	}
> +	while (!(Check & MISTA_RXINTR));
> +
> +	/* check if packet ready */
> +	if( Check & MISTA_RXINTR ) {
> +		/* Clear all RX Bits in MISTA Register */
> +		PUT_REG (REG_MISTA, Check & 0x0000FFFF);
> +
> +		/* process all waiting packets */
> +		while (eth->m_curRX_FD->m_status.bf.owner == 0) {
> +			/* If receive is successfull */
> +			if (eth->m_curRX_FD->m_status.bf.good) {
> +				nLen = eth->m_curRX_FD->m_status.bf.len;
> +				/* call back u-boot Receive function --> may call eth_send() */
> +				NetReceive ((u8 *)eth->m_curRX_FD->m_frameDataPtr.ui, nLen);
> +				printk (" %d bytes received\n", nLen);
> +			}
> +			/* clear status */
> +			eth->m_curRX_FD->m_status.ui = 0x0;
> +			/* set owner back to EMC */
> +			eth->m_curRX_FD->m_status.bf.owner = 0x02;
> +			/* advance to next descriptor */
> +			eth->m_curRX_FD = eth->m_curRX_FD->m_nextFD;
> +		}
> +	}
> +
> +	/* Receive Descriptor Unavailable interrupt -> remove halt state from RxDMA*/
> +	if (Check & MISTA_RDU) {
> +		printk ("Remove halt state from RxDMA\n");
> +		PUT_REG (REG_RSDR, 0x0);
> +		}
> +	#ifdef CONFIG_STATUS_LED
> +		status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);
> +	#endif
> +	return nLen;
> +}
> +
> +/* Halt ethernet engine */
> +void W90P710_eth_halt (struct eth_device *dev)
> +{
> +	printk ("ETH Halt...\n");
> +	/* disable MAC TX and RX*/
> +	PUT_REG (REG_MCMDR, GET_REG (REG_MCMDR) & (~(MCMDR_RXON | MCMDR_TXON)));
> +}
> +
> +/* Fill eth_device structure with W90P710 EMC functions */
> +int W90P710_EMC_initialize (bd_t *bis)
> +{
> +	struct eth_device *dev;
> +	dev = (struct eth_device *) malloc (sizeof (*dev));
> +
> +	if (dev == NULL)
> +		hang();
>   
return -1
> +
> +	memset (dev, 0, sizeof(*dev));
> +	sprintf (dev->name, "W90P710 EMC");
> +
> +	dev->iobase = 0;
> +	dev->priv = 0;
> +	dev->init = W90P710_eth_init;
> +	dev->halt = W90P710_eth_halt;
> +	dev->send = W90P710_eth_send;
> +	dev->recv = W90P710_eth_rx;
> +
> +	eth_register (dev);
> +	return 1;
> +}
> +#endif
> diff --git a/drivers/net/w90p710_eth.h b/drivers/net/w90p710_eth.h
> new file mode 100644
> index 0000000..296ca25
> --- /dev/null
> +++ b/drivers/net/w90p710_eth.h
> @@ -0,0 +1,277 @@
> +/*
> + * (C) Copyright 2008
> + * KSL Embedded Development Team <www.kslemb.com>
> + * Konstantin Vovk <ksl at kslemb.com>
> + *
> + * 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
> + *
> + * Description:   Ethernet interface
> + * Runtime Env:   W90P710 SoC
> + * Change History:
> + *     08-09-2008    Created  by ksl at kslemb.com
> + *
> + */
> +
> +#ifndef __W90P710_ETH_H
> +#define __W90P710_ETH_H
> +
> +/* MAC MII Management Data Control and Address Register(MIIDA) */
> +/*#define MDCCR    0x00000000   */    /* MDC clock rating      */
> +#define MDCCR		0x00F80000	/* MDC clock rating */
> +#define PHYAD		0x00000100	/* PHY Address */
> +#define PHYWR		0x00010000	/* Write Operation */
> +#define PHYBUSY		0x00020000	/* Busy Bit */
> +#define PHYPreSP	0x00040000	/* Preamble Suppress */
> +
> +/* MAC Command Register(MCMDR) Bits */
> +#define MCMDR_RXON	0x00000001	/* Receive ON */
> +#define MCMDR_ALP	0x00000002	/* Accept Long Packet */
> +#define MCMDR_ARP	0x00000004	/* Accept Runt Packet */
> +#define MCMDR_ACP	0x00000008	/* Accept Control Packet */
> +#define MCMDR_AEP	0x00000010	/* Accept Error Packet */
> +#define MCMDR_SPCRC	0x00000020	/* Accept Strip CRC Value */
> +#define MCMDR_TXON	0x00000100	/* Transmit On */
> +#define MCMDR_NDEF	0x00000200	/* No defer */
> +#define MCMDR_SDPZ	0x00010000	/* Send Pause */
> +#define MCMDR_EnSQE	0x00020000	/* Enable SQE test */
> +#define MCMDR_FDUP	0x00040000	/* Full Duplex */
> +#define MCMDR_EnMDC	0x00080000	/* Enable MDC signal */
> +#define MCMDR_OPMOD	0x00100000	/* Operation Mode */
> +#define MCMDR_LBK	0x00200000	/* Loop Back */
> +#define MCMDR_EnRMII	0x00400000	/* Enable RMII */
> +#define MCMDR_LAN	0x00800000	/* LAN Port Setting Mode */
> +#define MCMDR_SWR	0x01000000	/* Software Reset */
> +
> +/* MAC Interrupt Status Register (MISTA) Bits */
> +#define MISTA_RXINTR	0x00000001	/* Interrupt on Receive */
> +#define MISTA_CRCE	0x00000002	/* CRC Error */
> +#define MISTA_RXOV	0x00000004	/* Receive FIFO Overflow error  */
> +#define MISTA_PTLE	0x00000008	/* Packet Too Long Error */
> +#define MISTA_RXGD	0x00000010	/* Receive Good */
> +#define MISTA_ALIE	0x00000020	/* Alignment Error */
> +#define MISTA_RP	0x00000040	/* Runt Packet */
> +#define MISTA_MMP	0x00000080	/* More Missed Packets than miss rolling over counter flag */
> +#define MISTA_DFOI	0x00000100	/* DMA receive frame over maximum size interrupt */
> +#define MISTA_DENI	0x00000200	/* DMA early notification interrupt  */
> +#define MISTA_RDU	0x00000400	/* Receive Descriptor Unavailable interrupt */
> +#define MISTA_RxBErr	0x00000800	/* Receive Bus Error interrupt */
> +#define MISTA_NATOK	0x00001000	/* NAT Processing OK */
> +#define MISTA_NATErr	0x00002000	/* NAT Processing Error */
> +#define MISTA_CFR	0x00004000	/* Control Frame Receive */
> +#define MISTA_TXINTR	0x00010000	/* Interrupt on Transmit */
> +#define MISTA_TXEMP	0x00020000	/* Transmit FIFO Empty   */
> +#define MISTA_TXCP	0x00040000	/* Transmit Completion */
> +#define MISTA_EXDEF	0x00080000	/* Defer */
> +#define MISTA_NCS	0x00100000	/* No Carrier Sense */
> +#define MISTA_TXABT	0x00200000	/* Transmit Abort */
> +#define MISTA_LC	0x00400000	/* Late Collision */
> +#define MISTA_TDU	0x00800000	/* Transmit Descriptor Unavailable interrupt */
> +#define MISTA_TxBErr	0x01000000	/* Transmit Bus Error interrupt */
> +
> +/* MAC Interrupt Enable Register(MIEN) */
> +#define EnRXINTR	0x00000001	/* Enable Interrupt on Receive Interrupt */
> +#define EnCRCE		0x00000002	/* Enable CRC Error Interrupt */
> +#define EnRXOV		0x00000004	/* Enable Receive FIFO Overflow Interrupt */
> +#define EnPTLE		0x00000008	/* Enable Packet Too Long Interrupt */
> +#define EnRXGD		0x00000010	/* Enable Receive Good Interrupt */
> +#define EnALIE		0x00000020	/* Enable Alignment Error Interrupt */
> +#define EnRP		0x00000040	/* Enable Runt Packet on Receive Interrupt */
> +#define EnMMP		0x00000080	/* Enable More Missed Packets Interrupt */
> +#define EnDFO		0x00000100	/* Enable DMA receive frame over maximum size Interrupt */
> +#define EnDEN		0x00000200	/* Enable DMA early notification Interrupt */
> +#define EnRDU		0x00000400	/* Enable Receive Descriptor Unavailable Interrupt */
> +#define EnRxBErr	0x00000800	/* Enable Receive Bus ERROR interrupt */
> +#define EnNATOK		0x00001000	/* Enable NAT Processing OK Interrupt */
> +#define EnNATErr	0x00002000	/* Enable NAT Processing Error Interrupt */
> +#define EnCFR		0x00004000	/* Enable Control Frame Receive Interrupt */
> +#define EnTXINTR	0x00010000	/* Enable Interrupt on Transmit Interrupt */
> +#define EnTXEMP		0x00020000	/* Enable Transmit FIFO Empty Interrupt */
> +#define EnTXCP		0x00040000	/* Enable Transmit Completion Interrupt */
> +#define EnEXDEF		0x00080000	/* Enable Defer Interrupt */
> +#define EnNCS		0x00100000	/* Enable No Carrier Sense Interrupt */
> +#define EnTXABT		0x00200000	/* Enable Transmit Abort Interrupt */
> +#define EnLC		0x00400000	/* Enable Late Collision Interrupt */
> +#define EnTDU		0x00800000	/* Enable Transmit Descriptor Unavailable Interrupt */
> +#define EnTxBErr	0x01000000	/* Enable Transmit Bus ERROR Interrupt */
> +
> +/* CAM Command Register(CAMCMR) Bits */
> +#define	CAM_AUP		0x0001		/* Accept Packets with Unicast Address */
> +#define	CAM_AMP		0x0002		/* Accept Packets with Multicast Address */
> +#define	CAM_ABP		0x0004		/* Accept Packets with Broadcast Address */
> +#define	CAM_CCAM	0x0008		/* 0: Accept Packets CAM Recognizes and Reject Others */
> +					/* 1: Reject Packets CAM Recognizes and Accept Others */
> +#define	CAM_ECMP	0x0010		/* Enable CAM Compare */
> +
> +/* PHY Register Description */
> +#define	PHY_CNTL_REG	0x00
> +#define	PHY_STATUS_REG	0x01
> +#define	PHY_ID1_REG	0x02
> +#define	PHY_ID2_REG	0x03
> +#define	PHY_ANA_REG	0x04
> +#define	PHY_ANLPA_REG	0x05
> +#define	PHY_ANE_REG	0x06
> +
> +#define	PHY_DSC_REG	0x10
> +#define	PHY_DSCS_REG	0x11
> +#define	PHY_10BTCS_REG	0x12
> +#define	PHY_SINT_REG	0x15
> +#define	PHY_SREC_REG	0x16
> +#define	PHY_DISC_REG	0x17
> +
>   
These ones are already defined in include/linux/mii.h (also in 
include/miiphy.h, but please use the Linux one)
> +/* PHY Control Register Bits */
> +#define	RESET_PHY	(1 << 15)
> +#define	ENABLE_LOOPBACK	(1 << 14)
> +#define	DR_100MB	(1 << 13)
> +#define	ENABLE_AN	(1 << 12)
> +#define	PHY_POWER_DOWN	(1 << 11)
> +#define	PHY_MAC_ISOLATE	(1 << 10)
> +#define	RESTART_AN	(1 << 9)
> +#define	PHY_FULLDUPLEX	(1 << 8)
> +#define	PHY_COL_TEST	(1 << 7)
> +
> +/* PHY Status Register Bits */
> +#define AN_COMPLETE	(1 << 5)
> +
> +/* PHY Auto-negotiation Advertisement Register Bits */
> +#define DR100_TX_FULL	(1 << 8)
> +#define DR100_TX_HALF	(1 << 7)
> +#define DR10_TX_FULL	(1 << 6)
> +#define DR10_TX_HALF	(1 << 5)
> +#define IEEE_802_3_CSMA_CD	1
> +
> +#define	ETH_MAC_ADDR_SIZE	(6)	/* dst,src addr is 6 bytes each */
> +#define	ETH_MaxTxFrames		(16)	/* Max number of Tx Frames */
> +
> +/* type of ethernet packets */
> +#define	ETH_TYPE_ARP	(0x0806)
> +#define	ETH_TYPE_IP	(0x0800)
> +
>   
> +#define	ETH_HDR_SIZE	(14)		/* Dest[6]+Src[6]+LengthorType[2] */
>   
These are already in include/net.h
> +
> +/* W90P710 bit field for TX Descriptor Word 0 */
> +typedef struct __BF_TX_Options {
> +	unsigned int padding:1;		/*  PadEN  - Padding Enable */
> +	unsigned int crc_en:1;		/*  CRCApp - CRC Append */
> +	unsigned int macTxIrqEnbl:1;	/*  IntEn  - Transmit Interrupt Enable */
> +	unsigned int reserved:28;	/*  Reserved */
> +	unsigned int owner:1;		/*  Owner  - Ownership */
> +} BF_TX_Options;
> +
>   
Please don't use all these typedefs. The meaning gets lost quickly.
> +/* W90P710 TX descriptor Word 0 as a union */
> +typedef union _TX_Options {
> +	unsigned int	ui;
> +	BF_TX_Options	bf;
> +} TX_Options;
> +
> +/* W90P710 bit field for Transmit Buffer Starting Address word */
> +typedef struct __BF_FrameDataPtr {
> +	unsigned int BO:2;
> +	unsigned int dataPtr:30;
> +} BF_FrameDataPtr;
> +
> +/* W90P710 TX descriptor Word 1 as a union */
> +typedef union _FrameDataPtr {
> +	unsigned int	ui;
> +	BF_FrameDataPtr	bf;
> +} FrameDataPtr;
> +
> +/* W90P710 Third word of the TX Buffer descriptor */
> +typedef struct __BF_TX_Status {
> +	unsigned int len:16;		/* Frame length */
> +	unsigned int intTx:1;		/* TXINTR - Transmittion interrupt */
> +	unsigned int txDefer:1;		/* DEF - Transmission Deffered */
> +	unsigned int Reserverd1:1;   	/* Reserved */
> +	unsigned int complete:1;	/* TXCP - Transmission Complete */
> +	unsigned int defer:1;		/* EXDEF - Deffer Exceed */
> +	unsigned int noCarrier:1;	/* NCS - No Carrier Sense */
> +	unsigned int exColl:1;		/* TXABT - Transmission Abort */
> +	unsigned int lateColl:1;	/* LC - Late Collision */
> +	unsigned int halted:1;		/* TXHA - Transmission Halted */
> +	unsigned int paused:1;		/* PAU - Transmission Paused */
> +	unsigned int SQErr:1;		/* SQE - SQE Error */
> +	unsigned int Reserverd2:1;	/* Reserved */
> +	unsigned int txCollCnt:4;	/* CCNT - Collision Count */
> +} BF_TX_Status;
> +
> +/*
> + * W90P710 Third word of the TX Buffer descriptor as a union of the
> + * WORD and Status + Byte count
> + */
> +typedef union _TX_Status {
> +	unsigned int	ui;
> +	BF_TX_Status	bf;
> +} TX_Status;
> +
> +/* W90P710 TX descriptor structure */
> +typedef struct __TX_FrameDescriptor {
> +	TX_Options		m_opt;
> +	volatile FrameDataPtr	m_frameDataPtr;
> +	volatile TX_Status	m_status;
> +	struct __TX_FrameDescriptor *m_nextFD;
> +} TX_FrameDescriptor __attribute__ ((aligned(16)));
> +
> +/* W90P710 Rx Buffer Descriptor Word 0 */
> +typedef struct __BF_RX_Status {
> +	unsigned int len:16;		/* frame length */
> +	unsigned int intRx:1;		/* RXINTR - Receive Interrupt */
> +	unsigned int crcErr:1;		/* CRCE - CRC Error */
> +	unsigned int Reserved1:1;	/* Reserved */
> +	unsigned int longErr:1;		/* PTLE - Packet Too Long */
> +	unsigned int good:1;		/* RXGD - Frame Reception Complete */
> +	unsigned int alignErr:1;	/* ALIE - Alignment Error */
> +	unsigned int RuntPack:1;	/* RP - Runt Packet */
> +	unsigned int Reserved2:7;	/* Reserved */
> +	unsigned int owner:2;		/* Owner  - Ownership */
> +} BF_RX_Status;
> +
> +/* W90P710 Rx Buffer Descriptor */
> +typedef union _RX_Status {
> +	unsigned int ui;
> +	BF_RX_Status bf;
> +} RX_Status;
> +
> +/* RX Buffer descriptor structure */
> +typedef struct __RX_FrameDescriptor
> +{
> +	volatile RX_Status m_status;
> +	volatile FrameDataPtr m_frameDataPtr;
> +	volatile unsigned int m_reserved;
> +	struct __RX_FrameDescriptor *m_nextFD;
> +} RX_FrameDescriptor __attribute__ ((aligned(16)));
> +
> +/*  MAC Frame Structure */
> +struct __MACFrame {
> +	unsigned char m_dstAddr[6];
> +	unsigned char m_srcAddr[6];
> +	unsigned short	m_lengthOrType;
> +	unsigned char m_payload[1506];
> +} __attribute__ ((packed));
> +
> +typedef struct __MACFrame MACFrame;
> +
> +/* Ethernet Control block */
> +typedef struct __ETH {
> +	TX_FrameDescriptor *m_curTX_FD;		/* pointer to current TX frame descriptor */
> +	TX_FrameDescriptor *m_baseTX_FD;	/* pointer to base TX frame descriptor */
> +	RX_FrameDescriptor *m_curRX_FD;		/* pointer to current RX frame descriptor */
> +	RX_FrameDescriptor *m_baseRX_FD;	/* pointer to base RX frame descriptor */
> +	unsigned char *m_mac;			/* pointer to our MAC address */
> +} ETH;
> +
> +#endif
> diff --git a/include/netdev.h b/include/netdev.h
> index ce1ecbd..676638f 100644
> --- a/include/netdev.h
> +++ b/include/netdev.h
> @@ -57,7 +57,6 @@ int mcffec_initialize(bd_t *bis);
>   int mpc512x_fec_initialize(bd_t *bis);
>   int mpc5xxx_fec_initialize(bd_t *bis);
>   int mpc8220_fec_initialize(bd_t *bis);
> -int mpc82xx_scc_enet_initialize(bd_t *bis);
>   int natsemi_initialize(bd_t *bis);
>   int npe_initialize(bd_t *bis);
>   int ns8382x_initialize(bd_t *bis);
> @@ -71,7 +70,7 @@ int skge_initialize(bd_t *bis);
>   int tsi108_eth_initialize(bd_t *bis);
>   int uec_initialize(int index);
>   int uli526x_initialize(bd_t *bis);
> -int sh_eth_initialize(bd_t *bis);
> +int W90P710_EMC_initialize(bd_t *bis);
>   
You mangled this file too. Please be more careful. Also, please don't 
capitalize the function name.
>   /* Boards with PCI network controllers can call this from their board_eth_init()
>    * function to initialize whatever's on board.
>   
regards,
Ben


More information about the U-Boot mailing list