Project

General

Profile

Mityarm RGMII1 question » smsc.c

changed file to add lan8820 - david mckinley, 03/19/2014 02:06 PM

 
1
/*
2
 * drivers/net/phy/smsc.c
3
 *
4
 * Driver for SMSC PHYs
5
 *
6
 * Author: Herbert Valerio Riedel
7
 *
8
 * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
9
 *
10
 * This program is free software; you can redistribute  it and/or modify it
11
 * under  the terms of  the GNU General  Public License as published by the
12
 * Free Software Foundation;  either version 2 of the  License, or (at your
13
 * option) any later version.
14
 *
15
 * Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@smsc.com
16
 *
17
 */
18

    
19
#include <linux/kernel.h>
20
#include <linux/module.h>
21
#include <linux/mii.h>
22
#include <linux/ethtool.h>
23
#include <linux/phy.h>
24
#include <linux/netdevice.h>
25

    
26
#define MII_LAN83C185_ISF 29 /* Interrupt Source Flags */
27
#define MII_LAN83C185_IM  30 /* Interrupt Mask */
28
#define MII_LAN83C185_CTRL_STATUS 17 /* Mode/Status Register */
29

    
30
#define MII_LAN83C185_ISF_INT1 (1<<1) /* Auto-Negotiation Page Received */
31
#define MII_LAN83C185_ISF_INT2 (1<<2) /* Parallel Detection Fault */
32
#define MII_LAN83C185_ISF_INT3 (1<<3) /* Auto-Negotiation LP Ack */
33
#define MII_LAN83C185_ISF_INT4 (1<<4) /* Link Down */
34
#define MII_LAN83C185_ISF_INT5 (1<<5) /* Remote Fault Detected */
35
#define MII_LAN83C185_ISF_INT6 (1<<6) /* Auto-Negotiation complete */
36
#define MII_LAN83C185_ISF_INT7 (1<<7) /* ENERGYON */
37

    
38
#define MII_LAN83C185_ISF_INT_ALL (0x0e)
39

    
40
#define MII_LAN83C185_ISF_INT_PHYLIB_EVENTS \
41
	(MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4 | \
42
	 MII_LAN83C185_ISF_INT7)
43

    
44
#define MII_LAN83C185_EDPWRDOWN	(1 << 13) /* EDPWRDOWN */
45

    
46
static int SMSC_config_aneg(struct phy_device *phydev)
47
{
48
	int err;
49
	printk(KERN_ALERT "SMSC_config_aneg\n");
50
	phydev->duplex = DUPLEX_FULL;
51
	phydev->speed = SPEED_100;
52
	phydev->autoneg = AUTONEG_DISABLE;
53
	phydev->interface == PHY_INTERFACE_MODE_RGMII_ID;
54
	err = phy_write(phydev, 0, 0x2000);
55
	if(err<0) return err;
56
	return 0;
57
}
58

    
59
static int smsc_phy_config_intr(struct phy_device *phydev)
60
{
61
	int rc = phy_write (phydev, MII_LAN83C185_IM,
62
			((PHY_INTERRUPT_ENABLED == phydev->interrupts)
63
			? MII_LAN83C185_ISF_INT_PHYLIB_EVENTS		: 0));
64
	/*int rd = phy_write (phydev, 0, 0x2000); // override auto mdx for now. force 100M*/
65
	return rc < 0 ? rc : 0;
66
}
67

    
68
static int smsc_phy_ack_interrupt(struct phy_device *phydev)
69
{
70
	int rc = phy_read (phydev, MII_LAN83C185_ISF);
71

    
72
	return rc < 0 ? rc : 0;
73
}
74

    
75
static int smsc_phy_config_init(struct phy_device *phydev)
76
{
77
	int phyregloop;
78
	int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
79
	if (rc < 0)
80
		return rc;
81

    
82
	/* Enable energy detect mode for this SMSC Transceivers */
83
	//c = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
84
	//	       rc | MII_LAN83C185_EDPWRDOWN);
85
	//if (rc < 0)
86
	//	return rc;
87
	printk(KERN_ALERT "smsc_phy_config_init\n");
88
	int rd = phy_write (phydev, 0, 0x2000); // override auto mdx for now. force 100M
89
	//
90
	// dump the phy registers
91
	for(phyregloop = 0; phyregloop<6; phyregloop++)
92
	{
93
		rc = phy_read(phydev, phyregloop);
94
		printk(KERN_ALERT "..... smsc PHY REGS: %d: VAL: %x \n", phyregloop, rc);
95
	}
96
	return smsc_phy_ack_interrupt (phydev);
97
}
98

    
99
static int lan911x_config_init(struct phy_device *phydev)
100
{
101
	return smsc_phy_ack_interrupt(phydev);
102
}
103

    
104
static struct phy_driver lan83c185_driver = {
105
	.phy_id		= 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
106
	.phy_id_mask	= 0xfffffff0,
107
	.name		= "SMSC LAN83C185",
108

    
109
	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
110
				| SUPPORTED_Asym_Pause),
