All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Warren <biggerbadderben@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] Add support for Faraday Ethernet IP FTMAC100
Date: Tue, 31 Mar 2009 21:37:27 -0700	[thread overview]
Message-ID: <49D2EF87.3040202@gmail.com> (raw)
In-Reply-To: <200903310813.n2V8DBic010484@ftcpcw82.faraday.com.tw>

Hi Po Yu Chang,

PoYu_Chuang wrote:
> This patch adds support for Faraday Technology Ethernet IP - FTMAC100
>
> Signed-off-by: Po-Yu Chuang <ratbert@faraday-tech.com>
>   
Please use a valid e-mail address (hint - it should have an @ sign).  
You may want to provide a brief description of the controller here.
> ---
> diff -ruN u-boot-2009.03/drivers/net/ftmac100.c FA5A320LINUX26_u-boot/drivers/net/ftmac100.c
>   
It's best to use git tools to generate the patch.  If you use 
git-send-email you're more-or-less guaranteed to avoid line-wrapping issues.
> --- 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@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];
>   
This is a strange way of doing this.  Do you really need to use two 
variables?
> +
> +	debug("ftmac100_set_mac()\n");
> +
> +	outl(maddr, ftmac100_base + FTMAC100_OFFSET_MAC_MADR);
> +	outl(laddr, ftmac100_base + FTMAC100_OFFSET_MAC_LADR);
>   
Others have mentioned not using outl(), so echo'd here
> +}
> +
> +/*
> + * disable transmitter, receiver
> + */
> +void
> +eth_halt(void)
> +{
> +	debug("eth_halt()\n");
> +
> +	outl(0, ftmac100_base + FTMAC100_OFFSET_MACCR);
> +}
>   
Please don't use the old-style API (eth_halt(), eth_init() etc.)  You 
should have a single xxx_initialize() function that fills in an 
eth_device struct with function pointers to static functions.  You'll 
find lots of examples in drivers/net
> +
> +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@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

In general, this is quite promising - thanks a lot!  We tend to not 
include drivers without a board that uses it.  Please consider 
submitting your board code too.

regards,
Ben

  parent reply	other threads:[~2009-04-01  4:37 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-31  8:13 [U-Boot] [PATCH] Add support for Faraday Ethernet IP FTMAC100 PoYu_Chuang
2009-03-31  8:51 ` Jean-Christophe PLAGNIOL-VILLARD
2009-03-31  9:18 ` Mike Frysinger
2009-04-01  4:37 ` Ben Warren [this message]
  -- strict thread matches above, loose matches on Subject: below --
2009-04-01  2:25 Ratbert Po-Yu Chuang(莊博宇)
2009-04-01  3:35 Ratbert Po-Yu Chuang(莊博宇)

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=49D2EF87.3040202@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.