1170525Syongari/*	$NetBSD: icsphy.c,v 1.41 2006/11/16 21:24:07 christos Exp $	*/
2170525Syongari
3170525Syongari/*-
4170525Syongari * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
5170525Syongari * All rights reserved.
6170525Syongari *
7170525Syongari * This code is derived from software contributed to The NetBSD Foundation
8170525Syongari * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9170525Syongari * NASA Ames Research Center.
10170525Syongari *
11170525Syongari * Redistribution and use in source and binary forms, with or without
12170525Syongari * modification, are permitted provided that the following conditions
13170525Syongari * are met:
14170525Syongari * 1. Redistributions of source code must retain the above copyright
15170525Syongari *    notice, this list of conditions and the following disclaimer.
16170525Syongari * 2. Redistributions in binary form must reproduce the above copyright
17170525Syongari *    notice, this list of conditions and the following disclaimer in the
18170525Syongari *    documentation and/or other materials provided with the distribution.
19170525Syongari *
20170525Syongari * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21170525Syongari * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22170525Syongari * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23170525Syongari * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24170525Syongari * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25170525Syongari * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26170525Syongari * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27170525Syongari * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28170525Syongari * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29170525Syongari * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30170525Syongari * POSSIBILITY OF SUCH DAMAGE.
31170525Syongari */
32170525Syongari
33170525Syongari/*
34170525Syongari * Copyright (c) 1997 Manuel Bouyer.  All rights reserved.
35170525Syongari *
36170525Syongari * Redistribution and use in source and binary forms, with or without
37170525Syongari * modification, are permitted provided that the following conditions
38170525Syongari * are met:
39170525Syongari * 1. Redistributions of source code must retain the above copyright
40170525Syongari *    notice, this list of conditions and the following disclaimer.
41170525Syongari * 2. Redistributions in binary form must reproduce the above copyright
42170525Syongari *    notice, this list of conditions and the following disclaimer in the
43170525Syongari *    documentation and/or other materials provided with the distribution.
44170525Syongari *
45170525Syongari * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
46170525Syongari * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47170525Syongari * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
48170525Syongari * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
49170525Syongari * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50170525Syongari * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
51170525Syongari * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
52170525Syongari * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53170525Syongari * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
54170525Syongari * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55170525Syongari */
56170525Syongari
57170525Syongari#include <sys/cdefs.h>
58170525Syongari__FBSDID("$FreeBSD: stable/11/sys/dev/mii/icsphy.c 337755 2018-08-14 14:17:20Z markj $");
59170525Syongari
60170525Syongari/*
61170525Syongari * driver for Integrated Circuit Systems' ICS1889-1893 ethernet 10/100 PHY
62170525Syongari * datasheet from www.icst.com
63170525Syongari */
64170525Syongari
65170525Syongari#include <sys/param.h>
66170525Syongari#include <sys/systm.h>
67170525Syongari#include <sys/kernel.h>
68170525Syongari#include <sys/module.h>
69170525Syongari#include <sys/socket.h>
70170525Syongari#include <sys/bus.h>
71170525Syongari
72170525Syongari#include <net/if.h>
73170525Syongari#include <net/if_media.h>
74170525Syongari
75170525Syongari#include <dev/mii/mii.h>
76170525Syongari#include <dev/mii/miivar.h>
77170525Syongari#include "miidevs.h"
78170525Syongari
79170525Syongari#include <dev/mii/icsphyreg.h>
80170525Syongari
81170525Syongari#include "miibus_if.h"
82170525Syongari
83170525Syongaristatic int	icsphy_probe(device_t dev);
84170525Syongaristatic int	icsphy_attach(device_t dev);
85170525Syongari
86170525Syongaristatic device_method_t icsphy_methods[] = {
87170525Syongari	/* device interface */
88170525Syongari	DEVMETHOD(device_probe,		icsphy_probe),
89170525Syongari	DEVMETHOD(device_attach,	icsphy_attach),
90170525Syongari	DEVMETHOD(device_detach,	mii_phy_detach),
91170525Syongari	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
92227908Smarius	DEVMETHOD_END
93170525Syongari};
94170525Syongari
95170525Syongaristatic devclass_t icsphy_devclass;
96170525Syongari
97170525Syongaristatic driver_t icsphy_driver = {
98170525Syongari	"icsphy",
99170525Syongari	icsphy_methods,
100221407Smarius	sizeof(struct mii_softc)
101170525Syongari};
102170525Syongari
103170525SyongariDRIVER_MODULE(icsphy, miibus, icsphy_driver, icsphy_devclass, 0, 0);
104170525Syongari
105170525Syongaristatic int	icsphy_service(struct mii_softc *, struct mii_data *, int);
106170525Syongaristatic void	icsphy_status(struct mii_softc *);
107170525Syongaristatic void	icsphy_reset(struct mii_softc *);
108170525Syongari
109170525Syongaristatic const struct mii_phydesc icsphys[] = {
110221407Smarius	MII_PHY_DESC(ICS, 1889),
111221407Smarius	MII_PHY_DESC(ICS, 1890),
112221407Smarius	MII_PHY_DESC(ICS, 1892),
113221407Smarius	MII_PHY_DESC(ICS, 1893),
114337755Smarkj	MII_PHY_DESC(ICS, 1893C),
115170525Syongari	MII_PHY_END
116170525Syongari};
117170525Syongari
118221407Smariusstatic const struct mii_phy_funcs icsphy_funcs = {
119221407Smarius	icsphy_service,
120221407Smarius	icsphy_status,
121221407Smarius	icsphy_reset
122221407Smarius};
123221407Smarius
124170525Syongaristatic int
125170525Syongariicsphy_probe(device_t dev)
126170525Syongari{
127170525Syongari
128170525Syongari	return (mii_phy_dev_probe(dev, icsphys, BUS_PROBE_DEFAULT));
129170525Syongari}
130170525Syongari
131170525Syongaristatic int
132170525Syongariicsphy_attach(device_t dev)
133170525Syongari{
134170525Syongari
135221407Smarius	mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE,
136221407Smarius	    &icsphy_funcs, 1);
137170525Syongari	return (0);
138170525Syongari}
139170525Syongari
140170525Syongaristatic int
141170525Syongariicsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
142170525Syongari{
143170525Syongari
144170525Syongari	switch (cmd) {
145170525Syongari	case MII_POLLSTAT:
146170525Syongari		break;
147170525Syongari
148170525Syongari	case MII_MEDIACHG:
149170525Syongari		mii_phy_setmedia(sc);
150170525Syongari		break;
151170525Syongari
152170525Syongari	case MII_TICK:
153170525Syongari		if (mii_phy_tick(sc) == EJUSTRETURN)
154170525Syongari			return (0);
155170525Syongari		break;
156170525Syongari	}
157170525Syongari
158170525Syongari	/* Update the media status. */
159221407Smarius	PHY_STATUS(sc);
160170525Syongari
161170525Syongari	/* Callback if something changed. */
162170525Syongari	mii_phy_update(sc, cmd);
163170525Syongari	return (0);
164170525Syongari}
165170525Syongari
166170525Syongaristatic void
167170525Syongariicsphy_status(struct mii_softc *sc)
168170525Syongari{
169170525Syongari	struct mii_data *mii = sc->mii_pdata;
170170525Syongari	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
171170525Syongari	int bmcr, qpr;
172170525Syongari
173170525Syongari	mii->mii_media_status = IFM_AVALID;
174170525Syongari	mii->mii_media_active = IFM_ETHER;
175170525Syongari
176170525Syongari	/*
177170525Syongari	 * Don't get link from the BMSR.  It's available in the QPR,
178170525Syongari	 * and we have to read it twice to unlatch it anyhow.  This
179170525Syongari	 * gives us fewer register reads.
180170525Syongari	 */
181170525Syongari	qpr = PHY_READ(sc, MII_ICSPHY_QPR);		/* unlatch */
182170525Syongari	qpr = PHY_READ(sc, MII_ICSPHY_QPR);		/* real value */
183170525Syongari
184170525Syongari	if (qpr & QPR_LINK)
185170525Syongari		mii->mii_media_status |= IFM_ACTIVE;
186170525Syongari
187170525Syongari	bmcr = PHY_READ(sc, MII_BMCR);
188170525Syongari	if (bmcr & BMCR_ISO) {
189170525Syongari		mii->mii_media_active |= IFM_NONE;
190170525Syongari		mii->mii_media_status = 0;
191170525Syongari		return;
192170525Syongari	}
193170525Syongari
194170525Syongari	if (bmcr & BMCR_LOOP)
195170525Syongari		mii->mii_media_active |= IFM_LOOP;
196170525Syongari
197170525Syongari	if (bmcr & BMCR_AUTOEN) {
198170525Syongari		if ((qpr & QPR_ACOMP) == 0) {
199170525Syongari			/* Erg, still trying, I guess... */
200170525Syongari			mii->mii_media_active |= IFM_NONE;
201170525Syongari			return;
202170525Syongari		}
203170525Syongari		if (qpr & QPR_SPEED)
204170525Syongari			mii->mii_media_active |= IFM_100_TX;
205170525Syongari		else
206170525Syongari			mii->mii_media_active |= IFM_10_T;
207170525Syongari		if (qpr & QPR_FDX)
208221407Smarius			mii->mii_media_active |=
209221407Smarius			    IFM_FDX | mii_phy_flowstatus(sc);
210170525Syongari		else
211170525Syongari			mii->mii_media_active |= IFM_HDX;
212170525Syongari	} else
213170525Syongari		mii->mii_media_active = ife->ifm_media;
214170525Syongari}
215170525Syongari
216170525Syongaristatic void
217170525Syongariicsphy_reset(struct mii_softc *sc)
218170525Syongari{
219170525Syongari
220170525Syongari	mii_phy_reset(sc);
221170525Syongari	/* set powerdown feature */
222221407Smarius	switch (sc->mii_mpd_model) {
223221407Smarius		case MII_MODEL_ICS_1890:
224221407Smarius		case MII_MODEL_ICS_1893:
225170525Syongari			PHY_WRITE(sc, MII_ICSPHY_ECR2, ECR2_100AUTOPWRDN);
226170525Syongari			break;
227221407Smarius		case MII_MODEL_ICS_1892:
228170525Syongari			PHY_WRITE(sc, MII_ICSPHY_ECR2,
229170525Syongari			    ECR2_10AUTOPWRDN|ECR2_100AUTOPWRDN);
230170525Syongari			break;
231170525Syongari		default:
232170525Syongari			/* 1889 have no ECR2 */
233170525Syongari			break;
234170525Syongari	}
235170525Syongari	/*
236170525Syongari	 * There is no description that the reset do auto-negotiation in the
237170525Syongari	 * data sheet.
238170525Syongari	 */
239170525Syongari	PHY_WRITE(sc, MII_BMCR, BMCR_S100|BMCR_STARTNEG|BMCR_FDX);
240170525Syongari}
241