1250386Sadrian/*-
2250386Sadrian * Copyright (c) 2013 Luiz Otavio O Souza.
3250386Sadrian * Copyright (c) 2011-2012 Stefan Bethke.
4250386Sadrian * Copyright (c) 2012 Adrian Chadd.
5250386Sadrian * All rights reserved.
6250386Sadrian *
7250386Sadrian * Redistribution and use in source and binary forms, with or without
8250386Sadrian * modification, are permitted provided that the following conditions
9250386Sadrian * are met:
10250386Sadrian * 1. Redistributions of source code must retain the above copyright
11250386Sadrian *    notice, this list of conditions and the following disclaimer.
12250386Sadrian * 2. Redistributions in binary form must reproduce the above copyright
13250386Sadrian *    notice, this list of conditions and the following disclaimer in the
14250386Sadrian *    documentation and/or other materials provided with the distribution.
15250386Sadrian *
16250386Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17250386Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18250386Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19250386Sadrian * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20250386Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21250386Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22250386Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23250386Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24250386Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25250386Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26250386Sadrian * SUCH DAMAGE.
27250386Sadrian *
28250386Sadrian * $FreeBSD$
29250386Sadrian */
30250386Sadrian
31250386Sadrian#include <sys/param.h>
32250386Sadrian#include <sys/bus.h>
33250386Sadrian#include <sys/errno.h>
34250386Sadrian#include <sys/kernel.h>
35262848Sbrueffer#include <sys/lock.h>
36262848Sbrueffer#include <sys/mutex.h>
37250386Sadrian#include <sys/systm.h>
38250386Sadrian#include <sys/socket.h>
39250386Sadrian
40250386Sadrian#include <net/if.h>
41250386Sadrian
42250386Sadrian#include <dev/mii/mii.h>
43250386Sadrian
44250386Sadrian#include <dev/etherswitch/etherswitch.h>
45250386Sadrian#include <dev/etherswitch/ip17x/ip17x_phy.h>
46250386Sadrian#include <dev/etherswitch/ip17x/ip17x_reg.h>
47250386Sadrian#include <dev/etherswitch/ip17x/ip17x_var.h>
48250386Sadrian
49250386Sadrian#include "mdio_if.h"
50250386Sadrian#include "miibus_if.h"
51250386Sadrian#include "etherswitch_if.h"
52250386Sadrian
53250386Sadrianint
54250386Sadrianip17x_readphy(device_t dev, int phy, int reg)
55250386Sadrian{
56250386Sadrian	struct ip17x_softc *sc;
57250386Sadrian	int data;
58250386Sadrian
59250386Sadrian	sc = device_get_softc(dev);
60250386Sadrian	IP17X_LOCK_ASSERT(sc, MA_NOTOWNED);
61250386Sadrian
62250386Sadrian	if (phy < 0 || phy >= 32)
63250386Sadrian		return (ENXIO);
64250386Sadrian	if (reg < 0 || reg >= 32)
65250386Sadrian		return (ENXIO);
66250386Sadrian
67250386Sadrian	IP17X_LOCK(sc);
68250386Sadrian	data = MDIO_READREG(device_get_parent(dev), phy, reg);
69250386Sadrian	IP17X_UNLOCK(sc);
70250386Sadrian
71250386Sadrian	return (data);
72250386Sadrian}
73250386Sadrian
74250386Sadrianint
75250386Sadrianip17x_writephy(device_t dev, int phy, int reg, int data)
76250386Sadrian{
77250386Sadrian	struct ip17x_softc *sc;
78250386Sadrian	int err;
79250386Sadrian
80250386Sadrian	sc = device_get_softc(dev);
81250386Sadrian	IP17X_LOCK_ASSERT(sc, MA_NOTOWNED);
82250386Sadrian
83250386Sadrian	if (phy < 0 || phy >= 32)
84250386Sadrian		return (ENXIO);
85250386Sadrian	if (reg < 0 || reg >= 32)
86250386Sadrian		return (ENXIO);
87250386Sadrian
88250386Sadrian	IP17X_LOCK(sc);
89250386Sadrian	err = MDIO_WRITEREG(device_get_parent(dev), phy, reg, data);
90250386Sadrian	IP17X_UNLOCK(sc);
91250386Sadrian
92250386Sadrian	return (err);
93250386Sadrian}
94250386Sadrian
95250386Sadrianint
96250386Sadrianip17x_updatephy(device_t dev, int phy, int reg, int mask, int value)
97250386Sadrian{
98250386Sadrian	int val;
99250386Sadrian
100250386Sadrian	val = ip17x_readphy(dev, phy, reg);
101250386Sadrian	val &= ~mask;
102250386Sadrian	val |= value;
103250386Sadrian	return (ip17x_writephy(dev, phy, reg, val));
104250386Sadrian}
105