Root/target/linux/coldfire/files-2.6.31/drivers/net/phy/broadcom522x.c

1/*
2 *Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
3 * Chenghu Wu <b16972@freescale.com>
4 *
5 * Driver for broadcom PHYs 522x
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/mii.h>
17#include <linux/ethtool.h>
18#include <linux/phy.h>
19#include <linux/netdevice.h>
20
21/* DP83865 phy identifier values */
22#define BCM5222_PHY_ID 0x00406320
23
24/* PHY Register */
25#define BCM5222_TIMEOUT 0x100
26
27/* MII Registers */
28#define BCM5222_CTRL 0x00
29#define BCM5222_STATUS 0x01
30#define BCM5222_ID_HIGH 0x02
31#define BCM5222_ID_LOW 0x03
32#define BCM5222_AN_ADV 0x04
33#define BCM5222_AN_LP 0x05
34#define BCM5222_AN_EXP 0x06
35#define BCM5222_AN_NEXTPG 0x07
36#define BCM5222_AN_LP_NPTX 0x08
37#define BCM5222_AUX_CS 0x18
38#define BCM5222_AUX_STATUS 0x19
39
40/* CONTROL Bits */
41#define BCM5222_CTRL_RESET 0x8000
42#define BCM5222_CTRL_LOOPBACK 0x4000
43#define BCM5222_CTRL_FORCE 0x2000
44#define BCM5222_CTRL_AUTOEN 0x1000
45#define BCM5222_CTRL_PWRDN 0x0800
46#define BCM5222_CTRL_ISOLATE 0x0400
47#define BCM5222_CTRL_RESTART 0x0200
48#define BCM5222_CTRL_DUPLEX 0x0100
49#define BCM5222_CTRL_COLLEN 0x0080
50
51/* STATUS Bits */
52#define BCM5222_STATUS_100T4 0x8000
53#define BCM5222_STATUS_100TXFDX 0x4000
54#define BCM5222_STATUS_100TX 0x2000
55#define BCM5222_STATUS_10FDX 0x1000
56#define BCM5222_STATUS_10 0x0800
57#define BCM5222_STATUS_MF_PREAMBLE 0x0040
58#define BCM5222_STATUS_AN_COMPLETE 0x0020
59#define BCM5222_STATUS_REMOTE_FAULT 0x0010
60#define BCM5222_STATUS_AN_CAPABLE 0x0008
61#define BCM5222_STATUS_LINK 0x0004
62#define BCM5222_STATUS_JABBER 0x0002
63#define BCM5222_STATUS_EXT_CAP 0x0001
64
65/* ID Values */
66#define BCM5222_ID_HIGH_VAL 0x0040
67#define BCM5222_ID_LOW_VAL 0x6320
68
69/* Advertise Bits */
70#define BCM5222_AN_ADV_NEXTPG 0x8000
71#define BCM5222_AN_ADV_REMOTE_FAULT 0x2000
72#define BCM5222_AN_ADV_PAUSE 0x0400
73#define BCM5222_AN_ADV_100T4 0x0200
74#define BCM5222_AN_ADV_100TXFDX 0x0100
75#define BCM5222_AN_ADV_100TX 0x0080
76#define BCM5222_AN_ADV_10FDX 0x0040
77#define BCM5222_AN_ADV_10 0x0020
78#define BCM5222_AN_ADV_8023 0x0001
79#define BCM5222_AN_ADV_ALL \
80    (BCM5222_AN_ADV_100TXFDX | \
81    BCM5222_AN_ADV_100TXFDX | \
82    BCM5222_AN_ADV_100TX | \
83    BCM5222_AN_ADV_10FDX | \
84    BCM5222_AN_ADV_10 | \
85    BCM5222_AN_ADV_8023)
86
87/* AUX CTRL/STATUS Bits */
88#define BCM5222_AUX_CS_JABBER_DIS 0x8000
89#define BCM5222_AUX_CS_FORCE_LINK 0x4000
90#define BCM5222_AUX_CS_10M_TX_PWR 0x0100
91#define BCM5222_AUX_CS_HSQ_LSQ_MASK 0x00c0
92#define BCM5222_AUX_CS_EDGE_RATE_MASK 0x0030
93#define BCM5222_AUX_CS_AN_IND 0x0008
94#define BCM5222_AUX_CS_SPEED_FORCE 0x0004
95#define BCM5222_AUX_CS_SPEED 0x0002
96#define BCM5222_AUX_CS_DUPLEX 0x0001
97
98/* AUX STATUS Bits */
99#define BCM5222_AUX_STATUS_AN_COMP 0x8000
100#define BCM5222_AUX_STATUS_AN_COMPACK 0x4000
101#define BCM5222_AUX_STATUS_AN_ACKDET 0x2000
102#define BCM5222_AUX_STATUS_AN_ABDET 0x1000
103#define BCM5222_AUX_STATUS_AN_PAUSE 0x0800
104#define BCM5222_AUX_STATUS_AN_HCDMASK 0x0700
105#define BCM5222_AUX_STATUS_AN_PDFAULT 0x0080
106#define BCM5222_AUX_STATUS_LP_RMTFAULT 0x0040
107#define BCM5222_AUX_STATUS_LP_PGRX 0x0020
108#define BCM5222_AUX_STATUS_LP_NEGABLE 0x0010
109#define BCM5222_AUX_STATUS_SPEED 0x0008
110#define BCM5222_AUX_STATUS_LINK 0x0004
111#define BCM5222_AUX_STATUS_AN_EN 0x0002
112#define BCM5222_AUX_STATUS_JABBER 0x0001
113
114static int bcm5222_config_intr(struct phy_device *phydev)
115{
116    int err = 0;
117    printk(KERN_INFO "%s PHY_INTERRUPT %x\n",
118            __func__, phydev->interrupts);
119
120    return err;
121}
122
123static int bcm5222_ack_interrupt(struct phy_device *phydev)
124{
125    return 0;
126}
127
128static int bcm5222_config_init(struct phy_device *phydev)
129{
130    return bcm5222_ack_interrupt(phydev);
131}
132
133static int bcm5222_config_init_old(struct phy_device *phydev)
134{
135    int timeout;
136    int flag = 1;
137    int ret = phy_read(phydev, BCM5222_AUX_STATUS);
138    if (ret < 0) {
139        printk(KERN_INFO "%s MII_BCM5222_ISR %x\n",
140            __func__, ret);
141    }
142    /*
143    * reset
144    */
145    phy_write(phydev, BCM5222_CTRL, BCM5222_CTRL_RESET);
146
147    /* check that it cleared */
148    ret = phy_read(phydev, BCM5222_CTRL);
149    printk(KERN_INFO "%s BCM5222_CTRL %x\n",
150        __func__, ret);
151    /*if reset bit is set, return */
152    if (ret & BCM5222_CTRL_RESET) {
153        printk(KERN_ERR "%s %x = BCM5222_CTRL_RESET(%x)\n",
154            __func__, ret, BCM5222_CTRL_RESET);
155        return -ETIME;
156    }
157
158    /*
159    * setup auto-negotiation
160    */
161
162    /* disable */
163    phy_write(phydev, BCM5222_CTRL, 0);
164    ret = phy_read(phydev, BCM5222_CTRL);
165    printk(KERN_INFO "%s BCM5222_CTRL %x\n",
166        __func__, ret);
167    /* set the auto-negotiation advertisement register */
168    phy_write(phydev, BCM5222_AN_ADV, BCM5222_AN_ADV_ALL);
169    ret = phy_read(phydev, BCM5222_AN_ADV);
170    printk(KERN_INFO "%s BCM5222_AN_ADV %x, BCM5222_AN_ADV_ALL %x\n",
171        __func__, ret, BCM5222_AN_ADV_ALL);
172    /* enable */
173    phy_write(phydev, BCM5222_CTRL, BCM5222_CTRL_AUTOEN);
174    ret = phy_read(phydev, BCM5222_CTRL);
175    printk(KERN_INFO "%s BCM5222_CTRL %x\n",
176            __func__, ret);
177    printk(KERN_INFO "** wait for complete\n");
178
179    /* read aux status reg */
180    ret = phy_read(phydev, BCM5222_AUX_STATUS);
181    /* Wait for the auto-negotiation completion */
182    timeout = BCM5222_TIMEOUT;
183    while (!(ret & BCM5222_AUX_STATUS_AN_COMP)) {
184        if (!timeout--) {
185            flag = 0;
186            printk(KERN_INFO "BCM5222: TIMEOUT\n");
187            break;
188        }
189
190        mdelay(10);
191        /* Read PHY status register */
192        ret = phy_read(phydev, BCM5222_AUX_STATUS);
193    }
194
195    ret = phy_read(phydev, BCM5222_AUX_STATUS);
196    ret = phy_read(phydev, BCM5222_AN_ADV);
197    return 0;
198}
199
200static int bcm5222_read_status(struct phy_device *phydev)
201{
202    int ret;
203    ret = phy_read(phydev, BCM5222_AUX_STATUS);
204    printk(KERN_INFO "%s ret %x\n", __func__, ret);
205
206    if (ret & BCM5222_AUX_STATUS_LINK)
207        phydev->link = 1;
208    else
209        phydev->link = 0;
210
211    if (ret & BCM5222_AUX_STATUS_SPEED)
212        phydev->speed = SPEED_100;
213    else
214        phydev->speed = SPEED_10;
215
216    ret = phy_read(phydev, BCM5222_AUX_CS);
217    printk(KERN_INFO "%s ret %x\n", __func__, ret);
218    if (ret & BCM5222_AUX_CS_DUPLEX)
219        phydev->duplex = DUPLEX_FULL;
220    else
221        phydev->duplex = DUPLEX_HALF;
222    return 0;
223}
224
225static int bcm5222_config_aneg(struct phy_device *phydev)
226{
227    phy_read(phydev, BCM5222_AUX_STATUS);
228    phy_read(phydev, BCM5222_AN_ADV);
229    return 0;
230}
231
232static struct phy_driver bcm5222_driver = {
233    .phy_id = BCM5222_PHY_ID,
234    .phy_id_mask = 0xfffffff0,
235    .name = "Broadcom BCM5222",
236    .features = PHY_BASIC_FEATURES,
237    .flags = PHY_HAS_INTERRUPT,
238    .config_init = bcm5222_config_init,
239    .config_aneg = genphy_config_aneg,
240    .read_status = genphy_read_status,
241    .ack_interrupt = bcm5222_ack_interrupt,
242    .config_intr = bcm5222_config_intr,
243    .driver = {.owner = THIS_MODULE,}
244};
245
246static int __init bcm5222_init(void)
247{
248    int ret;
249
250    ret = phy_driver_register(&bcm5222_driver);
251    if (ret)
252        goto err1;
253
254    return 0;
255err1:
256    printk(KERN_INFO "register bcm5222 PHY driver fail\n");
257    return ret;
258}
259
260static void __exit bcm5222_exit(void)
261{
262    phy_driver_unregister(&bcm5222_driver);
263}
264
265MODULE_DESCRIPTION("Broadcom PHY driver");
266MODULE_LICENSE("GPL v2");
267
268module_init(bcm5222_init);
269module_exit(bcm5222_exit);
270

Archive Download this file



interactive