Deleted Added
full compact
if_smc.c (225354) if_smc.c (226995)
1/*-
2 * Copyright (c) 2008 Benno Rice. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 9 unchanged lines hidden (view full) ---

18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2008 Benno Rice. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 9 unchanged lines hidden (view full) ---

18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include <sys/cdefs.h>
26__FBSDID("$FreeBSD: head/sys/dev/smc/if_smc.c 225354 2011-09-02 20:35:22Z stas $");
26__FBSDID("$FreeBSD: head/sys/dev/smc/if_smc.c 226995 2011-11-01 16:13:59Z marius $");
27
28/*
29 * Driver for SMSC LAN91C111, may work for older variants.
30 */
31
32#ifdef HAVE_KERNEL_OPTION_HEADERS
33#include "opt_device_polling.h"
34#endif

--- 34 unchanged lines hidden (view full) ---

69
70#include <net/bpf.h>
71#include <net/bpfdesc.h>
72
73#include <dev/smc/if_smcreg.h>
74#include <dev/smc/if_smcvar.h>
75
76#include <dev/mii/mii.h>
27
28/*
29 * Driver for SMSC LAN91C111, may work for older variants.
30 */
31
32#ifdef HAVE_KERNEL_OPTION_HEADERS
33#include "opt_device_polling.h"
34#endif

--- 34 unchanged lines hidden (view full) ---

69
70#include <net/bpf.h>
71#include <net/bpfdesc.h>
72
73#include <dev/smc/if_smcreg.h>
74#include <dev/smc/if_smcvar.h>
75
76#include <dev/mii/mii.h>
77#include <dev/mii/mii_bitbang.h>
77#include <dev/mii/miivar.h>
78
79#define SMC_LOCK(sc) mtx_lock(&(sc)->smc_mtx)
80#define SMC_UNLOCK(sc) mtx_unlock(&(sc)->smc_mtx)
81#define SMC_ASSERT_LOCKED(sc) mtx_assert(&(sc)->smc_mtx, MA_OWNED)
82
83#define SMC_INTR_PRIORITY 0
84#define SMC_RX_PRIORITY 5

--- 33 unchanged lines hidden (view full) ---

118static void smc_task_tx(void *, int);
119
120static driver_filter_t smc_intr;
121static timeout_t smc_watchdog;
122#ifdef DEVICE_POLLING
123static poll_handler_t smc_poll;
124#endif
125
78#include <dev/mii/miivar.h>
79
80#define SMC_LOCK(sc) mtx_lock(&(sc)->smc_mtx)
81#define SMC_UNLOCK(sc) mtx_unlock(&(sc)->smc_mtx)
82#define SMC_ASSERT_LOCKED(sc) mtx_assert(&(sc)->smc_mtx, MA_OWNED)
83
84#define SMC_INTR_PRIORITY 0
85#define SMC_RX_PRIORITY 5

--- 33 unchanged lines hidden (view full) ---

