Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4b7780e authored by Andrew Victor's avatar Andrew Victor Committed by Jeff Garzik
Browse files

[PATCH] AT91RM9200 Ethernet driver



This patch adds support for the Ethernet controller integrated in the
Atmel AT91RM9200 SoC processor.

Changes since the previous submission (01/02/2006) are:
  - Make use of the clk.h clock infrastructure.
  - The multicast hash function is not crc32. [Patch by Pedro Perez]

Signed-off-by: default avatarAndrew Victor <andrew@sanpeople.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent e93252fa
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -31,3 +31,11 @@ config ARM_ETHERH
	help
	  If you have an Acorn system with one of these network cards, you
	  should say Y to this option if you wish to use it with Linux.

config ARM_AT91_ETHER
	tristate "AT91RM9200 Ethernet support"
	depends on NET_ETHERNET && ARM && ARCH_AT91RM9200
	select MII
	help
	  If you wish to compile a kernel for the AT91RM9200 and enable
	  ethernet support, then you should always answer Y to this.
+1 −0
Original line number Diff line number Diff line
@@ -7,3 +7,4 @@ obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
obj-$(CONFIG_ARM_ETHERH)	+= etherh.o
obj-$(CONFIG_ARM_ETHER3)	+= ether3.o
obj-$(CONFIG_ARM_ETHER1)	+= ether1.o
obj-$(CONFIG_ARM_AT91_ETHER)	+= at91_ether.o
+1110 −0

File added.

Preview size limit exceeded, changes collapsed.

+101 −0
Original line number Diff line number Diff line
/*
 * Ethernet driver for the Atmel AT91RM9200 (Thunder)
 *
 *  Copyright (C) SAN People (Pty) Ltd
 *
 * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
 * Initial version by Rick Bronson.
 *
 * 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.
 */

#ifndef AT91_ETHERNET
#define AT91_ETHERNET


/* Davicom 9161 PHY */
#define MII_DM9161_ID	0x0181b880
#define MII_DM9161A_ID	0x0181b8a0

/* Davicom specific registers */
#define MII_DSCR_REG	16
#define MII_DSCSR_REG	17
#define MII_DSINTR_REG	21

/* Intel LXT971A PHY */
#define MII_LXT971A_ID	0x001378E0

/* Intel specific registers */
#define MII_ISINTE_REG	18
#define MII_ISINTS_REG	19
#define MII_LEDCTRL_REG	20

/* Realtek RTL8201 PHY */
#define MII_RTL8201_ID	0x00008200

/* Broadcom BCM5221 PHY */
#define MII_BCM5221_ID	0x004061e0

/* Broadcom specific registers */
#define MII_BCMINTR_REG	26

/* National Semiconductor DP83847 */
#define MII_DP83847_ID	0x20005c30

/* Altima AC101L PHY */
#define MII_AC101L_ID	0x00225520

/* Micrel KS8721 PHY */
#define MII_KS8721_ID	0x00221610

/* ........................................................................ */

#define MAX_RBUFF_SZ	0x600		/* 1518 rounded up */
#define MAX_RX_DESCR	9		/* max number of receive buffers */

#define EMAC_DESC_DONE	0x00000001	/* bit for if DMA is done */
#define EMAC_DESC_WRAP	0x00000002	/* bit for wrap */

#define EMAC_BROADCAST	0x80000000	/* broadcast address */
#define EMAC_MULTICAST	0x40000000	/* multicast address */
#define EMAC_UNICAST	0x20000000	/* unicast address */

struct rbf_t
{
	unsigned int addr;
	unsigned long size;
};

struct recv_desc_bufs
{
	struct rbf_t descriptors[MAX_RX_DESCR];		/* must be on sizeof (rbf_t) boundary */
	char recv_buf[MAX_RX_DESCR][MAX_RBUFF_SZ];	/* must be on long boundary */
};

struct at91_private
{
	struct net_device_stats stats;
	struct mii_if_info mii;			/* ethtool support */
	struct at91_eth_data board_data;	/* board-specific configuration */

	/* PHY */
	unsigned long phy_type;			/* type of PHY (PHY_ID) */
	spinlock_t lock;			/* lock for MDI interface */
	short phy_media;			/* media interface type */
	unsigned short phy_address;		/* 5-bit MDI address of PHY (0..31) */

	/* Transmit */
	struct sk_buff *skb;			/* holds skb until xmit interrupt completes */
	dma_addr_t skb_physaddr;		/* phys addr from pci_map_single */
	int skb_length;				/* saved skb length for pci_unmap_single */

	/* Receive */
	int rxBuffIndex;			/* index into receive descriptor list */
	struct recv_desc_bufs *dlist;		/* descriptor list address */
	struct recv_desc_bufs *dlist_phys;	/* descriptor list physical address */
};

