[U-Boot] [PATCH] Add support for Faraday Ethernet IP FTMAC100
PoYu_Chuang
ratbert at ftcpcw82.faraday.com.tw
Tue Mar 31 10:13:11 CEST 2009
This patch adds support for Faraday Technology Ethernet IP - FTMAC100
Signed-off-by: Po-Yu Chuang <ratbert at faraday-tech.com>
---
diff -ruN u-boot-2009.03/drivers/net/ftmac100.c FA5A320LINUX26_u-boot/drivers/net/ftmac100.c
--- u-boot-2009.03/drivers/net/ftmac100.c 1970-01-01 08:00:00.000000000 +0800
+++ FA5A320LINUX26_u-boot/drivers/net/ftmac100.c 2009-03-31 15:20:33.000000000 +0800
@@ -0,0 +1,219 @@
+/*
+ * Faraday FTMAC100 Ethernet
+ *
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert at faraday-tech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#undef DEBUG
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+#include <asm/io.h>
+#include "ftmac100.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static unsigned int ftmac100_base = CONFIG_SYS_MAC100_BASE;
+
+static volatile struct ftmac100_txdes txdes[1];
+static volatile struct ftmac100_rxdes rxdes[PKTBUFSRX];
+static int rx_index;
+
+/*
+ * Reset MAC
+ */
+static void
+ftmac100_reset(void)
+{
+ debug("ftmac100_reset()\n");
+
+ outl(FTMAC100_MACCR_SW_RST, ftmac100_base + FTMAC100_OFFSET_MACCR);
+
+ while (inl(ftmac100_base + FTMAC100_OFFSET_MACCR) & FTMAC100_MACCR_SW_RST);
+}
+
+/*
+ * Set MAC address
+ */
+static void
+ftmac100_set_mac(const unsigned char *mac)
+{
+ unsigned short maddr = mac[0] << 8 | mac[1];
+ unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
+
+ debug("ftmac100_set_mac()\n");
+
+ outl(maddr, ftmac100_base + FTMAC100_OFFSET_MAC_MADR);
+ outl(laddr, ftmac100_base + FTMAC100_OFFSET_MAC_LADR);
+}
+
+/*
+ * disable transmitter, receiver
+ */
+void
+eth_halt(void)
+{
+ debug("eth_halt()\n");
+
+ outl(0, ftmac100_base + FTMAC100_OFFSET_MACCR);
+}
+
+int
+eth_init(bd_t *bd)
+{
+ int i;
+ unsigned int maccr;
+
+ debug("eth_init()\n");
+
+ ftmac100_reset();
+
+ /* set the ethernet address */
+
+ ftmac100_set_mac(gd->bd->bi_enetaddr);
+
+ /* disable all interrupts */
+
+ outl(0, ftmac100_base + FTMAC100_OFFSET_IMR);
+
+ /* initialize descriptors */
+
+ rx_index = 0;
+
+ txdes[0].txdes1 = FTMAC100_TXDES1_EDOTR;
+ rxdes[PKTBUFSRX - 1].rxdes1 = FTMAC100_RXDES1_EDORR;
+
+ for (i = 0; i < PKTBUFSRX; i++) {
+ rxdes[i].rxdes2 = (unsigned int)NetRxPackets[i]; /* RXBUF_BADR */
+ rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE(PKTSIZE_ALIGN);
+ rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN;
+ }
+
+ /* transmit ring */
+
+ outl(txdes, ftmac100_base + FTMAC100_OFFSET_TXR_BADR);
+
+ /* receive ring */
+
+ outl(rxdes, ftmac100_base + FTMAC100_OFFSET_RXR_BADR);
+
+ /* poll receive descriptor automatically */
+
+ outl(FTMAC100_APTC_RXPOLL_CNT(1), ftmac100_base + FTMAC100_OFFSET_APTC);
+
+ /* enable transmitter, receiver */
+
+ maccr = FTMAC100_MACCR_XMT_EN
+ | FTMAC100_MACCR_RCV_EN
+ | FTMAC100_MACCR_XDMA_EN
+ | FTMAC100_MACCR_RDMA_EN
+ | FTMAC100_MACCR_CRC_APD
+ | FTMAC100_MACCR_ENRX_IN_HALFTX
+ | FTMAC100_MACCR_RX_RUNT
+ | FTMAC100_MACCR_RX_BROADPKT;
+
+ outl(maccr, ftmac100_base + FTMAC100_OFFSET_MACCR);
+
+ return 0;
+}
+
+/*
+ * Get a data block via Ethernet
+ */
+int
+eth_rx(void)
+{
+ volatile struct ftmac100_rxdes *curr_des = &rxdes[rx_index];
+ unsigned short rxlen;
+
+ if (curr_des->rxdes0 & FTMAC100_RXDES0_RXDMA_OWN) {
+ return -1;
+ }
+
+ if (curr_des->rxdes0 & ( FTMAC100_RXDES0_RX_ERR
+ | FTMAC100_RXDES0_CRC_ERR
+ | FTMAC100_RXDES0_FTL
+ | FTMAC100_RXDES0_RUNT
+ | FTMAC100_RXDES0_RX_ODD_NB)) {
+ return -1;
+ }
+
+ rxlen = FTMAC100_RXDES0_RFL(curr_des->rxdes0);
+
+ debug("eth_rx(): RX buffer %d, %x received\n", rx_index, rxlen);
+
+ /* pass the packet up to the protocol layers. */
+
+ NetReceive((void *)curr_des->rxdes2, rxlen);
+
+ /* release buffer to DMA */
+
+ curr_des->rxdes0 |= FTMAC100_RXDES0_RXDMA_OWN;
+
+ rx_index = (rx_index + 1) % PKTBUFSRX;
+
+ return 0;
+}
+
+/*
+ * Send a data block via Ethernet
+ */
+int
+eth_send(volatile void *packet, int length)
+{
+ volatile struct ftmac100_txdes *curr_des = txdes;
+ int tmo;
+
+ if (curr_des->txdes0 & FTMAC100_TXDES0_TXPKT_TXDMA_OWN) {
+ debug("eth_send(): no TX descriptor available\n");
+ return -1;
+ }
+
+ debug("eth_send(%x, %x)\n", (int)packet, length);
+
+ /* initiate a transmit sequence */
+
+ curr_des->txdes2 = (unsigned int)packet; /* TXBUF_BADR */
+
+ curr_des->txdes1 &= FTMAC100_TXDES1_EDOTR;
+ curr_des->txdes1 |= FTMAC100_TXDES1_FTS
+ | FTMAC100_TXDES1_LTS
+ | FTMAC100_TXDES1_TXBUF_SIZE((length < 64) ? 64 : length);
+
+ curr_des->txdes0 = FTMAC100_TXDES0_TXPKT_TXDMA_OWN;
+
+ /* start transmit */
+
+ outl(1, ftmac100_base + FTMAC100_OFFSET_TXPD);
+
+ /* wait for transfer to succeed */
+
+ tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
+ while (curr_des->txdes0 & FTMAC100_TXDES0_TXPKT_TXDMA_OWN) {
+ if (get_timer(0) >= tmo) {
+ debug("eth_send(): timed out\n");
+ return -1;
+ }
+ }
+
+ debug("eth_send(): packet sent\n");
+
+ return 0;
+}
+
diff -ruN u-boot-2009.03/drivers/net/ftmac100.h FA5A320LINUX26_u-boot/drivers/net/ftmac100.h
--- u-boot-2009.03/drivers/net/ftmac100.h 1970-01-01 08:00:00.000000000 +0800
+++ FA5A320LINUX26_u-boot/drivers/net/ftmac100.h 2009-03-31 15:49:05.000000000 +0800
@@ -0,0 +1,146 @@
+/*
+ * Faraday FTMAC100 Ethernet
+ *
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert at faraday-tech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __FTMAC100_H
+#define __FTMAC100_H
+
+#define FTMAC100_OFFSET_ISR 0x00
+#define FTMAC100_OFFSET_IMR 0x04
+#define FTMAC100_OFFSET_MAC_MADR 0x08
+#define FTMAC100_OFFSET_MAC_LADR 0x0c
+#define FTMAC100_OFFSET_MAHT0 0x10
+#define FTMAC100_OFFSET_MAHT1 0x14
+#define FTMAC100_OFFSET_TXPD 0x18
+#define FTMAC100_OFFSET_RXPD 0x1c
+#define FTMAC100_OFFSET_TXR_BADR 0x20
+#define FTMAC100_OFFSET_RXR_BADR 0x24
+#define FTMAC100_OFFSET_ITC 0x28
+#define FTMAC100_OFFSET_APTC 0x2c
+#define FTMAC100_OFFSET_DBLAC 0x30
+#define FTMAC100_OFFSET_MACCR 0x88
+#define FTMAC100_OFFSET_MACSR 0x8c
+#define FTMAC100_OFFSET_PHYCR 0x90
+#define FTMAC100_OFFSET_PHYWDATA 0x94
+#define FTMAC100_OFFSET_FCR 0x98
+#define FTMAC100_OFFSET_BPR 0x9c
+#define FTMAC100_OFFSET_TS 0xc4
+#define FTMAC100_OFFSET_DMAFIFOS 0xc8
+#define FTMAC100_OFFSET_TM 0xcc
+#define FTMAC100_OFFSET_TX_MCOL_SCOL 0xd4
+#define FTMAC100_OFFSET_RPF_AEP 0xd8
+#define FTMAC100_OFFSET_XM_PG 0xdc
+#define FTMAC100_OFFSET_RUNT_TLCC 0xe0
+#define FTMAC100_OFFSET_CRCER_FTL 0xe4
+#define FTMAC100_OFFSET_RLC_RCC 0xe8
+#define FTMAC100_OFFSET_BROC 0xec
+#define FTMAC100_OFFSET_MULCA 0xf0
+#define FTMAC100_OFFSET_RP 0xf4
+#define FTMAC100_OFFSET_XP 0xf8
+
+/*
+ * Interrupt status register & interrupt mask register
+ */
+#define FTMAC100_INT_RPKT_FINISH (1 << 0)
+#define FTMAC100_INT_NORXBUF (1 << 1)
+#define FTMAC100_INT_XPKT_FINISH (1 << 2)
+#define FTMAC100_INT_NOTXBUF (1 << 3)
+#define FTMAC100_INT_XPKT_OK (1 << 4)
+#define FTMAC100_INT_XPKT_LOST (1 << 5)
+#define FTMAC100_INT_RPKT_SAV (1 << 6)
+#define FTMAC100_INT_RPKT_LOST (1 << 7)
+#define FTMAC100_INT_AHB_ERR (1 << 8)
+#define FTMAC100_INT_PHYSTS_CHG (1 << 9)
+
+/*
+ * Automatic polling timer control register
+ */
+#define FTMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0)
+#define FTMAC100_APTC_RXPOLL_TIME_SEL (1 << 4)
+#define FTMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8)
+#define FTMAC100_APTC_TXPOLL_TIME_SEL (1 << 12)
+
+/*
+ * MAC control register
+ */
+#define FTMAC100_MACCR_XDMA_EN (1 << 0)
+#define FTMAC100_MACCR_RDMA_EN (1 << 1)
+#define FTMAC100_MACCR_SW_RST (1 << 2)
+#define FTMAC100_MACCR_LOOP_EN (1 << 3)
+#define FTMAC100_MACCR_CRC_DIS (1 << 4)
+#define FTMAC100_MACCR_XMT_EN (1 << 5)
+#define FTMAC100_MACCR_ENRX_IN_HALFTX (1 << 6)
+#define FTMAC100_MACCR_RCV_EN (1 << 8)
+#define FTMAC100_MACCR_HT_MULTI_EN (1 << 9)
+#define FTMAC100_MACCR_RX_RUNT (1 << 10)
+#define FTMAC100_MACCR_RX_FTL (1 << 11)
+#define FTMAC100_MACCR_RCV_ALL (1 << 12)
+#define FTMAC100_MACCR_CRC_APD (1 << 14)
+#define FTMAC100_MACCR_FULLDUP (1 << 15)
+#define FTMAC100_MACCR_RX_MULTIPKT (1 << 16)
+#define FTMAC100_MACCR_RX_BROADPKT (1 << 17)
+
+/*
+ * Transmit descriptor, aligned to 16 bytes
+ */
+struct ftmac100_txdes {
+ unsigned int txdes0;
+ unsigned int txdes1;
+ unsigned int txdes2; /* TXBUF_BADR */
+ unsigned int txdes3; /* not used by HW */
+} __attribute__ ((aligned(16)));
+
+#define FTMAC100_TXDES0_TXPKT_LATECOL (1 << 0)
+#define FTMAC100_TXDES0_TXPKT_EXSCOL (1 << 1)
+#define FTMAC100_TXDES0_TXPKT_TXDMA_OWN (1 << 31)
+
+#define FTMAC100_TXDES1_TXBUF_SIZE(x) ((x) & 0x7ff)
+#define FTMAC100_TXDES1_LTS (1 << 27)
+#define FTMAC100_TXDES1_FTS (1 << 28)
+#define FTMAC100_TXDES1_TX2FIC (1 << 29)
+#define FTMAC100_TXDES1_TXIC (1 << 30)
+#define FTMAC100_TXDES1_EDOTR (1 << 31)
+
+/*
+ * Receive descriptor, aligned to 16 bytes
+ */
+struct ftmac100_rxdes {
+ unsigned int rxdes0;
+ unsigned int rxdes1;
+ unsigned int rxdes2; /* RXBUF_BADR */
+ unsigned int rxdes3; /* not used by HW */
+} __attribute__ ((aligned(16)));
+
+#define FTMAC100_RXDES0_RFL(des) ((des) & 0x7ff)
+#define FTMAC100_RXDES0_MULTICAST (1 << 16)
+#define FTMAC100_RXDES0_BROADCAST (1 << 17)
+#define FTMAC100_RXDES0_RX_ERR (1 << 18)
+#define FTMAC100_RXDES0_CRC_ERR (1 << 19)
+#define FTMAC100_RXDES0_FTL (1 << 20)
+#define FTMAC100_RXDES0_RUNT (1 << 21)
+#define FTMAC100_RXDES0_RX_ODD_NB (1 << 22)
+#define FTMAC100_RXDES0_LRS (1 << 28)
+#define FTMAC100_RXDES0_FRS (1 << 29)
+#define FTMAC100_RXDES0_RXDMA_OWN (1 << 31)
+
+#define FTMAC100_RXDES1_RXBUF_SIZE(x) ((x) & 0x7ff)
+#define FTMAC100_RXDES1_EDORR (1 << 31)
+
+#endif /* __FTMAC100_H */
diff -ruN u-boot-2009.03/drivers/net/Makefile FA5A320LINUX26_u-boot/drivers/net/Makefile
--- u-boot-2009.03/drivers/net/Makefile 2009-03-22 05:04:41.000000000 +0800
+++ FA5A320LINUX26_u-boot/drivers/net/Makefile 2009-03-31 15:35:35.000000000 +0800
@@ -38,6 +38,7 @@
COBJS-$(CONFIG_EEPRO100) += eepro100.o
COBJS-$(CONFIG_ENC28J60) += enc28j60.o
COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o
+COBJS-$(CONFIG_DRIVER_FTMAC100) += ftmac100.o
COBJS-$(CONFIG_GRETH) += greth.o
COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
More information about the U-Boot
mailing list