1 /* $NetBSD: pnaphy.c,v 1.19 2008/05/04 17:06:10 xtraeme Exp $ */
4 * Copyright 2001 Wasabi Systems, Inc.
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following 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 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
39 * Driver for generic HomePNA 1.0 PHYs.
41 * HomePNA 1.0 PHYs are pretty simple -- they support exactly one
42 * media type, and don't do autonegotiation.
44 * HomePNA PHYs often have vendor-specific registers for tuning
45 * the network connection, but we don't deal with any of that
49 #include <sys/cdefs.h>
50 __KERNEL_RCSID(0, "$NetBSD: pnaphy.c,v 1.19 2008/05/04 17:06:10 xtraeme Exp $");
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/kernel.h>
55 #include <sys/device.h>
56 #include <sys/socket.h>
57 #include <sys/errno.h>
60 #include <net/if_media.h>
62 #include <dev/mii/mii.h>
63 #include <dev/mii/miivar.h>
64 #include <dev/mii/miidevs.h>
66 static int pnaphymatch(device_t
, cfdata_t
, void *);
67 static void pnaphyattach(device_t
, device_t
, void *);
69 CFATTACH_DECL_NEW(pnaphy
, sizeof(struct mii_softc
),
70 pnaphymatch
, pnaphyattach
, mii_phy_detach
, mii_phy_activate
);
72 static int pnaphy_service(struct mii_softc
*, struct mii_data
*, int);
73 static void pnaphy_status(struct mii_softc
*);
75 static const struct mii_phy_funcs pnaphy_funcs
= {
76 pnaphy_service
, pnaphy_status
, mii_phy_reset
,
79 static const struct mii_phydesc pnaphys
[] = {
80 { MII_OUI_yyAMD
, MII_MODEL_yyAMD_79c901home
,
81 MII_STR_yyAMD_79c901home
},
88 pnaphymatch(device_t parent
, cfdata_t match
, void *aux
)
90 struct mii_attach_args
*ma
= aux
;
92 if (mii_phy_match(ma
, pnaphys
) != NULL
) {
94 * Match higher than ukphy, but lower than a specific
104 pnaphyattach(device_t parent
, device_t self
, void *aux
)
106 struct mii_softc
*sc
= device_private(self
);
107 struct mii_attach_args
*ma
= aux
;
108 struct mii_data
*mii
= ma
->mii_data
;
109 const struct mii_phydesc
*mpd
;
111 mpd
= mii_phy_match(ma
, pnaphys
);
112 aprint_naive(": Media interface\n");
113 aprint_normal(": %s, rev. %d\n", mpd
->mpd_name
, MII_REV(ma
->mii_id2
));
116 sc
->mii_inst
= mii
->mii_instance
;
117 sc
->mii_phy
= ma
->mii_phyno
;
118 sc
->mii_funcs
= &pnaphy_funcs
;
120 sc
->mii_flags
= ma
->mii_flags
| MIIF_IS_HPNA
; /* force HomePNA */
121 sc
->mii_anegticks
= MII_ANEGTICKS
;
125 sc
->mii_capabilities
=
126 PHY_READ(sc
, MII_BMSR
) & ma
->mii_capmask
;
127 aprint_normal_dev(self
, "");
128 if ((sc
->mii_capabilities
& BMSR_MEDIAMASK
) == 0)
129 aprint_error("no media present");
131 mii_phy_add_media(sc
);
136 pnaphy_service(struct mii_softc
*sc
, struct mii_data
*mii
, int cmd
)
138 struct ifmedia_entry
*ife
= mii
->mii_media
.ifm_cur
;
144 * If we're not polling our PHY instance, just return.
146 if (IFM_INST(ife
->ifm_media
) != sc
->mii_inst
)
152 * If the media indicates a different PHY instance,
155 if (IFM_INST(ife
->ifm_media
) != sc
->mii_inst
) {
156 reg
= PHY_READ(sc
, MII_BMCR
);
157 PHY_WRITE(sc
, MII_BMCR
, reg
| BMCR_ISO
);
162 * If the interface is not up, don't do anything.
164 if ((mii
->mii_ifp
->if_flags
& IFF_UP
) == 0)
167 mii_phy_setmedia(sc
);
172 * If we're not currently selected, just return.
174 if (IFM_INST(ife
->ifm_media
) != sc
->mii_inst
)
177 if (mii_phy_tick(sc
) == EJUSTRETURN
)
186 /* Update the media status. */
189 /* Callback if something changed. */
190 mii_phy_update(sc
, cmd
);
195 pnaphy_status(struct mii_softc
*sc
)
197 struct mii_data
*mii
= sc
->mii_pdata
;
198 struct ifmedia_entry
*ife
= mii
->mii_media
.ifm_cur
;
201 mii
->mii_media_status
= IFM_AVALID
;
202 mii
->mii_media_active
= IFM_ETHER
;
204 bmsr
= PHY_READ(sc
, MII_BMSR
) | PHY_READ(sc
, MII_BMSR
);
206 if (bmsr
& BMSR_LINK
)
207 mii
->mii_media_status
|= IFM_ACTIVE
;
209 bmcr
= PHY_READ(sc
, MII_BMCR
);
210 if (bmcr
& BMCR_ISO
) {
211 mii
->mii_media_active
|= IFM_NONE
;
212 mii
->mii_media_status
= 0;
216 if (bmcr
& BMCR_LOOP
)
217 mii
->mii_media_active
|= IFM_LOOP
;
220 * On HomePNA PHYs, the current media is always the selected
223 * XXX May not be the case w/ HomePNA 2.
225 mii
->mii_media_active
= ife
->ifm_media
;