summaryrefslogtreecommitdiffstats
path: root/target/linux/coldfire/files-2.6.31/arch/m68k/include/asm/mcffec.h
blob: 4581f9e43ee862c3a34c013d2cea8663801879f2 (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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
 * Copyright (C) 2008-2009 Freescale Semiconductor, Inc. All rights reserved.
 * Author: Chenghu Wu <b16972@freescale.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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 *
 */
#ifndef __MCFFEC_H__
#define __MCFFEC_H
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include <asm/pgtable.h>

/* The FEC stores dest/src/type, data, and checksum for receive packets.
 */
#define PKT_MAXBUF_SIZE         1518

/*
 * The 5270/5271/5280/5282/532x RX control register also contains maximum frame
 * size bits. Other FEC hardware does not, so we need to take that into
 * account when setting it.
 */
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
	defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
	defined(CONFIG_M537x) || defined(CONFIG_M5301x) || \
	defined(CONFIG_M5445X)
#define OPT_FRAME_SIZE  (PKT_MAXBUF_SIZE << 16)
#else
#define OPT_FRAME_SIZE  0
#endif
/*
 * Some hardware gets it MAC address out of local flash memory.
 * if this is non-zero then assume it is the address to get MAC from.
 */
#if defined(CONFIG_NETtel)
#define FEC_FLASHMAC    0xf0006006
#elif defined(CONFIG_GILBARCONAP) || defined(CONFIG_SCALES)
#define FEC_FLASHMAC    0xf0006000
#elif defined(CONFIG_CANCam)
#define FEC_FLASHMAC    0xf0020000
#elif defined(CONFIG_M5272C3)
#define FEC_FLASHMAC    (0xffe04000 + 4)
#elif defined(CONFIG_MOD5272)
#define FEC_FLASHMAC    0xffc0406b
#else
#define FEC_FLASHMAC    0
#endif

#ifdef CONFIG_FEC_DMA_USE_SRAM
#define TX_RING_SIZE            8      /* Must be power of two */
#define TX_RING_MOD_MASK        7      /*   for this to work */
#else
#define TX_RING_SIZE            16      /* Must be power of two */
#define TX_RING_MOD_MASK        15      /*   for this to work */
#endif

typedef struct fec {
	unsigned long   fec_reserved0;
	unsigned long   fec_ievent;             /* Interrupt event reg */
	unsigned long   fec_imask;              /* Interrupt mask reg */
	unsigned long   fec_reserved1;
	unsigned long   fec_r_des_active;       /* Receive descriptor reg */
	unsigned long   fec_x_des_active;       /* Transmit descriptor reg */
	unsigned long   fec_reserved2[3];
	unsigned long   fec_ecntrl;             /* Ethernet control reg */
	unsigned long   fec_reserved3[6];
	unsigned long   fec_mii_data;           /* MII manage frame reg */
	unsigned long   fec_mii_speed;          /* MII speed control reg */
	unsigned long   fec_reserved4[7];
	unsigned long   fec_mib_ctrlstat;       /* MIB control/status reg */
	unsigned long   fec_reserved5[7];
	unsigned long   fec_r_cntrl;            /* Receive control reg */
	unsigned long   fec_reserved6[15];
	unsigned long   fec_x_cntrl;            /* Transmit Control reg */
	unsigned long   fec_reserved7[7];
	unsigned long   fec_addr_low;           /* Low 32bits MAC address */
	unsigned long   fec_addr_high;          /* High 16bits MAC address */
	unsigned long   fec_opd;                /* Opcode + Pause duration */
	unsigned long   fec_reserved8[10];
	unsigned long   fec_hash_table_high;    /* High 32bits hash table */
	unsigned long   fec_hash_table_low;     /* Low 32bits hash table */
	unsigned long   fec_grp_hash_table_high;/* High 32bits hash table */
	unsigned long   fec_grp_hash_table_low; /* Low 32bits hash table */
	unsigned long   fec_reserved9[7];
	unsigned long   fec_x_wmrk;             /* FIFO transmit water mark */
	unsigned long   fec_reserved10;
	unsigned long   fec_r_bound;            /* FIFO receive bound reg */
	unsigned long   fec_r_fstart;           /* FIFO receive start reg */
	unsigned long   fec_reserved11[11];
	unsigned long   fec_r_des_start;        /* Receive descriptor ring */
	unsigned long   fec_x_des_start;        /* Transmit descriptor ring */
	unsigned long   fec_r_buff_size;        /* Maximum receive buff size */
} fec_t;

/*
 *      Define the buffer descriptor structure.
 */
typedef struct bufdesc {
	unsigned short  cbd_sc;                 /* Control and status info */
	unsigned short  cbd_datlen;             /* Data length */
	unsigned long   cbd_bufaddr;            /* Buffer address */
} cbd_t;

/* Forward declarations of some structures to support different PHYs
 */
typedef struct {
	uint mii_data;
	void (*funct)(uint mii_reg, struct net_device *dev);
} phy_cmd_t;

typedef struct {
	uint id;
	char *name;

	const phy_cmd_t *config;
	const phy_cmd_t *startup;
	const phy_cmd_t *ack_int;
	const phy_cmd_t *shutdown;
} phy_info_t;

/* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
 * tx_bd_base always point to the base of the buffer descriptors.  The
 * cur_rx and cur_tx point to the currently available buffer.
 * The dirty_tx tracks the current buffer that is being sent by the
 * controller.  The cur_tx and dirty_tx are equal under both completely
 * empty and completely full conditions.  The empty/ready indicator in
 * the buffer descriptor determines the actual condition.
 */
struct fec_enet_private {
	/* Hardware registers of the FEC device */
	volatile fec_t	*hwp;

	struct net_device *netdev;
	struct platform_device *pdev;
	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
	unsigned char *tx_bounce[TX_RING_SIZE];
	struct	sk_buff *tx_skbuff[TX_RING_SIZE];
	ushort	skb_cur;
	ushort	skb_dirty;

	/* CPM dual port RAM relative addresses.
	*/
	cbd_t	*rx_bd_base;		/* Address of Rx and Tx buffers. */
	cbd_t	*tx_bd_base;
	cbd_t	*cur_rx, *cur_tx;		/* The next free ring entry */
	cbd_t	*dirty_tx;	/* The ring entries to be free()ed. */
	uint	tx_full;
	/* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
	spinlock_t hw_lock;

	/* hold while accessing the mii_list_t() elements */
	spinlock_t mii_lock;
	struct mii_bus *mdio_bus;
	struct phy_device *phydev;

	uint	phy_id;
	uint	phy_id_done;
	uint	phy_status;
	uint	phy_speed;
	phy_info_t const	*phy;
	struct work_struct phy_task;
	volatile fec_t	*phy_hwp;

	uint	sequence_done;
	uint	mii_phy_task_queued;

	uint	phy_addr;

	int	index;
	int	opened;
	int	link;
	int	old_link;
	int	full_duplex;
	int     duplex;
	int	speed;
	int     msg_enable;
};

struct fec_platform_private {
	struct platform_device  *pdev;

	unsigned long           quirks;
	int                     num_slots;      /* Slots on controller */
	struct fec_enet_private *fep_host[0];      /* Pointers to hosts */
};

#endif