- Replace lnc(4) driver with NetBSD's le(4), which gives us better performance,
[dragonfly.git] / sys / dev / netif / mii_layer / e1000phy.c
1 /* $FreeBSD: src/sys/dev/mii/e1000phy.c,v 1.1.2.2 2002/11/08 21:53:49 semenu Exp $ */
2 /* $DragonFly: src/sys/dev/netif/mii_layer/e1000phy.c,v 1.7 2005/10/24 16:55:40 dillon Exp $ */
3 /*
4  * Principal Author: Parag Patel
5  * Copyright (c) 2001
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice unmodified, this list of conditions, and the following
13  *    disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * Additonal Copyright (c) 2001 by Traakan Software under same licence.
31  * Secondary Author: Matthew Jacob
32  */
33
34 /*
35  * driver for the Marvell 88E1000 series external 1000/100/10-BT PHY.
36  */
37
38 /*
39  * Support added for the Marvell 88E1011 (Alaska) 1000/100/10baseTX and
40  * 1000baseSX PHY.
41  * Nathan Binkert <nate@openbsd.org>
42  * Jung-uk Kim <jkim@niksun.com>
43  */
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/socket.h>
49 #include <sys/bus.h>
50
51 #include <machine/clock.h>
52
53 #include <net/if.h>
54 #include <net/if_media.h>
55
56 #include "mii.h"
57 #include "miivar.h"
58 #include "miidevs.h"
59
60 #include "e1000phyreg.h"
61
62 #include "miibus_if.h"
63
64 static int e1000phy_probe(device_t);
65 static int e1000phy_attach(device_t);
66 static int e1000phy_detach(device_t);
67
68 static device_method_t e1000phy_methods[] = {
69         /* device interface */
70         DEVMETHOD(device_probe,         e1000phy_probe),
71         DEVMETHOD(device_attach,        e1000phy_attach),
72         DEVMETHOD(device_detach,        e1000phy_detach),
73         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
74         { 0, 0 }
75 };
76
77 static devclass_t e1000phy_devclass;
78 static driver_t e1000phy_driver = {
79         "e1000phy", e1000phy_methods, sizeof (struct mii_softc)
80 };
81 DRIVER_MODULE(e1000phy, miibus, e1000phy_driver, e1000phy_devclass, 0, 0);
82
83 int     e1000phy_service(struct mii_softc *, struct mii_data *, int);
84 void    e1000phy_status(struct mii_softc *);
85
86 static int      e1000phy_mii_phy_auto(struct mii_softc *, int);
87 extern void     mii_phy_auto_timeout(void *);
88 static void     e1000phy_reset(struct mii_softc *);
89
90 static int e1000phy_debug = 0;
91
92 static int
93 e1000phy_probe(device_t dev)
94 {
95         struct mii_attach_args *ma;
96         u_int32_t id;
97
98         ma = device_get_ivars(dev);
99         id = ((ma->mii_id1 << 16) | ma->mii_id2) & E1000_ID_MASK;
100         if (id != E1000_ID_88E1000
101             && id != E1000_ID_88E1000S
102             && id != E1000_ID_88E1011) {
103                 return ENXIO;
104         }
105
106         device_set_desc(dev, MII_STR_MARVELL_E1000);
107         return 0;
108 }
109
110 static int
111 e1000phy_attach(device_t dev)
112 {
113         struct mii_softc *sc;
114         struct mii_attach_args *ma;
115         struct mii_data *mii;
116         const char *sep = "";
117         u_int32_t id;
118
119         getenv_int("e1000phy_debug", &e1000phy_debug);
120
121         sc = device_get_softc(dev);
122         ma = device_get_ivars(dev);
123         mii_softc_init(sc, ma);
124         sc->mii_dev = device_get_parent(dev);
125         mii = device_get_softc(sc->mii_dev);
126         LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
127
128         sc->mii_inst = mii->mii_instance;
129         sc->mii_service = e1000phy_service;
130         sc->mii_pdata = mii;
131         sc->mii_flags |= MIIF_NOISOLATE;
132
133         id = ((ma->mii_id1 << 16) | ma->mii_id2) & E1000_ID_MASK;
134         if (id == E1000_ID_88E1011
135             && (PHY_READ(sc, E1000_ESSR) & E1000_ESSR_FIBER_LINK))
136                 sc->mii_flags |= MIIF_HAVEFIBER;
137         mii->mii_instance++;
138         e1000phy_reset(sc);
139
140 #define ADD(m, c)       ifmedia_add(&mii->mii_media, (m), (c), NULL)
141 #define PRINT(s)        printf("%s%s", sep, s); sep = ", "
142
143 #if     0
144         ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
145             E1000_CR_ISOLATE);
146 #endif
147
148         device_printf(dev, " ");
149         if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
150                 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst),
151                                 E1000_CR_SPEED_1000 | E1000_CR_FULL_DUPLEX);
152                 PRINT("1000baseTX-FDX");
153                 /*
154                 TODO - apparently 1000BT-simplex not supported?
155                 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst),
156                                 E1000_CR_SPEED_1000);
157                 PRINT("1000baseTX");
158                 */
159                 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst),
160                                 E1000_CR_SPEED_100 | E1000_CR_FULL_DUPLEX);
161                 PRINT("100baseTX-FDX");
162                 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst),
163                                 E1000_CR_SPEED_100);
164                 PRINT("100baseTX");
165                 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst),
166                                 E1000_CR_SPEED_10 | E1000_CR_FULL_DUPLEX);
167                 PRINT("10baseTX-FDX");
168                 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst),
169                                 E1000_CR_SPEED_10);
170                 PRINT("10baseTX");
171         } else {
172                 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst),
173                                 E1000_CR_SPEED_1000);
174                 PRINT("1000baseSX-FDX");
175         }
176         ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0);
177         PRINT("auto");
178
179         printf("\n");
180 #undef ADD
181 #undef PRINT
182
183         MIIBUS_MEDIAINIT(sc->mii_dev);
184         return(0);
185 }
186
187 static int
188 e1000phy_detach(device_t dev)
189 {
190         struct mii_softc *sc;
191         struct mii_data *mii;
192
193         sc = device_get_softc(dev);
194         mii = device_get_softc(device_get_parent(dev));
195
196         if (sc->mii_flags & MIIF_DOINGAUTO)
197                 callout_stop(&sc->mii_auto_ch);
198
199         sc->mii_dev = NULL;
200         LIST_REMOVE(sc, mii_list);
201
202         return 0;
203 }
204
205 static void
206 e1000phy_reset(struct mii_softc *sc)
207 {
208         u_int32_t reg;
209         int i;
210
211         /* initialize custom E1000 registers to magic values */
212         reg = PHY_READ(sc, E1000_SCR);
213         reg &= ~E1000_SCR_AUTO_X_MODE;
214         PHY_WRITE(sc, E1000_SCR, reg);
215
216         /* normal PHY reset */
217         /*mii_phy_reset(sc);*/
218         reg = PHY_READ(sc, E1000_CR);
219         reg |= E1000_CR_RESET;
220         PHY_WRITE(sc, E1000_CR, reg);
221
222         for (i = 0; i < 500; i++) {
223                 DELAY(1);
224                 reg = PHY_READ(sc, E1000_CR);
225                 if (!(reg & E1000_CR_RESET))
226                         break;
227         }
228
229         /* set more custom E1000 registers to magic values */
230         reg = PHY_READ(sc, E1000_SCR);
231         reg |= E1000_SCR_ASSERT_CRS_ON_TX;
232         PHY_WRITE(sc, E1000_SCR, reg);
233
234         reg = PHY_READ(sc, E1000_ESCR);
235         reg |= E1000_ESCR_TX_CLK_25;
236         PHY_WRITE(sc, E1000_ESCR, reg);
237
238         /* even more magic to reset DSP? */
239         PHY_WRITE(sc, 29, 0x1d);
240         PHY_WRITE(sc, 30, 0xc1);
241         PHY_WRITE(sc, 30, 0x00);
242 }
243
244 int
245 e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
246 {
247         struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
248         int reg;
249
250         switch (cmd) {
251         case MII_POLLSTAT:
252                 /*
253                  * If we're not polling our PHY instance, just return.
254                  */
255                 if (IFM_INST(ife->ifm_media) != sc->mii_inst)
256                         return (0);
257                 break;
258
259         case MII_MEDIACHG:
260                 /*
261                  * If the media indicates a different PHY instance,
262                  * isolate ourselves.
263                  */
264                 if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
265                         reg = PHY_READ(sc, E1000_CR);
266                         PHY_WRITE(sc, E1000_CR, reg | E1000_CR_ISOLATE);
267                         return (0);
268                 }
269
270                 /*
271                  * If the interface is not up, don't do anything.
272                  */
273                 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) {
274                         break;
275                 }
276
277                 switch (IFM_SUBTYPE(ife->ifm_media)) {
278                 case IFM_AUTO:
279                         /*
280                          * If we're already in auto mode, just return.
281                          */
282                         if (sc->mii_flags & MIIF_DOINGAUTO) {
283                                 return (0);
284                         }
285                         e1000phy_reset(sc);
286                         (void)e1000phy_mii_phy_auto(sc, 1);
287                         break;
288
289                 case IFM_1000_SX:
290                         e1000phy_reset(sc);
291
292                         PHY_WRITE(sc, E1000_CR,
293                             E1000_CR_FULL_DUPLEX | E1000_CR_SPEED_1000);
294                         PHY_WRITE(sc, E1000_AR, E1000_FA_1000X_FD);
295                         break;
296
297                 case IFM_1000_T:
298                         if (sc->mii_flags & MIIF_DOINGAUTO)
299                                 return (0);
300
301                         e1000phy_reset(sc);
302
303                         /* TODO - any other way to force 1000BT? */
304                         (void)e1000phy_mii_phy_auto(sc, 1);
305                         break;
306
307                 case IFM_100_TX:
308                         e1000phy_reset(sc);
309
310                         if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) {
311                                 PHY_WRITE(sc, E1000_CR,
312                                     E1000_CR_FULL_DUPLEX | E1000_CR_SPEED_100);
313                                 PHY_WRITE(sc, E1000_AR, E1000_AR_100TX_FD);
314                         } else {
315                                 PHY_WRITE(sc, E1000_CR, E1000_CR_SPEED_100);
316                                 PHY_WRITE(sc, E1000_AR, E1000_AR_100TX);
317                         }
318                         break;
319
320                 case IFM_10_T:
321                         e1000phy_reset(sc);
322
323                         if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) {
324                                 PHY_WRITE(sc, E1000_CR,
325                                     E1000_CR_FULL_DUPLEX | E1000_CR_SPEED_10);
326                                 PHY_WRITE(sc, E1000_AR, E1000_AR_10T_FD);
327                         } else {
328                                 PHY_WRITE(sc, E1000_CR, E1000_CR_SPEED_10);
329                                 PHY_WRITE(sc, E1000_AR, E1000_AR_10T);
330                         }
331
332                         break;
333
334                 default:
335                         return (EINVAL);
336                 }
337
338                 break;
339
340         case MII_TICK:
341                 /*
342                  * If we're not currently selected, just return.
343                  */
344                 if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
345                         return (0);
346                 }
347
348                 /*
349                  * Only used for autonegotiation.
350                  */
351                 if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
352                         return (0);
353                 }
354
355                 /*
356                  * Is the interface even up?
357                  */
358                 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) {
359                         return (0);
360                 }
361
362                 /*
363                  * Only retry autonegotiation every 5 seconds.
364                  */
365                 if (++(sc->mii_ticks) != 5) {
366                         return (0);
367                 }
368                 sc->mii_ticks = 0;
369
370                 /*
371                  * Check to see if we have link.  If we do, we don't
372                  * need to restart the autonegotiation process.  Read
373                  * the BMSR twice in case it's latched.
374                  */
375                 reg = PHY_READ(sc, E1000_SR) | PHY_READ(sc, E1000_SR);
376
377                 if (reg & E1000_SR_LINK_STATUS)
378                         break;
379
380                 e1000phy_reset(sc);
381
382                 if (e1000phy_mii_phy_auto(sc, 0) == EJUSTRETURN) {
383                         return(0);
384                 }
385
386                 break;
387         }
388
389         /* Update the media status. */
390         e1000phy_status(sc);
391
392         /* Callback if something changed. */
393         if (sc->mii_active != mii->mii_media_active || cmd == MII_MEDIACHG) {
394                 MIIBUS_STATCHG(sc->mii_dev);
395                 sc->mii_active = mii->mii_media_active;
396         }
397
398         return (0);
399 }
400
401 void
402 e1000phy_status(struct mii_softc *sc)
403 {
404         struct mii_data *mii = sc->mii_pdata;
405         int bmsr, bmcr, esr, ssr, isr, ar, lpar;
406
407         mii->mii_media_status = IFM_AVALID;
408         mii->mii_media_active = IFM_ETHER;
409
410         bmsr = PHY_READ(sc, E1000_SR) | PHY_READ(sc, E1000_SR);
411         esr = PHY_READ(sc, E1000_ESR);
412         bmcr = PHY_READ(sc, E1000_CR);
413         ssr = PHY_READ(sc, E1000_SSR);
414         isr = PHY_READ(sc, E1000_ISR);
415         ar = PHY_READ(sc, E1000_AR);
416         lpar = PHY_READ(sc, E1000_LPAR);
417
418         if (bmsr & E1000_SR_LINK_STATUS)
419                 mii->mii_media_status |= IFM_ACTIVE;
420
421         if (bmcr & E1000_CR_LOOPBACK)
422                 mii->mii_media_active |= IFM_LOOP;
423
424         if ((sc->mii_flags & MIIF_DOINGAUTO) &&
425             (!(bmsr & E1000_SR_AUTO_NEG_COMPLETE) || !(ssr & E1000_SSR_LINK) ||
426             !(ssr & E1000_SSR_SPD_DPLX_RESOLVED))) {
427                 /* Erg, still trying, I guess... */
428                 mii->mii_media_active |= IFM_NONE;
429                 return;
430         }
431
432         if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
433                 if (ssr & E1000_SSR_1000MBS)
434                         mii->mii_media_active |= IFM_1000_T;
435                 else if (ssr & E1000_SSR_100MBS)
436                         mii->mii_media_active |= IFM_100_TX;
437                 else
438                         mii->mii_media_active |= IFM_10_T;
439         } else {
440                 if (ssr & E1000_SSR_1000MBS)
441                         mii->mii_media_active |= IFM_1000_SX;
442         }
443
444         if (ssr & E1000_SSR_DUPLEX)
445                 mii->mii_media_active |= IFM_FDX;
446         else
447                 mii->mii_media_active |= IFM_HDX;
448
449         if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
450                 /* FLAG0==rx-flow-control FLAG1==tx-flow-control */
451                 if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) {
452                         mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1;
453                 } else if (!(ar & E1000_AR_PAUSE) && (ar & E1000_AR_ASM_DIR) &&
454                     (lpar & E1000_LPAR_PAUSE) && (lpar & E1000_LPAR_ASM_DIR)) {
455                         mii->mii_media_active |= IFM_FLAG1;
456                 } else if ((ar & E1000_AR_PAUSE) && (ar & E1000_AR_ASM_DIR) &&
457                     !(lpar & E1000_LPAR_PAUSE) && (lpar & E1000_LPAR_ASM_DIR)) {
458                         mii->mii_media_active |= IFM_FLAG0;
459                 }
460         }
461 }
462
463 static int
464 e1000phy_mii_phy_auto(struct mii_softc *mii, int waitfor)
465 {
466         int bmsr, i;
467
468         if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) {
469                 if ((mii->mii_flags & MIIF_HAVEFIBER) == 0) {
470                         PHY_WRITE(mii, E1000_AR, E1000_AR_10T | E1000_AR_10T_FD |
471                             E1000_AR_100TX | E1000_AR_100TX_FD | 
472                             E1000_AR_PAUSE | E1000_AR_ASM_DIR);
473                         PHY_WRITE(mii, E1000_1GCR, E1000_1GCR_1000T_FD);
474                         PHY_WRITE(mii, E1000_CR,
475                             E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG);
476                 }
477         }
478
479         if (waitfor) {
480                 /* Wait 5 seconds for it to complete. */
481                 for (i = 0; i < 5000; i++) {
482                         bmsr =
483                             PHY_READ(mii, E1000_SR) | PHY_READ(mii, E1000_SR);
484
485                         if (bmsr & E1000_SR_AUTO_NEG_COMPLETE) {
486                                 return (0);
487                         }
488                         DELAY(1000);
489                 }
490
491                 /*
492                  * Don't need to worry about clearing MIIF_DOINGAUTO.
493                  * If that's set, a timeout is pending, and it will
494                  * clear the flag. [do it anyway]
495                  */
496         }
497
498         /*
499          * Just let it finish asynchronously.  This is for the benefit of
500          * the tick handler driving autonegotiation.  Don't want 500ms
501          * delays all the time while the system is running!
502          */
503         if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) {
504                 mii->mii_flags |= MIIF_DOINGAUTO;
505                 mii->mii_ticks = 0;
506                 callout_reset(&mii->mii_auto_ch, 5 * hz,
507                                 mii_phy_auto_timeout, mii);
508         }
509         return (EJUSTRETURN);
510 }