This source file includes following definitions.
- sm_pcmcia_match
- sm_pcmcia_attach
- sm_pcmcia_detach
- sm_pcmcia_activate
- sm_pcmcia_ascii_enaddr
- sm_pcmcia_funce_enaddr
- sm_pcmcia_lannid_ciscallback
- sm_pcmcia_enable
- sm_pcmcia_disable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 #include "bpfilter.h"
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/mbuf.h>
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48 #include <sys/errno.h>
49 #include <sys/syslog.h>
50 #include <sys/selinfo.h>
51 #include <sys/timeout.h>
52 #include <sys/device.h>
53
54 #include <net/if.h>
55 #include <net/if_dl.h>
56 #include <net/if_media.h>
57
58 #ifdef INET
59 #include <netinet/in.h>
60 #include <netinet/in_systm.h>
61 #include <netinet/in_var.h>
62 #include <netinet/ip.h>
63 #include <netinet/if_ether.h>
64 #endif
65
66 #if NBPFILTER > 0
67 #include <net/bpf.h>
68 #endif
69
70 #include <machine/intr.h>
71 #include <machine/bus.h>
72
73 #include <net/if_media.h>
74
75 #include <dev/mii/mii.h>
76 #include <dev/mii/miivar.h>
77
78 #include <dev/ic/smc91cxxreg.h>
79 #include <dev/ic/smc91cxxvar.h>
80
81 #include <dev/pcmcia/pcmciareg.h>
82 #include <dev/pcmcia/pcmciavar.h>
83 #include <dev/pcmcia/pcmciadevs.h>
84
85 int sm_pcmcia_match(struct device *, void *, void *);
86 void sm_pcmcia_attach(struct device *, struct device *, void *);
87 int sm_pcmcia_detach(struct device *, int);
88 int sm_pcmcia_activate(struct device *, enum devact);
89
90 struct sm_pcmcia_softc {
91 struct smc91cxx_softc sc_smc;
92
93
94 struct pcmcia_io_handle sc_pcioh;
95 int sc_io_window;
96 void *sc_ih;
97 struct pcmcia_function *sc_pf;
98 };
99
100 struct cfattach sm_pcmcia_ca = {
101 sizeof(struct sm_pcmcia_softc), sm_pcmcia_match, sm_pcmcia_attach,
102 sm_pcmcia_detach, sm_pcmcia_activate
103 };
104
105 int sm_pcmcia_enable(struct smc91cxx_softc *);
106 void sm_pcmcia_disable(struct smc91cxx_softc *);
107
108 int sm_pcmcia_ascii_enaddr(const char *, u_int8_t *);
109 int sm_pcmcia_funce_enaddr(struct device *, u_int8_t *);
110
111 int sm_pcmcia_lannid_ciscallback(struct pcmcia_tuple *, void *);
112
113 struct sm_pcmcia_product {
114 u_int16_t spp_vendor;
115 u_int16_t spp_product;
116 int spp_expfunc;
117 } sm_pcmcia_prod[] = {
118 { PCMCIA_VENDOR_MEGAHERTZ2, PCMCIA_PRODUCT_MEGAHERTZ2_XJACK,
119 0 },
120 { PCMCIA_VENDOR_MEGAHERTZ2, PCMCIA_PRODUCT_MEGAHERTZ2_XJEM1144,
121 0 },
122 { PCMCIA_VENDOR_NEWMEDIA, PCMCIA_PRODUCT_NEWMEDIA_BASICS,
123 0 },
124 { PCMCIA_VENDOR_SMC, PCMCIA_PRODUCT_SMC_8020,
125 0 },
126 { PCMCIA_VENDOR_PSION, PCMCIA_PRODUCT_PSION_GOLDCARD,
127 0 }
128 };
129
130 int
131 sm_pcmcia_match(parent, match, aux)
132 struct device *parent;
133 void *match, *aux;
134 {
135 struct pcmcia_attach_args *pa = aux;
136 int i;
137
138 for (i = 0; i < sizeof(sm_pcmcia_prod)/sizeof(sm_pcmcia_prod[0]); i++)
139 if (pa->manufacturer == sm_pcmcia_prod[i].spp_vendor &&
140 pa->product == sm_pcmcia_prod[i].spp_product &&
141 pa->pf->number == sm_pcmcia_prod[i].spp_expfunc)
142 return (1);
143 return (0);
144 }
145
146 void
147 sm_pcmcia_attach(parent, self, aux)
148 struct device *parent, *self;
149 void *aux;
150 {
151 struct sm_pcmcia_softc *psc = (struct sm_pcmcia_softc *)self;
152 struct smc91cxx_softc *sc = &psc->sc_smc;
153 struct pcmcia_attach_args *pa = aux;
154 struct pcmcia_config_entry *cfe;
155 u_int8_t myla[ETHER_ADDR_LEN], *enaddr = NULL;
156 const char *intrstr;
157
158 psc->sc_pf = pa->pf;
159 cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head);
160
161
162 pcmcia_function_init(pa->pf, cfe);
163 if (pcmcia_function_enable(pa->pf)) {
164 printf(": function enable failed\n");
165 return;
166 }
167
168
169
170
171 if (pcmcia_io_alloc(pa->pf, 0, cfe->iospace[0].length,
172 cfe->iospace[0].length, &psc->sc_pcioh)) {
173 printf(": can't allocate i/o space\n");
174 return;
175 }
176
177 sc->sc_bst = psc->sc_pcioh.iot;
178 sc->sc_bsh = psc->sc_pcioh.ioh;
179
180 #ifdef notyet
181 sc->sc_enable = sm_pcmcia_enable;
182 sc->sc_disable = sm_pcmcia_disable;
183 #endif
184 sc->sc_enabled = 1;
185
186 if (pcmcia_io_map(pa->pf, (cfe->flags & PCMCIA_CFE_IO16) ?
187 PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8, 0, cfe->iospace[0].length,
188 &psc->sc_pcioh, &psc->sc_io_window)) {
189 printf(": can't map i/o space\n");
190 return;
191 }
192
193 printf(" port 0x%lx/%lu", psc->sc_pcioh.addr,
194 (u_long)psc->sc_pcioh.size);
195
196
197
198
199 if (sm_pcmcia_funce_enaddr(parent, myla))
200 enaddr = myla;
201
202
203
204
205 if (enaddr == NULL) {
206 char *cisstr = NULL;
207
208 switch (pa->manufacturer) {
209 case PCMCIA_VENDOR_MEGAHERTZ2:
210 cisstr = pa->pf->sc->card.cis1_info[3];
211 break;
212 case PCMCIA_VENDOR_SMC:
213 cisstr = pa->pf->sc->card.cis1_info[2];
214 break;
215 }
216 if (cisstr != NULL && sm_pcmcia_ascii_enaddr(cisstr, myla))
217 enaddr = myla;
218 }
219
220 if (enaddr == NULL)
221 printf(", unable to get Ethernet address\n");
222
223 psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET,
224 smc91cxx_intr, sc, sc->sc_dev.dv_xname);
225 intrstr = pcmcia_intr_string(psc->sc_pf, psc->sc_ih);
226 if (*intrstr)
227 printf(", %s", intrstr);
228
229
230 smc91cxx_attach(sc, enaddr);
231
232 #ifdef notyet
233 pcmcia_function_disable(pa->pf);
234 #endif
235 }
236
237 int
238 sm_pcmcia_detach(dev, flags)
239 struct device *dev;
240 int flags;
241 {
242 struct sm_pcmcia_softc *psc = (struct sm_pcmcia_softc *)dev;
243 struct ifnet *ifp = &psc->sc_smc.sc_arpcom.ac_if;
244 int rv = 0;
245
246 pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
247 pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
248
249 ether_ifdetach(ifp);
250 if_detach(ifp);
251
252 return (rv);
253 }
254
255 int
256 sm_pcmcia_activate(dev, act)
257 struct device *dev;
258 enum devact act;
259 {
260 struct sm_pcmcia_softc *sc = (struct sm_pcmcia_softc *)dev;
261 struct ifnet *ifp = &sc->sc_smc.sc_arpcom.ac_if;
262 int s;
263
264 s = splnet();
265 switch (act) {
266 case DVACT_ACTIVATE:
267 pcmcia_function_enable(sc->sc_pf);
268 sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
269 smc91cxx_intr, sc, sc->sc_smc.sc_dev.dv_xname);
270 smc91cxx_init(&sc->sc_smc);
271 break;
272
273 case DVACT_DEACTIVATE:
274 ifp->if_timer = 0;
275 if (ifp->if_flags & IFF_RUNNING)
276 smc91cxx_stop(&sc->sc_smc);
277 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
278 pcmcia_function_disable(sc->sc_pf);
279 break;
280 }
281 splx(s);
282 return (0);
283 }
284
285 int
286 sm_pcmcia_ascii_enaddr(cisstr, myla)
287 const char *cisstr;
288 u_int8_t *myla;
289 {
290 char enaddr_str[12];
291 int i, j;
292
293 if (strlen(cisstr) != 12) {
294
295 return (0);
296 }
297 bcopy(cisstr, enaddr_str, sizeof enaddr_str);
298 for (i = 0; i < 6; i++) {
299 for (j = 0; j < 2; j++) {
300
301 if (enaddr_str[(i * 2) + j] >= 'a' &&
302 enaddr_str[(i * 2) + j] <= 'z')
303 enaddr_str[(i * 2) + j] -= 'a' - 'A';
304
305
306 if (enaddr_str[(i * 2) + j] >= '0' &&
307 enaddr_str[(i * 2) + j] <= '9')
308 myla[i] |= enaddr_str[(i * 2) + j]
309 - '0';
310 else if (enaddr_str[(i * 2) + j] >= 'A' &&
311 enaddr_str[(i * 2) + j] <= 'F')
312 myla[i] |= enaddr_str[(i * 2) + j]
313 - 'A' + 10;
314 else {
315
316 return (0);
317 }
318
319
320 if (j == 0)
321 myla[i] <<= 4;
322 }
323 }
324
325 return (1);
326 }
327
328 int
329 sm_pcmcia_funce_enaddr(parent, myla)
330 struct device *parent;
331 u_int8_t *myla;
332 {
333
334 return (pcmcia_scan_cis(parent, sm_pcmcia_lannid_ciscallback, myla));
335 }
336
337 int
338 sm_pcmcia_lannid_ciscallback(tuple, arg)
339 struct pcmcia_tuple *tuple;
340 void *arg;
341 {
342 u_int8_t *myla = arg;
343 int i;
344
345 if (tuple->code == PCMCIA_CISTPL_FUNCE || tuple->code ==
346 PCMCIA_CISTPL_SPCL) {
347
348 if (tuple->length < 2)
349 return (0);
350
351 if ((pcmcia_tuple_read_1(tuple, 0) !=
352 PCMCIA_TPLFE_TYPE_LAN_NID) ||
353 (pcmcia_tuple_read_1(tuple, 1) != ETHER_ADDR_LEN))
354 return (0);
355
356 for (i = 0; i < ETHER_ADDR_LEN; i++)
357 myla[i] = pcmcia_tuple_read_1(tuple, i + 2);
358 return (1);
359 }
360 return (0);
361 }
362
363 int
364 sm_pcmcia_enable(sc)
365 struct smc91cxx_softc *sc;
366 {
367 struct sm_pcmcia_softc *psc = (struct sm_pcmcia_softc *)sc;
368
369
370 psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, smc91cxx_intr,
371 sc, sc->sc_dev.dv_xname);
372 if (psc->sc_ih == NULL) {
373 printf("%s: couldn't establish interrupt handler\n",
374 sc->sc_dev.dv_xname);
375 return (1);
376 }
377
378 return (pcmcia_function_enable(psc->sc_pf));
379 }
380
381 void
382 sm_pcmcia_disable(sc)
383 struct smc91cxx_softc *sc;
384 {
385 struct sm_pcmcia_softc *psc = (struct sm_pcmcia_softc *)sc;
386
387 pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
388 pcmcia_function_disable(psc->sc_pf);
389 }