This source file includes following definitions.
- rln_pcmcia_product_lookup
- rln_pcmcia_match
- rln_pcmcia_attach
- rln_pcmcia_detach
- rln_pcmcia_activate
- rlnintr_pcmcia
1
2
3
4
5
6
7
8 #include <sys/param.h>
9 #include <sys/systm.h>
10 #include <sys/socket.h>
11 #include <sys/device.h>
12 #include <sys/queue.h>
13
14 #include <net/if.h>
15
16 #ifdef INET
17 #include <netinet/in.h>
18 #include <netinet/if_ether.h>
19 #endif
20
21 #include <machine/bus.h>
22 #include <machine/intr.h>
23
24 #include <dev/ic/rln.h>
25 #include <dev/ic/rlnvar.h>
26 #include <dev/ic/rlnreg.h>
27
28 #include <dev/pcmcia/pcmciareg.h>
29 #include <dev/pcmcia/pcmciavar.h>
30 #include <dev/pcmcia/pcmciadevs.h>
31
32 struct rln_pcmcia_softc {
33 struct rln_softc psc_rln;
34
35 struct pcmcia_io_handle psc_pcioh;
36 int sc_io_window;
37 struct pcmcia_function *psc_pf;
38 void *psc_ih;
39 };
40
41 static int rln_pcmcia_match(struct device *, void *, void *);
42 static struct rln_pcmcia_product * rln_pcmcia_product_lookup(struct pcmcia_attach_args *);
43 static void rln_pcmcia_attach(struct device *, struct device *, void *);
44 static int rln_pcmcia_detach(struct device *, int);
45 static int rln_pcmcia_activate(struct device *, enum devact);
46 static int rlnintr_pcmcia(void *arg);
47
48 struct cfattach rln_pcmcia_ca = {
49 sizeof(struct rln_pcmcia_softc), rln_pcmcia_match, rln_pcmcia_attach,
50 rln_pcmcia_detach, rln_pcmcia_activate
51 };
52
53 static struct rln_pcmcia_product {
54 u_int16_t manufacturer;
55 u_int16_t product;
56 const char *cis[4];
57 u_int8_t flags;
58 } rln_pcmcia_products[] = {
59
60 { PCMCIA_VENDOR_PROXIM,
61 PCMCIA_PRODUCT_PROXIM_ROAMABOUT_2400FH,
62 PCMCIA_CIS_PROXIM_ROAMABOUT_2400FH,
63 0 },
64
65 { PCMCIA_VENDOR_COMPEX,
66 PCMCIA_PRODUCT_COMPEX_AMP_WIRELESS,
67 PCMCIA_CIS_COMPEX_AMP_WIRELESS,
68 0 },
69
70 { PCMCIA_VENDOR_PROXIM,
71 PCMCIA_PRODUCT_PROXIM_RANGELAN2_7401,
72 PCMCIA_CIS_PROXIM_RANGELAN2_7401,
73 0 },
74
75 { PCMCIA_VENDOR_INVALID,
76 PCMCIA_PRODUCT_INVALID,
77 PCMCIA_CIS_PROXIM_RL2_7200,
78 0 },
79 { PCMCIA_VENDOR_INVALID,
80 PCMCIA_PRODUCT_INVALID,
81 PCMCIA_CIS_PROXIM_RL2_7400,
82 0 },
83 { PCMCIA_VENDOR_INVALID,
84 PCMCIA_PRODUCT_INVALID,
85 PCMCIA_CIS_PROXIM_SYMPHONY,
86 0 }
87 };
88 #define NPRODUCTS (sizeof rln_pcmcia_products / sizeof rln_pcmcia_products[0])
89
90
91 static struct rln_pcmcia_product *
92 rln_pcmcia_product_lookup(pa)
93 struct pcmcia_attach_args *pa;
94 {
95 int i, j;
96 struct rln_pcmcia_product *rpp;
97
98 for (i = 0; i < NPRODUCTS; i++) {
99 rpp = &rln_pcmcia_products[i];
100 if (rpp->manufacturer != PCMCIA_VENDOR_INVALID &&
101 rpp->manufacturer != pa->manufacturer)
102 continue;
103 if (rpp->product != PCMCIA_PRODUCT_INVALID &&
104 rpp->product != pa->product)
105 continue;
106 for (j = 0; j < 4; j++) {
107 if (rpp->cis[j] == NULL)
108 return rpp;
109 if (pa->card->cis1_info[j] &&
110 strcmp(pa->card->cis1_info[j], rpp->cis[j]) != 0)
111 break;
112 }
113 if (j == 4)
114 return rpp;
115 }
116 return NULL;
117 }
118
119
120 static int
121 rln_pcmcia_match(parent, match, aux)
122 struct device *parent;
123 void *match, *aux;
124 {
125 struct pcmcia_attach_args *pa = aux;
126
127 return (rln_pcmcia_product_lookup(pa) != NULL);
128 }
129
130
131 void
132 rln_pcmcia_attach(parent, self, aux)
133 struct device *parent, *self;
134 void *aux;
135 {
136 struct rln_pcmcia_softc *psc = (void *) self;
137 struct rln_softc *sc = &psc->psc_rln;
138 struct pcmcia_attach_args *pa = aux;
139 struct pcmcia_config_entry *cfe;
140 struct rln_pcmcia_product *rpp;
141 const char *intrstr;
142
143 psc->psc_pf = pa->pf;
144 cfe = SIMPLEQ_FIRST(&psc->psc_pf->cfe_head);
145
146
147 if (cfe->flags & PCMCIA_CFE_IO16)
148 sc->sc_width = 16;
149 else if (cfe->flags & PCMCIA_CFE_IO8)
150 sc->sc_width = 8;
151 else
152 sc->sc_width = 0;
153
154 #ifdef DIAGNOSTIC
155
156 if (cfe->num_memspace != 0)
157 printf(": unexpected number of memory spaces (%d)\n",
158 cfe->num_memspace);
159 if (cfe->num_iospace != 1)
160 printf(": unexpected number of i/o spaces (%d)\n",
161 cfe->num_iospace);
162 else if (cfe->iospace[0].length != RLN_NPORTS)
163 printf(": unexpected size of i/o space (0x%x)\n",
164 cfe->iospace[0].length);
165 if (sc->sc_width == 0)
166 printf(": unknown bus width\n");
167 #endif
168
169 pcmcia_function_init(psc->psc_pf, cfe);
170
171
172 if (pcmcia_io_alloc(psc->psc_pf, 0, RLN_NPORTS,
173 RLN_NPORTS, &psc->psc_pcioh)) {
174 printf(": can't allocate i/o space\n");
175 return;
176 }
177
178 sc->sc_iot = psc->psc_pcioh.iot;
179 sc->sc_ioh = psc->psc_pcioh.ioh;
180
181
182 if (pcmcia_io_map(psc->psc_pf, ((sc->sc_width == 8) ? PCMCIA_WIDTH_IO8 :
183 (sc->sc_width == 16) ? PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_AUTO),
184 0, RLN_NPORTS, &psc->psc_pcioh, &psc->sc_io_window)) {
185 printf(": can't map i/o space\n");
186 return;
187 }
188 printf(" port 0x%lx/%d", psc->psc_pcioh.addr, RLN_NPORTS);
189
190
191 if (pcmcia_function_enable(psc->psc_pf)) {
192 printf(": function enable failed\n");
193 return;
194 }
195
196 #ifdef notyet
197 sc->enable = rln_pcmcia_enable;
198 sc->disable = rln_pcmcia_disable;
199 #endif
200
201 rpp = rln_pcmcia_product_lookup(pa);
202
203
204 sc->sc_cardtype = 0;
205 switch (psc->psc_pf->ccr_base) {
206 case 0x0100:
207 sc->sc_cardtype |= RLN_CTYPE_ONE_PIECE;
208 break;
209 case 0x0800:
210 sc->sc_cardtype &= ~RLN_CTYPE_ONE_PIECE;
211 break;
212 #ifdef DIAGNOSTIC
213 default:
214 printf(": cannot tell if one or two piece (ccr addr %x)\n",
215 sc->sc_dev.dv_xname, psc->psc_pf->ccr_base);
216 #endif
217 }
218
219
220 sc->sc_irq = 15;
221
222
223
224
225
226
227 psc->psc_ih = pcmcia_intr_establish(psc->psc_pf, IPL_NET,
228 rlnintr_pcmcia, sc, sc->sc_dev.dv_xname);
229 intrstr = pcmcia_intr_string(psc->sc_pf, psc->sc_ih);
230 if (*intrstr)
231 printf(", %s", intrstr);
232 sc->sc_ih = NULL;
233
234 #ifdef DIAGNOSTIC
235 if (rpp->manufacturer == PCMCIA_VENDOR_INVALID)
236 printf(" manf %04x prod %04x", pa->manufacturer, pa->product);
237 #endif
238
239 rln_reset(sc);
240 rlnconfig(sc);
241 printf("\n");
242 }
243
244 static int
245 rln_pcmcia_detach(dev, flags)
246 struct device *dev;
247 int flags;
248 {
249 struct rln_pcmcia_softc *psc = (struct rln_pcmcia_softc *)dev;
250 struct rln_softc *sc = (struct rln_softc *)dev;
251 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
252 int rv = 0;
253
254 pcmcia_io_unmap(psc->psc_pf, psc->sc_io_window);
255 pcmcia_io_free(psc->psc_pf, &psc->psc_pcioh);
256
257 ether_ifdetach(ifp);
258 if_detach(ifp);
259
260 return (rv);
261 }
262
263 static int
264 rln_pcmcia_activate(dev, act)
265 struct device *dev;
266 enum devact act;
267 {
268 struct rln_pcmcia_softc *psc = (struct rln_pcmcia_softc *)dev;
269 struct rln_softc *sc = (struct rln_softc *)dev;
270 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
271 int s;
272
273 s = splnet();
274 switch (act) {
275 case DVACT_ACTIVATE:
276 pcmcia_function_enable(psc->psc_pf);
277 psc->psc_ih = pcmcia_intr_establish(psc->psc_pf, IPL_NET,
278 rlnintr_pcmcia, psc, sc->sc_dev.dv_xname);
279 rlninit(sc);
280 break;
281
282 case DVACT_DEACTIVATE:
283 ifp->if_timer = 0;
284 if (ifp->if_flags & IFF_RUNNING)
285 rlnstop(sc);
286 pcmcia_intr_disestablish(psc->psc_pf, psc->psc_ih);
287 pcmcia_function_disable(psc->psc_pf);
288 break;
289 }
290 splx(s);
291 return (0);
292 }
293
294
295 static int
296 rlnintr_pcmcia(arg)
297 void *arg;
298 {
299 struct rln_softc *sc = (struct rln_softc *)arg;
300 struct rln_pcmcia_softc *psc = (struct rln_pcmcia_softc *)sc;
301 int opt;
302 int ret;
303
304
305 opt = pcmcia_ccr_read(psc->psc_pf, PCMCIA_CCR_OPTION);
306 pcmcia_ccr_write(psc->psc_pf, PCMCIA_CCR_OPTION, opt);
307
308
309 ret = rlnintr(sc);
310
311 return (ret);
312 }