111
	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
112

    
113
	/* basic functions */
114
	.config_aneg	= genphy_config_aneg,
115
	.read_status	= genphy_read_status,
116
	.config_init	= smsc_phy_config_init,
117

    
118
	/* IRQ related */
119
	.ack_interrupt	= smsc_phy_ack_interrupt,
120
	.config_intr	= smsc_phy_config_intr,
121

    
122
	.suspend	= genphy_suspend,
123
	.resume		= genphy_resume,
124

    
125
	.driver		= { .owner = THIS_MODULE, }
126
};
127

    
128
static struct phy_driver lan8187_driver = {
129
	.phy_id		= 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */
130
	.phy_id_mask	= 0xfffffff0,
131
	.name		= "SMSC LAN8187",
132

    
133
	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
134
				| SUPPORTED_Asym_Pause),
135
	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
136

    
137
	/* basic functions */
138
	.config_aneg	= genphy_config_aneg,
139
	.read_status	= genphy_read_status,
140
	.config_init	= smsc_phy_config_init,
141

    
142
	/* IRQ related */
143
	.ack_interrupt	= smsc_phy_ack_interrupt,
144
	.config_intr	= smsc_phy_config_intr,
145

    
146
	.suspend	= genphy_suspend,
147
	.resume		= genphy_resume,
148

    
149
	.driver		= { .owner = THIS_MODULE, }
150
};
151

    
152
static struct phy_driver lan8700_driver = {
153
	.phy_id		= 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
154
	.phy_id_mask	= 0xfffffff0,
155
	.name		= "SMSC LAN8700",
156

    
157
	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
158
				| SUPPORTED_Asym_Pause),
159
	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
160

    
161
	/* basic functions */
162
	.config_aneg	= genphy_config_aneg,
163
	.read_status	= genphy_read_status,
164
	.config_init	= smsc_phy_config_init,
165

    
166
	/* IRQ related */
167
	.ack_interrupt	= smsc_phy_ack_interrupt,
168
	.config_intr	= smsc_phy_config_intr,
169

    
170
	.suspend	= genphy_suspend,
171
	.resume		= genphy_resume,
172

    
173
	.driver		= { .owner = THIS_MODULE, }
174
};
175
static struct phy_driver lan8820_driver = {
176
	.phy_id		= 0x0007c0e0, /* OUI=0x00800f, Model#=0x0c */
177
	.phy_id_mask	= 0xfffffff0,
178
	.name		= "SMSC LAN8820",
179

    
180
	.features	= PHY_BASIC_FEATURES,
181
	.flags		= PHY_POLL,
182

    
183
	/* basic functions */
184
	//.speed		= SPEED_100,
185
	//.autoneg 	= AUTONEG_DISABLE,
186
	.config_aneg	= &SMSC_config_aneg,
187
	.read_status	= genphy_read_status,
188
	.config_init	= smsc_phy_config_init,
189

    
190
	/* IRQ related */
191
	.ack_interrupt	= smsc_phy_ack_interrupt,
192
	.config_intr	= smsc_phy_config_intr,
193

    
194
	//.suspend	= genphy_suspend,
195
	//.resume		= genphy_resume,
196

    
197
	.driver		= { .owner = THIS_MODULE, }
198
};
199

    
200
static struct phy_driver lan911x_int_driver = {
201
	.phy_id		= 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */
202
	.phy_id_mask	= 0xfffffff0,
203
	.name		= "SMSC LAN911x Internal PHY",
204

    
205
	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
206
				| SUPPORTED_Asym_Pause),
