1 /*	$OpenBSD: rln.c,v 1.16 2004/05/12 06:35:10 tedu Exp $	*/
2 /*
3  * David Leonard <d@openbsd.org>, 1999. Public Domain.
4  *
5  * Driver for the Proxim RangeLAN2 wireless network adaptor.
6  *
7  * Information and ideas gleaned from disassembly of Dave Koberstein's
8  * <davek@komacke.com> Linux driver (apparently based on Proxim source),
9  * from Yoichi Shinoda's <shinoda@cs.washington.edu> BSDI driver, and
10  * Geoff Voelker's <voelker@cs.washington.edu> Linux port of the same.
11  *
12  */
13 
14 #include "bpfilter.h"
15 
16 #include <sys/param.h>
17 #include <sys/systm.h>
18 #include <sys/mbuf.h>
19 #include <sys/socket.h>
20 #include <sys/ioctl.h>
21 #include <sys/syslog.h>
22 #include <sys/device.h>
23 #include <sys/kernel.h>
24 
25 #include <net/if.h>
26 #include <net/if_media.h>
27 
28 #ifdef INET
29 #include <netinet/in.h>
30 #include <netinet/if_ether.h>
31 #endif
32 
33 #if NBPFILTER > 0
34 #include <net/bpf.h>
35 #endif
36 
37 #include <machine/bus.h>
38 #include <machine/intr.h>
39 
40 #include <dev/ic/rln.h>
41 #include <dev/ic/rlnvar.h>
42 #include <dev/ic/rlnreg.h>
43 #include <dev/ic/rlncmd.h>
44 
45 /* Autoconfig definition of driver back-end. */
46 struct cfdriver rln_cd = {
47 	NULL, "rln", DV_IFNET
48 };
49 
50 void	rlninit(struct rln_softc *);
51 void	rlnstart(struct ifnet*);
52 void	rlnwatchdog(struct ifnet*);
53 int	rlnioctl(struct ifnet *, u_long, caddr_t);
54 void	rlnstop(struct rln_softc *);
55 
56 /* Interrupt handler. */
57 void	rlnsoftintr(void *);
58 
59 /* Packet I/O. */
60 int	rln_transmit(struct rln_softc *, struct mbuf *,
61 			int, int);
62 struct mbuf * rlnget(struct rln_softc *, struct rln_mm_cmd *,
63 			int);
64 
65 /* Card protocol-level functions. */
66 int	rln_getenaddr(struct rln_softc *, u_int8_t *);
67 int	rln_getpromvers(struct rln_softc *, char *, int);
68 int	rln_sendinit(struct rln_softc *);
69 #if notyet
70 int	rln_roamconfig(struct rln_softc *);
71 int	rln_roam(struct rln_softc *);
72 int	rln_multicast(struct rln_softc *, int);
73 int	rln_searchsync(struct rln_softc *);
74 int	rln_iosetparam(struct rln_softc *, struct rln_param *);
75 int	rln_lockprom(struct rln_softc *);
76 int	rln_ito(struct rln_softc *);
77 int	rln_standby(struct rln_softc *);
78 #endif
79 
80 /* Back-end attach and configure. Assumes card has been reset. */
81 void
rlnconfig(sc)82 rlnconfig(sc)
83 	struct rln_softc * sc;
84 {
85 	struct ifnet *	ifp = &sc->sc_arpcom.ac_if;
86 	char		promvers[7];
87 	int		i;
88 
89 	dprintf(" [attach %p]", sc);
90 
91 	/* Use the flags supplied from config. */
92 	sc->sc_cardtype |= sc->sc_dev.dv_cfdata->cf_flags;
93 
94 	/* Initialise values in the soft state. */
95 	sc->sc_pktseq = 0;	/* rln_newseq() */
96 	sc->sc_txseq = 0;
97 	sc->sc_state = 0;
98 
99 	/* Initialise user-configurable params. */
100 	sc->sc_param.rp_roam_config = RLN_ROAM_NORMAL;
101 	sc->sc_param.rp_security = RLN_SECURITY_DEFAULT;
102 	sc->sc_param.rp_station_type = RLN_STATIONTYPE_ALTMASTER;
103 	sc->sc_param.rp_domain = 0;
104 	sc->sc_param.rp_channel = 1;
105 	sc->sc_param.rp_subchannel = 1;
106 
107 	bzero(sc->sc_param.rp_master, sizeof sc->sc_param.rp_master);
108 
109 	/* Initialise the message mailboxes. */
110 	for (i = 0; i < RLN_NMBOX; i++)
111 		sc->sc_mbox[i].mb_state = RLNMBOX_VOID;
112 
113 	/* Probe for some properties. */
114 	printf(", %s-piece",
115 	    (sc->sc_cardtype & RLN_CTYPE_ONE_PIECE) ? "one" : "two");
116 	if (sc->sc_cardtype & RLN_CTYPE_OEM)
117 		printf(" oem");
118 	if (sc->sc_cardtype & RLN_CTYPE_UISA)
119 		printf(" micro-isa");
120 
121 	/* Read the card's PROM revision. */
122 	if (rln_getpromvers(sc, promvers, sizeof promvers)) {
123 		printf(": could not read PROM version\n");
124 		return;
125 	}
126 	printf(", fw %.7s", promvers);
127 
128 	/* Fetch the card's MAC address. */
129 	if (rln_getenaddr(sc, sc->sc_arpcom.ac_enaddr)) {
130 		printf(": could not read MAC address\n");
131 		return;
132 	}
133 	printf(", addr %s", ether_sprintf(sc->sc_arpcom.ac_enaddr));
134 
135 	timeout_set(&sc->sc_timeout, rlnsoftintr, sc);
136 
137 	/* Attach as a network interface. */
138 	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
139 	ifp->if_softc = sc;
140 	ifp->if_start = rlnstart;
141 	ifp->if_ioctl = rlnioctl;
142 	ifp->if_watchdog = rlnwatchdog;
143 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
144 	IFQ_SET_READY(&ifp->if_snd);
145 	if_attach(ifp);
146 	ether_ifattach(ifp);
147 }
148 
149 /* Bring device up. */
150 void
rlninit(sc)151 rlninit(sc)
152 	struct rln_softc * sc;
153 {
154 	/* LLDInit() */
155 	struct ifnet * ifp = &sc->sc_arpcom.ac_if;
156 	int s;
157 
158 	s = splnet();
159 	dprintf(" [init]");
160 
161 	sc->sc_intsel = 0;
162 	sc->sc_status = 0;
163 	sc->sc_control = 0;
164 	ifp->if_flags &= ~IFF_RUNNING;
165 	ifp->if_flags &= ~IFF_OACTIVE;
166 
167 	/* Do a hard reset. */
168 	if (rln_reset(sc)) {
169 		printf("%s: could not reset card\n", sc->sc_dev.dv_xname);
170 		goto fail;
171 	}
172 	sc->sc_state = 0;	/* Also clears RLN_STATE_NEEDINIT. */
173 
174 	/* Use this host's name as a master name. */
175 	if (!cold && sc->sc_param.rp_master[0] == '\0') {
176 		bcopy(hostname, sc->sc_param.rp_master,
177 		    min(hostnamelen, sizeof sc->sc_param.rp_master));
178 	}
179 
180 	rln_enable(sc, 1);
181 
182 	/* Initialise operational params. */
183 	if (rln_sendinit(sc)) {
184 		printf("%s: could not set card parameters\n",
185 		    sc->sc_dev.dv_xname);
186 		goto fail;
187 	}
188 #if 0
189 	rln_roamconfig(sc);
190 	/* rln_lockprom(sc); */
191 	/* SendSetITO() */
192 	rln_multicast(sc, 1);
193 	rln_roam(sc);
194 
195 	/* Synchronise with something. */
196 	rln_searchsync(sc);
197 #endif
198 	ifp->if_flags |= IFF_RUNNING;
199 	rlnstart(ifp);
200 	splx(s);
201 
202 	return;
203 
204     fail:
205 	ifp->if_flags &= ~IFF_UP;
206 	splx(s);
207 	return;
208 }
209 
210 /* Start outputting on interface. This is always called at splnet(). */
211 void
rlnstart(ifp)212 rlnstart(ifp)
213 	struct ifnet *	ifp;
214 {
215 	struct rln_softc * sc = (struct rln_softc *)ifp->if_softc;
216 	struct mbuf *	m0;
217 	int		len, pad, ret, s;
218 
219 	dprintf(" start[");
220 
221 	if (sc->sc_state & RLN_STATE_NEEDINIT)
222 		rlninit(sc);
223 
224 	/* Don't transmit if interface is busy or not running. */
225 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) {
226 		dprintf(" %s] ", (ifp->if_flags & IFF_OACTIVE) ?
227 		    "busy" : "stopped");
228 		return;
229 	}
230 
231 	/* Don't transmit if we are not synchronised. */
232 	if ((sc->sc_state & RLN_STATE_SYNC) == 0) {
233 		dprintf(" nosync]");
234 		return;
235 	}
236 
237 	rln_enable(sc, 1);
238 
239     startagain:
240 	s = splimp();
241 	IFQ_DEQUEUE(&ifp->if_snd, m0);
242 	splx(s);
243 
244 	if (m0 == NULL) {
245 		dprintf(" empty]");
246 		return;
247 	}
248 
249 #if NBPFILTER > 0
250 	/* Tap packet stream here for BPF listeners. */
251 	if (ifp->if_bpf)
252 		bpf_mtap(ifp->if_bpf, m0);
253 #endif
254 
255 	/* We need to use m->m_pkthdr.len, so require the header. */
256 	if ((m0->m_flags & M_PKTHDR) == 0) {
257 		printf("%s: no mbuf header\n", sc->sc_dev.dv_xname);
258 		goto oerror;
259 	}
260 
261 	len = m0->m_pkthdr.len;
262 
263 #define PACKETMIN	(sizeof (struct ether_header) + ETHERMIN)
264 #define PACKETMAX	(sizeof (struct ether_header) + ETHERMTU + 4)
265 
266 	/* Packet size has to be an even number between 60 and 1518 octets. */
267 	pad = len & 1;
268 	if (len + pad < PACKETMIN)
269 		pad = PACKETMIN - len;
270 
271 	if (len + pad > PACKETMAX) {
272 		printf("%s: packet too big (%d > %d)\n",
273 		    sc->sc_dev.dv_xname, len + pad,
274 		    PACKETMAX);
275 		++ifp->if_oerrors;
276 		m_freem(m0);
277 		goto startagain;
278 	}
279 
280 	ret = rln_transmit(sc, m0, len, pad);
281 	if (ret)
282 		goto oerror;
283 
284 	ifp->if_flags |= IFF_OACTIVE;
285 	m_freem(m0);
286 
287 	dprintf(" sent]");
288 	return;
289 
290 oerror:
291 	++ifp->if_oerrors;
292 	m_freem(m0);
293 	rln_need_reset(sc);
294 	return;
295 }
296 
297 /* Transmit one packet. */
298 int
rln_transmit(sc,m0,len,pad)299 rln_transmit(sc, m0, len, pad)
300 	struct rln_softc *	sc;
301 	struct mbuf *	m0;
302 	int 		len;
303 	int 		pad;
304 {
305 	struct mbuf *	m;
306 	int 		zfirst;
307 	int 		actlen;
308 	int 		tlen = len + pad;
309 	struct rln_msg_tx_state state;
310 	static u_int8_t zeroes[60];
311 	struct rln_mm_sendpacket cmd = { RLN_MM_SENDPACKET };
312 
313 	/* Does the packet start with a zero bit? */
314 	zfirst = ((*mtod(m0, u_int8_t *) & 1) == 0);
315 
316 	cmd.mode =
317 		RLN_MM_SENDPACKET_MODE_BIT7 |
318 		   (zfirst ? RLN_MM_SENDPACKET_MODE_ZFIRST : 0) |
319 		   (0 ? RLN_MM_SENDPACKET_MODE_QFSK : 0),	/* sc->qfsk? */
320 	cmd.power = 0x70;	/* 0x70 or 0xf0 */
321 	cmd.length_lo = htons(4 + tlen) & 0xff;
322 	cmd.length_hi = (htons(4 + tlen) >> 8) & 0xff;
323 	cmd.xxx1 = 0;
324 	cmd.xxx2 = 0;
325 	cmd.xxx3 = 0;
326 
327 	/* A unique packet-level sequence number, independent of sc_seq. */
328 	cmd.sequence = sc->sc_txseq;
329 	sc->sc_txseq++;
330 	if (sc->sc_txseq > RLN_MAXSEQ)
331 		sc->sc_txseq = 0;
332 
333 	dprintf(" T[%d+%d", len, pad);
334 
335 	if (rln_msg_tx_start(sc, &cmd, sizeof cmd + tlen, &state))
336 		goto error;
337 
338 	cmd.mm_cmd.cmd_seq = rln_newseq(sc);
339 
340 	/* Send the SENDPACKET command header  */
341 #ifdef RLNDUMP
342 	printf("%s: send %c%d seq %d data ", sc->sc_dev.dv_xname,
343 	    cmd.mm_cmd.cmd_letter, cmd.mm_cmd.cmd_fn, cmd.mm_cmd.cmd_seq);
344 	RLNDUMPHEX(&cmd, sizeof cmd);
345 	printf(":");
346 #endif
347 	rln_msg_tx_data(sc, &cmd, sizeof cmd, &state);
348 
349 	/* XXX do we need to insert a hardware header here??? */
350 
351 	/* Follow the header immediately with the packet payload */
352 	actlen = 0;
353 	for (m = m0; m; m = m->m_next)	{
354 		if (m->m_len) {
355 #ifdef RLNDUMP
356 			RLNDUMPHEX(mtod(m, void *), m->m_len);
357 #endif
358 			rln_msg_tx_data(sc, mtod(m, void *), m->m_len, &state);
359 		}
360 		if (m->m_next)
361 			printf("|");
362 		actlen += m->m_len;
363 	}
364 #ifdef DIAGNOSTIC
365 	if (actlen != len)
366 		panic("rln_transmit: len %d != %d", actlen, len);
367 	if (pad > sizeof zeroes)
368 		panic("rln_transmit: pad %d > %d", pad, sizeof zeroes);
369 #endif
370 	if (pad) {
371 #ifdef RLNDUMP
372 		printf(":");
373 		RLNDUMPHEX(zeroes, pad);
374 #endif
375 		rln_msg_tx_data(sc, zeroes, pad, &state);
376 	}
377 
378 #ifdef RLNDUMP
379 	printf("\n");
380 #endif
381 	if (rln_msg_tx_end(sc, &state))
382 		goto error;
383 	return (0);
384 
385     error:
386 	dprintf(" error]");
387 	return (-1);
388 }
389 
390 /* (Supposedly) called when interrupts are suspiciously absent. */
391 void
rlnwatchdog(ifp)392 rlnwatchdog(ifp)
393 	struct ifnet * ifp;
394 {
395 	struct rln_softc * sc = (struct rln_softc *)ifp->if_softc;
396 
397 	log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
398 	++sc->sc_arpcom.ac_if.if_oerrors;
399 	rlninit(sc);
400 	rln_enable(sc, 1);
401 }
402 
403 /* Handle single card interrupt. */
404 int
rlnintr(arg)405 rlnintr(arg)
406 	void *	arg;
407 {
408 	struct rln_softc * sc = (struct rln_softc *)arg;
409 
410 	dprintf("!");
411 
412 	/* Tell card not to interrupt any more. */
413 	rln_enable(sc, 0);
414 
415 	if (cold)
416 		/* During autoconfig - must handle interrupts now. */
417 		rlnsoftintr(sc);
418 	else
419 		/* Handle later. */
420 		timeout_add(&sc->sc_timeout, 1);
421 
422 	return (1);
423 }
424 
425 /* Process earlier card interrupt at splsoftnet. */
426 void
rlnsoftintr(arg)427 rlnsoftintr(arg)
428 	void * arg;
429 {
430 	struct rln_softc *sc = (struct rln_softc *)arg;
431 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
432 	int len;
433 	u_int8_t w;
434 	struct rln_mm_cmd hdr;
435 	int s;
436 
437 	s = splsoftnet();
438 	dprintf(" si(");
439 
440     again:
441 	/* Save wakeup state. */
442 	w = rln_wakeup(sc, RLN_WAKEUP_SET);
443 
444 	if ((len = rln_rx_request(sc, 300)) < 0) {
445 		/* Error in transfer. */
446 		rln_need_reset(sc);
447 		rln_rx_end(sc);
448 	} else if (len < sizeof hdr) {
449 		/* Short message. */
450 		rln_rx_end(sc);
451 		printf("%s: short msg (%d)\n", sc->sc_dev.dv_xname, len);
452 		ifp->if_ierrors++;
453 	} else {
454 		/* Valid message: read header and process. */
455 		rln_rx_data(sc, &hdr, sizeof hdr);
456 		rlnread(sc, &hdr, len);
457 	}
458 
459 	/* Ensure that wakeup state is unchanged if transmitting. */
460 	if (ifp->if_flags & IFF_OACTIVE)
461 		w |= RLN_WAKEUP_NOCHANGE;
462 	rln_wakeup(sc, w);
463 
464 	/* Check for more interrupts. */
465 	if ((sc->sc_state & RLN_STATE_NEEDINIT) == 0 &&
466 	    rln_status_rx_ready(sc)) {
467 		if (rln_status_rx_read(sc) == RLN_STATUS_RX_ERROR) {
468 #ifdef DIAGNOSTIC
469 			printf("%s: protocol error\n", sc->sc_dev.dv_xname);
470 #endif
471 			DELAY(100 * 1000);	/* Woah, baby. */
472 			rln_clear_nak(sc);
473 		} else {
474 #ifdef DIAGNOSTIC
475 			printf("%s: intr piggyback\n", sc->sc_dev.dv_xname);
476 #endif
477 			goto again;
478 		}
479 	}
480 
481 	rln_eoi(sc);
482 	rln_enable(sc, 1);
483 
484 	dprintf(")");
485 	splx(s);
486 }
487 
488 /* Read and process a message from the card. */
489 void
rlnread(sc,hdr,len)490 rlnread(sc, hdr, len)
491 	struct rln_softc *sc;
492 	struct rln_mm_cmd *hdr;
493 	int len;
494 {
495 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
496 	struct mbuf *m;
497 	u_int8_t data[1538];
498 	u_int8_t  *buf;
499 	size_t	  buflen;
500 	struct rln_pdata pd = RLN_PDATA_INIT;
501 	struct rln_mm_synchronised * syncp = (struct rln_mm_synchronised *)data;
502 	int s;
503 
504 	dprintf(" [read]");
505 
506 	/* Were we waiting for this message? */
507 	if (rln_mbox_lock(sc, hdr->cmd_seq, (void **)&buf, &buflen) == 0) {
508 #ifdef DIAGNOSTIC
509 		if (buflen < sizeof *hdr)
510 			panic("rlnread buflen");
511 #endif
512 		bcopy(hdr, buf, sizeof *hdr);
513 		buf += sizeof *hdr;
514 		len -= sizeof *hdr;
515 		buflen -= sizeof *hdr;
516 		if (len) {
517 			if (len == buflen)		/* Expected size */
518 				rln_rx_pdata(sc, buf, len, &pd);
519 			else if (len < buflen) {	/* Underfill */
520 #ifdef DIAGNOSTIC
521 				printf("%s: underfill %d<%d, cmd %c%d\n",
522 					sc->sc_dev.dv_xname,
523 					len, buflen,
524 					hdr->cmd_letter, hdr->cmd_fn);
525 #endif
526 				rln_rx_pdata(sc, buf, len, &pd);
527 			} else {			/* Overflow */
528 #ifdef DIAGNOSTIC
529 				printf("%s: overflow %d>%d, cmd %c%d\n",
530 					sc->sc_dev.dv_xname,
531 					len, buflen,
532 					hdr->cmd_letter, hdr->cmd_fn);
533 #endif
534 				rln_rx_pdata(sc, buf, buflen, &pd);
535 				/* Drain the rest somewhere. */
536 				rln_rx_pdata(sc, data, len - buflen, &pd);
537 			}
538 		}
539 		rln_rx_end(sc);
540 
541 		/* This message can now be handled by the waiter. */
542 		rln_mbox_unlock(sc, hdr->cmd_seq, len + sizeof *hdr);
543 		return;
544 	}
545 
546 	/* Otherwise, handle the message, right here, right now. */
547 
548 	/* Check if we can cope with the size of this message. */
549 	if (len > sizeof data) {
550 		printf("%s: msg too big (%d)\n", sc->sc_dev.dv_xname, len);
551 		ifp->if_ierrors++;
552 		rln_rx_end(sc);
553 		/* rln_need_reset(sc); */
554 		return;
555 	}
556 
557 	/* Check for error results. */
558 	if (hdr->cmd_error & 0x80) {
559 		printf("%s: command error 0x%02x command %c%d len=%d\n",
560 			sc->sc_dev.dv_xname,
561 			hdr->cmd_error & ~0x80,
562 			hdr->cmd_letter, hdr->cmd_fn,
563 			len);
564 		ifp->if_ierrors++;
565 		rln_rx_end(sc);
566 		rln_need_reset(sc);
567 		return;
568 	}
569 
570 	/*
571 	 * "b1": Receiving a packet is a special case.
572 	 * We wish to read the data with pio straight into an
573 	 * mbuf to avoid a memory-memory copy.
574 	 */
575 	if (hdr->cmd_letter == 'b' && hdr->cmd_fn == 1) {
576 		m = rlnget(sc, hdr, len);
577 		rln_rx_end(sc);
578 		if (m == NULL)
579 			return;
580 		ifp->if_ipackets++;
581 #ifdef DIAGNOSTIC
582 		if (bcmp(mtod(m, u_int8_t *), "prox", 4) == 0) {
583 			printf("%s: proxim special packet received\n",
584 			    sc->sc_dev.dv_xname);
585 		}
586 #endif
587 
588 #if NBPFILTER > 0
589 		if (ifp->if_bpf)
590 			bpf_mtap(ifp->if_bpf, m);
591 #endif
592 
593 		ether_input_mbuf(ifp, m);
594 		return;
595 	}
596 
597 
598 	/* Otherwise we read the packet into a buffer on the stack. */
599 	bcopy(hdr, data, sizeof *hdr);
600 	if (len > sizeof *hdr)
601 		rln_rx_pdata(sc, data + sizeof *hdr, len - sizeof *hdr, &pd);
602 	rln_rx_end(sc);
603 
604 #ifdef RLNDUMP
605 	printf("%s: recv %c%d seq %d data ", sc->sc_dev.dv_xname,
606 	    hdr->cmd_letter, hdr->cmd_fn, hdr->cmd_seq);
607 	RLNDUMPHEX(hdr, sizeof hdr);
608 	printf(":");
609 	RLNDUMPHEX(data + sizeof hdr, len - sizeof hdr);
610 	printf("\n");
611 #endif
612 
613 	switch (RLN_MM_CMD(hdr->cmd_letter, hdr->cmd_fn)) {
614 	case RLN_MM_CMD('b', 0):			/* b0: Transmit done. */
615 #ifdef DIAGNOSTIC
616 		if (len != 7)
617 			printf("%s: 'b0' len %d != 7\n",
618 			    sc->sc_dev.dv_xname, len);
619 #endif
620 		ifp->if_flags &= ~IFF_OACTIVE;
621 		ifp->if_opackets++;
622 		s = splnet();
623 		rlnstart(ifp);
624 		splx(s);
625 		break;
626 
627 	case RLN_MM_CMD('a', 20):			/* a20: Card fault. */
628 		printf("%s: hardware fault\n", sc->sc_dev.dv_xname);
629 		break;
630 
631 	case RLN_MM_CMD('a', 4):			/* a4: Sync'd. */
632 		if (bcmp(syncp->enaddr, sc->sc_arpcom.ac_enaddr,
633 		    ETHER_ADDR_LEN) == 0) {
634 			/* Sync'd to own enaddr. */
635  /*
636   * From http://www.proxim.com/support/faq/7400.shtml
637   * 3. RLNSETUP reports that I'm synchronized to my own MAC address. What
638   *    does that mean?
639   *    You are the acting Master for this network. Either you are
640   *    configured as the Master or as an Alternate Master. If you are an
641   *    Alternate Master, you may be out of range or on a different Domain
642   *    and Security ID from the true Master.
643   */
644 
645 			printf("%s: nothing to sync to; now master ",
646 			    sc->sc_dev.dv_xname);
647 		}
648 		else
649 			printf("%s: synchronised to ", sc->sc_dev.dv_xname);
650 		printf("%.11s (%s) channel %d/%d\n",
651 		    syncp->mastername,
652 		    ether_sprintf(syncp->enaddr),
653 		    syncp->channel,
654 		    syncp->subchannel);
655 
656 		/* Record the new circumstances. */
657 		sc->sc_param.rp_channel = syncp->channel;
658 		sc->sc_param.rp_subchannel = syncp->subchannel;
659 		sc->sc_state |= RLN_STATE_SYNC;
660 
661 		/* Resume sending. */
662 		s = splnet();
663 		rlnstart(ifp);
664 		splx(s);
665 		break;
666 
667 	case RLN_MM_CMD('a', 5):			/* a4: Lost sync. */
668 		printf("%s: lost sync\n", sc->sc_dev.dv_xname);
669 		sc->sc_state &= ~RLN_STATE_SYNC;
670 		break;
671 
672 	case RLN_MM_CMD('a', 18):			/* a18: Roaming. */
673 		printf("%s: roaming\n", sc->sc_dev.dv_xname);
674 		break;
675 	default:
676 #ifdef DIAGNOSTIC
677 		printf("%s: msg `%c%d' seq %d data {",
678 		    sc->sc_dev.dv_xname,
679 		    hdr->cmd_letter, hdr->cmd_fn, hdr->cmd_seq);
680 		RLNDUMPHEX(hdr, sizeof hdr);
681 		printf(":");
682 		RLNDUMPHEX(data, len);
683 		printf("}\n");
684 #endif
685 		break;
686 	}
687 
688 }
689 
690 /* Extract a received network packet from the card. */
691 struct mbuf *
rlnget(sc,hdr,totlen)692 rlnget(sc, hdr, totlen)
693 	struct rln_softc *sc;
694 	struct rln_mm_cmd *hdr;
695 	int totlen;
696 {
697 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
698 	int len;
699 	int pad;
700 	struct mbuf *m, **mp, *top;
701 	struct rln_pdata pd = RLN_PDATA_INIT;
702 	struct {
703 		u_int8_t rssi;
704 		u_int8_t xxx1;	/* always 00? */
705 		u_int16_t len;	/* payload length */
706 		u_int8_t xxx2;	/* always 00? */
707 		u_int8_t xxx3;	/* always c0? */
708 		u_int8_t seq;
709 		u_int8_t xxx4;
710 		struct	ether_addr to;	 /* destination station addr */
711 		struct	ether_addr from; /* sending station addr */
712 	} hwhdr;
713 
714 	dprintf(" [get]");
715 
716 #ifdef RLNDUMP
717 	/* Decode the command header: */
718 	printf("%s: recv %c%d seq %d data ", sc->sc_dev.dv_xname,
719 	    hdr->cmd_letter, hdr->cmd_fn, hdr->cmd_seq);
720 	RLNDUMPHEX(hdr, sizeof hdr);
721 	printf(":");
722 #endif
723 	totlen -= sizeof *hdr;
724 
725 #ifdef DIAGNOSTIC
726 	if (totlen <= 0) {
727 		printf("%s: empty packet", sc->sc_dev.dv_xname);
728 		goto drop;
729 	}
730 #endif
731 
732 	/* Decode the hardware header: */
733 	rln_rx_pdata(sc, &hwhdr, sizeof hwhdr, &pd);
734 	totlen -= sizeof hwhdr;
735 #ifdef RLNDUMP
736 	RLNDUMPHEX(&hwhdr, sizeof hwhdr);
737 	printf("/");
738 #endif
739 	/* (Most of the following code fleeced from elink3.c.) */
740 
741 	MGETHDR(m, M_DONTWAIT, MT_DATA);
742 	if (m == NULL)
743 		goto drop;
744 	m->m_pkthdr.rcvif = ifp;
745 	m->m_pkthdr.len = totlen;
746 	/*
747 	 * Insert some leading padding in the mbuf, so that payload data is
748 	 * aligned.
749 	 */
750 	pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
751 	m->m_data += pad;
752 	len = MHLEN - pad;
753 	top = 0;
754 	mp = &top;
755 
756 	while (totlen > 0) {
757 		if (top) {
758 			MGET(m, M_DONTWAIT, MT_DATA);
759 			if (m == NULL) {
760 				m_freem(top);
761 				goto drop;
762 			}
763 			len = MLEN;
764 		}
765 		if (totlen >= MINCLSIZE) {
766 			MCLGET(m, M_DONTWAIT);
767 			if (m->m_flags & M_EXT) {
768 				len = MCLBYTES;
769 				if (!top) {
770 					m->m_data += pad;
771 					len -= pad;
772 				}
773 			}
774 		}
775 		len = min(totlen, len);
776 		rln_rx_pdata(sc, mtod(m, u_int8_t *), len, &pd);
777 #ifdef RLNDUMP
778 		RLNDUMPHEX(mtod(m, u_int8_t *), len);
779 		if (totlen != len)
780 			printf("|");
781 #endif
782 		m->m_len = len;
783 		totlen -= len;
784 		*mp = m;
785 		mp = &m->m_next;
786 	}
787 #ifdef RLNDUMP
788 	printf("\n");
789 #endif
790 	return top;
791 
792 drop:
793 #ifdef RLNDUMP
794 	printf(": drop\n");
795 #endif
796 	ifp->if_iqdrops++;
797 	return NULL;
798 }
799 
800 /* Interface control. */
801 int
rlnioctl(ifp,cmd,data)802 rlnioctl(ifp, cmd, data)
803 	struct ifnet *ifp;
804 	u_long cmd;
805 	caddr_t data;
806 {
807 	struct rln_softc *sc = ifp->if_softc;
808 	struct ifaddr *ifa = (struct ifaddr *)data;
809 	int s, error;
810 	int need_init;
811 
812 	printf("%s: ioctl cmd[%c/%d] data=%x\n", sc->sc_dev.dv_xname,
813 		IOCGROUP(cmd), IOCBASECMD(cmd), data);
814 
815 	s = splnet();
816 	if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) != 0) {
817 		splx(s);
818 		return error;
819 	}
820 
821 	switch (cmd) {
822 	case SIOCSIFADDR:
823 		/* Set address. */
824 		ifp->if_flags |= IFF_UP;
825 
826 		switch (ifa->ifa_addr->sa_family) {
827 #ifdef INET
828 		case AF_INET:
829 			rlninit(sc);
830 			arp_ifinit(&sc->sc_arpcom, ifa);
831 			break;
832 #endif
833 		default:
834 			rlninit(sc);
835 			break;
836 		}
837 		break;
838 
839 	case SIOCSIFFLAGS:
840 		need_init = 0;
841 
842 		if ((ifp->if_flags & IFF_UP) == 0 &&
843 		    (ifp->if_flags & IFF_RUNNING) != 0) {
844 			/* Was running, want down: stop. */
845 			rlnstop(sc);
846 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
847 			   (ifp->if_flags & IFF_RUNNING) == 0) {
848 			/* Was not running, want up: start. */
849 			need_init = 1;
850 		}
851 
852 		if (ifp->if_flags & IFF_RUNNING) {
853 			if ((ifp->if_flags & IFF_PROMISC) &&
854 			    (sc->sc_state & RLN_STATE_PROMISC) == 0) {
855 				sc->sc_state |= RLN_STATE_PROMISC;
856 				need_init = 1;
857 			}
858 			else if ((ifp->if_flags & IFF_PROMISC) == 0 &&
859 			    (sc->sc_state & RLN_STATE_PROMISC)) {
860 				sc->sc_state &= ~RLN_STATE_PROMISC;
861 				need_init = 1;
862 			}
863 		}
864 
865 		if (need_init)
866 			rlninit(sc);
867 
868 		break;
869 
870 	case SIOCADDMULTI:
871 	case SIOCDELMULTI:
872 		error = EOPNOTSUPP;
873 		break;
874 
875 #if notyet
876 	case RLNIOSPARAM:
877 		error = rln_iosetparam(sc, (struct rln_param *)&data);
878 		break;
879 
880 	case RLNIOGPARAM:
881 		bcopy(&sc->sc_param, (struct rln_param *)&data,
882 		    sizeof sc->sc_param);
883 		break;
884 #endif
885 
886 	default:
887 		error = EINVAL;
888 		break;
889 	}
890 
891 	splx(s);
892 	return (error);
893 }
894 
895 /* Stop output from the card. */
896 void
rlnstop(sc)897 rlnstop(sc)
898 	struct rln_softc *sc;
899 {
900 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
901 
902 	dprintf(" [stop]");
903 	ifp->if_flags &= ~IFF_RUNNING;
904 	rln_enable(sc, 0);
905 }
906 
907 /* Get MAC address from card. */
908 int
rln_getenaddr(sc,enaddr)909 rln_getenaddr(sc, enaddr)
910 	struct rln_softc *sc;
911 	u_int8_t * enaddr;
912 {
913 	struct rln_mm_cmd query = RLN_MM_GETENADDR;
914 	struct rln_mm_gotenaddr response = { RLN_MM_GETENADDR };
915 
916 	if (rln_msg_txrx(sc, &query, sizeof query,
917 	    &response, sizeof response))
918 		return (-1);
919 	bcopy(response.enaddr, enaddr, sizeof response.enaddr);
920 	return (0);
921 };
922 
923 /* Get firmware version string from card. */
924 int
rln_getpromvers(sc,ver,verlen)925 rln_getpromvers(sc, ver, verlen)
926 	struct rln_softc *sc;
927 	char *ver;
928 	int verlen;
929 {
930 	struct rln_mm_cmd query = RLN_MM_GETPROMVERSION;
931 	struct rln_mm_gotpromversion response = { RLN_MM_GOTPROMVERSION };
932 	int i;
933 
934 #ifdef DIAGNOSTIC
935 	if (verlen != sizeof response.version)
936 		panic("rln_getpromvers");
937 #endif
938 
939 	if (rln_msg_txrx(sc, &query, sizeof query,
940 	    &response, sizeof response))
941 		return (-1);
942 	bcopy(response.version, ver, verlen);
943 	/* Nul trailing spaces. */
944 	for (i = verlen - 1; i >= 0 && ver[i] <= ' '; i--)
945 		ver[i] = '\0';
946 	return (0);
947 };
948 
949 /* Set default operational parameters on card. */
950 int
rln_sendinit(sc)951 rln_sendinit(sc)
952 	struct rln_softc *sc;
953 {
954 	struct rln_mm_init init = { RLN_MM_INIT };
955 	struct rln_mm_initted iresponse;
956 #if 0
957 	struct rln_mm_setmagic magic = { RLN_MM_SETMAGIC };
958 	struct rln_mm_disablehopping hop = { RLN_MM_DISABLEHOPPING };
959 	struct rln_mm_cmd response;
960 #endif
961 
962 	bzero((char *)&init + sizeof init.mm_cmd,
963 		sizeof init - sizeof init.mm_cmd);
964 
965 	dprintf(" [setting parameters]");
966 	init.opmode = (sc->sc_state & RLN_STATE_PROMISC ?
967 	    RLN_MM_INIT_OPMODE_PROMISC : RLN_MM_INIT_OPMODE_NORMAL);
968 	init.stationtype = sc->sc_param.rp_station_type;
969 
970 	/* Spread-spectrum frequency hopping. */
971 	init.hop_period = 1;
972 	init.bfreq = 2;
973 	init.sfreq = 7;
974 
975 	/* Choose channel. */
976 	init.channel = sc->sc_param.rp_channel;
977 	init.subchannel = sc->sc_param.rp_subchannel;
978 	init.domain = sc->sc_param.rp_domain;
979 
980 	/* Name of this station when acting as master. */
981 	bcopy(sc->sc_param.rp_master, init.mastername, sizeof init.mastername);
982 
983 	/* Security params. */
984 	init.sec1 = (sc->sc_param.rp_security & 0x0000ff) >> 0;
985 	init.sec2 = (sc->sc_param.rp_security & 0x00ff00) >> 8;
986 	init.sec3 = (sc->sc_param.rp_security & 0xff0000) >> 16;
987 
988 	init.sync_to = 1;
989 	bzero(init.syncname, sizeof init.syncname);
990 
991 	if (rln_msg_txrx(sc, &init, sizeof init,
992 	    &iresponse, sizeof iresponse))
993 		return (-1);
994 #if 0
995 	dprintf(" [setting magic]");
996 	magic.fairness_slot = 3;	/* lite: 1, norm: 3, off: -1 */
997 	magic.deferral_slot = 3;	/* lite: 0, norm: 3, off: -1 */
998 	magic.regular_mac_retry = 7;
999 	magic.frag_mac_retry = 10;
1000 	magic.regular_mac_qfsk = 2;
1001 	magic.frag_mac_qfsk = 5;
1002 	magic.xxx1 = 0xff;
1003 	magic.xxx2 = 0xff;
1004 	magic.xxx3 = 0xff;
1005 	magic.xxx4 = 0x00;
1006 	if (rln_msg_txrx(sc, &magic, sizeof magic,
1007 	    &response, sizeof response))
1008 		return (-1);
1009 
1010 	dprintf(" [disabling freq hopping]");
1011 	hop.hopflag = RLN_MM_DISABLEHOPPING_HOPFLAG_DISABLE;
1012 	if (rln_msg_txrx(sc, &hop, sizeof hop,
1013 	    &response, sizeof response))
1014 		return (-1);
1015 
1016 #endif
1017 	return (0);
1018 }
1019 
1020 #if notyet
1021 /* Configure the way the card leaves a basestation. */
1022 int
rln_roamconfig(sc)1023 rln_roamconfig(sc)
1024 	struct rln_softc *sc;
1025 {
1026 	struct rln_mm_setroaming roam = { RLN_MM_SETROAMING };
1027 	struct rln_mm_cmd response;
1028 	static int retry[3] = { 6, 6, 4 };
1029 	static int rssi[3] = { 5, 15, 5 };
1030 
1031 	dprintf(" [roamconfig]");
1032 #ifdef DIAGNOSTIC
1033 	if (sc->sc_param.rp_roam_config > 2)
1034 		panic("roamconfig");
1035 #endif
1036 	roam.sync_alarm = 0;
1037 	roam.retry_thresh = retry[sc->sc_param.rp_roam_config];
1038 	roam.rssi_threshold = rssi[sc->sc_param.rp_roam_config];
1039 	roam.xxx1 = 0x5a;
1040 	roam.sync_rssi_threshold = 0;
1041 	roam.xxx2 = 0x5a;
1042 	roam.missed_sync = 0x4;
1043 	if (rln_msg_txrx(sc, &roam, sizeof roam,
1044 	    &response, sizeof response))
1045 		return (-1);
1046 
1047 	return (0);
1048 }
1049 
1050 /* Enable roaming. */
1051 int
rln_roam(sc)1052 rln_roam(sc)
1053 	struct rln_softc *sc;
1054 {
1055 	struct rln_mm_cmd roam = RLN_MM_ROAM;
1056 	struct rln_mm_cmd response;
1057 
1058 	return (rln_msg_txrx(sc, &roam, sizeof roam,
1059 	    &response, sizeof response));
1060 }
1061 
1062 /* Enable multicast capability. */
1063 int
rln_multicast(sc,enable)1064 rln_multicast(sc, enable)
1065 	struct rln_softc *sc;
1066 	int enable;
1067 {
1068 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1069 	struct rln_mm_multicast mcast = { RLN_MM_MULTICAST };
1070 	struct rln_mm_cmd response;
1071 	int ret;
1072 
1073 	mcast.enable = enable;
1074 
1075 	ret = rln_msg_txrx(sc, &mcast, sizeof mcast,
1076 	    &response, sizeof response);
1077 	if (ret == 0) {
1078 		if (enable)
1079 			ifp->if_flags |= IFF_MULTICAST;
1080 		else
1081 			ifp->if_flags &= ~IFF_MULTICAST;
1082 	}
1083 	return (ret);
1084 }
1085 
1086 /* Search for and sync with any master. */
1087 int
rln_searchsync(sc)1088 rln_searchsync(sc)
1089 	struct rln_softc *sc;
1090 {
1091 	struct rln_mm_search search = { RLN_MM_SEARCH };
1092 	struct rln_mm_searching response;
1093 
1094 	bzero(search.xxx1, sizeof search.xxx1);
1095 	search.domain = sc->sc_param.rp_domain;
1096 	search.roaming = 1;
1097 	search.xxx3 = 0;
1098 	search.xxx4 = 1;
1099 	search.xxx5 = 0;
1100 	bzero(search.xxx6, sizeof search.xxx6);
1101 
1102 	return (rln_msg_txrx(sc, &search, sizeof search,
1103 		&response, sizeof response));
1104 }
1105 
1106 /* Set values from an external parameter block. */
1107 int
rln_iosetparam(sc,param)1108 rln_iosetparam(sc, param)
1109 	struct rln_softc *sc;
1110 	struct rln_param *param;
1111 {
1112 	int error = 0;
1113 
1114 	if (param->rp_roam_config > 2)
1115 		error = EINVAL;
1116 	if (param->rp_security > 0x00ffffff)
1117 		error = EINVAL;
1118 	if (param->rp_station_type > 2)
1119 		error = EINVAL;
1120 	if (param->rp_channel > 15)
1121 		error = EINVAL;
1122 	if (param->rp_subchannel > 15)
1123 		error = EINVAL;
1124 	if (error == 0) {
1125 		/* Apply immediately. */
1126 		bcopy(param, &sc->sc_param, sizeof *param);
1127 		if (rln_sendinit(sc))
1128 			error = EIO;
1129 	}
1130 	return (error);
1131 }
1132 
1133 /* Protect the eeprom from storing a security ID(?) */
1134 int
rln_lockprom(sc)1135 rln_lockprom(sc)
1136 	struct rln_softc *sc;
1137 {
1138 	struct rln_mm_cmd lock = RLN_MM_EEPROM_PROTECT;
1139 	struct rln_mm_cmd response;
1140 
1141 	/* XXX Always yields an error? */
1142 	return (rln_msg_txrx(sc, &lock, sizeof lock,
1143 	    &response, sizeof response));
1144 }
1145 
1146 /* Set the h/w Inactivity Time Out timer on the card. */
1147 int
rln_ito(sc)1148 rln_ito(sc)
1149 	struct rln_softc * sc;
1150 {
1151 	struct rln_mm_setito ito = { RLN_MM_MULTICAST };
1152 	struct rln_mm_cmd response;
1153 
1154 	ito.xxx = 3;
1155 	ito.timeout = LLDInactivityTimeOut /* enabler, 0 or 1 */;
1156 	ito.bd_wakeup = LLDBDWakeup /* 0 */;
1157 	ito.pm_sync = LLDPMSync /* 0 */;
1158 	ito.sniff_time = ito.timeout ? LLDSniffTime /* 0 */ : 0;
1159 
1160 	if (rln_msg_txrx(sc, &ito, sizeof ito,
1161 	    &response, sizeof response))
1162 		return (-1);
1163 }
1164 
1165 /* Put the card into standby mode. */
1166 int
rln_standby(sc)1167 rln_standby(sc)
1168 	struct rln_softc * sc;
1169 {
1170 	struct rln_mm_standby standby = { RLN_MM_STANDBY };
1171 
1172 	standby.xxx = 0;
1173 	if (rln_msg_txrx(sc, &ito, sizeof ito, NULL, 0))
1174 		return (-1);
1175 }
1176 
1177 void
rln_crypt(userkey,cardkey)1178 rln_crypt(userkey, cardkey)
1179 	char *userkey;		/* User's string (max 20 chars). */
1180 	u_int8_t *cardkey;	/* 20 bits (3 bytes) */
1181 {
1182 	/*
1183 	 * From <http://www.proxim.com/learn/whiteppr/rl2security.shtml>
1184 	 * "RangeLAN2 Security Features":
1185 	 *
1186          *  The Security ID is a unique, 20 character alphanumeric
1187          *  string defined and configured by the user. It must be
1188          *  identically configured in every radio intended to
1189          *  communicate with others in the same network. Once
1190          *  configured, the Security ID is reduced to 20 bits by a
1191          *  proprietary algorithm confidential to Proxim. It is
1192          *  merged with the radio MAC address (a 12 character field
1193          *  unique to every radio), scrambled and stored using another
1194          *  proprietary, confidential algorithm.
1195 	 */
1196         int32_t key;
1197         int8_t ret;
1198         int i;
1199 	int len;
1200 	int32_t multiplicand = 0x80000181;
1201 	int64_t res;
1202 
1203 	/*
1204 	 * This algorithm is `compatible' with Proxim's first
1205 	 * `proprietary confidential algorithm': i.e., it appears
1206 	 * to be functionally identical.
1207 	 */
1208 	len = strlen(s);
1209         key = 0x030201;
1210         for (i = 0; i < len; i++) {
1211 
1212                 key *= userkey[i];
1213                 res = (int64_t)multiplicand * key;
1214                 key = key - 0xfffffd *
1215 		    (((key + (int32_t)(res >> 32)) >> 23) - (key >> 31));
1216         }
1217 
1218         cardkey[0] = (key >> 16) & 0xff;
1219         cardkey[1] = (key >> 8) & 0xff;
1220         cardkey[2] = key & 0xff;
1221 
1222 	cardkey[0] |= 0x03; 	/* Restrict key space by 2 bits. */
1223 }
1224 #endif
1225