8139cp: fix VLAN unregistration
[linux-2.6] / drivers / net / ibm_emac / ibm_emac_phy.c
1 /*
2  * drivers/net/ibm_emac/ibm_emac_phy.c
3  *
4  * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
5  * Borrowed from sungem_phy.c, though I only kept the generic MII
6  * driver for now.
7  * 
8  * This file should be shared with other drivers or eventually
9  * merged as the "low level" part of miilib
10  * 
11  * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
12  * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
13  *
14  */
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/types.h>
18 #include <linux/netdevice.h>
19 #include <linux/mii.h>
20 #include <linux/ethtool.h>
21 #include <linux/delay.h>
22
23 #include <asm/ocp.h>
24
25 #include "ibm_emac_core.h"
26 #include "ibm_emac_phy.h"
27
28 static inline int phy_read(struct mii_phy *phy, int reg)
29 {
30         return phy->mdio_read(phy->dev, phy->address, reg);
31 }
32
33 static inline void phy_write(struct mii_phy *phy, int reg, int val)
34 {
35         phy->mdio_write(phy->dev, phy->address, reg, val);
36 }
37
38 /*
39  * polls MII_BMCR until BMCR_RESET bit clears or operation times out.
40  *
41  * returns:
42  *      >= 0 => success, value in BMCR returned to caller
43  *      -EBUSY => failure, RESET bit never cleared
44  *      otherwise => failure, lower level PHY read failed
45  */
46 static int mii_spin_reset_complete(struct mii_phy *phy)
47 {
48         int val;
49         int limit = 10000;
50
51         while (limit--) {
52                 val = phy_read(phy, MII_BMCR);
53                 if (val >= 0 && !(val & BMCR_RESET))
54                         return val;     /* success */
55                 udelay(10);
56         }
57         if (val & BMCR_RESET)
58                 val = -EBUSY;
59
60         if (net_ratelimit())
61                 printk(KERN_ERR "emac%d: PHY reset timeout (%d)\n", 
62                        ((struct ocp_enet_private *)phy->dev->priv)->def->index,
63                        val);
64         return val;                 
65 }
66
67 int mii_reset_phy(struct mii_phy *phy)
68 {
69         int val;
70
71         val = phy_read(phy, MII_BMCR);
72         val &= ~BMCR_ISOLATE;
73         val |= BMCR_RESET;
74         phy_write(phy, MII_BMCR, val);
75
76         udelay(300);
77
78         val = mii_spin_reset_complete(phy);
79         if (val >= 0 && (val & BMCR_ISOLATE))
80                 phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
81
82         return val < 0;
83 }
84
85 static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
86 {
87         int ctl, adv;
88
89         phy->autoneg = AUTONEG_ENABLE;
90         phy->speed = SPEED_10;
91         phy->duplex = DUPLEX_HALF;
92         phy->pause = phy->asym_pause = 0;
93         phy->advertising = advertise;
94
95         /* Setup standard advertise */
96         adv = phy_read(phy, MII_ADVERTISE);
97         if (adv < 0)
98                 return adv;
99         adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
100                  ADVERTISE_PAUSE_ASYM);
101         if (advertise & ADVERTISED_10baseT_Half)
102                 adv |= ADVERTISE_10HALF;
103         if (advertise & ADVERTISED_10baseT_Full)
104                 adv |= ADVERTISE_10FULL;
105         if (advertise & ADVERTISED_100baseT_Half)
106                 adv |= ADVERTISE_100HALF;
107         if (advertise & ADVERTISED_100baseT_Full)
108                 adv |= ADVERTISE_100FULL;
109         if (advertise & ADVERTISED_Pause)
110                 adv |= ADVERTISE_PAUSE_CAP;
111         if (advertise & ADVERTISED_Asym_Pause)
112                 adv |= ADVERTISE_PAUSE_ASYM;
113         phy_write(phy, MII_ADVERTISE, adv);
114
115         if (phy->features &
116             (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
117                 adv = phy_read(phy, MII_CTRL1000);
118                 if (adv < 0)
119                         return adv;
120                 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
121                 if (advertise & ADVERTISED_1000baseT_Full)
122                         adv |= ADVERTISE_1000FULL;
123                 if (advertise & ADVERTISED_1000baseT_Half)
124                         adv |= ADVERTISE_1000HALF;
125                 phy_write(phy, MII_CTRL1000, adv);
126         }
127
128         /* Start/Restart aneg */
129         /* on some PHYs (e.g. National DP83843) a write to MII_ADVERTISE
130          * causes BMCR_RESET to be set on the next read of MII_BMCR, which
131          * if not checked for causes the PHY to be reset below */
132         ctl = mii_spin_reset_complete(phy);
133         if (ctl < 0)
134                 return ctl;
135
136         ctl |= BMCR_ANENABLE | BMCR_ANRESTART;
137         phy_write(phy, MII_BMCR, ctl);
138
139         return 0;
140 }
141
142 static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
143 {
144         int ctl;
145
146         phy->autoneg = AUTONEG_DISABLE;
147         phy->speed = speed;
148         phy->duplex = fd;
149         phy->pause = phy->asym_pause = 0;
150
151         /* First reset the PHY */
152         mii_reset_phy(phy);
153
154         ctl = phy_read(phy, MII_BMCR);
155         if (ctl < 0)
156                 return ctl;
157         ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE | BMCR_SPEED1000);
158
159         /* Select speed & duplex */
160         switch (speed) {
161         case SPEED_10:
162                 break;
163         case SPEED_100:
164                 ctl |= BMCR_SPEED100;
165                 break;
166         case SPEED_1000:
167                 ctl |= BMCR_SPEED1000;
168                 break;
169         default:
170                 return -EINVAL;
171         }
172         if (fd == DUPLEX_FULL)
173                 ctl |= BMCR_FULLDPLX;
174         phy_write(phy, MII_BMCR, ctl);
175
176         return 0;
177 }
178
179 static int genmii_poll_link(struct mii_phy *phy)
180 {
181         int status;
182
183         /* Clear latched value with dummy read */
184         phy_read(phy, MII_BMSR);
185         status = phy_read(phy, MII_BMSR);
186         if (status < 0 || (status & BMSR_LSTATUS) == 0)
187                 return 0;
188         if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
189                 return 0;
190         return 1;
191 }
192
193 static int genmii_read_link(struct mii_phy *phy)
194 {
195         if (phy->autoneg == AUTONEG_ENABLE) {
196                 int glpa = 0;
197                 int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
198                 if (lpa < 0)
199                         return lpa;
200
201                 if (phy->features &
202                     (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
203                         int adv = phy_read(phy, MII_CTRL1000);
204                         glpa = phy_read(phy, MII_STAT1000);
205
206                         if (glpa < 0 || adv < 0)
207                                 return adv;
208
209                         glpa &= adv << 2;
210                 }
211
212                 phy->speed = SPEED_10;
213                 phy->duplex = DUPLEX_HALF;
214                 phy->pause = phy->asym_pause = 0;
215
216                 if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
217                         phy->speed = SPEED_1000;
218                         if (glpa & LPA_1000FULL)
219                                 phy->duplex = DUPLEX_FULL;
220                 } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
221                         phy->speed = SPEED_100;
222                         if (lpa & LPA_100FULL)
223                                 phy->duplex = DUPLEX_FULL;
224                 } else if (lpa & LPA_10FULL)
225                         phy->duplex = DUPLEX_FULL;
226
227                 if (phy->duplex == DUPLEX_FULL) {
228                         phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
229                         phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
230                 }
231         } else {
232                 int bmcr = phy_read(phy, MII_BMCR);
233                 if (bmcr < 0)
234                         return bmcr;
235
236                 if (bmcr & BMCR_FULLDPLX)
237                         phy->duplex = DUPLEX_FULL;
238                 else
239                         phy->duplex = DUPLEX_HALF;
240                 if (bmcr & BMCR_SPEED1000)
241                         phy->speed = SPEED_1000;
242                 else if (bmcr & BMCR_SPEED100)
243                         phy->speed = SPEED_100;
244                 else
245                         phy->speed = SPEED_10;
246
247                 phy->pause = phy->asym_pause = 0;
248         }
249         return 0;
250 }
251
252 /* Generic implementation for most 10/100/1000 PHYs */
253 static struct mii_phy_ops generic_phy_ops = {
254         .setup_aneg     = genmii_setup_aneg,
255         .setup_forced   = genmii_setup_forced,
256         .poll_link      = genmii_poll_link,
257         .read_link      = genmii_read_link
258 };
259
260 static struct mii_phy_def genmii_phy_def = {
261         .phy_id         = 0x00000000,
262         .phy_id_mask    = 0x00000000,
263         .name           = "Generic MII",
264         .ops            = &generic_phy_ops
265 };
266
267 /* CIS8201 */
268 #define MII_CIS8201_10BTCSR     0x16
269 #define  TENBTCSR_ECHO_DISABLE  0x2000
270 #define MII_CIS8201_EPCR        0x17
271 #define  EPCR_MODE_MASK         0x3000
272 #define  EPCR_GMII_MODE         0x0000
273 #define  EPCR_RGMII_MODE        0x1000
274 #define  EPCR_TBI_MODE          0x2000
275 #define  EPCR_RTBI_MODE         0x3000
276 #define MII_CIS8201_ACSR        0x1c
277 #define  ACSR_PIN_PRIO_SELECT   0x0004
278
279 static int cis8201_init(struct mii_phy *phy)
280 {
281         int epcr;
282
283         epcr = phy_read(phy, MII_CIS8201_EPCR);
284         if (epcr < 0)
285                 return epcr;
286
287         epcr &= ~EPCR_MODE_MASK;
288
289         switch (phy->mode) {
290         case PHY_MODE_TBI:
291                 epcr |= EPCR_TBI_MODE;
292                 break;
293         case PHY_MODE_RTBI:
294                 epcr |= EPCR_RTBI_MODE;
295                 break;
296         case PHY_MODE_GMII:
297                 epcr |= EPCR_GMII_MODE;
298                 break;
299         case PHY_MODE_RGMII:
300         default:
301                 epcr |= EPCR_RGMII_MODE;
302         }
303
304         phy_write(phy, MII_CIS8201_EPCR, epcr);
305         
306         /* MII regs override strap pins */
307         phy_write(phy, MII_CIS8201_ACSR, 
308                   phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
309
310         /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
311         phy_write(phy, MII_CIS8201_10BTCSR,
312                   phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
313
314         return 0;
315 }
316
317 static struct mii_phy_ops cis8201_phy_ops = {
318         .init           = cis8201_init,
319         .setup_aneg     = genmii_setup_aneg,
320         .setup_forced   = genmii_setup_forced,
321         .poll_link      = genmii_poll_link,
322         .read_link      = genmii_read_link
323 };
324
325 static struct mii_phy_def cis8201_phy_def = {
326         .phy_id         = 0x000fc410,
327         .phy_id_mask    = 0x000ffff0,
328         .name           = "CIS8201 Gigabit Ethernet",
329         .ops            = &cis8201_phy_ops
330 };
331
332 static struct mii_phy_def *mii_phy_table[] = {
333         &cis8201_phy_def,
334         &genmii_phy_def,
335         NULL
336 };
337
338 int mii_phy_probe(struct mii_phy *phy, int address)
339 {
340         struct mii_phy_def *def;
341         int i;
342         int id;
343
344         phy->autoneg = AUTONEG_DISABLE;
345         phy->advertising = 0;
346         phy->address = address;
347         phy->speed = SPEED_10;
348         phy->duplex = DUPLEX_HALF;
349         phy->pause = phy->asym_pause = 0;
350
351         /* Take PHY out of isolate mode and reset it. */
352         if (mii_reset_phy(phy))
353                 return -ENODEV;
354
355         /* Read ID and find matching entry */
356         id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
357         if (id < 0)
358                 return -ENODEV;
359         for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
360                 if ((id & def->phy_id_mask) == def->phy_id)
361                         break;
362         /* Should never be NULL (we have a generic entry), but... */
363         if (!def)
364                 return -ENODEV;
365
366         phy->def = def;
367
368         /* Determine PHY features if needed */
369         phy->features = def->features;
370         if (!phy->features) {
371                 u16 bmsr = phy_read(phy, MII_BMSR);
372                 if (bmsr & BMSR_ANEGCAPABLE)
373                         phy->features |= SUPPORTED_Autoneg;
374                 if (bmsr & BMSR_10HALF)
375                         phy->features |= SUPPORTED_10baseT_Half;
376                 if (bmsr & BMSR_10FULL)
377                         phy->features |= SUPPORTED_10baseT_Full;
378                 if (bmsr & BMSR_100HALF)
379                         phy->features |= SUPPORTED_100baseT_Half;
380                 if (bmsr & BMSR_100FULL)
381                         phy->features |= SUPPORTED_100baseT_Full;
382                 if (bmsr & BMSR_ESTATEN) {
383                         u16 esr = phy_read(phy, MII_ESTATUS);
384                         if (esr & ESTATUS_1000_TFULL)
385                                 phy->features |= SUPPORTED_1000baseT_Full;
386                         if (esr & ESTATUS_1000_THALF)
387                                 phy->features |= SUPPORTED_1000baseT_Half;
388                 }
389                 phy->features |= SUPPORTED_MII;
390         }
391
392         /* Setup default advertising */
393         phy->advertising = phy->features;
394
395         return 0;
396 }
397
398 MODULE_LICENSE("GPL");