source: rtems-libbsd/freebsd/dev/dc/pnphy.c @ 5ad09a1

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 5ad09a1 was 5ad09a1, checked in by Joel Sherrill <joel.sherrill@…>, on 03/22/12 at 13:02:26

Add DEC Tulip, Broadcomm (bce, bfe, bge), and SMC 9111x NICs

  • Property mode set to 100644
File size: 6.6 KB
Line 
1#include <freebsd/machine/rtems-bsd-config.h>
2
3/*
4 * Copyright (c) 1997, 1998, 1999
5 *      Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *      This product includes software developed by Bill Paul.
18 * 4. Neither the name of the author nor the names of any co-contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <freebsd/sys/cdefs.h>
36__FBSDID("$FreeBSD$");
37
38/*
39 * Pseudo-driver for media selection on the Lite-On PNIC 82c168
40 * chip.  The NWAY support on this chip is horribly broken, so we
41 * only support manual mode selection.  This is lame, but getting
42 * NWAY to work right is amazingly difficult.
43 */
44
45#include <freebsd/sys/param.h>
46#include <freebsd/sys/systm.h>
47#include <freebsd/sys/kernel.h>
48#include <freebsd/sys/socket.h>
49#include <freebsd/sys/errno.h>
50#include <freebsd/sys/lock.h>
51#include <freebsd/sys/module.h>
52#include <freebsd/sys/mutex.h>
53#include <freebsd/sys/bus.h>
54
55#include <freebsd/net/if.h>
56#include <freebsd/net/if_arp.h>
57#include <freebsd/net/if_media.h>
58
59#include <freebsd/dev/mii/mii.h>
60#include <freebsd/dev/mii/miivar.h>
61#include <freebsd/local/miidevs.h>
62
63#include <freebsd/machine/bus.h>
64#include <freebsd/machine/resource.h>
65#include <freebsd/sys/bus.h>
66
67#include <freebsd/dev/dc/if_dcreg.h>
68
69#include <freebsd/local/miibus_if.h>
70
71#define DC_SETBIT(sc, reg, x)                           \
72        CSR_WRITE_4(sc, reg,                            \
73                CSR_READ_4(sc, reg) | x)
74
75#define DC_CLRBIT(sc, reg, x)                           \
76        CSR_WRITE_4(sc, reg,                            \
77                CSR_READ_4(sc, reg) & ~x)
78
79static int pnphy_probe(device_t);
80static int pnphy_attach(device_t);
81
82static device_method_t pnphy_methods[] = {
83        /* device interface */
84        DEVMETHOD(device_probe,         pnphy_probe),
85        DEVMETHOD(device_attach,        pnphy_attach),
86        DEVMETHOD(device_detach,        mii_phy_detach),
87        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
88        { 0, 0 }
89};
90
91static devclass_t pnphy_devclass;
92
93static driver_t pnphy_driver = {
94        "pnphy",
95        pnphy_methods,
96        sizeof(struct mii_softc)
97};
98
99DRIVER_MODULE(pnphy, miibus, pnphy_driver, pnphy_devclass, 0, 0);
100
101static int      pnphy_service(struct mii_softc *, struct mii_data *, int);
102static void     pnphy_status(struct mii_softc *);
103
104static int
105pnphy_probe(device_t dev)
106{
107        struct mii_attach_args *ma;
108
109        ma = device_get_ivars(dev);
110
111        /*
112         * The dc driver will report the 82c168 vendor and device
113         * ID to let us know that it wants us to attach.
114         */
115        if (ma->mii_id1 != DC_VENDORID_LO ||
116            ma->mii_id2 != DC_DEVICEID_82C168)
117                return (ENXIO);
118
119        device_set_desc(dev, "PNIC 82c168 media interface");
120
121        return (BUS_PROBE_DEFAULT);
122}
123
124static int
125pnphy_attach(device_t dev)
126{
127        struct mii_softc *sc;
128        struct mii_attach_args *ma;
129        struct mii_data *mii;
130
131        sc = device_get_softc(dev);
132        ma = device_get_ivars(dev);
133        sc->mii_dev = device_get_parent(dev);
134        mii = ma->mii_data;
135        LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
136
137        sc->mii_flags = miibus_get_flags(dev);
138        sc->mii_inst = mii->mii_instance++;
139        sc->mii_phy = ma->mii_phyno;
140        sc->mii_service = pnphy_service;
141        sc->mii_pdata = mii;
142
143        /*
144         * Apparently, we can neither isolate nor do loopback.
145         */
146        sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP;
147
148        sc->mii_capabilities =
149            BMSR_100TXFDX | BMSR_100TXHDX | BMSR_10TFDX | BMSR_10THDX;
150        sc->mii_capabilities &= ma->mii_capmask;
151        device_printf(dev, " ");
152        mii_phy_add_media(sc);
153        printf("\n");
154
155        MIIBUS_MEDIAINIT(sc->mii_dev);
156        return (0);
157}
158
159static int
160pnphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
161{
162        struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
163
164        switch (cmd) {
165        case MII_POLLSTAT:
166                break;
167
168        case MII_MEDIACHG:
169                /*
170                 * If the interface is not up, don't do anything.
171                 */
172                if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
173                        break;
174
175                switch (IFM_SUBTYPE(ife->ifm_media)) {
176                case IFM_AUTO:
177                        /* NWAY is busted on this chip */
178                case IFM_100_T4:
179                        /*
180                         * XXX Not supported as a manual setting right now.
181                         */
182                        return (EINVAL);
183                case IFM_100_TX:
184                        mii->mii_media_active = IFM_ETHER | IFM_100_TX;
185                        if ((ife->ifm_media & IFM_GMASK) == IFM_FDX)
186                                mii->mii_media_active |= IFM_FDX;
187                        MIIBUS_STATCHG(sc->mii_dev);
188                        return (0);
189                case IFM_10_T:
190                        mii->mii_media_active = IFM_ETHER | IFM_10_T;
191                        if ((ife->ifm_media & IFM_GMASK) == IFM_FDX)
192                                mii->mii_media_active |= IFM_FDX;
193                        MIIBUS_STATCHG(sc->mii_dev);
194                        return (0);
195                default:
196                        return (EINVAL);
197                }
198                break;
199
200        case MII_TICK:
201                /*
202                 * Is the interface even up?
203                 */
204                if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
205                        return (0);
206
207                break;
208        }
209
210        /* Update the media status. */
211        pnphy_status(sc);
212
213        /* Callback if something changed. */
214        mii_phy_update(sc, cmd);
215        return (0);
216}
217
218static void
219pnphy_status(struct mii_softc *sc)
220{
221        struct mii_data *mii = sc->mii_pdata;
222        int reg;
223        struct dc_softc         *dc_sc;
224
225        dc_sc = mii->mii_ifp->if_softc;
226
227        mii->mii_media_status = IFM_AVALID;
228        mii->mii_media_active = IFM_ETHER;
229
230        reg = CSR_READ_4(dc_sc, DC_ISR);
231
232        if (!(reg & DC_ISR_LINKFAIL))
233                mii->mii_media_status |= IFM_ACTIVE;
234
235        if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_SPEEDSEL)
236                mii->mii_media_active |= IFM_10_T;
237        else
238                mii->mii_media_active |= IFM_100_TX;
239        if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_FULLDUPLEX)
240                mii->mii_media_active |= IFM_FDX;
241        else
242                mii->mii_media_active |= IFM_HDX;
243}
Note: See TracBrowser for help on using the repository browser.