#endif
+138 −0
Original line number Diff line number Diff line
/*
 * include/asm-arm/arch-at91rm9200/at91rm9200_emac.h
 *
 * Copyright (C) 2005 Ivan Kokshaysky
 * Copyright (C) SAN People
 *
 * Ethernet MAC registers.
 * Based on AT91RM9200 datasheet revision E.
 *
 * 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.
 */

#ifndef AT91RM9200_EMAC_H
#define AT91RM9200_EMAC_H

#define	AT91_EMAC_CTL		0x00	/* Control Register */
#define		AT91_EMAC_LB		(1 <<  0)	/* Loopback */
#define		AT91_EMAC_LBL		(1 <<  1)	/* Loopback Local */
#define		AT91_EMAC_RE		(1 <<  2)	/* Receive Enable */
#define		AT91_EMAC_TE		(1 <<  3)	/* Transmit Enable */
#define		AT91_EMAC_MPE		(1 <<  4)	/* Management Port Enable */
#define		AT91_EMAC_CSR		(1 <<  5)	/* Clear Statistics Registers */
#define		AT91_EMAC_INCSTAT	(1 <<  6)	/* Increment Statistics Registers */
#define		AT91_EMAC_WES		(1 <<  7)	/* Write Enable for Statistics Registers */
#define		AT91_EMAC_BP		(1 <<  8)	/* Back Pressure */

#define	AT91_EMAC_CFG		0x04	/* Configuration Register */
#define		AT91_EMAC_SPD		(1 <<  0)	/* Speed */
#define		AT91_EMAC_FD		(1 <<  1)	/* Full Duplex */
#define		AT91_EMAC_BR		(1 <<  2)	/* Bit Rate */
#define		AT91_EMAC_CAF		(1 <<  4)	/* Copy All Frames */
#define		AT91_EMAC_NBC		(1 <<  5)	/* No Broadcast */
#define		AT91_EMAC_MTI		(1 <<  6)	/* Multicast Hash Enable */
#define		AT91_EMAC_UNI		(1 <<  7)	/* Unicast Hash Enable */
#define		AT91_EMAC_BIG		(1 <<  8)	/* Receive 1522 Bytes */
#define		AT91_EMAC_EAE		(1 <<  9)	/* External Address Match Enable */
#define		AT91_EMAC_CLK		(3 << 10)	/* MDC Clock Divisor */
#define		AT91_EMAC_CLK_DIV8		(0 << 10)
#define		AT91_EMAC_CLK_DIV16		(1 << 10)
#define		AT91_EMAC_CLK_DIV32		(2 << 10)
#define		AT91_EMAC_CLK_DIV64		(3 << 10)
#define		AT91_EMAC_RTY		(1 << 12)	/* Retry Test */
#define		AT91_EMAC_RMII		(1 << 13)	/* Reduce MII (RMII) */

#define	AT91_EMAC_SR		0x08	/* Status Register */
#define		AT91_EMAC_SR_LINK	(1 <<  0)	/* Link */
#define		AT91_EMAC_SR_MDIO	(1 <<  1)	/* MDIO pin */
#define		AT91_EMAC_SR_IDLE	(1 <<  2)	/* PHY idle */

#define	AT91_EMAC_TAR		0x0c	/* Transmit Address Register */

#define	AT91_EMAC_TCR		0x10	/* Transmit Control Register */
#define		AT91_EMAC_LEN		(0x7ff << 0)	/* Transmit Frame Length */
#define		AT91_EMAC_NCRC		(1     << 15)	/* No CRC */

#define	AT91_EMAC_TSR		0x14	/* Transmit Status Register */
#define		AT91_EMAC_TSR_OVR	(1 <<  0)	/* Transmit Buffer Overrun */
#define		AT91_EMAC_TSR_COL	(1 <<  1)	/* Collision Occurred */
#define		AT91_EMAC_TSR_RLE	(1 <<  2)	/* Retry Limit Exceeded */
#define		AT91_EMAC_TSR_IDLE	(1 <<  3)	/* Transmitter Idle */
#define		AT91_EMAC_TSR_BNQ	(1 <<  4)	/* Transmit Buffer not Queued */
#define		AT91_EMAC_TSR_COMP	(1 <<  5)	/* Transmit Complete */
#define		AT91_EMAC_TSR_UND	(1 <<  6)	/* Transmit Underrun */

#define	AT91_EMAC_RBQP		0x18	/* Receive Buffer Queue Pointer */

#define	AT91_EMAC_RSR		0x20	/* Receive Status Register */
#define		AT91_EMAC_RSR_BNA	(1 <<  0)	/* Buffer Not Available */
#define		AT91_EMAC_RSR_REC	(1 <<  1)	/* Frame Received */
#define		AT91_EMAC_RSR_OVR	(1 <<  2)	/* RX Overrun */

