From: Ben Warren <biggerbadderben@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 2/3] Add support W90P710 EMC interface
Date: Mon, 09 Feb 2009 22:35:56 -0800 [thread overview]
Message-ID: <4991204C.3070302@gmail.com> (raw)
In-Reply-To: <49900F21.3020507@svitonline.com>
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@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 = ð->m_baseTX_FD[i+1];
> + }
> +
> + /* make the list circular */
> + eth->m_baseTX_FD[i-1].m_nextFD = ð->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 = ð->m_baseRX_FD[i+1];
> + }
> + /* make the list circular */
> + eth->m_baseRX_FD[i-1].m_nextFD = ð->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@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
prev parent reply other threads:[~2009-02-10 6:35 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-09 11:10 [U-Boot] [PATCH 2/3] Add support W90P710 EMC interface Vovk Konstantin
2009-02-09 12:51 ` Jean-Christophe PLAGNIOL-VILLARD
2009-02-09 20:13 ` Wolfgang Denk
2009-02-10 6:35 ` Ben Warren [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4991204C.3070302@gmail.com \
--to=biggerbadderben@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.