]> git.sur5r.net Git - u-boot/commitdiff
net/Blackfin: move on-chip MAC driver into drivers/net/
authorMike Frysinger <vapier@gentoo.org>
Mon, 25 Feb 2008 04:58:13 +0000 (23:58 -0500)
committerWolfgang Denk <wd@denx.de>
Tue, 25 Mar 2008 21:35:26 +0000 (22:35 +0100)
The Blackfin on-chip MAC driver was being managed in the BF537-STAMP board
directory, but it is not board specific, so relocate it to the drivers dir
so that other Blackfin ports can utilize it.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
board/bf537-stamp/Makefile
board/bf537-stamp/ether_bf537.c [deleted file]
board/bf537-stamp/ether_bf537.h [deleted file]
drivers/net/Makefile
drivers/net/bfin_mac.c [new file with mode: 0644]
drivers/net/bfin_mac.h [new file with mode: 0644]

index cdffc333ebfbef2aff3f963b3a3970df11bc745a..5d223933715522af22cc256da5973581709c1ba6 100644 (file)
@@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).a
 
-COBJS  := $(BOARD).o ether_bf537.o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o
+COBJS  := $(BOARD).o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
diff --git a/board/bf537-stamp/ether_bf537.c b/board/bf537-stamp/ether_bf537.c
deleted file mode 100644 (file)
index 6c514c6..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * ADI Blackfin 537 MAC Ethernet
- *
- * Copyright (c) 2005 Analog Device, Inc.
- *
- * 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 <config.h>
-#include <asm/blackfin.h>
-#include <net.h>
-#include <command.h>
-#include <malloc.h>
-#include "ether_bf537.h"
-
-#include <asm/mach-common/bits/dma.h>
-#include <asm/mach-common/bits/emac.h>
-#include <asm/mach-common/bits/pll.h>
-
-#ifdef CONFIG_POST
-#include <post.h>
-#endif
-
-#undef DEBUG_ETHERNET
-
-#ifdef DEBUG_ETHERNET
-#define DEBUGF(fmt,args...) printf(fmt,##args)
-#else
-#define DEBUGF(fmt,args...)
-#endif
-
-#if defined(CONFIG_CMD_NET)
-
-#define RXBUF_BASE_ADDR                0xFF900000
-#define TXBUF_BASE_ADDR                0xFF800000
-#define TX_BUF_CNT             1
-
-#define TOUT_LOOP              1000000
-
-ADI_ETHER_BUFFER *txbuf[TX_BUF_CNT];
-ADI_ETHER_BUFFER *rxbuf[PKTBUFSRX];
-static u16 txIdx;              /* index of the current RX buffer */
-static u16 rxIdx;              /* index of the current TX buffer */
-
-u8 SrcAddr[6];
-u16 PHYregs[NO_PHY_REGS];      /* u16 PHYADDR; */
-
-/* DMAx_CONFIG values at DMA Restart */
-const ADI_DMA_CONFIG_REG rxdmacfg = { 1, 1, 2, 0, 0, 0, 0, 5, 7 };
-
-#if 0
-       rxdmacfg.b_DMA_EN = 1;  /* enabled */
-       rxdmacfg.b_WNR    = 1;  /* write to memory */
-       rxdmacfg.b_WDSIZE = 2;  /* wordsize is 32 bits */
-       rxdmacfg.b_DMA2D  = 0;  /* N/A */
-       rxdmacfg.b_RESTART= 0;  /* N/A */
-       rxdmacfg.b_DI_SEL = 0;  /* N/A */
-       rxdmacfg.b_DI_EN  = 0;  /* no interrupt */
-       rxdmacfg.b_NDSIZE = 5;  /* 5 half words is desc size. */
-       rxdmacfg.b_FLOW   = 7;  /* large desc flow  */
-#endif
-
-const ADI_DMA_CONFIG_REG txdmacfg = { 1, 0, 2, 0, 0, 0, 0, 5, 7 };
-
-#if 0
-       txdmacfg.b_DMA_EN = 1;  /* enabled */
-       txdmacfg.b_WNR    = 0;  /* read from memory */
-       txdmacfg.b_WDSIZE = 2;  /* wordsize is 32 bits */
-       txdmacfg.b_DMA2D  = 0;  /* N/A */
-       txdmacfg.b_RESTART= 0;  /* N/A */
-       txdmacfg.b_DI_SEL = 0;  /* N/A */
-       txdmacfg.b_DI_EN  = 0;  /* no interrupt */
-       txdmacfg.b_NDSIZE = 5;  /* 5 half words is desc size. */
-       txdmacfg.b_FLOW   = 7;  /* large desc flow */
-#endif
-
-ADI_ETHER_BUFFER *SetupRxBuffer(int no);
-ADI_ETHER_BUFFER *SetupTxBuffer(int no);
-
-static int bfin_EMAC_init(struct eth_device *dev, bd_t * bd);
-static void bfin_EMAC_halt(struct eth_device *dev);
-static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet,
-                         int length);
-static int bfin_EMAC_recv(struct eth_device *dev);
-
-int bfin_EMAC_initialize(bd_t * bis)
-{
-       struct eth_device *dev;
-       dev = (struct eth_device *)malloc(sizeof(*dev));
-       if (dev == NULL)
-               hang();
-
-       memset(dev, 0, sizeof(*dev));
-       sprintf(dev->name, "BF537 ETHERNET");
-
-       dev->iobase = 0;
-       dev->priv = 0;
-       dev->init = bfin_EMAC_init;
-       dev->halt = bfin_EMAC_halt;
-       dev->send = bfin_EMAC_send;
-       dev->recv = bfin_EMAC_recv;
-
-       eth_register(dev);
-
-       return 1;
-}
-
-static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet,
-                         int length)
-{
-       int i;
-       int result = 0;
-       unsigned int *buf;
-       buf = (unsigned int *)packet;
-
-       if (length <= 0) {
-               printf("Ethernet: bad packet size: %d\n", length);
-               goto out;
-       }
-
-       if ((*pDMA2_IRQ_STATUS & DMA_ERR) != 0) {
-               printf("Ethernet: tx DMA error\n");
-               goto out;
-       }
-
-       for (i = 0; (*pDMA2_IRQ_STATUS & DMA_RUN) != 0; i++) {
-               if (i > TOUT_LOOP) {
-                       puts("Ethernet: tx time out\n");
-                       goto out;
-               }
-       }
-       txbuf[txIdx]->FrmData->NoBytes = length;
-       memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length);
-       txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData;
-       *pDMA2_NEXT_DESC_PTR = &txbuf[txIdx]->Dma[0];
-       *pDMA2_CONFIG = *(u16 *) (void *)(&txdmacfg);
-       *pEMAC_OPMODE |= TE;
-
-       for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) {
-               if (i > TOUT_LOOP) {
-                       puts("Ethernet: tx error\n");
-                       goto out;
-               }
-       }
-       result = txbuf[txIdx]->StatusWord;
-       txbuf[txIdx]->StatusWord = 0;
-       if ((txIdx + 1) >= TX_BUF_CNT)
-               txIdx = 0;
-       else
-               txIdx++;
-      out:
-       DEBUGF("BFIN EMAC send: length = %d\n", length);
-       return result;
-}
-
-static int bfin_EMAC_recv(struct eth_device *dev)
-{
-       int length = 0;
-
-       for (;;) {
-               if ((rxbuf[rxIdx]->StatusWord & RX_COMP) == 0) {
-                       length = -1;
-                       break;
-               }
-               if ((rxbuf[rxIdx]->StatusWord & RX_DMAO) != 0) {
-                       printf("Ethernet: rx dma overrun\n");
-                       break;
-               }
-               if ((rxbuf[rxIdx]->StatusWord & RX_OK) == 0) {
-                       printf("Ethernet: rx error\n");
-                       break;
-               }
-               length = rxbuf[rxIdx]->StatusWord & 0x000007FF;
-               if (length <= 4) {
-                       printf("Ethernet: bad frame\n");
-                       break;
-               }
-               NetRxPackets[rxIdx] =
-                   (volatile uchar *)(rxbuf[rxIdx]->FrmData->Dest);
-               NetReceive(NetRxPackets[rxIdx], length - 4);
-               *pDMA1_IRQ_STATUS |= DMA_DONE | DMA_ERR;
-               rxbuf[rxIdx]->StatusWord = 0x00000000;
-               if ((rxIdx + 1) >= PKTBUFSRX)
-                       rxIdx = 0;
-               else
-                       rxIdx++;
-       }
-
-       return length;
-}
-
-/**************************************************************
- *
- * Ethernet Initialization Routine
- *
- *************************************************************/
-
-static int bfin_EMAC_init(struct eth_device *dev, bd_t * bd)
-{
-       u32 opmode;
-       int dat;
-       int i;
-       DEBUGF("Eth_init: ......\n");
-
-       txIdx = 0;
-       rxIdx = 0;
-
-/* Initialize System Register */
-       if (SetupSystemRegs(&dat) < 0)
-               return -1;
-
-/* Initialize EMAC address */
-       SetupMacAddr(SrcAddr);
-
-/* Initialize TX and RX buffer */
-       for (i = 0; i < PKTBUFSRX; i++) {
-               rxbuf[i] = SetupRxBuffer(i);
-               if (i > 0) {
-                       rxbuf[i - 1]->Dma[1].NEXT_DESC_PTR =
-                           &(rxbuf[i]->Dma[0]);
-                       if (i == (PKTBUFSRX - 1))
-                               rxbuf[i]->Dma[1].NEXT_DESC_PTR =
-                                   &(rxbuf[0]->Dma[0]);
-               }
-       }
-       for (i = 0; i < TX_BUF_CNT; i++) {
-               txbuf[i] = SetupTxBuffer(i);
-               if (i > 0) {
-                       txbuf[i - 1]->Dma[1].NEXT_DESC_PTR =
-                           &(txbuf[i]->Dma[0]);
-                       if (i == (TX_BUF_CNT - 1))
-                               txbuf[i]->Dma[1].NEXT_DESC_PTR =
-                                   &(txbuf[0]->Dma[0]);
-               }
-       }
-
-       /* Set RX DMA */
-       *pDMA1_NEXT_DESC_PTR = &rxbuf[0]->Dma[0];
-       *pDMA1_CONFIG = *((u16 *) (void *)&rxbuf[0]->Dma[0].CONFIG);
-
-       /* Wait MII done */
-       PollMdcDone();
-
-       /* We enable only RX here */
-       /* ASTP   : Enable Automatic Pad Stripping
-          PR     : Promiscuous Mode for test
-          PSF    : Receive frames with total length less than 64 bytes.
-          FDMODE : Full Duplex Mode
-          LB     : Internal Loopback for test
-          RE     : Receiver Enable */
-       if (dat == FDMODE)
-               opmode = ASTP | FDMODE | PSF;
-       else
-               opmode = ASTP | PSF;
-       opmode |= RE;
-#ifdef CONFIG_BFIN_MAC_RMII
-       opmode |= TE | RMII;
-#endif
-       /* Turn on the EMAC */
-       *pEMAC_OPMODE = opmode;
-       return 0;
-}
-
-static void bfin_EMAC_halt(struct eth_device *dev)
-{
-       DEBUGF("Eth_halt: ......\n");
-       /* Turn off the EMAC */
-       *pEMAC_OPMODE = 0x00000000;
-       /* Turn off the EMAC RX DMA */
-       *pDMA1_CONFIG = 0x0000;
-       *pDMA2_CONFIG = 0x0000;
-
-}
-
-void SetupMacAddr(u8 * MACaddr)
-{
-       char *tmp, *end;
-       int i;
-       /* this depends on a little-endian machine */
-       tmp = getenv("ethaddr");
-       if (tmp) {
-               for (i = 0; i < 6; i++) {
-                       MACaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
-                       if (tmp)
-                               tmp = (*end) ? end + 1 : end;
-               }
-
-#ifndef CONFIG_NETCONSOLE
-               printf("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n",
-                      MACaddr[0], MACaddr[1],
-                      MACaddr[2], MACaddr[3], MACaddr[4], MACaddr[5]);
-#endif
-               *pEMAC_ADDRLO = MACaddr[0] | MACaddr[1] << 8 |
-                   MACaddr[2] << 16 | MACaddr[3] << 24;
-               *pEMAC_ADDRHI = MACaddr[4] | MACaddr[5] << 8;
-       }
-}
-
-void PollMdcDone(void)
-{
-       /* poll the STABUSY bit */
-       while (*pEMAC_STAADD & STABUSY) ;
-}
-
-void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data)
-{
-       PollMdcDone();
-
-       *pEMAC_STADAT = Data;
-
-       *pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) |
-           STAOP | STAIE | STABUSY;
-}
-
-/*********************************************************************************
- *             Read an off-chip register in a PHY through the MDC/MDIO port     *
- *********************************************************************************/
-u16 RdPHYReg(u16 PHYAddr, u16 RegAddr)
-{
-       u16 Data;
-
-       PollMdcDone();
-
-       *pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) |
-           STAIE | STABUSY;
-
-       PollMdcDone();
-
-       Data = (u16) * pEMAC_STADAT;
-
-       PHYregs[RegAddr] = Data;        /* save shadow copy */
-
-       return Data;
-}
-
-void SoftResetPHY(void)
-{
-       u16 phydat;
-       /* set the reset bit */
-       WrPHYReg(PHYADDR, PHY_MODECTL, PHY_RESET);
-       /* and clear it again */
-       WrPHYReg(PHYADDR, PHY_MODECTL, 0x0000);
-       do {
-               /* poll until reset is complete */
-               phydat = RdPHYReg(PHYADDR, PHY_MODECTL);
-       } while ((phydat & PHY_RESET) != 0);
-}
-
-int SetupSystemRegs(int *opmode)
-{
-       u16 sysctl, phydat;
-       int count = 0;
-       /* Enable PHY output */
-       *pVR_CTL |= CLKBUFOE;
-       /* MDC  = 2.5 MHz */
-       sysctl = SET_MDCDIV(24);
-       /* Odd word alignment for Receive Frame DMA word */
-       /* Configure checksum support and rcve frame word alignment */
-       sysctl |= RXDWA | RXCKS;
-       *pEMAC_SYSCTL = sysctl;
-       /* auto negotiation on  */
-       /* full duplex */
-       /* 100 Mbps */
-       phydat = PHY_ANEG_EN | PHY_DUPLEX | PHY_SPD_SET;
-       WrPHYReg(PHYADDR, PHY_MODECTL, phydat);
-       do {
-               udelay(1000);
-               phydat = RdPHYReg(PHYADDR, PHY_MODESTAT);
-               if (count > 3000) {
-                       printf
-                           ("Link is down, please check your network connection\n");
-                       return -1;
-               }
-               count++;
-       } while (!(phydat & 0x0004));
-
-       phydat = RdPHYReg(PHYADDR, PHY_ANLPAR);
-
-       if ((phydat & 0x0100) || (phydat & 0x0040))
-               *opmode = FDMODE;
-       else
-               *opmode = 0;
-
-       *pEMAC_MMC_CTL = RSTC | CROLL;
-
-       /* Initialize the TX DMA channel registers */
-       *pDMA2_X_COUNT = 0;
-       *pDMA2_X_MODIFY = 4;
-       *pDMA2_Y_COUNT = 0;
-       *pDMA2_Y_MODIFY = 0;
-
-       /* Initialize the RX DMA channel registers */
-       *pDMA1_X_COUNT = 0;
-       *pDMA1_X_MODIFY = 4;
-       *pDMA1_Y_COUNT = 0;
-       *pDMA1_Y_MODIFY = 0;
-       return 0;
-}
-
-ADI_ETHER_BUFFER *SetupRxBuffer(int no)
-{
-       ADI_ETHER_FRAME_BUFFER *frmbuf;
-       ADI_ETHER_BUFFER *buf;
-       int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2;   /* ensure a multi. of 4 */
-       int total_size = nobytes_buffer + RECV_BUFSIZE;
-
-       buf = (ADI_ETHER_BUFFER *) (RXBUF_BASE_ADDR + no * total_size);
-       frmbuf =
-           (ADI_ETHER_FRAME_BUFFER *) (RXBUF_BASE_ADDR + no * total_size +
-                                       nobytes_buffer);
-
-       memset(buf, 0x00, nobytes_buffer);
-       buf->FrmData = frmbuf;
-       memset(frmbuf, 0xfe, RECV_BUFSIZE);
-
-       /* set up first desc to point to receive frame buffer */
-       buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
-       buf->Dma[0].START_ADDR = (u32) buf->FrmData;
-       buf->Dma[0].CONFIG.b_DMA_EN = 1;        /* enabled */
-       buf->Dma[0].CONFIG.b_WNR = 1;   /* Write to memory */
-       buf->Dma[0].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
-       buf->Dma[0].CONFIG.b_NDSIZE = 5;        /* 5 half words is desc size. */
-       buf->Dma[0].CONFIG.b_FLOW = 7;  /* large desc flow */
-
-       /* set up second desc to point to status word */
-       buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
-       buf->Dma[1].START_ADDR = (u32) & buf->IPHdrChksum;
-       buf->Dma[1].CONFIG.b_DMA_EN = 1;        /* enabled */
-       buf->Dma[1].CONFIG.b_WNR = 1;   /* Write to memory */
-       buf->Dma[1].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
-       buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
-       buf->Dma[1].CONFIG.b_NDSIZE = 5;        /* must be 0 when FLOW is 0 */
-       buf->Dma[1].CONFIG.b_FLOW = 7;  /* stop */
-
-       return buf;
-}
-
-ADI_ETHER_BUFFER *SetupTxBuffer(int no)
-{
-       ADI_ETHER_FRAME_BUFFER *frmbuf;
-       ADI_ETHER_BUFFER *buf;
-       int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2;   /* ensure a multi. of 4 */
-       int total_size = nobytes_buffer + RECV_BUFSIZE;
-
-       buf = (ADI_ETHER_BUFFER *) (TXBUF_BASE_ADDR + no * total_size);
-       frmbuf =
-           (ADI_ETHER_FRAME_BUFFER *) (TXBUF_BASE_ADDR + no * total_size +
-                                       nobytes_buffer);
-
-       memset(buf, 0x00, nobytes_buffer);
-       buf->FrmData = frmbuf;
-       memset(frmbuf, 0x00, RECV_BUFSIZE);
-
-       /* set up first desc to point to receive frame buffer */
-       buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
-       buf->Dma[0].START_ADDR = (u32) buf->FrmData;
-       buf->Dma[0].CONFIG.b_DMA_EN = 1;        /* enabled */
-       buf->Dma[0].CONFIG.b_WNR = 0;   /* Read to memory */
-       buf->Dma[0].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
-       buf->Dma[0].CONFIG.b_NDSIZE = 5;        /* 5 half words is desc size. */
-       buf->Dma[0].CONFIG.b_FLOW = 7;  /* large desc flow */
-
-       /* set up second desc to point to status word */
-       buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
-       buf->Dma[1].START_ADDR = (u32) & buf->StatusWord;
-       buf->Dma[1].CONFIG.b_DMA_EN = 1;        /* enabled */
-       buf->Dma[1].CONFIG.b_WNR = 1;   /* Write to memory */
-       buf->Dma[1].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
-       buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
-       buf->Dma[1].CONFIG.b_NDSIZE = 0;        /* must be 0 when FLOW is 0 */
-       buf->Dma[1].CONFIG.b_FLOW = 0;  /* stop */
-
-       return buf;
-}
-
-#if defined(CONFIG_POST) && defined(CFG_POST_ETHER)
-int ether_post_test(int flags)
-{
-       uchar buf[64];
-       int i, value = 0;
-       int length;
-
-       printf("\n--------");
-       bfin_EMAC_init(NULL, NULL);
-       /* construct the package */
-       buf[0] = buf[6] = (unsigned char)(*pEMAC_ADDRLO & 0xFF);
-       buf[1] = buf[7] = (unsigned char)((*pEMAC_ADDRLO & 0xFF00) >> 8);
-       buf[2] = buf[8] = (unsigned char)((*pEMAC_ADDRLO & 0xFF0000) >> 16);
-       buf[3] = buf[9] = (unsigned char)((*pEMAC_ADDRLO & 0xFF000000) >> 24);
-       buf[4] = buf[10] = (unsigned char)(*pEMAC_ADDRHI & 0xFF);
-       buf[5] = buf[11] = (unsigned char)((*pEMAC_ADDRHI & 0xFF00) >> 8);
-       buf[12] = 0x08;         /* Type: ARP */
-       buf[13] = 0x06;
-       buf[14] = 0x00;         /* Hardware type: Ethernet */
-       buf[15] = 0x01;
-       buf[16] = 0x08;         /* Protocal type: IP */
-       buf[17] = 0x00;
-       buf[18] = 0x06;         /* Hardware size    */
-       buf[19] = 0x04;         /* Protocol size    */
-       buf[20] = 0x00;         /* Opcode: request  */
-       buf[21] = 0x01;
-
-       for (i = 0; i < 42; i++)
-               buf[i + 22] = i;
-       printf("--------Send 64 bytes......\n");
-       bfin_EMAC_send(NULL, (volatile void *)buf, 64);
-       for (i = 0; i < 100; i++) {
-               udelay(10000);
-               if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) {
-                       value = 1;
-                       break;
-               }
-       }
-       if (value == 0) {
-               printf("--------EMAC can't receive any data\n");
-               eth_halt();
-               return -1;
-       }
-       length = rxbuf[rxIdx]->StatusWord & 0x000007FF - 4;
-       for (i = 0; i < length; i++) {
-               if (rxbuf[rxIdx]->FrmData->Dest[i] != buf[i]) {
-                       printf("--------EMAC receive error data!\n");
-                       eth_halt();
-                       return -1;
-               }
-       }
-       printf("--------receive %d bytes, matched\n", length);
-       bfin_EMAC_halt(NULL);
-       return 0;
-}
-#endif
-#endif
diff --git a/board/bf537-stamp/ether_bf537.h b/board/bf537-stamp/ether_bf537.h
deleted file mode 100644 (file)
index 22fc392..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#define PHYADDR                        0x01
-#define NO_PHY_REGS            0x20
-
-#define DEFAULT_PHY_PHYID1     0x0007
-#define DEFAULT_PHY_PHYID2     0xC0A3
-#define PHY_MODECTL            0x00
-#define PHY_MODESTAT           0x01
-#define PHY_PHYID1             0x02
-#define PHY_PHYID2             0x03
-#define PHY_ANAR               0x04
-#define PHY_ANLPAR             0x05
-#define PHY_ANER               0x06
-
-#define PHY_RESET              0x8000
-#define PHY_ANEG_EN            0x1000
-#define PHY_DUPLEX             0x0100
-#define PHY_SPD_SET            0x2000
-
-#define RECV_BUFSIZE           (0x614)
-
-typedef volatile u32 reg32;
-typedef volatile u16 reg16;
-
-typedef struct ADI_DMA_CONFIG_REG {
-       u16 b_DMA_EN:1;         /* 0    Enabled                         */
-       u16 b_WNR:1;            /* 1    Direction                       */
-       u16 b_WDSIZE:2;         /* 2:3  Transfer word size              */
-       u16 b_DMA2D:1;          /* 4    DMA mode                        */
-       u16 b_RESTART:1;        /* 5    Retain FIFO                     */
-       u16 b_DI_SEL:1;         /* 6    Data interrupt timing select    */
-       u16 b_DI_EN:1;          /* 7    Data interrupt enabled          */
-       u16 b_NDSIZE:4;         /* 8:11 Flex descriptor size            */
-       u16 b_FLOW:3;           /* 12:14Flow                            */
-} ADI_DMA_CONFIG_REG;
-
-typedef struct adi_ether_frame_buffer {
-       u16 NoBytes;            /* the no. of following bytes   */
-       u8 Dest[6];             /* destination MAC address      */
-       u8 Srce[6];             /* source MAC address           */
-       u16 LTfield;            /* length/type field            */
-       u8 Data[0];             /* payload bytes                */
-} ADI_ETHER_FRAME_BUFFER;
-/* 16 bytes/struct     */
-
-typedef struct dma_descriptor {
-       struct dma_descriptor *NEXT_DESC_PTR;
-       u32 START_ADDR;
-       ADI_DMA_CONFIG_REG CONFIG;
-} DMA_DESCRIPTOR;
-/* 10 bytes/struct in 12 bytes */
-
-typedef struct adi_ether_buffer {
-       DMA_DESCRIPTOR Dma[2];          /* first for the frame, second for the status */
-       ADI_ETHER_FRAME_BUFFER *FrmData;/* pointer to data */
-       struct adi_ether_buffer *pNext; /* next buffer */
-       struct adi_ether_buffer *pPrev; /* prev buffer */
-       u16 IPHdrChksum;                /* the IP header checksum */
-       u16 IPPayloadChksum;            /* the IP header and payload checksum */
-       volatile u32 StatusWord;        /* the frame status word */
-} ADI_ETHER_BUFFER;
-/* 40 bytes/struct in 44 bytes */
-
-void SetupMacAddr(u8 * MACaddr);
-
-void PollMdcDone(void);
-void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data);
-u16 RdPHYReg(u16 PHYAddr, u16 RegAddr);
-void SoftResetPHY(void);
-void DumpPHYRegs(void);
-
-int SetupSystemRegs(int *opmode);
index b9723fa78f20e3fc023dd353a206ed6ec45bc597..321bd08adb6b96976ca405b49e96fef03f847d8b 100644 (file)
@@ -27,6 +27,7 @@ LIB   := $(obj)libnet.a
 
 COBJS-y += 3c589.o
 COBJS-y += bcm570x.o bcm570x_autoneg.o 5701rls.o
+COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o
 COBJS-y += cs8900.o
 COBJS-y += dc2114x.o
 COBJS-y += dm9000x.o
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
new file mode 100644 (file)
index 0000000..afe122a
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * Driver for Blackfin On-Chip MAC device
+ *
+ * Copyright (c) 2005-2008 Analog Device, Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <net.h>
+#include <command.h>
+#include <malloc.h>
+
+#include <asm/blackfin.h>
+#include <asm/mach-common/bits/dma.h>
+#include <asm/mach-common/bits/emac.h>
+#include <asm/mach-common/bits/pll.h>
+
+#include "bfin_mac.h"
+
+#ifdef CONFIG_POST
+#include <post.h>
+#endif
+
+#undef DEBUG_ETHERNET
+
+#ifdef DEBUG_ETHERNET
+#define DEBUGF(fmt, args...) printf(fmt, ##args)
+#else
+#define DEBUGF(fmt, args...)
+#endif
+
+#define RXBUF_BASE_ADDR                0xFF900000
+#define TXBUF_BASE_ADDR                0xFF800000
+#define TX_BUF_CNT             1
+
+#define TOUT_LOOP              1000000
+
+ADI_ETHER_BUFFER *txbuf[TX_BUF_CNT];
+ADI_ETHER_BUFFER *rxbuf[PKTBUFSRX];
+static u16 txIdx;              /* index of the current RX buffer */
+static u16 rxIdx;              /* index of the current TX buffer */
+
+u16 PHYregs[NO_PHY_REGS];      /* u16 PHYADDR; */
+
+/* DMAx_CONFIG values at DMA Restart */
+const ADI_DMA_CONFIG_REG rxdmacfg = {
+       .b_DMA_EN  = 1, /* enabled */
+       .b_WNR     = 1, /* write to memory */
+       .b_WDSIZE  = 2, /* wordsize is 32 bits */
+       .b_DMA2D   = 0,
+       .b_RESTART = 0,
+       .b_DI_SEL  = 0,
+       .b_DI_EN   = 0, /* no interrupt */
+       .b_NDSIZE  = 5, /* 5 half words is desc size */
+       .b_FLOW    = 7  /* large desc flow */
+};
+
+const ADI_DMA_CONFIG_REG txdmacfg = {
+       .b_DMA_EN  = 1, /* enabled */
+       .b_WNR     = 0, /* read from memory */
+       .b_WDSIZE  = 2, /* wordsize is 32 bits */
+       .b_DMA2D   = 0,
+       .b_RESTART = 0,
+       .b_DI_SEL  = 0,
+       .b_DI_EN   = 0, /* no interrupt */
+       .b_NDSIZE  = 5, /* 5 half words is desc size */
+       .b_FLOW    = 7  /* large desc flow */
+};
+
+int bfin_EMAC_initialize(bd_t *bis)
+{
+       struct eth_device *dev;
+       dev = (struct eth_device *)malloc(sizeof(*dev));
+       if (dev == NULL)
+               hang();
+
+       memset(dev, 0, sizeof(*dev));
+       sprintf(dev->name, "Blackfin EMAC");
+
+       dev->iobase = 0;
+       dev->priv = 0;
+       dev->init = bfin_EMAC_init;
+       dev->halt = bfin_EMAC_halt;
+       dev->send = bfin_EMAC_send;
+       dev->recv = bfin_EMAC_recv;
+
+       eth_register(dev);
+
+       return 1;
+}
+
+static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet,
+                         int length)
+{
+       int i;
+       int result = 0;
+       unsigned int *buf;
+       buf = (unsigned int *)packet;
+
+       if (length <= 0) {
+               printf("Ethernet: bad packet size: %d\n", length);
+               goto out;
+       }
+
+       if ((*pDMA2_IRQ_STATUS & DMA_ERR) != 0) {
+               printf("Ethernet: tx DMA error\n");
+               goto out;
+       }
+
+       for (i = 0; (*pDMA2_IRQ_STATUS & DMA_RUN) != 0; i++) {
+               if (i > TOUT_LOOP) {
+                       puts("Ethernet: tx time out\n");
+                       goto out;
+               }
+       }
+       txbuf[txIdx]->FrmData->NoBytes = length;
+       memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length);
+       txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData;
+       *pDMA2_NEXT_DESC_PTR = &txbuf[txIdx]->Dma[0];
+       *pDMA2_CONFIG = *(u16 *) (void *)(&txdmacfg);
+       *pEMAC_OPMODE |= TE;
+
+       for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) {
+               if (i > TOUT_LOOP) {
+                       puts("Ethernet: tx error\n");
+                       goto out;
+               }
+       }
+       result = txbuf[txIdx]->StatusWord;
+       txbuf[txIdx]->StatusWord = 0;
+       if ((txIdx + 1) >= TX_BUF_CNT)
+               txIdx = 0;
+       else
+               txIdx++;
+ out:
+       DEBUGF("BFIN EMAC send: length = %d\n", length);
+       return result;
+}
+
+static int bfin_EMAC_recv(struct eth_device *dev)
+{
+       int length = 0;
+
+       for (;;) {
+               if ((rxbuf[rxIdx]->StatusWord & RX_COMP) == 0) {
+                       length = -1;
+                       break;
+               }
+               if ((rxbuf[rxIdx]->StatusWord & RX_DMAO) != 0) {
+                       printf("Ethernet: rx dma overrun\n");
+                       break;
+               }
+               if ((rxbuf[rxIdx]->StatusWord & RX_OK) == 0) {
+                       printf("Ethernet: rx error\n");
+                       break;
+               }
+               length = rxbuf[rxIdx]->StatusWord & 0x000007FF;
+               if (length <= 4) {
+                       printf("Ethernet: bad frame\n");
+                       break;
+               }
+               NetRxPackets[rxIdx] =
+                   (volatile uchar *)(rxbuf[rxIdx]->FrmData->Dest);
+               NetReceive(NetRxPackets[rxIdx], length - 4);
+               *pDMA1_IRQ_STATUS |= DMA_DONE | DMA_ERR;
+               rxbuf[rxIdx]->StatusWord = 0x00000000;
+               if ((rxIdx + 1) >= PKTBUFSRX)
+                       rxIdx = 0;
+               else
+                       rxIdx++;
+       }
+
+       return length;
+}
+
+/**************************************************************
+ *
+ * Ethernet Initialization Routine
+ *
+ *************************************************************/
+
+static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd)
+{
+       u32 opmode;
+       int dat;
+       int i;
+       DEBUGF("Eth_init: ......\n");
+
+       txIdx = 0;
+       rxIdx = 0;
+
+/* Initialize System Register */
+       if (SetupSystemRegs(&dat) < 0)
+               return -1;
+
+/* Initialize EMAC address */
+       bfin_EMAC_setup_addr(bd);
+
+/* Initialize TX and RX buffer */
+       for (i = 0; i < PKTBUFSRX; i++) {
+               rxbuf[i] = SetupRxBuffer(i);
+               if (i > 0) {
+                       rxbuf[i - 1]->Dma[1].NEXT_DESC_PTR =
+                           &(rxbuf[i]->Dma[0]);
+                       if (i == (PKTBUFSRX - 1))
+                               rxbuf[i]->Dma[1].NEXT_DESC_PTR =
+                                   &(rxbuf[0]->Dma[0]);
+               }
+       }
+       for (i = 0; i < TX_BUF_CNT; i++) {
+               txbuf[i] = SetupTxBuffer(i);
+               if (i > 0) {
+                       txbuf[i - 1]->Dma[1].NEXT_DESC_PTR =
+                           &(txbuf[i]->Dma[0]);
+                       if (i == (TX_BUF_CNT - 1))
+                               txbuf[i]->Dma[1].NEXT_DESC_PTR =
+                                   &(txbuf[0]->Dma[0]);
+               }
+       }
+
+       /* Set RX DMA */
+       *pDMA1_NEXT_DESC_PTR = &rxbuf[0]->Dma[0];
+       *pDMA1_CONFIG = *((u16 *) (void *)&rxbuf[0]->Dma[0].CONFIG);
+
+       /* Wait MII done */
+       PollMdcDone();
+
+       /* We enable only RX here */
+       /* ASTP   : Enable Automatic Pad Stripping
+          PR     : Promiscuous Mode for test
+          PSF    : Receive frames with total length less than 64 bytes.
+          FDMODE : Full Duplex Mode
+          LB     : Internal Loopback for test
+          RE     : Receiver Enable */
+       if (dat == FDMODE)
+               opmode = ASTP | FDMODE | PSF;
+       else
+               opmode = ASTP | PSF;
+       opmode |= RE;
+#ifdef CONFIG_BFIN_MAC_RMII
+       opmode |= TE | RMII;
+#endif
+       /* Turn on the EMAC */
+       *pEMAC_OPMODE = opmode;
+       return 0;
+}
+
+static void bfin_EMAC_halt(struct eth_device *dev)
+{
+       DEBUGF("Eth_halt: ......\n");
+       /* Turn off the EMAC */
+       *pEMAC_OPMODE = 0x00000000;
+       /* Turn off the EMAC RX DMA */
+       *pDMA1_CONFIG = 0x0000;
+       *pDMA2_CONFIG = 0x0000;
+
+}
+
+void bfin_EMAC_setup_addr(bd_t *bd)
+{
+       *pEMAC_ADDRLO =
+               bd->bi_enetaddr[0] |
+               bd->bi_enetaddr[1] << 8 |
+               bd->bi_enetaddr[2] << 16 |
+               bd->bi_enetaddr[3] << 24;
+       *pEMAC_ADDRHI =
+               bd->bi_enetaddr[4] |
+               bd->bi_enetaddr[5] << 8;
+}
+
+static void PollMdcDone(void)
+{
+       /* poll the STABUSY bit */
+       while (*pEMAC_STAADD & STABUSY) ;
+}
+
+static void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data)
+{
+       PollMdcDone();
+
+       *pEMAC_STADAT = Data;
+
+       *pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) |
+           STAOP | STAIE | STABUSY;
+}
+
+/*********************************************************************************
+ *             Read an off-chip register in a PHY through the MDC/MDIO port     *
+ *********************************************************************************/
+static u16 RdPHYReg(u16 PHYAddr, u16 RegAddr)
+{
+       u16 Data;
+
+       PollMdcDone();
+
+       *pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) |
+           STAIE | STABUSY;
+
+       PollMdcDone();
+
+       Data = (u16) * pEMAC_STADAT;
+
+       PHYregs[RegAddr] = Data;        /* save shadow copy */
+
+       return Data;
+}
+
+#if 0 /* dead code ? */
+static void SoftResetPHY(void)
+{
+       u16 phydat;
+       /* set the reset bit */
+       WrPHYReg(PHYADDR, PHY_MODECTL, PHY_RESET);
+       /* and clear it again */
+       WrPHYReg(PHYADDR, PHY_MODECTL, 0x0000);
+       do {
+               /* poll until reset is complete */
+               phydat = RdPHYReg(PHYADDR, PHY_MODECTL);
+       } while ((phydat & PHY_RESET) != 0);
+}
+#endif
+
+static int SetupSystemRegs(int *opmode)
+{
+       u16 sysctl, phydat;
+       int count = 0;
+       /* Enable PHY output */
+       *pVR_CTL |= CLKBUFOE;
+       /* Set all the pins to peripheral mode */
+
+#ifndef CONFIG_BFIN_MAC_RMII
+       *pPORTH_FER = 0xFFFF;
+#ifdef __ADSPBF52x__
+       *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2;
+#endif
+#else
+#if defined(__ADSPBF536__) || defined(__ADSPBF537__)
+       *pPORTH_FER = 0xC373;
+#endif
+#ifdef __ADSPBF52x__
+       *pPORTH_FER = 0x01FF;
+       *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2;
+#endif
+#endif
+       /* MDC  = 2.5 MHz */
+       sysctl = SET_MDCDIV(24);
+       /* Odd word alignment for Receive Frame DMA word */
+       /* Configure checksum support and rcve frame word alignment */
+       sysctl |= RXDWA | RXCKS;
+       *pEMAC_SYSCTL = sysctl;
+       /* auto negotiation on  */
+       /* full duplex */
+       /* 100 Mbps */
+       phydat = PHY_ANEG_EN | PHY_DUPLEX | PHY_SPD_SET;
+       WrPHYReg(PHYADDR, PHY_MODECTL, phydat);
+       do {
+               udelay(1000);
+               phydat = RdPHYReg(PHYADDR, PHY_MODESTAT);
+               if (count > 3000) {
+                       printf
+                           ("Link is down, please check your network connection\n");
+                       return -1;
+               }
+               count++;
+       } while (!(phydat & 0x0004));
+
+       phydat = RdPHYReg(PHYADDR, PHY_ANLPAR);
+
+       if ((phydat & 0x0100) || (phydat & 0x0040))
+               *opmode = FDMODE;
+       else
+               *opmode = 0;
+
+       *pEMAC_MMC_CTL = RSTC | CROLL;
+
+       /* Initialize the TX DMA channel registers */
+       *pDMA2_X_COUNT = 0;
+       *pDMA2_X_MODIFY = 4;
+       *pDMA2_Y_COUNT = 0;
+       *pDMA2_Y_MODIFY = 0;
+
+       /* Initialize the RX DMA channel registers */
+       *pDMA1_X_COUNT = 0;
+       *pDMA1_X_MODIFY = 4;
+       *pDMA1_Y_COUNT = 0;
+       *pDMA1_Y_MODIFY = 0;
+       return 0;
+}
+
+ADI_ETHER_BUFFER *SetupRxBuffer(int no)
+{
+       ADI_ETHER_FRAME_BUFFER *frmbuf;
+       ADI_ETHER_BUFFER *buf;
+       int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2;   /* ensure a multi. of 4 */
+       int total_size = nobytes_buffer + RECV_BUFSIZE;
+
+       buf = (ADI_ETHER_BUFFER *) (RXBUF_BASE_ADDR + no * total_size);
+       frmbuf =
+           (ADI_ETHER_FRAME_BUFFER *) (RXBUF_BASE_ADDR + no * total_size +
+                                       nobytes_buffer);
+
+       memset(buf, 0x00, nobytes_buffer);
+       buf->FrmData = frmbuf;
+       memset(frmbuf, 0xfe, RECV_BUFSIZE);
+
+       /* set up first desc to point to receive frame buffer */
+       buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
+       buf->Dma[0].START_ADDR = (u32) buf->FrmData;
+       buf->Dma[0].CONFIG.b_DMA_EN = 1;        /* enabled */
+       buf->Dma[0].CONFIG.b_WNR = 1;   /* Write to memory */
+       buf->Dma[0].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
+       buf->Dma[0].CONFIG.b_NDSIZE = 5;        /* 5 half words is desc size. */
+       buf->Dma[0].CONFIG.b_FLOW = 7;  /* large desc flow */
+
+       /* set up second desc to point to status word */
+       buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
+       buf->Dma[1].START_ADDR = (u32) & buf->IPHdrChksum;
+       buf->Dma[1].CONFIG.b_DMA_EN = 1;        /* enabled */
+       buf->Dma[1].CONFIG.b_WNR = 1;   /* Write to memory */
+       buf->Dma[1].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
+       buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
+       buf->Dma[1].CONFIG.b_NDSIZE = 5;        /* must be 0 when FLOW is 0 */
+       buf->Dma[1].CONFIG.b_FLOW = 7;  /* stop */
+
+       return buf;
+}
+
+ADI_ETHER_BUFFER *SetupTxBuffer(int no)
+{
+       ADI_ETHER_FRAME_BUFFER *frmbuf;
+       ADI_ETHER_BUFFER *buf;
+       int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2;   /* ensure a multi. of 4 */
+       int total_size = nobytes_buffer + RECV_BUFSIZE;
+
+       buf = (ADI_ETHER_BUFFER *) (TXBUF_BASE_ADDR + no * total_size);
+       frmbuf =
+           (ADI_ETHER_FRAME_BUFFER *) (TXBUF_BASE_ADDR + no * total_size +
+                                       nobytes_buffer);
+
+       memset(buf, 0x00, nobytes_buffer);
+       buf->FrmData = frmbuf;
+       memset(frmbuf, 0x00, RECV_BUFSIZE);
+
+       /* set up first desc to point to receive frame buffer */
+       buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
+       buf->Dma[0].START_ADDR = (u32) buf->FrmData;
+       buf->Dma[0].CONFIG.b_DMA_EN = 1;        /* enabled */
+       buf->Dma[0].CONFIG.b_WNR = 0;   /* Read to memory */
+       buf->Dma[0].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
+       buf->Dma[0].CONFIG.b_NDSIZE = 5;        /* 5 half words is desc size. */
+       buf->Dma[0].CONFIG.b_FLOW = 7;  /* large desc flow */
+
+       /* set up second desc to point to status word */
+       buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
+       buf->Dma[1].START_ADDR = (u32) & buf->StatusWord;
+       buf->Dma[1].CONFIG.b_DMA_EN = 1;        /* enabled */
+       buf->Dma[1].CONFIG.b_WNR = 1;   /* Write to memory */
+       buf->Dma[1].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
+       buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
+       buf->Dma[1].CONFIG.b_NDSIZE = 0;        /* must be 0 when FLOW is 0 */
+       buf->Dma[1].CONFIG.b_FLOW = 0;  /* stop */
+
+       return buf;
+}
+
+#if defined(CONFIG_POST) && defined(CFG_POST_ETHER)
+int ether_post_test(int flags)
+{
+       uchar buf[64];
+       int i, value = 0;
+       int length;
+
+       printf("\n--------");
+       bfin_EMAC_init(NULL, NULL);
+       /* construct the package */
+       buf[0] = buf[6] = (unsigned char)(*pEMAC_ADDRLO & 0xFF);
+       buf[1] = buf[7] = (unsigned char)((*pEMAC_ADDRLO & 0xFF00) >> 8);
+       buf[2] = buf[8] = (unsigned char)((*pEMAC_ADDRLO & 0xFF0000) >> 16);
+       buf[3] = buf[9] = (unsigned char)((*pEMAC_ADDRLO & 0xFF000000) >> 24);
+       buf[4] = buf[10] = (unsigned char)(*pEMAC_ADDRHI & 0xFF);
+       buf[5] = buf[11] = (unsigned char)((*pEMAC_ADDRHI & 0xFF00) >> 8);
+       buf[12] = 0x08;         /* Type: ARP */
+       buf[13] = 0x06;
+       buf[14] = 0x00;         /* Hardware type: Ethernet */
+       buf[15] = 0x01;
+       buf[16] = 0x08;         /* Protocal type: IP */
+       buf[17] = 0x00;
+       buf[18] = 0x06;         /* Hardware size    */
+       buf[19] = 0x04;         /* Protocol size    */
+       buf[20] = 0x00;         /* Opcode: request  */
+       buf[21] = 0x01;
+
+       for (i = 0; i < 42; i++)
+               buf[i + 22] = i;
+       printf("--------Send 64 bytes......\n");
+       bfin_EMAC_send(NULL, (volatile void *)buf, 64);
+       for (i = 0; i < 100; i++) {
+               udelay(10000);
+               if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) {
+                       value = 1;
+                       break;
+               }
+       }
+       if (value == 0) {
+               printf("--------EMAC can't receive any data\n");
+               eth_halt();
+               return -1;
+       }
+       length = rxbuf[rxIdx]->StatusWord & 0x000007FF - 4;
+       for (i = 0; i < length; i++) {
+               if (rxbuf[rxIdx]->FrmData->Dest[i] != buf[i]) {
+                       printf("--------EMAC receive error data!\n");
+                       eth_halt();
+                       return -1;
+               }
+       }
+       printf("--------receive %d bytes, matched\n", length);
+       bfin_EMAC_halt(NULL);
+       return 0;
+}
+#endif
diff --git a/drivers/net/bfin_mac.h b/drivers/net/bfin_mac.h
new file mode 100644 (file)
index 0000000..c8a94d0
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * bfin_mac.h - some defines/structures for the Blackfin on-chip MAC.
+ *
+ * Copyright (c) 2005-2008 Analog Device, Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_MAC_H__
+#define __BFIN_MAC_H__
+
+#define PHYADDR                        0x01
+#define NO_PHY_REGS            0x20
+
+#define DEFAULT_PHY_PHYID1     0x0007
+#define DEFAULT_PHY_PHYID2     0xC0A3
+#define PHY_MODECTL            0x00
+#define PHY_MODESTAT           0x01
+#define PHY_PHYID1             0x02
+#define PHY_PHYID2             0x03
+#define PHY_ANAR               0x04
+#define PHY_ANLPAR             0x05
+#define PHY_ANER               0x06
+
+#define PHY_RESET              0x8000
+#define PHY_ANEG_EN            0x1000
+#define PHY_DUPLEX             0x0100
+#define PHY_SPD_SET            0x2000
+
+#define RECV_BUFSIZE           (0x614)
+
+typedef volatile u32 reg32;
+typedef volatile u16 reg16;
+
+typedef struct ADI_DMA_CONFIG_REG {
+       u16 b_DMA_EN:1;         /* 0    Enabled                         */
+       u16 b_WNR:1;            /* 1    Direction                       */
+       u16 b_WDSIZE:2;         /* 2:3  Transfer word size              */
+       u16 b_DMA2D:1;          /* 4    DMA mode                        */
+       u16 b_RESTART:1;        /* 5    Retain FIFO                     */
+       u16 b_DI_SEL:1;         /* 6    Data interrupt timing select    */
+       u16 b_DI_EN:1;          /* 7    Data interrupt enabled          */
+       u16 b_NDSIZE:4;         /* 8:11 Flex descriptor size            */
+       u16 b_FLOW:3;           /* 12:14Flow                            */
+} ADI_DMA_CONFIG_REG;
+
+typedef struct adi_ether_frame_buffer {
+       u16 NoBytes;            /* the no. of following bytes   */
+       u8 Dest[6];             /* destination MAC address      */
+       u8 Srce[6];             /* source MAC address           */
+       u16 LTfield;            /* length/type field            */
+       u8 Data[0];             /* payload bytes                */
+} ADI_ETHER_FRAME_BUFFER;
+/* 16 bytes/struct     */
+
+typedef struct dma_descriptor {
+       struct dma_descriptor *NEXT_DESC_PTR;
+       u32 START_ADDR;
+       ADI_DMA_CONFIG_REG CONFIG;
+} DMA_DESCRIPTOR;
+/* 10 bytes/struct in 12 bytes */
+
+typedef struct adi_ether_buffer {
+       DMA_DESCRIPTOR Dma[2];          /* first for the frame, second for the status */
+       ADI_ETHER_FRAME_BUFFER *FrmData;/* pointer to data */
+       struct adi_ether_buffer *pNext; /* next buffer */
+       struct adi_ether_buffer *pPrev; /* prev buffer */
+       u16 IPHdrChksum;                /* the IP header checksum */
+       u16 IPPayloadChksum;            /* the IP header and payload checksum */
+       volatile u32 StatusWord;        /* the frame status word */
+} ADI_ETHER_BUFFER;
+/* 40 bytes/struct in 44 bytes */
+
+static ADI_ETHER_BUFFER *SetupRxBuffer(int no);
+static ADI_ETHER_BUFFER *SetupTxBuffer(int no);
+
+static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd);
+static void bfin_EMAC_halt(struct eth_device *dev);
+static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet, int length);
+static int bfin_EMAC_recv(struct eth_device *dev);
+
+static void PollMdcDone(void);
+static void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data);
+static u16 RdPHYReg(u16 PHYAddr, u16 RegAddr);
+static int SetupSystemRegs(int *opmode);
+
+static void bfin_EMAC_setup_addr(bd_t *bd);
+
+#endif