This source file includes following definitions.
- art_match
- art_softc_attach
- art_ioctl
- art_ifm_change
- art_ifm_status
- art_ifm_options
- art_onesec
- art_linkstate
- art_mask_tsmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <sys/param.h>
21 #include <sys/types.h>
22
23 #include <sys/device.h>
24 #include <sys/proc.h>
25 #include <sys/socket.h>
26 #include <sys/sockio.h>
27 #include <sys/syslog.h>
28 #include <sys/systm.h>
29
30 #include <machine/bus.h>
31
32 #include <net/if.h>
33 #include <net/if_media.h>
34 #include <net/if_sppp.h>
35
36 #include <dev/pci/musyccvar.h>
37 #include <dev/pci/if_art.h>
38
39 #define ART_E1_MASK 0xffffffff
40 #define ART_T1_MASK 0x01fffffe
41
42 int art_match(struct device *, void *, void *);
43 void art_softc_attach(struct device *, struct device *, void *);
44
45 int art_ioctl(struct ifnet *, u_long, caddr_t);
46 int art_ifm_change(struct ifnet *);
47 void art_ifm_status(struct ifnet *, struct ifmediareq *);
48 int art_ifm_options(struct ifnet *, struct channel_softc *, u_int);
49 void art_onesec(void *);
50 void art_linkstate(void *);
51 u_int32_t art_mask_tsmap(u_int, u_int32_t);
52
53 struct cfattach art_ca = {
54 sizeof(struct art_softc), art_match, art_softc_attach
55 };
56
57 struct cfdriver art_cd = {
58 NULL, "art", DV_DULL
59 };
60
61 int
62 art_match(struct device *parent, void *match, void *aux)
63 {
64 struct musycc_attach_args *ma = aux;
65
66 if (ma->ma_type == MUSYCC_FRAMER_BT8370)
67 return (1);
68 return (0);
69 }
70
71
72
73
74 extern int hz;
75
76 void
77 art_softc_attach(struct device *parent, struct device *self, void *aux)
78 {
79 struct art_softc *sc = (struct art_softc *)self;
80 struct musycc_softc *psc = (struct musycc_softc *)parent;
81 struct musycc_attach_args *ma = aux;
82
83 printf(" \"%s\"", ma->ma_product);
84
85 if (ebus_attach_device(&sc->art_ebus, psc, ma->ma_base,
86 ma->ma_size) != 0) {
87 printf(": could not map framer\n");
88 return;
89 }
90
91
92 sc->art_port = ma->ma_port;
93 sc->art_slot = ma->ma_slot;
94 sc->art_gnum = ma->ma_gnum;
95 sc->art_type = ma->ma_flags & 0x03;
96
97 sc->art_channel = musycc_channel_create(self->dv_xname, 1);
98 if (sc->art_channel == NULL) {
99 printf(": could not alloc channel descriptor\n");
100 return;
101 }
102
103 if (musycc_channel_attach(psc, sc->art_channel, self, sc->art_gnum) ==
104 -1) {
105 printf(": unable to attach to hdlc controller\n");
106 return;
107 }
108
109 ifmedia_init(&sc->art_ifm, 0, art_ifm_change, art_ifm_status);
110 ifmedia_add(&sc->art_ifm,
111 IFM_MAKEWORD(IFM_TDM, IFM_TDM_T1, 0, 0), 0, NULL);
112 ifmedia_add(&sc->art_ifm,
113 IFM_MAKEWORD(IFM_TDM, IFM_TDM_T1_AMI, 0, 0), 0, NULL);
114 ifmedia_add(&sc->art_ifm,
115 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1, 0, 0), 0, NULL);
116 ifmedia_add(&sc->art_ifm,
117 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1_G704, 0, 0), 0, NULL);
118 ifmedia_add(&sc->art_ifm,
119 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1_G704_CRC4, 0, 0), 0, NULL);
120
121 ifmedia_add(&sc->art_ifm,
122 IFM_MAKEWORD(IFM_TDM, IFM_TDM_T1, IFM_TDM_MASTER, 0), 0, NULL);
123 ifmedia_add(&sc->art_ifm,
124 IFM_MAKEWORD(IFM_TDM, IFM_TDM_T1_AMI, IFM_TDM_MASTER, 0), 0, NULL);
125 ifmedia_add(&sc->art_ifm,
126 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1, IFM_TDM_MASTER, 0), 0, NULL);
127 ifmedia_add(&sc->art_ifm,
128 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1_G704, IFM_TDM_MASTER, 0), 0, NULL);
129 ifmedia_add(&sc->art_ifm,
130 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1_G704_CRC4, IFM_TDM_MASTER, 0),
131 0, NULL);
132
133 ifmedia_add(&sc->art_ifm,
134 IFM_MAKEWORD(IFM_TDM, IFM_TDM_T1, IFM_TDM_PPP, 0), 0, NULL);
135 ifmedia_add(&sc->art_ifm,
136 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1, IFM_TDM_PPP, 0), 0, NULL);
137 ifmedia_add(&sc->art_ifm,
138 IFM_MAKEWORD(IFM_TDM, IFM_TDM_T1_AMI, IFM_TDM_PPP, 0), 0, NULL);
139 ifmedia_add(&sc->art_ifm,
140 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1_G704, IFM_TDM_PPP, 0), 0, NULL);
141 ifmedia_add(&sc->art_ifm,
142 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1_G704_CRC4, IFM_TDM_PPP, 0), 0,
143 NULL);
144
145 ifmedia_add(&sc->art_ifm,
146 IFM_MAKEWORD(IFM_TDM, IFM_TDM_T1, IFM_TDM_PPP | IFM_TDM_MASTER, 0),
147 0, NULL);
148 ifmedia_add(&sc->art_ifm,
149 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1, IFM_TDM_PPP | IFM_TDM_MASTER, 0),
150 0, NULL);
151 ifmedia_add(&sc->art_ifm,
152 IFM_MAKEWORD(IFM_TDM, IFM_TDM_T1_AMI, IFM_TDM_PPP | IFM_TDM_MASTER,
153 0), 0, NULL);
154 ifmedia_add(&sc->art_ifm,
155 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1_G704, IFM_TDM_PPP |
156 IFM_TDM_MASTER, 0), 0, NULL);
157 ifmedia_add(&sc->art_ifm,
158 IFM_MAKEWORD(IFM_TDM, IFM_TDM_E1_G704_CRC4, IFM_TDM_PPP |
159 IFM_TDM_MASTER, 0), 0, NULL);
160
161 printf("\n");
162
163 if (bt8370_reset(sc) != 0)
164 return;
165
166
167 timeout_set(&sc->art_onesec, art_onesec, sc);
168
169 ifmedia_set(&sc->art_ifm, IFM_TDM|IFM_TDM_E1_G704_CRC4);
170 sc->art_media = sc->art_ifm.ifm_media;
171
172 bt8370_set_frame_mode(sc, sc->art_type, IFM_TDM_E1_G704_CRC4, 0);
173 musycc_attach_sppp(sc->art_channel, art_ioctl);
174
175
176 sc->art_linkstatehook = hook_establish(
177 sc->art_channel->cc_ifp->if_linkstatehooks, 0, art_linkstate, sc);
178
179
180 timeout_add(&sc->art_onesec, hz);
181 }
182
183
184 int
185 art_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
186 {
187 struct ifreq *ifr = (struct ifreq*) data;
188 struct channel_softc *cc = ifp->if_softc;
189 struct art_softc *ac = (struct art_softc *)cc->cc_parent;
190 u_int32_t tsmap;
191 int s, rv = 0;
192
193 s = splnet();
194 switch (command) {
195 case SIOCSIFADDR:
196 if ((rv = musycc_init_channel(cc, ac->art_slot)))
197 break;
198 rv = sppp_ioctl(ifp, command, data);
199 break;
200 case SIOCSIFTIMESLOT:
201 if ((rv = suser(curproc, 0)) != 0)
202 break;
203 rv = copyin(ifr->ifr_data, &tsmap, sizeof(tsmap));
204 if (rv)
205 break;
206 if (art_mask_tsmap(IFM_SUBTYPE(ac->art_media), tsmap) !=
207 tsmap) {
208 rv = EINVAL;
209 break;
210 }
211 if (ac->art_type == ART_SBI_SINGLE &&
212 (IFM_SUBTYPE(ac->art_media) == IFM_TDM_T1 ||
213 IFM_SUBTYPE(ac->art_media) == IFM_TDM_T1_AMI))
214
215
216
217
218 tsmap >>= 1;
219
220 cc->cc_tslots = tsmap;
221 rv = musycc_init_channel(cc, ac->art_slot);
222 break;
223 case SIOCGIFTIMESLOT:
224 tsmap = cc->cc_tslots;
225 if (ac->art_type == ART_SBI_SINGLE &&
226 (IFM_SUBTYPE(ac->art_media) == IFM_TDM_T1 ||
227 IFM_SUBTYPE(ac->art_media) == IFM_TDM_T1_AMI))
228 tsmap <<= 1;
229 rv = copyout(&tsmap, ifr->ifr_data, sizeof(tsmap));
230 break;
231 case SIOCSIFFLAGS:
232
233
234
235
236 if (ifr->ifr_flags & IFF_UP && cc->cc_state != CHAN_RUNNING) {
237 if ((rv = musycc_init_channel(cc, ac->art_slot)))
238 break;
239 } else if ((ifr->ifr_flags & IFF_UP) == 0 &&
240 cc->cc_state == CHAN_RUNNING)
241 musycc_stop_channel(cc);
242 rv = sppp_ioctl(ifp, command, data);
243 break;
244 case SIOCSIFMEDIA:
245 case SIOCGIFMEDIA:
246 if (ac != NULL)
247 rv = ifmedia_ioctl(ifp, ifr, &ac->art_ifm, command);
248 else
249 rv = EINVAL;
250 break;
251 default:
252 rv = sppp_ioctl(ifp, command, data);
253 break;
254 }
255 splx(s);
256 return (rv);
257 }
258
259 int
260 art_ifm_change(struct ifnet *ifp)
261 {
262 struct channel_softc *cc = ifp->if_softc;
263 struct art_softc *ac = (struct art_softc *)cc->cc_parent;
264 struct ifmedia *ifm = &ac->art_ifm;
265 int rv, s, baudrate;
266
267 ACCOOM_PRINTF(2, ("%s: art_ifm_change %08x\n", ifp->if_xname,
268 ifm->ifm_media));
269
270 if (IFM_TYPE(ifm->ifm_media) != IFM_TDM)
271 return (EINVAL);
272
273
274 if ((rv = art_ifm_options(ifp, cc, IFM_OPTIONS(ifm->ifm_media))) != 0)
275 return (rv);
276
277
278 if (IFM_SUBTYPE(ifm->ifm_media) != IFM_SUBTYPE(ac->art_media) ||
279 IFM_MODE(ifm->ifm_media) != IFM_MODE(ac->art_media)) {
280 ACCOOM_PRINTF(0, ("%s: art_ifm_change type %d mode %x\n",
281 ifp->if_xname, IFM_SUBTYPE(ifm->ifm_media),
282 IFM_MODE(ifm->ifm_media)));
283
284 bt8370_set_frame_mode(ac, ac->art_type,
285 IFM_SUBTYPE(ifm->ifm_media), IFM_MODE(ifm->ifm_media));
286
287 if (IFM_SUBTYPE(ifm->ifm_media) != IFM_SUBTYPE(ac->art_media)) {
288
289 cc->cc_tslots = art_mask_tsmap(
290 IFM_SUBTYPE(ifm->ifm_media), cc->cc_tslots);
291
292 if (ac->art_type == ART_SBI_SINGLE &&
293 (IFM_SUBTYPE(ifm->ifm_media) == IFM_TDM_T1 ||
294 IFM_SUBTYPE(ifm->ifm_media) == IFM_TDM_T1_AMI) &&
295 (IFM_SUBTYPE(ac->art_media) != IFM_TDM_T1 &&
296 IFM_SUBTYPE(ac->art_media) != IFM_TDM_T1_AMI))
297
298
299
300
301
302 cc->cc_tslots >>= 1;
303 else if (ac->art_type == ART_SBI_SINGLE &&
304 (IFM_SUBTYPE(ifm->ifm_media) != IFM_TDM_T1 &&
305 IFM_SUBTYPE(ifm->ifm_media) != IFM_TDM_T1_AMI) &&
306 (IFM_SUBTYPE(ac->art_media) == IFM_TDM_T1 ||
307 IFM_SUBTYPE(ac->art_media) == IFM_TDM_T1_AMI))
308
309 cc->cc_tslots <<= 1;
310 }
311
312
313 if ((rv = musycc_init_channel(cc, ac->art_slot)))
314 return (rv);
315 }
316
317 baudrate = ifmedia_baudrate(ac->art_media);
318 if (baudrate != ifp->if_baudrate) {
319 ifp->if_baudrate = baudrate;
320 s = splsoftnet();
321 if_link_state_change(ifp), baudrate;
322 splx(s);
323 }
324
325 ac->art_media = ifm->ifm_media;
326
327 return (0);
328 }
329
330 void
331 art_ifm_status(struct ifnet *ifp, struct ifmediareq *ifmreq)
332 {
333 struct art_softc *ac;
334
335 ac = (struct art_softc *)
336 ((struct channel_softc *)ifp->if_softc)->cc_parent;
337 ifmreq->ifm_status = IFM_AVALID;
338 if (ifp->if_link_state == LINK_STATE_UP)
339 ifmreq->ifm_status |= IFM_ACTIVE;
340 ifmreq->ifm_active = ac->art_media;
341
342 return;
343 }
344
345 int
346 art_ifm_options(struct ifnet *ifp, struct channel_softc *cc, u_int options)
347 {
348 struct art_softc *ac = (struct art_softc *)cc->cc_parent;
349 u_int flags = cc->cc_ppp.pp_flags;
350 int rv;
351
352 if (options == IFM_TDM_PPP) {
353 flags &= ~PP_CISCO;
354 flags |= PP_KEEPALIVE;
355 } else if (options == 0) {
356 flags |= PP_CISCO;
357 flags |= PP_KEEPALIVE;
358 } else {
359 ACCOOM_PRINTF(0, ("%s: Unsupported ifmedia options\n",
360 ifp->if_xname));
361 return (EINVAL);
362 }
363 if (flags != cc->cc_ppp.pp_flags) {
364 musycc_stop_channel(cc);
365 cc->cc_ppp.pp_flags = flags;
366 if ((rv = musycc_init_channel(cc, ac->art_slot)))
367 return (rv);
368 return (sppp_ioctl(ifp, SIOCSIFFLAGS, NULL));
369 }
370 return (0);
371 }
372
373 void
374 art_onesec(void *arg)
375 {
376 struct art_softc *ac = arg;
377 struct ifnet *ifp = ac->art_channel->cc_ifp;
378 struct sppp *ppp = &ac->art_channel->cc_ppp;
379 int s, rv, link_state;
380
381 rv = bt8370_link_status(ac);
382 switch (rv) {
383 case 1:
384 link_state = LINK_STATE_UP;
385
386 ebus_set_led(ac->art_channel, 1, MUSYCC_LED_GREEN);
387 break;
388 case 0:
389 link_state = LINK_STATE_DOWN;
390
391 ebus_set_led(ac->art_channel, 1,
392 MUSYCC_LED_GREEN | MUSYCC_LED_RED);
393 break;
394 default:
395 link_state = LINK_STATE_DOWN;
396
397 ebus_set_led(ac->art_channel, 0, MUSYCC_LED_GREEN);
398 break;
399 }
400
401 if (link_state != ifp->if_link_state) {
402 s = splsoftnet();
403 if (link_state == LINK_STATE_UP)
404 ppp->pp_up(ppp);
405 else
406 ppp->pp_down(ppp);
407 splx(s);
408 }
409
410
411
412
413 musycc_tick(ac->art_channel);
414
415
416
417
418 timeout_add(&ac->art_onesec, hz);
419 }
420
421 void
422 art_linkstate(void *arg)
423 {
424 struct art_softc *ac = arg;
425 struct ifnet *ifp = ac->art_channel->cc_ifp;
426
427 if (ifp->if_link_state == LINK_STATE_UP)
428
429 ebus_set_led(ac->art_channel, 0, MUSYCC_LED_RED);
430 else
431
432 ebus_set_led(ac->art_channel, 1, MUSYCC_LED_RED);
433 }
434
435 u_int32_t
436 art_mask_tsmap(u_int mode, u_int32_t tsmap)
437 {
438 switch (mode) {
439 case IFM_TDM_E1:
440 case IFM_TDM_E1_G704:
441 case IFM_TDM_E1_G704_CRC4:
442 return (tsmap & ART_E1_MASK);
443 case IFM_TDM_T1_AMI:
444 case IFM_TDM_T1:
445 return (tsmap & ART_T1_MASK);
446 default:
447 return (tsmap);
448 }
449 }