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
|