#define	AT91_EMAC_ISR		0x24	/* Interrupt Status Register */
#define		AT91_EMAC_DONE		(1 <<  0)	/* Management Done */
#define		AT91_EMAC_RCOM		(1 <<  1)	/* Receive Complete */
#define		AT91_EMAC_RBNA		(1 <<  2)	/* Receive Buffer Not Available */
#define		AT91_EMAC_TOVR		(1 <<  3)	/* Transmit Buffer Overrun */
#define		AT91_EMAC_TUND		(1 <<  4)	/* Transmit Buffer Underrun */
#define		AT91_EMAC_RTRY		(1 <<  5)	/* Retry Limit */
#define		AT91_EMAC_TBRE		(1 <<  6)	/* Transmit Buffer Register Empty */
#define		AT91_EMAC_TCOM		(1 <<  7)	/* Transmit Complete */
#define		AT91_EMAC_TIDLE		(1 <<  8)	/* Transmit Idle */
#define		AT91_EMAC_LINK		(1 <<  9)	/* Link */
#define		AT91_EMAC_ROVR		(1 << 10)	/* RX Overrun */
#define		AT91_EMAC_ABT		(1 << 11)	/* Abort */

#define	AT91_EMAC_IER		0x28	/* Interrupt Enable Register */
#define	AT91_EMAC_IDR		0x2c	/* Interrupt Disable Register */
#define	AT91_EMAC_IMR		0x30	/* Interrupt Mask Register */

#define	AT91_EMAC_MAN		0x34	/* PHY Maintenance Register */
#define		AT91_EMAC_DATA		(0xffff << 0)	/* MDIO Data */
#define		AT91_EMAC_REGA		(0x1f	<< 18)	/* MDIO Register */
#define		AT91_EMAC_PHYA		(0x1f	<< 23)	/* MDIO PHY Address */
#define		AT91_EMAC_RW		(3	<< 28)	/* Read/Write operation */
#define			AT91_EMAC_RW_W		(1 << 28)
#define			AT91_EMAC_RW_R		(2 << 28)
#define		AT91_EMAC_MAN_802_3	0x40020000	/* IEEE 802.3 value */

/*
 * Statistics Registers.
 */
#define AT91_EMAC_FRA		0x40	/* Frames Transmitted OK */
#define AT91_EMAC_SCOL		0x44	/* Single Collision Frame */
#define AT91_EMAC_MCOL		0x48	/* Multiple Collision Frame */
#define AT91_EMAC_OK		0x4c	/* Frames Received OK */
#define AT91_EMAC_SEQE		0x50	/* Frame Check Sequence Error */
#define AT91_EMAC_ALE		0x54	/* Alignmemt Error */
#define AT91_EMAC_DTE		0x58	/* Deffered Transmission Frame */
#define AT91_EMAC_LCOL		0x5c	/* Late Collision */
#define AT91_EMAC_ECOL		0x60	/* Excessive Collision */
#define AT91_EMAC_TUE		0x64	/* Transmit Underrun Error */
#define AT91_EMAC_CSE		0x68	/* Carrier Sense Error */
#define AT91_EMAC_DRFC		0x6c	/* Discard RX Frame */
#define AT91_EMAC_ROV		0x70	/* Receive Overrun */
#define AT91_EMAC_CDE		0x74	/* Code Error */
#define AT91_EMAC_ELR		0x78	/* Excessive Length Error */
#define AT91_EMAC_RJB		0x7c	/* Receive Jabber */
#define AT91_EMAC_USF		0x80	/* Undersize Frame */
#define AT91_EMAC_SQEE		0x84	/* SQE Test Error */

/*
 * Address Registers.
 */
#define AT91_EMAC_HSL		0x90	/* Hash Address Low [31:0] */
#define AT91_EMAC_HSH		0x94	/* Hash Address High [63:32] */
#define AT91_EMAC_SA1L		0x98	/* Specific Address 1 Low, bytes 0-3 */
#define AT91_EMAC_SA1H		0x9c	/* Specific Address 1 High, bytes 4-5 */
#define AT91_EMAC_SA2L		0xa0	/* Specific Address 2 Low, bytes 0-3 */
#define AT91_EMAC_SA2H		0xa4	/* Specific Address 2 High, bytes 4-5 */
#define AT91_EMAC_SA3L		0xa8	/* Specific Address 3 Low, bytes 0-3 */
#define AT91_EMAC_SA3H		0xac	/* Specific Address 3 High, bytes 4-5 */
#define AT91_EMAC_SA4L		0xb0	/* Specific Address 4 Low, bytes 0-3 */
#define AT91_EMAC_SA4H		0xb4	/* Specific Address 4 High, bytes 4-5 */

#endif