This source file includes following definitions.
- re_cardbus_probe
- re_cardbus_attach
- re_cardbus_setup
- re_cardbus_detach
- re_cardbus_shutdown
- re_cardbus_powerhook
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <sys/param.h>
24 #include <sys/endian.h>
25 #include <sys/systm.h>
26 #include <sys/sockio.h>
27 #include <sys/mbuf.h>
28 #include <sys/malloc.h>
29 #include <sys/kernel.h>
30 #include <sys/device.h>
31 #include <sys/timeout.h>
32 #include <sys/socket.h>
33
34 #include <net/if.h>
35 #include <net/if_dl.h>
36 #include <net/if_media.h>
37
38 #ifdef INET
39 #include <netinet/in.h>
40 #include <netinet/in_systm.h>
41 #include <netinet/in_var.h>
42 #include <netinet/ip.h>
43 #include <netinet/if_ether.h>
44 #endif
45
46 #include <dev/mii/mii.h>
47 #include <dev/mii/miivar.h>
48
49 #include <dev/pci/pcidevs.h>
50
51 #include <dev/cardbus/cardbusvar.h>
52
53 #include <dev/ic/rtl81x9reg.h>
54 #include <dev/ic/revar.h>
55
56 struct re_cardbus_softc {
57
58 struct rl_softc sc_rl;
59
60
61 void *sc_ih;
62 cardbus_devfunc_t ct;
63 cardbustag_t sc_tag;
64 int sc_csr;
65 int sc_cben;
66 int sc_bar_reg;
67 pcireg_t sc_bar_val;
68 int sc_intrline;
69
70 bus_size_t sc_mapsize;
71 };
72
73 int re_cardbus_probe(struct device *, void *, void *);
74 void re_cardbus_attach(struct device *, struct device *, void *);
75 int re_cardbus_detach(struct device *, int);
76 void re_cardbus_setup(struct rl_softc *);
77
78 void re_cardbus_shutdown(void *);
79 void re_cardbus_powerhook(int, void *);
80
81
82
83
84 struct cfattach re_cardbus_ca = {
85 sizeof(struct re_cardbus_softc),
86 re_cardbus_probe,
87 re_cardbus_attach,
88 re_cardbus_detach
89 };
90
91 const struct cardbus_matchid re_cardbus_devices[] = {
92 { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169 },
93 };
94
95
96
97
98
99 int
100 re_cardbus_probe(struct device *parent, void *match, void *aux)
101 {
102 return (cardbus_matchbyid((struct cardbus_attach_args *)aux,
103 re_cardbus_devices,
104 sizeof(re_cardbus_devices)/sizeof(re_cardbus_devices[0])));
105 }
106
107
108
109
110
111 void
112 re_cardbus_attach(struct device *parent, struct device *self, void *aux)
113 {
114 struct re_cardbus_softc *csc = (struct re_cardbus_softc *)self;
115 struct rl_softc *sc = &csc->sc_rl;
116 struct cardbus_attach_args *ca = aux;
117 struct cardbus_softc *psc =
118 (struct cardbus_softc *)sc->sc_dev.dv_parent;
119 cardbus_chipset_tag_t cc = psc->sc_cc;
120 cardbus_function_tag_t cf = psc->sc_cf;
121 cardbus_devfunc_t ct = ca->ca_ct;
122 bus_addr_t adr;
123 char intrstr[16];
124
125 sc->sc_dmat = ca->ca_dmat;
126 csc->ct = ct;
127 csc->sc_tag = ca->ca_tag;
128 csc->sc_intrline = ca->ca_intrline;
129
130
131
132
133 if (Cardbus_mapreg_map(ct, RL_PCI_LOMEM, CARDBUS_MAPREG_TYPE_MEM, 0,
134 &sc->rl_btag, &sc->rl_bhandle, &adr, &csc->sc_mapsize) == 0) {
135 csc->sc_cben = CARDBUS_MEM_ENABLE;
136 csc->sc_csr |= CARDBUS_COMMAND_MEM_ENABLE;
137 csc->sc_bar_reg = RL_PCI_LOMEM;
138 csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_MEM;
139 } else {
140 printf(": can't map mem space\n");
141 return;
142 }
143
144
145 Cardbus_function_enable(ct);
146
147
148
149 re_cardbus_setup(sc);
150
151
152 csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline,
153 IPL_NET, re_intr, sc, sc->sc_dev.dv_xname);
154 if (csc->sc_ih == NULL) {
155 printf(": couldn't establish interrupt at %s",
156 ca->ca_intrline);
157 Cardbus_function_disable(csc->ct);
158 return;
159 }
160 snprintf(intrstr, sizeof(intrstr), "irq %d", ca->ca_intrline);
161
162 sc->sc_flags |= RL_ENABLED;
163 sc->rl_type = RL_8169;
164
165 sc->sc_sdhook = shutdownhook_establish(re_cardbus_shutdown, sc);
166 sc->sc_pwrhook = powerhook_establish(re_cardbus_powerhook, sc);
167
168
169 re_attach(sc, intrstr);
170 }
171
172
173
174
175 void
176 re_cardbus_setup(struct rl_softc *sc)
177 {
178 struct re_cardbus_softc *csc = (struct re_cardbus_softc *)sc;
179 cardbus_devfunc_t ct = csc->ct;
180 cardbus_chipset_tag_t cc = ct->ct_cc;
181 cardbus_function_tag_t cf = ct->ct_cf;
182 pcireg_t reg, command;
183 int pmreg;
184
185
186 if (cardbus_get_capability(cc, cf, csc->sc_tag,
187 PCI_CAP_PWRMGMT, &pmreg, 0)) {
188 command = cardbus_conf_read(cc, cf, csc->sc_tag,
189 pmreg + PCI_PMCSR);
190
191 if (command & RL_PSTATE_MASK) {
192 pcireg_t iobase, membase, irq;
193
194
195 iobase = cardbus_conf_read(cc, cf, csc->sc_tag, RL_PCI_LOIO);
196 membase = cardbus_conf_read(cc, cf, csc->sc_tag, RL_PCI_LOMEM);
197 irq = cardbus_conf_read(cc, cf, csc->sc_tag, RL_PCI_INTLINE);
198
199
200 printf("%s: chip is in D%d power mode "
201 "-- setting to D0\n", sc->sc_dev.dv_xname,
202 command & RL_PSTATE_MASK);
203 command &= RL_PSTATE_MASK;
204 cardbus_conf_write(cc, cf, csc->sc_tag, pmreg + PCI_PMCSR,
205 command);
206
207
208 cardbus_conf_write(cc, cf, csc->sc_tag, RL_PCI_LOIO, iobase);
209 cardbus_conf_write(cc, cf, csc->sc_tag, RL_PCI_LOMEM, membase);
210 cardbus_conf_write(cc, cf, csc->sc_tag, RL_PCI_INTLINE, irq);
211 }
212 }
213
214
215 (*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_cben);
216 (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
217
218
219 cardbus_conf_write(cc, cf, csc->sc_tag, csc->sc_bar_reg, csc->sc_bar_val);
220
221
222 reg = cardbus_conf_read(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG);
223 reg &= ~(CARDBUS_COMMAND_IO_ENABLE|CARDBUS_COMMAND_MEM_ENABLE);
224 reg |= csc->sc_csr;
225 cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG, reg);
226
227
228 reg = cardbus_conf_read(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG);
229 if (CARDBUS_LATTIMER(reg) < 0x20) {
230 reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
231 reg |= (0x20 << CARDBUS_LATTIMER_SHIFT);
232 cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG, reg);
233 }
234 }
235
236
237
238
239 int
240 re_cardbus_detach(struct device *self, int flags)
241 {
242 struct re_cardbus_softc *csc = (void *)self;
243 struct rl_softc *sc = &csc->sc_rl;
244 struct cardbus_devfunc *ct = csc->ct;
245 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
246
247
248 timeout_del(&sc->timer_handle);
249
250
251 if (LIST_FIRST(&sc->sc_mii.mii_phys) != NULL)
252 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
253
254
255 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
256 ether_ifdetach(ifp);
257 if_detach(ifp);
258
259
260 if (sc->sc_sdhook != NULL)
261 shutdownhook_disestablish(sc->sc_sdhook);
262 if (sc->sc_pwrhook != NULL)
263 powerhook_disestablish(sc->sc_pwrhook);
264
265
266 if (csc->sc_ih != NULL)
267 cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih);
268
269
270 Cardbus_mapreg_unmap(ct, csc->sc_bar_reg, sc->rl_btag, sc->rl_bhandle,
271 csc->sc_mapsize);
272
273 return (0);
274 }
275
276 void
277 re_cardbus_shutdown(void *arg)
278 {
279 struct rl_softc *sc = arg;
280 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
281
282 re_stop(ifp, 1);
283 }
284
285 void
286 re_cardbus_powerhook(int why, void *arg)
287 {
288 struct rl_softc *sc = arg;
289 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
290
291 if (why == PWR_RESUME)
292 re_init(ifp);
293 }