207
	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
208

    
209
	/* basic functions */
210
	.config_aneg	= genphy_config_aneg,
211
	.read_status	= genphy_read_status,
212
	.config_init	= lan911x_config_init,
213

    
214
	/* IRQ related */
215
	.ack_interrupt	= smsc_phy_ack_interrupt,
216
	.config_intr	= smsc_phy_config_intr,
217

    
218
	.suspend	= genphy_suspend,
219
	.resume		= genphy_resume,
220

    
221
	.driver		= { .owner = THIS_MODULE, }
222
};
223

    
224
static struct phy_driver lan8710_driver = {
225
	.phy_id		= 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
226
	.phy_id_mask	= 0xfffffff0,
227
	.name		= "SMSC LAN8710/LAN8720",
228

    
229
	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
230
				| SUPPORTED_Asym_Pause),
231
	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
232

    
233
	/* basic functions */
234
	.config_aneg	= genphy_config_aneg,
235
	.read_status	= genphy_read_status,
236
	.config_init	= smsc_phy_config_init,
237

    
238
	/* IRQ related */
239
	.ack_interrupt	= smsc_phy_ack_interrupt,
240
	.config_intr	= smsc_phy_config_intr,
241

    
242
	.suspend	= genphy_suspend,
243
	.resume		= genphy_resume,
244

    
245
	.driver		= { .owner = THIS_MODULE, }
246
};
247

    
248
static int __init smsc_init(void)
249
{
250
	int ret;
251
	printk(KERN_ALERT "INIT SMSC PHY.\n");
252

    
253
	ret = phy_driver_register (&lan83c185_driver);
254
	if (ret)
255
		goto err1;
256

    
257
	ret = phy_driver_register (&lan8187_driver);
258
	if (ret)
259
		goto err2;
260

    
261
	ret = phy_driver_register (&lan8700_driver);
262
	if (ret)
263
		goto err3;
264
	ret = phy_driver_register  (&lan8820_driver);
265
        printk(KERN_ALERT "SMSC lan8820_driver status: %x\n", ret);
266
	if (ret)
267
		goto err6;
268

    
269
	ret = phy_driver_register (&lan911x_int_driver);
270
	if (ret)
271
		goto err4;
272

    
273
	ret = phy_driver_register (&lan8710_driver);
274
	if (ret)
275
		goto err5;
276

    
277
	return 0;
278
err6:
279
	phy_driver_unregister (&lan8820_driver);
280
err5:
281
	phy_driver_unregister (&lan911x_int_driver);
282
err4:
283
	phy_driver_unregister (&lan8700_driver);
284
err3:
285
	phy_driver_unregister (&lan8187_driver);
286
err2:
287
	phy_driver_unregister (&lan83c185_driver);
288
err1:
289
	return ret;
290
}
291

    
292
static void __exit smsc_exit(void)
293
{
294
	phy_driver_unregister (&lan8710_driver);
295
	phy_driver_unregister (&lan8820_driver);
296
	phy_driver_unregister (&lan911x_int_driver);
297
	phy_driver_unregister (&lan8700_driver);
298
	phy_driver_unregister (&lan8187_driver);
299
	phy_driver_unregister (&lan83c185_driver);
300
}
301

    
302
MODULE_DESCRIPTION("SMSC PHY driver");
303
MODULE_AUTHOR("Herbert Valerio Riedel");
304
MODULE_LICENSE("GPL");
305

    
306
module_init(smsc_init);
307
module_exit(smsc_exit);
308

    
309
static struct mdio_device_id __maybe_unused smsc_tbl[] = {
310
	{ 0x0007c0a0, 0xfffffff0 },
311
	{ 0x0007c0b0, 0xfffffff0 },
312
	{ 0x0007c0c0, 0xfffffff0 },
313
	{ 0x0007c0d0, 0xfffffff0 },
314
	{ 0x0007c0e0, 0xfffffff0 },
315
	{ 0x0007c0f0, 0xfffffff0 },
316
	{ }
317
};
318

    
319
MODULE_DEVICE_TABLE(mdio, smsc_tbl);
(3-3/5) Go to top
Add picture from clipboard (Maximum size: 1 GB)