119static void smc_task_tx(void *, int);
120
121static driver_filter_t smc_intr;
122static timeout_t smc_watchdog;
123#ifdef DEVICE_POLLING
124static poll_handler_t smc_poll;
125#endif
126
127/*
128 * MII bit-bang glue
129 */
130static uint32_t smc_mii_bitbang_read(device_t);
131static void smc_mii_bitbang_write(device_t, uint32_t);
132
133static const struct mii_bitbang_ops smc_mii_bitbang_ops = {
134 smc_mii_bitbang_read,
135 smc_mii_bitbang_write,
136 {
137 MGMT_MDO, /* MII_BIT_MDO */
138 MGMT_MDI, /* MII_BIT_MDI */
139 MGMT_MCLK, /* MII_BIT_MDC */
140 MGMT_MDOE, /* MII_BIT_DIR_HOST_PHY */
141 0, /* MII_BIT_DIR_PHY_HOST */
142 }
143};
144
126static __inline void
127smc_select_bank(struct smc_softc *sc, uint16_t bank)
128{
129
145static __inline void
146smc_select_bank(struct smc_softc *sc, uint16_t bank)
147{
148
149 bus_barrier(sc->smc_reg, BSR, 2,
150 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
130 bus_write_2(sc->smc_reg, BSR, bank & BSR_BANK_MASK);
151 bus_write_2(sc->smc_reg, BSR, bank & BSR_BANK_MASK);
152 bus_barrier(sc->smc_reg, BSR, 2,
153 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
131}
132
133/* Never call this when not in bank 2. */
134static __inline void
135smc_mmu_wait(struct smc_softc *sc)
136{
137
138 KASSERT((bus_read_2(sc->smc_reg, BSR) &
139 BSR_BANK_MASK) == 2, ("%s: smc_mmu_wait called when not in bank 2",
140 device_get_nameunit(sc->smc_dev)));
141 while (bus_read_2(sc->smc_reg, MMUCR) & MMUCR_BUSY)
142 ;
143}
144
145static __inline uint8_t
154}
155
156/* Never call this when not in bank 2. */
157static __inline void
158smc_mmu_wait(struct smc_softc *sc)
159{
160
161 KASSERT((bus_read_2(sc->smc_reg, BSR) &
162 BSR_BANK_MASK) == 2, ("%s: smc_mmu_wait called when not in bank 2",
163 device_get_nameunit(sc->smc_dev)));
164 while (bus_read_2(sc->smc_reg, MMUCR) & MMUCR_BUSY)
165 ;
166}
167
168static __inline uint8_t
146smc_read_1(struct smc_softc *sc, bus_addr_t offset)
169smc_read_1(struct smc_softc *sc, bus_size_t offset)
147{
148
149 return (bus_read_1(sc->smc_reg, offset));
150}
151
152static __inline void
170{
171
172 return (bus_read_1(sc->smc_reg, offset));
173}
174
175static __inline void
153smc_write_1(struct smc_softc *sc, bus_addr_t offset, uint8_t val)
176smc_write_1(struct smc_softc *sc, bus_size_t offset, uint8_t val)
154{
155
156 bus_write_1(sc->smc_reg, offset, val);
157}
158
159static __inline uint16_t
177{
178
179 bus_write_1(sc->smc_reg, offset, val);
180}
181
182static __inline uint16_t
160smc_read_2(struct smc_softc *sc, bus_addr_t offset)
183smc_read_2(struct smc_softc *sc, bus_size_t offset)
161{
162
163 return (bus_read_2(sc->smc_reg, offset));
164}
165
166static __inline void
184{
185
186 return (bus_read_2(sc->smc_reg, offset));
187}
188
189static __inline void
167smc_write_2(struct smc_softc *sc, bus_addr_t offset, uint16_t val)
190smc_write_2(struct smc_softc *sc, bus_size_t offset, uint16_t val)
168{
169
170 bus_write_2(sc->smc_reg, offset, val);
171}
172
173static __inline void
191{
192
193 bus_write_2(sc->smc_reg, offset, val);
194}
195
196static __inline void
174smc_read_multi_2(struct smc_softc *sc, bus_addr_t offset, uint16_t *datap,
197smc_read_multi_2(struct smc_softc *sc, bus_size_t offset, uint16_t *datap,
175 bus_size_t count)
176{
177
178 bus_read_multi_2(sc->smc_reg, offset, datap, count);
179}
180
181static __inline void
198 bus_size_t count)
199{
200
201 bus_read_multi_2(sc->smc_reg, offset, datap, count);
202}
203
204static __inline void
182smc_write_multi_2(struct smc_softc *sc, bus_addr_t offset, uint16_t *datap,
205smc_write_multi_2(struct smc_softc *sc, bus_size_t offset, uint16_t *datap,
183 bus_size_t count)
184{
185
186 bus_write_multi_2(sc->smc_reg, offset, datap, count);
187}
188
206 bus_size_t count)
207{
208
209 bus_write_multi_2(sc->smc_reg, offset, datap, count);
210}
211
212static __inline void
213smc_barrier(struct smc_softc *sc, bus_size_t offset, bus_size_t length,
214 int flags)
215{
216
217 bus_barrier(sc->smc_reg, offset, length, flags);
218}
219
189int
190smc_probe(device_t dev)
191{
192 int rid, type, error;
193 uint16_t val;
194 struct smc_softc *sc;
195 struct resource *reg;
196

--- 698 unchanged lines hidden (view full) ---

895 * Update the interrupt mask.
896 */
897 if ((ifp->if_capenable & IFCAP_POLLING) == 0)
898 smc_write_1(sc, MSK, sc->smc_mask);
899
900 SMC_UNLOCK(sc);
901}
902
220int
221smc_probe(device_t dev)
222{
223 int rid, type, error;
224 uint16_t val;
225 struct smc_softc *sc;
226 struct resource *reg;
227

--- 698 unchanged lines hidden (view full) ---

926 * Update the interrupt mask.
927 */
928 if ((ifp->if_capenable & IFCAP_POLLING) == 0)
929 smc_write_1(sc, MSK, sc->smc_mask);
930
931 SMC_UNLOCK(sc);
932}
933
903static u_int
904smc_mii_readbits(struct smc_softc *sc, int nbits)
934static uint32_t
935smc_mii_bitbang_read(device_t dev)
905{
936{
906 u_int mgmt, mask, val;
937 struct smc_softc *sc;
938 uint32_t val;
907
939
940 sc = device_get_softc(dev);
941
908 SMC_ASSERT_LOCKED(sc);
909 KASSERT((smc_read_2(sc, BSR) & BSR_BANK_MASK) == 3,
942 SMC_ASSERT_LOCKED(sc);
943 KASSERT((smc_read_2(sc, BSR) & BSR_BANK_MASK) == 3,
910 ("%s: smc_mii_readbits called with bank %d (!= 3)",
944 ("%s: smc_mii_bitbang_read called with bank %d (!= 3)",
911 device_get_nameunit(sc->smc_dev),
912 smc_read_2(sc, BSR) & BSR_BANK_MASK));
913
945 device_get_nameunit(sc->smc_dev),
946 smc_read_2(sc, BSR) & BSR_BANK_MASK));
947
914 /*
915 * Set up the MGMT (aka MII) register.
916 */
917 mgmt = smc_read_2(sc, MGMT) & ~(MGMT_MCLK | MGMT_MDOE | MGMT_MDO);
918 smc_write_2(sc, MGMT, mgmt);
948 val = smc_read_2(sc, MGMT);
949 smc_barrier(sc, MGMT, 2,
950 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
919
951
920 /*
921 * Read the bits in.
922 */
923 for (mask = 1 << (nbits - 1), val = 0; mask; mask >>= 1) {
924 if (smc_read_2(sc, MGMT) & MGMT_MDI)
925 val |= mask;
926
927 smc_write_2(sc, MGMT, mgmt);
928 DELAY(1);
929 smc_write_2(sc, MGMT, mgmt | MGMT_MCLK);
930 DELAY(1);
931 }
932
933 return (val);
934}
935
936static void
952 return (val);
953}
954
955static void
937smc_mii_writebits(struct smc_softc *sc, u_int val, int nbits)
956smc_mii_bitbang_write(device_t dev, uint32_t val)
938{
957{
939 u_int mgmt, mask;
958 struct smc_softc *sc;
940
959
960 sc = device_get_softc(dev);
961
941 SMC_ASSERT_LOCKED(sc);
942 KASSERT((smc_read_2(sc, BSR) & BSR_BANK_MASK) == 3,
962 SMC_ASSERT_LOCKED(sc);
963 KASSERT((smc_read_2(sc, BSR) & BSR_BANK_MASK) == 3,
943 ("%s: smc_mii_writebits called with bank %d (!= 3)",
964 ("%s: smc_mii_bitbang_write called with bank %d (!= 3)",
944 device_get_nameunit(sc->smc_dev),
945 smc_read_2(sc, BSR) & BSR_BANK_MASK));
946
965 device_get_nameunit(sc->smc_dev),
966 smc_read_2(sc, BSR) & BSR_BANK_MASK));
967
947 /*
948 * Set up the MGMT (aka MII) register).
949 */
950 mgmt = smc_read_2(sc, MGMT) & ~(MGMT_MCLK | MGMT_MDOE | MGMT_MDO);
951 mgmt |= MGMT_MDOE;
952
953 /*
954 * Push the bits out.
955 */
956 for (mask = 1 << (nbits - 1); mask; mask >>= 1) {
957 if (val & mask)
958 mgmt |= MGMT_MDO;
959 else
960 mgmt &= ~MGMT_MDO;
961
962 smc_write_2(sc, MGMT, mgmt);
963 DELAY(1);
964 smc_write_2(sc, MGMT, mgmt | MGMT_MCLK);
965 DELAY(1);
966 }
968 smc_write_2(sc, MGMT, val);
969 smc_barrier(sc, MGMT, 2,
970 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
967}
968
969int
970smc_miibus_readreg(device_t dev, int phy, int reg)
971{
972 struct smc_softc *sc;
973 int val;
974
975 sc = device_get_softc(dev);
976
977 SMC_LOCK(sc);
978
979 smc_select_bank(sc, 3);
980
971}
972
973int
974smc_miibus_readreg(device_t dev, int phy, int reg)
975{
976 struct smc_softc *sc;
977 int val;
978
979 sc = device_get_softc(dev);
980
981 SMC_LOCK(sc);
982
983 smc_select_bank(sc, 3);
984
981 /*
982 * Send out the idle pattern.
983 */
984 smc_mii_writebits(sc, 0xffffffff, 32);
985 val = mii_bitbang_readreg(dev, &smc_mii_bitbang_ops, phy, reg);
985
986
986 /*
987 * Start code + read opcode + phy address + phy register
988 */
989 smc_mii_writebits(sc, 6 << 10 | phy << 5 | reg, 14);
990
991 /*
992 * Turnaround + data
993 */
994 val = smc_mii_readbits(sc, 18);
995
996 /*
997 * Reset the MDIO interface.
998 */
999 smc_write_2(sc, MGMT,
1000 smc_read_2(sc, MGMT) & ~(MGMT_MCLK | MGMT_MDOE | MGMT_MDO));
1001
1002 SMC_UNLOCK(sc);
1003 return (val);
1004}
1005
1006int
1007smc_miibus_writereg(device_t dev, int phy, int reg, int data)
1008{
1009 struct smc_softc *sc;
1010
1011 sc = device_get_softc(dev);
1012
1013 SMC_LOCK(sc);
1014
1015 smc_select_bank(sc, 3);
1016
987 SMC_UNLOCK(sc);
988 return (val);
989}
990
991int
992smc_miibus_writereg(device_t dev, int phy, int reg, int data)
993{
994 struct smc_softc *sc;
995
996 sc = device_get_softc(dev);
997
998 SMC_LOCK(sc);
999
1000 smc_select_bank(sc, 3);
1001
1017 /*
1018 * Send idle pattern.
1019 */
1020 smc_mii_writebits(sc, 0xffffffff, 32);
1002 mii_bitbang_writereg(dev, &smc_mii_bitbang_ops, phy, reg, data);
1021
1003
1022 /*
1023 * Start code + write opcode + phy address + phy register + turnaround
1024 * + data.
1025 */
1026 smc_mii_writebits(sc, 5 << 28 | phy << 23 | reg << 18 | 2 << 16 | data,
1027 32);
1028
1029 /*
1030 * Reset MDIO interface.
1031 */
1032 smc_write_2(sc, MGMT,
1033 smc_read_2(sc, MGMT) & ~(MGMT_MCLK | MGMT_MDOE | MGMT_MDO));
1034
1035 SMC_UNLOCK(sc);
1036 return (0);
1037}
1038
1039void
1040smc_miibus_statchg(device_t dev)
1041{
1042 struct smc_softc *sc;

--- 301 unchanged lines hidden ---
1004 SMC_UNLOCK(sc);
1005 return (0);
1006}
1007
1008void
1009smc_miibus_statchg(device_t dev)
1010{
1011 struct smc_softc *sc;

--- 301 unchanged lines hidden ---