summaryrefslogtreecommitdiffstats
path: root/target/linux/rb532/files-2.6.24/drivers/net/rc32434_eth.h
blob: 5ac6dc3546b1015ff99345e51481f05e554beff7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**************************************************************************
 *
 *  BRIEF MODULE DESCRIPTION
 *     Definitions for IDT RC32434 on-chip ethernet controller.
 *
 *  Copyright 2004 IDT Inc. (rischelp@idt.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  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.
 *
 *
 **************************************************************************
 * May 2004 rkt, neb
 *
 * Initial Release
 *
 * Aug 2004
 *
 * Added NAPI
 *
 **************************************************************************
 */


#include  <asm/rc32434/rc32434.h>
#include  <asm/rc32434/dma_v.h>
#include  <asm/rc32434/eth_v.h>

#define CONFIG_IDT_USE_NAPI 1
#define RC32434_DEBUG	2
//#define RC32434_PROC_DEBUG
#undef	RC32434_DEBUG

#ifdef RC32434_DEBUG

/* use 0 for production, 1 for verification, >2 for debug */
static int rc32434_debug = RC32434_DEBUG;
#define ASSERT(expr) \
	if(!(expr)) {	\
		printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
		#expr,__FILE__,__FUNCTION__,__LINE__);		}
#define DBG(lvl, format, arg...) if (rc32434_debug > lvl) printk(KERN_INFO "%s: " format, dev->name , ## arg)
#else
#define ASSERT(expr) do {} while (0)
#define DBG(lvl, format, arg...) do {} while (0)
#endif

#define INFO(format, arg...) printk(KERN_INFO "%s: " format, dev->name , ## arg)
#define ERR(format, arg...) printk(KERN_ERR "%s: " format, dev->name , ## arg)
#define WARN(format, arg...) printk(KERN_WARNING "%s: " format, dev->name , ## arg)		

/* the following must be powers of two */
#ifdef CONFIG_IDT_USE_NAPI
#define RC32434_NUM_RDS    64    		/* number of receive descriptors */
#define RC32434_NUM_TDS    64    		/* number of transmit descriptors */
#else
#define RC32434_NUM_RDS    128    		/* number of receive descriptors */
#define RC32434_NUM_TDS    128    		/* number of transmit descriptors */
#endif

#define RC32434_RBSIZE     1536  		/* size of one resource buffer = Ether MTU */
#define RC32434_RDS_MASK   (RC32434_NUM_RDS-1)
#define RC32434_TDS_MASK   (RC32434_NUM_TDS-1)
#define RD_RING_SIZE (RC32434_NUM_RDS * sizeof(struct DMAD_s))
#define TD_RING_SIZE (RC32434_NUM_TDS * sizeof(struct DMAD_s))

#define RC32434_TX_TIMEOUT HZ * 100

#define rc32434_eth0_regs ((ETH_t)(ETH0_VirtualAddress))
#define rc32434_eth1_regs ((ETH_t)(ETH1_VirtualAddress))

enum status	{ filled,	empty};
#define IS_DMA_FINISHED(X)   (((X) & (DMAD_f_m)) != 0)
#define IS_DMA_DONE(X)   (((X) & (DMAD_d_m)) != 0)


/* Information that need to be kept for each board. */
struct rc32434_local {
	ETH_t  eth_regs;
	DMA_Chan_t  rx_dma_regs;
	DMA_Chan_t  tx_dma_regs;
	volatile DMAD_t   td_ring;			/* transmit descriptor ring */ 
	volatile DMAD_t   rd_ring;			/* receive descriptor ring  */
	
	struct sk_buff* tx_skb[RC32434_NUM_TDS]; 	/* skbuffs for pkt to trans */
	struct sk_buff* rx_skb[RC32434_NUM_RDS]; 	/* skbuffs for pkt to trans */
	
	struct tasklet_struct * tx_tasklet;
	
	int	rx_next_done;
	int	rx_chain_head;
	int	rx_chain_tail;
	enum status	rx_chain_status;
	
	int	tx_next_done;
	int	tx_chain_head;
	int	tx_chain_tail;
	enum status	tx_chain_status;
	int tx_count;			
	int	tx_full;
	
	struct timer_list    mii_phy_timer;
	unsigned long duplex_mode;
	
	int   	rx_irq;
	int    tx_irq;
	int    ovr_irq;
	int    und_irq;
	
	struct net_device_stats stats;
	spinlock_t lock; 
	
	/* debug /proc entry */
	struct proc_dir_entry *ps;
	int dma_halt_cnt;  int dma_run_cnt;
	struct napi_struct napi;
	struct net_device *dev;
};

extern unsigned int idt_cpu_freq;

/* Index to functions, as function prototypes. */
static int rc32434_open(struct net_device *dev);
static int rc32434_send_packet(struct sk_buff *skb, struct net_device *dev);
static void rc32434_mii_handler(unsigned long data);
static irqreturn_t  rc32434_und_interrupt(int irq, void *dev_id);
static irqreturn_t rc32434_rx_dma_interrupt(int irq, void *dev_id);
static irqreturn_t rc32434_tx_dma_interrupt(int irq, void *dev_id);
#ifdef	RC32434_REVISION	
static irqreturn_t rc32434_ovr_interrupt(int irq, void *dev_id);
#endif
static int  rc32434_close(struct net_device *dev);
static struct net_device_stats *rc32434_get_stats(struct net_device *dev);
static void rc32434_multicast_list(struct net_device *dev);
static int  rc32434_init(struct net_device *dev);
static void rc32434_tx_timeout(struct net_device *dev);

static void rc32434_tx_tasklet(unsigned long tx_data_dev);
static int rc32434_poll(struct napi_struct *napi, int budget);
static void rc32434_cleanup_module(void);


static inline void rc32434_abort_dma(struct net_device *dev, DMA_Chan_t ch)
{
	if (__raw_readl(&ch->dmac) & DMAC_run_m) {
		__raw_writel(0x10, &ch->dmac); 
		
		while (!(__raw_readl(&ch->dmas) & DMAS_h_m))
			dev->trans_start = jiffies;		
		
		__raw_writel(0, &ch->dmas);  
	}
	
	__raw_writel(0, &ch->dmadptr); 
	__raw_writel(0, &ch->dmandptr); 
}