Line data Source code
1 : /* $OpenBSD: rtl80x9.c,v 1.11 2015/09/11 13:02:28 stsp Exp $ */
2 : /* $NetBSD: rtl80x9.c,v 1.1 1998/10/31 00:44:33 thorpej Exp $ */
3 :
4 : /*-
5 : * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 : * All rights reserved.
7 : *
8 : * This code is derived from software contributed to The NetBSD Foundation
9 : * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10 : * NASA Ames Research Center.
11 : *
12 : * Redistribution and use in source and binary forms, with or without
13 : * modification, are permitted provided that the following conditions
14 : * are met:
15 : * 1. Redistributions of source code must retain the above copyright
16 : * notice, this list of conditions and the following disclaimer.
17 : * 2. Redistributions in binary form must reproduce the above copyright
18 : * notice, this list of conditions and the following disclaimer in the
19 : * documentation and/or other materials provided with the distribution.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 : * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 : * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 : * POSSIBILITY OF SUCH DAMAGE.
32 : */
33 :
34 : #include "bpfilter.h"
35 :
36 : #include <sys/param.h>
37 : #include <sys/systm.h>
38 : #include <sys/mbuf.h>
39 : #include <sys/syslog.h>
40 : #include <sys/socket.h>
41 : #include <sys/device.h>
42 :
43 : #include <net/if.h>
44 : #include <net/if_media.h>
45 :
46 : #include <netinet/in.h>
47 : #include <netinet/if_ether.h>
48 :
49 : #include <machine/bus.h>
50 :
51 : #include <dev/ic/dp8390reg.h>
52 : #include <dev/ic/dp8390var.h>
53 :
54 : #include <dev/ic/ne2000var.h>
55 :
56 : #include <dev/ic/rtl80x9reg.h>
57 : #include <dev/ic/rtl80x9var.h>
58 :
59 : int
60 0 : rtl80x9_mediachange(dsc)
61 : struct dp8390_softc *dsc;
62 : {
63 :
64 : /*
65 : * Current media is already set up. Just reset the interface
66 : * to let the new value take hold. The new media will be
67 : * set up in ne_pci_rtl8029_init_card() called via dp8390_init().
68 : */
69 0 : dp8390_reset(dsc);
70 0 : return (0);
71 : }
72 :
73 : void
74 0 : rtl80x9_mediastatus(sc, ifmr)
75 : struct dp8390_softc *sc;
76 : struct ifmediareq *ifmr;
77 : {
78 0 : struct ifnet *ifp = &sc->sc_arpcom.ac_if;
79 0 : u_int8_t cr_proto = sc->cr_proto |
80 0 : ((ifp->if_flags & IFF_RUNNING) ? ED_CR_STA : ED_CR_STP);
81 :
82 : /*
83 : * Sigh, can detect which media is being used, but can't
84 : * detect if we have link or not.
85 : */
86 :
87 : /* Set NIC to page 3 registers. */
88 0 : NIC_PUT(sc->sc_regt, sc->sc_regh, ED_P0_CR, cr_proto | ED_CR_PAGE_3);
89 :
90 0 : if (NIC_GET(sc->sc_regt, sc->sc_regh, NERTL_RTL3_CONFIG0) &
91 : RTL3_CONFIG0_BNC)
92 0 : ifmr->ifm_active = IFM_ETHER|IFM_10_2;
93 : else {
94 0 : ifmr->ifm_active = IFM_ETHER|IFM_10_T;
95 0 : if (NIC_GET(sc->sc_regt, sc->sc_regh, NERTL_RTL3_CONFIG3) &
96 : RTL3_CONFIG3_FUDUP)
97 0 : ifmr->ifm_active |= IFM_FDX;
98 : }
99 :
100 : /* Set NIC to page 0 registers. */
101 0 : NIC_PUT(sc->sc_regt, sc->sc_regh, ED_P0_CR, cr_proto | ED_CR_PAGE_0);
102 0 : }
103 :
104 : void
105 0 : rtl80x9_init_card(sc)
106 : struct dp8390_softc *sc;
107 : {
108 0 : struct ifmedia *ifm = &sc->sc_media;
109 0 : struct ifnet *ifp = &sc->sc_arpcom.ac_if;
110 0 : u_int8_t cr_proto = sc->cr_proto |
111 0 : ((ifp->if_flags & IFF_RUNNING) ? ED_CR_STA : ED_CR_STP);
112 : u_int8_t reg;
113 :
114 : /* Set NIC to page 3 registers. */
115 0 : NIC_PUT(sc->sc_regt, sc->sc_regh, ED_P0_CR, cr_proto | ED_CR_PAGE_3);
116 :
117 : /* write enable config1-3. */
118 0 : NIC_PUT(sc->sc_regt, sc->sc_regh, NERTL_RTL3_EECR,
119 : RTL3_EECR_EEM1|RTL3_EECR_EEM0);
120 :
121 : /* First, set basic media type. */
122 0 : reg = NIC_GET(sc->sc_regt, sc->sc_regh, NERTL_RTL3_CONFIG2);
123 0 : reg &= ~(RTL3_CONFIG2_PL1|RTL3_CONFIG2_PL0);
124 0 : switch (IFM_SUBTYPE(ifm->ifm_cur->ifm_media)) {
125 : case IFM_AUTO:
126 : /* Nothing to do; both bits clear == auto-detect. */
127 : break;
128 :
129 : case IFM_10_T:
130 : /*
131 : * According to docs, this should be:
132 : * reg |= RTL3_CONFIG2_PL0;
133 : * but this doesn't work, so make it the same as AUTO.
134 : */
135 : break;
136 :
137 : case IFM_10_2:
138 0 : reg |= RTL3_CONFIG2_PL1|RTL3_CONFIG2_PL0;
139 0 : break;
140 : }
141 0 : NIC_PUT(sc->sc_regt, sc->sc_regh, NERTL_RTL3_CONFIG2, reg);
142 :
143 : /* Now, set duplex mode. */
144 0 : reg = NIC_GET(sc->sc_regt, sc->sc_regh, NERTL_RTL3_CONFIG3);
145 0 : if (ifm->ifm_cur->ifm_media & IFM_FDX)
146 0 : reg |= RTL3_CONFIG3_FUDUP;
147 : else
148 0 : reg &= ~RTL3_CONFIG3_FUDUP;
149 0 : NIC_PUT(sc->sc_regt, sc->sc_regh, NERTL_RTL3_CONFIG3, reg);
150 :
151 : /* write disable config1-3 */
152 0 : NIC_PUT(sc->sc_regt, sc->sc_regh, NERTL_RTL3_EECR, 0);
153 :
154 : /* Set NIC to page 0 registers. */
155 0 : NIC_PUT(sc->sc_regt, sc->sc_regh, ED_P0_CR, cr_proto | ED_CR_PAGE_0);
156 0 : }
157 :
158 : void
159 0 : rtl80x9_media_init(sc)
160 : struct dp8390_softc *sc;
161 : {
162 : static uint64_t rtl80x9_media[] = {
163 : IFM_ETHER|IFM_AUTO,
164 : IFM_ETHER|IFM_10_T,
165 : IFM_ETHER|IFM_10_T|IFM_FDX,
166 : IFM_ETHER|IFM_10_2,
167 : };
168 : static const int rtl80x9_nmedia =
169 : sizeof(rtl80x9_media) / sizeof(rtl80x9_media[0]);
170 :
171 : int i;
172 : uint64_t defmedia;
173 : u_int8_t conf2, conf3;
174 :
175 : /* Set NIC to page 3 registers. */
176 0 : bus_space_write_1(sc->sc_regt, sc->sc_regh, ED_P0_CR, ED_CR_PAGE_3);
177 :
178 0 : conf2 = bus_space_read_1(sc->sc_regt, sc->sc_regh, NERTL_RTL3_CONFIG2);
179 0 : conf3 = bus_space_read_1(sc->sc_regt, sc->sc_regh, NERTL_RTL3_CONFIG3);
180 :
181 0 : conf2 &= RTL3_CONFIG2_PL1|RTL3_CONFIG2_PL0;
182 :
183 0 : switch (conf2) {
184 : case 0:
185 : defmedia = IFM_ETHER|IFM_AUTO;
186 0 : break;
187 :
188 : case RTL3_CONFIG2_PL1|RTL3_CONFIG2_PL0:
189 : case RTL3_CONFIG2_PL1: /* XXX rtl docs sys 10base5, but chip cant do */
190 : defmedia = IFM_ETHER|IFM_10_2;
191 0 : break;
192 :
193 : case RTL3_CONFIG2_PL0:
194 0 : if (conf3 & RTL3_CONFIG3_FUDUP)
195 0 : defmedia = IFM_ETHER|IFM_10_T|IFM_FDX;
196 : else
197 : defmedia = IFM_ETHER|IFM_10_T;
198 : break;
199 : }
200 :
201 : /* Set NIC to page 0 registers. */
202 0 : bus_space_write_1(sc->sc_regt, sc->sc_regh, ED_P0_CR, ED_CR_PAGE_0);
203 :
204 0 : ifmedia_init(&sc->sc_media, 0, dp8390_mediachange, dp8390_mediastatus);
205 0 : for (i = 0; i < rtl80x9_nmedia; i++)
206 0 : ifmedia_add(&sc->sc_media, rtl80x9_media[i], 0, NULL);
207 0 : ifmedia_set(&sc->sc_media, defmedia);
208 0 : }
|