xref: /freebsd-13.1/sys/dev/an/if_an.c (revision a402f803)
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause
3  *
4  * Copyright (c) 1997, 1998, 1999
5  *	Bill Paul <[email protected]>.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Bill Paul.
18  * 4. Neither the name of the author nor the names of any co-contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 /*
35  * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD.
36  *
37  * Written by Bill Paul <[email protected]>
38  * Electrical Engineering Department
39  * Columbia University, New York City
40  */
41 
42 #include <sys/cdefs.h>
43 __FBSDID("$FreeBSD$");
44 
45 /*
46  * The Aironet 4500/4800 series cards come in PCMCIA, ISA and PCI form.
47  * This driver supports all three device types (PCI devices are supported
48  * through an extra PCI shim: /sys/dev/an/if_an_pci.c). ISA devices can be
49  * supported either using hard-coded IO port/IRQ settings or via Plug
50  * and Play. The 4500 series devices support 1Mbps and 2Mbps data rates.
51  * The 4800 devices support 1, 2, 5.5 and 11Mbps rates.
52  *
53  * Like the WaveLAN/IEEE cards, the Aironet NICs are all essentially
54  * PCMCIA devices. The ISA and PCI cards are a combination of a PCMCIA
55  * device and a PCMCIA to ISA or PCMCIA to PCI adapter card. There are
56  * a couple of important differences though:
57  *
58  * - Lucent ISA card looks to the host like a PCMCIA controller with
59  *   a PCMCIA WaveLAN card inserted. This means that even desktop
60  *   machines need to be configured with PCMCIA support in order to
61  *   use WaveLAN/IEEE ISA cards. The Aironet cards on the other hand
62  *   actually look like normal ISA and PCI devices to the host, so
63  *   no PCMCIA controller support is needed
64  *
65  * The latter point results in a small gotcha. The Aironet PCMCIA
66  * cards can be configured for one of two operating modes depending
67  * on how the Vpp1 and Vpp2 programming voltages are set when the
68  * card is activated. In order to put the card in proper PCMCIA
69  * operation (where the CIS table is visible and the interface is
70  * programmed for PCMCIA operation), both Vpp1 and Vpp2 have to be
71  * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages,
72  * which leaves the card in ISA/PCI mode, which prevents it from
73  * being activated as an PCMCIA device.
74  *
75  * Note that some PCMCIA controller software packages for Windows NT
76  * fail to set the voltages as well.
77  *
78  * The Aironet devices can operate in both station mode and access point
79  * mode. Typically, when programmed for station mode, the card can be set
80  * to automatically perform encapsulation/decapsulation of Ethernet II
81  * and 802.3 frames within 802.11 frames so that the host doesn't have
82  * to do it itself. This driver doesn't program the card that way: the
83  * driver handles all of the encapsulation/decapsulation itself.
84  */
85 
86 #include "opt_inet.h"
87 
88 #ifdef INET
89 #define ANCACHE			/* enable signal strength cache */
90 #endif
91 
92 #include <sys/param.h>
93 #include <sys/ctype.h>
94 #include <sys/systm.h>
95 #include <sys/sockio.h>
96 #include <sys/mbuf.h>
97 #include <sys/priv.h>
98 #include <sys/proc.h>
99 #include <sys/kernel.h>
100 #include <sys/socket.h>
101 #ifdef ANCACHE
102 #include <sys/syslog.h>
103 #endif
104 #include <sys/sysctl.h>
105 
106 #include <sys/module.h>
107 #include <sys/bus.h>
108 #include <machine/bus.h>
109 #include <sys/rman.h>
110 #include <sys/lock.h>
111 #include <sys/mutex.h>
112 #include <machine/resource.h>
113 #include <sys/malloc.h>
114 
115 #include <net/if.h>
116 #include <net/if_var.h>
117 #include <net/if_arp.h>
118 #include <net/if_dl.h>
119 #include <net/ethernet.h>
120 #include <net/if_types.h>
121 #include <net/if_media.h>
122 
123 #include <net80211/ieee80211_var.h>
124 #include <net80211/ieee80211_ioctl.h>
125 
126 #ifdef INET
127 #include <netinet/in.h>
128 #include <netinet/in_systm.h>
129 #include <netinet/in_var.h>
130 #include <netinet/ip.h>
131 #endif
132 
133 #include <net/bpf.h>
134 
135 #include <machine/md_var.h>
136 
137 #include <dev/an/if_aironet_ieee.h>
138 #include <dev/an/if_anreg.h>
139 
140 /* These are global because we need them in sys/pci/if_an_p.c. */
141 static void an_reset(struct an_softc *);
142 static int an_init_mpi350_desc(struct an_softc *);
143 static int an_ioctl(struct ifnet *, u_long, caddr_t);
144 static void an_init(void *);
145 static void an_init_locked(struct an_softc *);
146 static int an_init_tx_ring(struct an_softc *);
147 static void an_start(struct ifnet *);
148 static void an_start_locked(struct ifnet *);
149 static void an_watchdog(struct an_softc *);
150 static void an_rxeof(struct an_softc *);
151 static void an_txeof(struct an_softc *, int);
152 
153 static void an_promisc(struct an_softc *, int);
154 static int an_cmd(struct an_softc *, int, int);
155 static int an_cmd_struct(struct an_softc *, struct an_command *,
156     struct an_reply *);
157 static int an_read_record(struct an_softc *, struct an_ltv_gen *);
158 static int an_write_record(struct an_softc *, struct an_ltv_gen *);
159 static int an_read_data(struct an_softc *, int, int, caddr_t, int);
160 static int an_write_data(struct an_softc *, int, int, caddr_t, int);
161 static int an_seek(struct an_softc *, int, int, int);
162 static int an_alloc_nicmem(struct an_softc *, int, int *);
163 static int an_dma_malloc(struct an_softc *, bus_size_t, struct an_dma_alloc *,
164     int);
165 static void an_dma_free(struct an_softc *, struct an_dma_alloc *);
166 static void an_dma_malloc_cb(void *, bus_dma_segment_t *, int, int);
167 static void an_stats_update(void *);
168 static void an_setdef(struct an_softc *, struct an_req *);
169 #ifdef ANCACHE
170 static void an_cache_store(struct an_softc *, struct ether_header *,
171     struct mbuf *, u_int8_t, u_int8_t);
172 #endif
173 
174 /* function definitions for use with the Cisco's Linux configuration
175    utilities
176 */
177 
178 static int readrids(struct ifnet*, struct aironet_ioctl*);
179 static int writerids(struct ifnet*, struct aironet_ioctl*);
180 static int flashcard(struct ifnet*, struct aironet_ioctl*);
181 
182 static int cmdreset(struct ifnet *);
183 static int setflashmode(struct ifnet *);
184 static int flashgchar(struct ifnet *,int,int);
185 static int flashpchar(struct ifnet *,int,int);
186 static int flashputbuf(struct ifnet *);
187 static int flashrestart(struct ifnet *);
188 static int WaitBusy(struct ifnet *, int);
189 static int unstickbusy(struct ifnet *);
190 
191 static void an_dump_record	(struct an_softc *,struct an_ltv_gen *,
192 				    char *);
193 
194 static int an_media_change	(struct ifnet *);
195 static void an_media_status	(struct ifnet *, struct ifmediareq *);
196 
197 static int	an_dump = 0;
198 static int	an_cache_mode = 0;
199 
200 #define DBM 0
201 #define PERCENT 1
202 #define RAW 2
203 
204 static char an_conf[256];
205 static char an_conf_cache[256];
206 
207 /* sysctl vars */
208 
209 static SYSCTL_NODE(_hw, OID_AUTO, an, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
210     "Wireless driver parameters");
211 
212 /* XXX violate ethernet/netgraph callback hooks */
213 extern	void	(*ng_ether_attach_p)(struct ifnet *ifp);
214 extern	void	(*ng_ether_detach_p)(struct ifnet *ifp);
215 
216 static int
sysctl_an_dump(SYSCTL_HANDLER_ARGS)217 sysctl_an_dump(SYSCTL_HANDLER_ARGS)
218 {
219 	int	error, r, last;
220 	char 	*s = an_conf;
221 
222 	last = an_dump;
223 
224 	switch (an_dump) {
225 	case 0:
226 		strcpy(an_conf, "off");
227 		break;
228 	case 1:
229 		strcpy(an_conf, "type");
230 		break;
231 	case 2:
232 		strcpy(an_conf, "dump");
233 		break;
234 	default:
235 		snprintf(an_conf, 5, "%x", an_dump);
236 		break;
237 	}
238 
239 	error = sysctl_handle_string(oidp, an_conf, sizeof(an_conf), req);
240 
241 	if (strncmp(an_conf,"off", 3) == 0) {
242 		an_dump = 0;
243  	}
244 	if (strncmp(an_conf,"dump", 4) == 0) {
245 		an_dump = 1;
246 	}
247 	if (strncmp(an_conf,"type", 4) == 0) {
248 		an_dump = 2;
249 	}
250 	if (*s == 'f') {
251 		r = 0;
252 		for (;;s++) {
253 			if ((*s >= '0') && (*s <= '9')) {
254 				r = r * 16 + (*s - '0');
255 			} else if ((*s >= 'a') && (*s <= 'f')) {
256 				r = r * 16 + (*s - 'a' + 10);
257 			} else {
258 				break;
259 			}
260 		}
261 		an_dump = r;
262 	}
263 	if (an_dump != last)
264 		printf("Sysctl changed for Aironet driver\n");
265 
266 	return error;
267 }
268 
269 SYSCTL_PROC(_hw_an, OID_AUTO, an_dump,
270     CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 0, sizeof(an_conf),
271     sysctl_an_dump, "A",
272     "");
273 
274 static int
sysctl_an_cache_mode(SYSCTL_HANDLER_ARGS)275 sysctl_an_cache_mode(SYSCTL_HANDLER_ARGS)
276 {
277 	int	error;
278 
279 	switch (an_cache_mode) {
280 	case 1:
281 		strcpy(an_conf_cache, "per");
282 		break;
283 	case 2:
284 		strcpy(an_conf_cache, "raw");
285 		break;
286 	default:
287 		strcpy(an_conf_cache, "dbm");
288 		break;
289 	}
290 
291 	error = sysctl_handle_string(oidp, an_conf_cache,
292 			sizeof(an_conf_cache), req);
293 
294 	if (strncmp(an_conf_cache,"dbm", 3) == 0) {
295 		an_cache_mode = 0;
296 	}
297 	if (strncmp(an_conf_cache,"per", 3) == 0) {
298 		an_cache_mode = 1;
299  	}
300 	if (strncmp(an_conf_cache,"raw", 3) == 0) {
301 		an_cache_mode = 2;
302 	}
303 
304 	return error;
305 }
306 
307 SYSCTL_PROC(_hw_an, OID_AUTO, an_cache_mode,
308     CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 0, sizeof(an_conf_cache),
309     sysctl_an_cache_mode, "A",
310     "");
311 
312 /*
313  * We probe for an Aironet 4500/4800 card by attempting to
314  * read the default SSID list. On reset, the first entry in
315  * the SSID list will contain the name "tsunami." If we don't
316  * find this, then there's no card present.
317  */
318 int
an_probe(device_t dev)319 an_probe(device_t dev)
320 {
321 	struct an_softc *sc = device_get_softc(dev);
322 	struct an_ltv_ssidlist_new	ssid;
323 	int	error;
324 
325 	bzero((char *)&ssid, sizeof(ssid));
326 
327 	error = an_alloc_port(dev, 0, AN_IOSIZ);
328 	if (error != 0)
329 		return (0);
330 
331 	/* can't do autoprobing */
332 	if (rman_get_start(sc->port_res) == -1)
333 		return(0);
334 
335 	/*
336 	 * We need to fake up a softc structure long enough
337 	 * to be able to issue commands and call some of the
338 	 * other routines.
339 	 */
340 	ssid.an_len = sizeof(ssid);
341 	ssid.an_type = AN_RID_SSIDLIST;
342 
343 	/* Make sure interrupts are disabled. */
344 	sc->mpi350 = 0;
345 	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
346 	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 0xFFFF);
347 
348 	sc->an_dev = dev;
349 	mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
350 	    MTX_DEF);
351 	AN_LOCK(sc);
352 	an_reset(sc);
353 
354 	if (an_cmd(sc, AN_CMD_READCFG, 0)) {
355 		AN_UNLOCK(sc);
356 		goto fail;
357 	}
358 
359 	if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) {
360 		AN_UNLOCK(sc);
361 		goto fail;
362 	}
363 
364 	/* See if the ssid matches what we expect ... but doesn't have to */
365 	if (strcmp(ssid.an_entry[0].an_ssid, AN_DEF_SSID)) {
366 		AN_UNLOCK(sc);
367 		goto fail;
368 	}
369 
370 	AN_UNLOCK(sc);
371 	return(AN_IOSIZ);
372 fail:
373 	mtx_destroy(&sc->an_mtx);
374 	return(0);
375 }
376 
377 /*
378  * Allocate a port resource with the given resource id.
379  */
380 int
an_alloc_port(device_t dev,int rid,int size)381 an_alloc_port(device_t dev, int rid, int size)
382 {
383 	struct an_softc *sc = device_get_softc(dev);
384 	struct resource *res;
385 
386 	res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid,
387 					  size, RF_ACTIVE);
388 	if (res) {
389 		sc->port_rid = rid;
390 		sc->port_res = res;
391 		return (0);
392 	} else {
393 		return (ENOENT);
394 	}
395 }
396 
397 /*
398  * Allocate a memory resource with the given resource id.
399  */
an_alloc_memory(device_t dev,int rid,int size)400 int an_alloc_memory(device_t dev, int rid, int size)
401 {
402 	struct an_softc *sc = device_get_softc(dev);
403 	struct resource *res;
404 
405 	res = bus_alloc_resource_anywhere(dev, SYS_RES_MEMORY, &rid,
406 					  size, RF_ACTIVE);
407 	if (res) {
408 		sc->mem_rid = rid;
409 		sc->mem_res = res;
410 		sc->mem_used = size;
411 		return (0);
412 	} else {
413 		return (ENOENT);
414 	}
415 }
416 
417 /*
418  * Allocate a auxiliary memory resource with the given resource id.
419  */
an_alloc_aux_memory(device_t dev,int rid,int size)420 int an_alloc_aux_memory(device_t dev, int rid, int size)
421 {
422 	struct an_softc *sc = device_get_softc(dev);
423 	struct resource *res;
424 
425 	res = bus_alloc_resource_anywhere(dev, SYS_RES_MEMORY, &rid,
426 					  size, RF_ACTIVE);
427 	if (res) {
428 		sc->mem_aux_rid = rid;
429 		sc->mem_aux_res = res;
430 		sc->mem_aux_used = size;
431 		return (0);
432 	} else {
433 		return (ENOENT);
434 	}
435 }
436 
437 /*
438  * Allocate an irq resource with the given resource id.
439  */
440 int
an_alloc_irq(device_t dev,int rid,int flags)441 an_alloc_irq(device_t dev, int rid, int flags)
442 {
443 	struct an_softc *sc = device_get_softc(dev);
444 	struct resource *res;
445 
446 	res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
447 				     (RF_ACTIVE | flags));
448 	if (res) {
449 		sc->irq_rid = rid;
450 		sc->irq_res = res;
451 		return (0);
452 	} else {
453 		return (ENOENT);
454 	}
455 }
456 
457 static void
an_dma_malloc_cb(void * arg,bus_dma_segment_t * segs,int nseg,int error)458 an_dma_malloc_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
459 {
460 	bus_addr_t *paddr = (bus_addr_t*) arg;
461 	*paddr = segs->ds_addr;
462 }
463 
464 /*
465  * Alloc DMA memory and set the pointer to it
466  */
467 static int
an_dma_malloc(struct an_softc * sc,bus_size_t size,struct an_dma_alloc * dma,int mapflags)468 an_dma_malloc(struct an_softc *sc, bus_size_t size, struct an_dma_alloc *dma,
469     int mapflags)
470 {
471 	int r;
472 
473 	r = bus_dmamem_alloc(sc->an_dtag, (void**) &dma->an_dma_vaddr,
474 			     BUS_DMA_NOWAIT, &dma->an_dma_map);
475 	if (r != 0)
476 		goto fail_1;
477 
478 	r = bus_dmamap_load(sc->an_dtag, dma->an_dma_map, dma->an_dma_vaddr,
479 			    size,
480 			    an_dma_malloc_cb,
481 			    &dma->an_dma_paddr,
482 			    mapflags | BUS_DMA_NOWAIT);
483 	if (r != 0)
484 		goto fail_2;
485 
486 	dma->an_dma_size = size;
487 	return (0);
488 
489 fail_2:
490 	bus_dmamap_unload(sc->an_dtag, dma->an_dma_map);
491 fail_1:
492 	bus_dmamem_free(sc->an_dtag, dma->an_dma_vaddr, dma->an_dma_map);
493 	return (r);
494 }
495 
496 static void
an_dma_free(struct an_softc * sc,struct an_dma_alloc * dma)497 an_dma_free(struct an_softc *sc, struct an_dma_alloc *dma)
498 {
499 	bus_dmamap_unload(sc->an_dtag, dma->an_dma_map);
500 	bus_dmamem_free(sc->an_dtag, dma->an_dma_vaddr, dma->an_dma_map);
501 	dma->an_dma_vaddr = 0;
502 }
503 
504 /*
505  * Release all resources
506  */
507 void
an_release_resources(device_t dev)508 an_release_resources(device_t dev)
509 {
510 	struct an_softc *sc = device_get_softc(dev);
511 	int i;
512 
513 	if (sc->port_res) {
514 		bus_release_resource(dev, SYS_RES_IOPORT,
515 				     sc->port_rid, sc->port_res);
516 		sc->port_res = 0;
517 	}
518 	if (sc->mem_res) {
519 		bus_release_resource(dev, SYS_RES_MEMORY,
520 				     sc->mem_rid, sc->mem_res);
521 		sc->mem_res = 0;
522 	}
523 	if (sc->mem_aux_res) {
524 		bus_release_resource(dev, SYS_RES_MEMORY,
525 				     sc->mem_aux_rid, sc->mem_aux_res);
526 		sc->mem_aux_res = 0;
527 	}
528 	if (sc->irq_res) {
529 		bus_release_resource(dev, SYS_RES_IRQ,
530 				     sc->irq_rid, sc->irq_res);
531 		sc->irq_res = 0;
532 	}
533 	if (sc->an_rid_buffer.an_dma_paddr) {
534 		an_dma_free(sc, &sc->an_rid_buffer);
535 	}
536 	for (i = 0; i < AN_MAX_RX_DESC; i++)
537 		if (sc->an_rx_buffer[i].an_dma_paddr) {
538 			an_dma_free(sc, &sc->an_rx_buffer[i]);
539 		}
540 	for (i = 0; i < AN_MAX_TX_DESC; i++)
541 		if (sc->an_tx_buffer[i].an_dma_paddr) {
542 			an_dma_free(sc, &sc->an_tx_buffer[i]);
543 		}
544 	if (sc->an_dtag) {
545 		bus_dma_tag_destroy(sc->an_dtag);
546 	}
547 
548 }
549 
550 int
an_init_mpi350_desc(struct an_softc * sc)551 an_init_mpi350_desc(struct an_softc *sc)
552 {
553 	struct an_command	cmd_struct;
554 	struct an_reply		reply;
555 	struct an_card_rid_desc an_rid_desc;
556 	struct an_card_rx_desc	an_rx_desc;
557 	struct an_card_tx_desc	an_tx_desc;
558 	int			i, desc;
559 
560 	AN_LOCK_ASSERT(sc);
561 	if(!sc->an_rid_buffer.an_dma_paddr)
562 		an_dma_malloc(sc, AN_RID_BUFFER_SIZE,
563 				 &sc->an_rid_buffer, 0);
564 	for (i = 0; i < AN_MAX_RX_DESC; i++)
565 		if(!sc->an_rx_buffer[i].an_dma_paddr)
566 			an_dma_malloc(sc, AN_RX_BUFFER_SIZE,
567 				      &sc->an_rx_buffer[i], 0);
568 	for (i = 0; i < AN_MAX_TX_DESC; i++)
569 		if(!sc->an_tx_buffer[i].an_dma_paddr)
570 			an_dma_malloc(sc, AN_TX_BUFFER_SIZE,
571 				      &sc->an_tx_buffer[i], 0);
572 
573 	/*
574 	 * Allocate RX descriptor
575 	 */
576 	bzero(&reply,sizeof(reply));
577 	cmd_struct.an_cmd   = AN_CMD_ALLOC_DESC;
578 	cmd_struct.an_parm0 = AN_DESCRIPTOR_RX;
579 	cmd_struct.an_parm1 = AN_RX_DESC_OFFSET;
580 	cmd_struct.an_parm2 = AN_MAX_RX_DESC;
581 	if (an_cmd_struct(sc, &cmd_struct, &reply)) {
582 		if_printf(sc->an_ifp, "failed to allocate RX descriptor\n");
583 		return(EIO);
584 	}
585 
586 	for (desc = 0; desc < AN_MAX_RX_DESC; desc++) {
587 		bzero(&an_rx_desc, sizeof(an_rx_desc));
588 		an_rx_desc.an_valid = 1;
589 		an_rx_desc.an_len = AN_RX_BUFFER_SIZE;
590 		an_rx_desc.an_done = 0;
591 		an_rx_desc.an_phys = sc->an_rx_buffer[desc].an_dma_paddr;
592 
593 		for (i = 0; i < sizeof(an_rx_desc) / 4; i++)
594 			CSR_MEM_AUX_WRITE_4(sc, AN_RX_DESC_OFFSET
595 			    + (desc * sizeof(an_rx_desc))
596 			    + (i * 4),
597 			    ((u_int32_t *)(void *)&an_rx_desc)[i]);
598 	}
599 
600 	/*
601 	 * Allocate TX descriptor
602 	 */
603 
604 	bzero(&reply,sizeof(reply));
605 	cmd_struct.an_cmd   = AN_CMD_ALLOC_DESC;
606 	cmd_struct.an_parm0 = AN_DESCRIPTOR_TX;
607 	cmd_struct.an_parm1 = AN_TX_DESC_OFFSET;
608 	cmd_struct.an_parm2 = AN_MAX_TX_DESC;
609 	if (an_cmd_struct(sc, &cmd_struct, &reply)) {
610 		if_printf(sc->an_ifp, "failed to allocate TX descriptor\n");
611 		return(EIO);
612 	}
613 
614 	for (desc = 0; desc < AN_MAX_TX_DESC; desc++) {
615 		bzero(&an_tx_desc, sizeof(an_tx_desc));
616 		an_tx_desc.an_offset = 0;
617 		an_tx_desc.an_eoc = 0;
618 		an_tx_desc.an_valid = 0;
619 		an_tx_desc.an_len = 0;
620 		an_tx_desc.an_phys = sc->an_tx_buffer[desc].an_dma_paddr;
621 
622 		for (i = 0; i < sizeof(an_tx_desc) / 4; i++)
623 			CSR_MEM_AUX_WRITE_4(sc, AN_TX_DESC_OFFSET
624 			    + (desc * sizeof(an_tx_desc))
625 			    + (i * 4),
626 			    ((u_int32_t *)(void *)&an_tx_desc)[i]);
627 	}
628 
629 	/*
630 	 * Allocate RID descriptor
631 	 */
632 
633 	bzero(&reply,sizeof(reply));
634 	cmd_struct.an_cmd   = AN_CMD_ALLOC_DESC;
635 	cmd_struct.an_parm0 = AN_DESCRIPTOR_HOSTRW;
636 	cmd_struct.an_parm1 = AN_HOST_DESC_OFFSET;
637 	cmd_struct.an_parm2 = 1;
638 	if (an_cmd_struct(sc, &cmd_struct, &reply)) {
639 		if_printf(sc->an_ifp, "failed to allocate host descriptor\n");
640 		return(EIO);
641 	}
642 
643 	bzero(&an_rid_desc, sizeof(an_rid_desc));
644 	an_rid_desc.an_valid = 1;
645 	an_rid_desc.an_len = AN_RID_BUFFER_SIZE;
646 	an_rid_desc.an_rid = 0;
647 	an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr;
648 
649 	for (i = 0; i < sizeof(an_rid_desc) / 4; i++)
650 		CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4,
651 				    ((u_int32_t *)(void *)&an_rid_desc)[i]);
652 
653 	return(0);
654 }
655 
656 int
an_attach(struct an_softc * sc,int flags)657 an_attach(struct an_softc *sc, int flags)
658 {
659 	struct ifnet		*ifp;
660 	int			error = EIO;
661 	int			i, nrate, mword;
662 	u_int8_t		r;
663 
664 	gone_in(14, "EOL/EOS in 2007");
665 	ifp = sc->an_ifp = if_alloc(IFT_ETHER);
666 	if (ifp == NULL) {
667 		device_printf(sc->an_dev, "can not if_alloc()\n");
668 		goto fail;
669 	}
670 	ifp->if_softc = sc;
671 	if_initname(ifp, device_get_name(sc->an_dev),
672 	    device_get_unit(sc->an_dev));
673 
674 	sc->an_gone = 0;
675 	sc->an_associated = 0;
676 	sc->an_monitor = 0;
677 	sc->an_was_monitor = 0;
678 	sc->an_flash_buffer = NULL;
679 
680 	/* Reset the NIC. */
681 	AN_LOCK(sc);
682 	an_reset(sc);
683 	if (sc->mpi350) {
684 		error = an_init_mpi350_desc(sc);
685 		if (error)
686 			goto fail;
687 	}
688 
689 	/* Load factory config */
690 	if (an_cmd(sc, AN_CMD_READCFG, 0)) {
691 		device_printf(sc->an_dev, "failed to load config data\n");
692 		goto fail;
693 	}
694 
695 	/* Read the current configuration */
696 	sc->an_config.an_type = AN_RID_GENCONFIG;
697 	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
698 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
699 		device_printf(sc->an_dev, "read record failed\n");
700 		goto fail;
701 	}
702 
703 	/* Read the card capabilities */
704 	sc->an_caps.an_type = AN_RID_CAPABILITIES;
705 	sc->an_caps.an_len = sizeof(struct an_ltv_caps);
706 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) {
707 		device_printf(sc->an_dev, "read record failed\n");
708 		goto fail;
709 	}
710 
711 	/* Read ssid list */
712 	sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
713 	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new);
714 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
715 		device_printf(sc->an_dev, "read record failed\n");
716 		goto fail;
717 	}
718 
719 	/* Read AP list */
720 	sc->an_aplist.an_type = AN_RID_APLIST;
721 	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
722 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
723 		device_printf(sc->an_dev, "read record failed\n");
724 		goto fail;
725 	}
726 
727 #ifdef ANCACHE
728 	/* Read the RSSI <-> dBm map */
729 	sc->an_have_rssimap = 0;
730 	if (sc->an_caps.an_softcaps & 8) {
731 		sc->an_rssimap.an_type = AN_RID_RSSI_MAP;
732 		sc->an_rssimap.an_len = sizeof(struct an_ltv_rssi_map);
733 		if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_rssimap)) {
734 			device_printf(sc->an_dev,
735 			    "unable to get RSSI <-> dBM map\n");
736 		} else {
737 			device_printf(sc->an_dev, "got RSSI <-> dBM map\n");
738 			sc->an_have_rssimap = 1;
739 		}
740 	} else {
741 		device_printf(sc->an_dev, "no RSSI <-> dBM map\n");
742 	}
743 #endif
744 	AN_UNLOCK(sc);
745 
746 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
747 	ifp->if_ioctl = an_ioctl;
748 	ifp->if_start = an_start;
749 	ifp->if_init = an_init;
750 	ifp->if_baudrate = 10000000;
751 	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
752 	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
753 	IFQ_SET_READY(&ifp->if_snd);
754 
755 	bzero(sc->an_config.an_nodename, sizeof(sc->an_config.an_nodename));
756 	bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename,
757 	    sizeof(AN_DEFAULT_NODENAME) - 1);
758 
759 	bzero(sc->an_ssidlist.an_entry[0].an_ssid,
760 	      sizeof(sc->an_ssidlist.an_entry[0].an_ssid));
761 	bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_entry[0].an_ssid,
762 	    sizeof(AN_DEFAULT_NETNAME) - 1);
763 	sc->an_ssidlist.an_entry[0].an_len = strlen(AN_DEFAULT_NETNAME);
764 
765 	sc->an_config.an_opmode =
766 	    AN_OPMODE_INFRASTRUCTURE_STATION;
767 
768 	sc->an_tx_rate = 0;
769 	bzero((char *)&sc->an_stats, sizeof(sc->an_stats));
770 
771 	nrate = 8;
772 
773 	ifmedia_init(&sc->an_ifmedia, 0, an_media_change, an_media_status);
774 	if_printf(ifp, "supported rates: ");
775 #define	ADD(s, o)	ifmedia_add(&sc->an_ifmedia, \
776 	IFM_MAKEWORD(IFM_IEEE80211, (s), (o), 0), 0, NULL)
777 	ADD(IFM_AUTO, 0);
778 	ADD(IFM_AUTO, IFM_IEEE80211_ADHOC);
779 	for (i = 0; i < nrate; i++) {
780 		r = sc->an_caps.an_rates[i];
781 		mword = ieee80211_rate2media(NULL, r, IEEE80211_MODE_AUTO);
782 		if (mword == 0)
783 			continue;
784 		printf("%s%d%sMbps", (i != 0 ? " " : ""),
785 		    (r & IEEE80211_RATE_VAL) / 2, ((r & 0x1) != 0 ? ".5" : ""));
786 		ADD(mword, 0);
787 		ADD(mword, IFM_IEEE80211_ADHOC);
788 	}
789 	printf("\n");
790 	ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211,
791 	    IFM_AUTO, 0, 0));
792 #undef ADD
793 
794 	/*
795 	 * Call MI attach routine.
796 	 */
797 
798 	ether_ifattach(ifp, sc->an_caps.an_oemaddr);
799 	callout_init_mtx(&sc->an_stat_ch, &sc->an_mtx, 0);
800 
801 	return(0);
802 fail:
803 	AN_UNLOCK(sc);
804 	mtx_destroy(&sc->an_mtx);
805 	if (ifp != NULL)
806 		if_free(ifp);
807 	return(error);
808 }
809 
810 int
an_detach(device_t dev)811 an_detach(device_t dev)
812 {
813 	struct an_softc		*sc = device_get_softc(dev);
814 	struct ifnet		*ifp = sc->an_ifp;
815 
816 	if (sc->an_gone) {
817 		device_printf(dev,"already unloaded\n");
818 		return(0);
819 	}
820 	AN_LOCK(sc);
821 	an_stop(sc);
822 	sc->an_gone = 1;
823 	ifmedia_removeall(&sc->an_ifmedia);
824 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
825 	AN_UNLOCK(sc);
826 	ether_ifdetach(ifp);
827 	bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
828 	callout_drain(&sc->an_stat_ch);
829 	if_free(ifp);
830 	an_release_resources(dev);
831 	mtx_destroy(&sc->an_mtx);
832 	return (0);
833 }
834 
835 static void
an_rxeof(struct an_softc * sc)836 an_rxeof(struct an_softc *sc)
837 {
838 	struct ifnet   *ifp;
839 	struct ether_header *eh;
840 	struct ieee80211_frame *ih;
841 	struct an_rxframe rx_frame;
842 	struct an_rxframe_802_3 rx_frame_802_3;
843 	struct mbuf    *m;
844 	int		len, id, error = 0, i, count = 0;
845 	int		ieee80211_header_len;
846 	u_char		*bpf_buf;
847 	u_short		fc1;
848 	struct an_card_rx_desc an_rx_desc;
849 	u_int8_t	*buf;
850 
851 	AN_LOCK_ASSERT(sc);
852 
853 	ifp = sc->an_ifp;
854 
855 	if (!sc->mpi350) {
856 		id = CSR_READ_2(sc, AN_RX_FID);
857 
858 		if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) {
859 			/* read raw 802.11 packet */
860 			bpf_buf = sc->buf_802_11;
861 
862 			/* read header */
863 			if (an_read_data(sc, id, 0x0, (caddr_t)&rx_frame,
864 					 sizeof(rx_frame))) {
865 				if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
866 				return;
867 			}
868 
869 			/*
870 			 * skip beacon by default since this increases the
871 			 * system load a lot
872 			 */
873 
874 			if (!(sc->an_monitor & AN_MONITOR_INCLUDE_BEACON) &&
875 			    (rx_frame.an_frame_ctl &
876 			     IEEE80211_FC0_SUBTYPE_BEACON)) {
877 				return;
878 			}
879 
880 			if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) {
881 				len = rx_frame.an_rx_payload_len
882 					+ sizeof(rx_frame);
883 				/* Check for insane frame length */
884 				if (len > sizeof(sc->buf_802_11)) {
885 					if_printf(ifp, "oversized packet "
886 					       "received (%d, %d)\n",
887 					       len, MCLBYTES);
888 					if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
889 					return;
890 				}
891 
892 				bcopy((char *)&rx_frame,
893 				      bpf_buf, sizeof(rx_frame));
894 
895 				error = an_read_data(sc, id, sizeof(rx_frame),
896 					    (caddr_t)bpf_buf+sizeof(rx_frame),
897 					    rx_frame.an_rx_payload_len);
898 			} else {
899 				fc1=rx_frame.an_frame_ctl >> 8;
900 				ieee80211_header_len =
901 					sizeof(struct ieee80211_frame);
902 				if ((fc1 & IEEE80211_FC1_DIR_TODS) &&
903 				    (fc1 & IEEE80211_FC1_DIR_FROMDS)) {
904 					ieee80211_header_len += ETHER_ADDR_LEN;
905 				}
906 
907 				len = rx_frame.an_rx_payload_len
908 					+ ieee80211_header_len;
909 				/* Check for insane frame length */
910 				if (len > sizeof(sc->buf_802_11)) {
911 					if_printf(ifp, "oversized packet "
912 					       "received (%d, %d)\n",
913 					       len, MCLBYTES);
914 					if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
915 					return;
916 				}
917 
918 				ih = (struct ieee80211_frame *)bpf_buf;
919 
920 				bcopy((char *)&rx_frame.an_frame_ctl,
921 				      (char *)ih, ieee80211_header_len);
922 
923 				error = an_read_data(sc, id, sizeof(rx_frame) +
924 					    rx_frame.an_gaplen,
925 					    (caddr_t)ih +ieee80211_header_len,
926 					    rx_frame.an_rx_payload_len);
927 			}
928 			/* dump raw 802.11 packet to bpf and skip ip stack */
929 			BPF_TAP(ifp, bpf_buf, len);
930 		} else {
931 			MGETHDR(m, M_NOWAIT, MT_DATA);
932 			if (m == NULL) {
933 				if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
934 				return;
935 			}
936 			if (!(MCLGET(m, M_NOWAIT))) {
937 				m_freem(m);
938 				if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
939 				return;
940 			}
941 			m->m_pkthdr.rcvif = ifp;
942 			/* Read Ethernet encapsulated packet */
943 
944 #ifdef ANCACHE
945 			/* Read NIC frame header */
946 			if (an_read_data(sc, id, 0, (caddr_t)&rx_frame,
947 					 sizeof(rx_frame))) {
948 				m_freem(m);
949 				if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
950 				return;
951 			}
952 #endif
953 			/* Read in the 802_3 frame header */
954 			if (an_read_data(sc, id, 0x34,
955 					 (caddr_t)&rx_frame_802_3,
956 					 sizeof(rx_frame_802_3))) {
957 				m_freem(m);
958 				if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
959 				return;
960 			}
961 			if (rx_frame_802_3.an_rx_802_3_status != 0) {
962 				m_freem(m);
963 				if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
964 				return;
965 			}
966 			/* Check for insane frame length */
967 			len = rx_frame_802_3.an_rx_802_3_payload_len;
968 			if (len > sizeof(sc->buf_802_11)) {
969 				m_freem(m);
970 				if_printf(ifp, "oversized packet "
971 				       "received (%d, %d)\n",
972 				       len, MCLBYTES);
973 				if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
974 				return;
975 			}
976 			m->m_pkthdr.len = m->m_len =
977 				rx_frame_802_3.an_rx_802_3_payload_len + 12;
978 
979 			eh = mtod(m, struct ether_header *);
980 
981 			bcopy((char *)&rx_frame_802_3.an_rx_dst_addr,
982 			      (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
983 			bcopy((char *)&rx_frame_802_3.an_rx_src_addr,
984 			      (char *)&eh->ether_shost, ETHER_ADDR_LEN);
985 
986 			/* in mbuf header type is just before payload */
987 			error = an_read_data(sc, id, 0x44,
988 				    (caddr_t)&(eh->ether_type),
989 				    rx_frame_802_3.an_rx_802_3_payload_len);
990 
991 			if (error) {
992 				m_freem(m);
993 				if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
994 				return;
995 			}
996 			if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
997 
998 			/* Receive packet. */
999 #ifdef ANCACHE
1000 			an_cache_store(sc, eh, m,
1001 				rx_frame.an_rx_signal_strength,
1002 				rx_frame.an_rsvd0);
1003 #endif
1004 			AN_UNLOCK(sc);
1005 			(*ifp->if_input)(ifp, m);
1006 			AN_LOCK(sc);
1007 		}
1008 
1009 	} else { /* MPI-350 */
1010 		for (count = 0; count < AN_MAX_RX_DESC; count++){
1011 			for (i = 0; i < sizeof(an_rx_desc) / 4; i++)
1012 				((u_int32_t *)(void *)&an_rx_desc)[i]
1013 					= CSR_MEM_AUX_READ_4(sc,
1014 						AN_RX_DESC_OFFSET
1015 						+ (count * sizeof(an_rx_desc))
1016 						+ (i * 4));
1017 
1018 			if (an_rx_desc.an_done && !an_rx_desc.an_valid) {
1019 				buf = sc->an_rx_buffer[count].an_dma_vaddr;
1020 
1021 				MGETHDR(m, M_NOWAIT, MT_DATA);
1022 				if (m == NULL) {
1023 					if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1024 					return;
1025 				}
1026 				if (!(MCLGET(m, M_NOWAIT))) {
1027 					m_freem(m);
1028 					if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1029 					return;
1030 				}
1031 				m->m_pkthdr.rcvif = ifp;
1032 				/* Read Ethernet encapsulated packet */
1033 
1034 				/*
1035 				 * No ANCACHE support since we just get back
1036 				 * an Ethernet packet no 802.11 info
1037 				 */
1038 #if 0
1039 #ifdef ANCACHE
1040 				/* Read NIC frame header */
1041 				bcopy(buf, (caddr_t)&rx_frame,
1042 				      sizeof(rx_frame));
1043 #endif
1044 #endif
1045 				/* Check for insane frame length */
1046 				len = an_rx_desc.an_len + 12;
1047 				if (len > MCLBYTES) {
1048 					m_freem(m);
1049 					if_printf(ifp, "oversized packet "
1050 					       "received (%d, %d)\n",
1051 					       len, MCLBYTES);
1052 					if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1053 					return;
1054 				}
1055 
1056 				m->m_pkthdr.len = m->m_len =
1057 					an_rx_desc.an_len + 12;
1058 
1059 				eh = mtod(m, struct ether_header *);
1060 
1061 				bcopy(buf, (char *)eh,
1062 				      m->m_pkthdr.len);
1063 
1064 				if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
1065 
1066 				/* Receive packet. */
1067 #if 0
1068 #ifdef ANCACHE
1069 				an_cache_store(sc, eh, m,
1070 					rx_frame.an_rx_signal_strength,
1071 					rx_frame.an_rsvd0);
1072 #endif
1073 #endif
1074 				AN_UNLOCK(sc);
1075 				(*ifp->if_input)(ifp, m);
1076 				AN_LOCK(sc);
1077 
1078 				an_rx_desc.an_valid = 1;
1079 				an_rx_desc.an_len = AN_RX_BUFFER_SIZE;
1080 				an_rx_desc.an_done = 0;
1081 				an_rx_desc.an_phys =
1082 					sc->an_rx_buffer[count].an_dma_paddr;
1083 
1084 				for (i = 0; i < sizeof(an_rx_desc) / 4; i++)
1085 					CSR_MEM_AUX_WRITE_4(sc,
1086 					    AN_RX_DESC_OFFSET
1087 					    + (count * sizeof(an_rx_desc))
1088 					    + (i * 4),
1089 					    ((u_int32_t *)(void *)&an_rx_desc)[i]);
1090 
1091 			} else {
1092 				if_printf(ifp, "Didn't get valid RX packet "
1093 				       "%x %x %d\n",
1094 				       an_rx_desc.an_done,
1095 				       an_rx_desc.an_valid, an_rx_desc.an_len);
1096 			}
1097 		}
1098 	}
1099 }
1100 
1101 static void
an_txeof(struct an_softc * sc,int status)1102 an_txeof(struct an_softc *sc, int status)
1103 {
1104 	struct ifnet		*ifp;
1105 	int			id, i;
1106 
1107 	AN_LOCK_ASSERT(sc);
1108 	ifp = sc->an_ifp;
1109 
1110 	sc->an_timer = 0;
1111 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1112 
1113 	if (!sc->mpi350) {
1114 		id = CSR_READ_2(sc, AN_TX_CMP_FID(sc->mpi350));
1115 
1116 		if (status & AN_EV_TX_EXC) {
1117 			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1118 		} else
1119 			if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
1120 
1121 		for (i = 0; i < AN_TX_RING_CNT; i++) {
1122 			if (id == sc->an_rdata.an_tx_ring[i]) {
1123 				sc->an_rdata.an_tx_ring[i] = 0;
1124 				break;
1125 			}
1126 		}
1127 
1128 		AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT);
1129 	} else { /* MPI 350 */
1130 		id = CSR_READ_2(sc, AN_TX_CMP_FID(sc->mpi350));
1131 		if (!sc->an_rdata.an_tx_empty){
1132 			if (status & AN_EV_TX_EXC) {
1133 				if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1134 			} else
1135 				if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
1136 			AN_INC(sc->an_rdata.an_tx_cons, AN_MAX_TX_DESC);
1137 			if (sc->an_rdata.an_tx_prod ==
1138 			    sc->an_rdata.an_tx_cons)
1139 				sc->an_rdata.an_tx_empty = 1;
1140 		}
1141 	}
1142 
1143 	return;
1144 }
1145 
1146 /*
1147  * We abuse the stats updater to check the current NIC status. This
1148  * is important because we don't want to allow transmissions until
1149  * the NIC has synchronized to the current cell (either as the master
1150  * in an ad-hoc group, or as a station connected to an access point).
1151  *
1152  * Note that this function will be called via callout(9) with a lock held.
1153  */
1154 static void
an_stats_update(void * xsc)1155 an_stats_update(void *xsc)
1156 {
1157 	struct an_softc		*sc;
1158 	struct ifnet		*ifp;
1159 
1160 	sc = xsc;
1161 	AN_LOCK_ASSERT(sc);
1162 	ifp = sc->an_ifp;
1163 	if (sc->an_timer > 0 && --sc->an_timer == 0)
1164 		an_watchdog(sc);
1165 
1166 	sc->an_status.an_type = AN_RID_STATUS;
1167 	sc->an_status.an_len = sizeof(struct an_ltv_status);
1168 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_status))
1169 		return;
1170 
1171 	if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC)
1172 		sc->an_associated = 1;
1173 	else
1174 		sc->an_associated = 0;
1175 
1176 	/* Don't do this while we're transmitting */
1177 	if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
1178 		callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
1179 		return;
1180 	}
1181 
1182 	sc->an_stats.an_len = sizeof(struct an_ltv_stats);
1183 	sc->an_stats.an_type = AN_RID_32BITS_CUM;
1184 	if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len))
1185 		return;
1186 
1187 	callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
1188 
1189 	return;
1190 }
1191 
1192 void
an_intr(void * xsc)1193 an_intr(void *xsc)
1194 {
1195 	struct an_softc		*sc;
1196 	struct ifnet		*ifp;
1197 	u_int16_t		status;
1198 
1199 	sc = (struct an_softc*)xsc;
1200 
1201 	AN_LOCK(sc);
1202 
1203 	if (sc->an_gone) {
1204 		AN_UNLOCK(sc);
1205 		return;
1206 	}
1207 
1208 	ifp = sc->an_ifp;
1209 
1210 	/* Disable interrupts. */
1211 	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
1212 
1213 	status = CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350));
1214 	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), ~AN_INTRS(sc->mpi350));
1215 
1216 	if (status & AN_EV_MIC) {
1217 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_MIC);
1218 	}
1219 
1220 	if (status & AN_EV_LINKSTAT) {
1221 		if (CSR_READ_2(sc, AN_LINKSTAT(sc->mpi350))
1222 		    == AN_LINKSTAT_ASSOCIATED)
1223 			sc->an_associated = 1;
1224 		else
1225 			sc->an_associated = 0;
1226 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_LINKSTAT);
1227 	}
1228 
1229 	if (status & AN_EV_RX) {
1230 		an_rxeof(sc);
1231 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_RX);
1232 	}
1233 
1234 	if (sc->mpi350 && status & AN_EV_TX_CPY) {
1235 		an_txeof(sc, status);
1236 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX_CPY);
1237 	}
1238 
1239 	if (status & AN_EV_TX) {
1240 		an_txeof(sc, status);
1241 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX);
1242 	}
1243 
1244 	if (status & AN_EV_TX_EXC) {
1245 		an_txeof(sc, status);
1246 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX_EXC);
1247 	}
1248 
1249 	if (status & AN_EV_ALLOC)
1250 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
1251 
1252 	/* Re-enable interrupts. */
1253 	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
1254 
1255 	if ((ifp->if_flags & IFF_UP) && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
1256 		an_start_locked(ifp);
1257 
1258 	AN_UNLOCK(sc);
1259 
1260 	return;
1261 }
1262 
1263 static int
an_cmd_struct(struct an_softc * sc,struct an_command * cmd,struct an_reply * reply)1264 an_cmd_struct(struct an_softc *sc, struct an_command *cmd,
1265     struct an_reply *reply)
1266 {
1267 	int			i;
1268 
1269 	AN_LOCK_ASSERT(sc);
1270 	for (i = 0; i != AN_TIMEOUT; i++) {
1271 		if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) {
1272 			DELAY(1000);
1273 		} else
1274 			break;
1275 	}
1276 
1277 	if( i == AN_TIMEOUT) {
1278 		printf("BUSY\n");
1279 		return(ETIMEDOUT);
1280 	}
1281 
1282 	CSR_WRITE_2(sc, AN_PARAM0(sc->mpi350), cmd->an_parm0);
1283 	CSR_WRITE_2(sc, AN_PARAM1(sc->mpi350), cmd->an_parm1);
1284 	CSR_WRITE_2(sc, AN_PARAM2(sc->mpi350), cmd->an_parm2);
1285 	CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), cmd->an_cmd);
1286 
1287 	for (i = 0; i < AN_TIMEOUT; i++) {
1288 		if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_CMD)
1289 			break;
1290 		DELAY(1000);
1291 	}
1292 
1293 	reply->an_resp0 = CSR_READ_2(sc, AN_RESP0(sc->mpi350));
1294 	reply->an_resp1 = CSR_READ_2(sc, AN_RESP1(sc->mpi350));
1295 	reply->an_resp2 = CSR_READ_2(sc, AN_RESP2(sc->mpi350));
1296 	reply->an_status = CSR_READ_2(sc, AN_STATUS(sc->mpi350));
1297 
1298 	if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY)
1299 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350),
1300 		    AN_EV_CLR_STUCK_BUSY);
1301 
1302 	/* Ack the command */
1303 	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD);
1304 
1305 	if (i == AN_TIMEOUT)
1306 		return(ETIMEDOUT);
1307 
1308 	return(0);
1309 }
1310 
1311 static int
an_cmd(struct an_softc * sc,int cmd,int val)1312 an_cmd(struct an_softc *sc, int cmd, int val)
1313 {
1314 	int			i, s = 0;
1315 
1316 	AN_LOCK_ASSERT(sc);
1317 	CSR_WRITE_2(sc, AN_PARAM0(sc->mpi350), val);
1318 	CSR_WRITE_2(sc, AN_PARAM1(sc->mpi350), 0);
1319 	CSR_WRITE_2(sc, AN_PARAM2(sc->mpi350), 0);
1320 	CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), cmd);
1321 
1322 	for (i = 0; i < AN_TIMEOUT; i++) {
1323 		if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_CMD)
1324 			break;
1325 		else {
1326 			if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) == cmd)
1327 				CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), cmd);
1328 		}
1329 	}
1330 
1331 	for (i = 0; i < AN_TIMEOUT; i++) {
1332 		CSR_READ_2(sc, AN_RESP0(sc->mpi350));
1333 		CSR_READ_2(sc, AN_RESP1(sc->mpi350));
1334 		CSR_READ_2(sc, AN_RESP2(sc->mpi350));
1335 		s = CSR_READ_2(sc, AN_STATUS(sc->mpi350));
1336 		if ((s & AN_STAT_CMD_CODE) == (cmd & AN_STAT_CMD_CODE))
1337 			break;
1338 	}
1339 
1340 	/* Ack the command */
1341 	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD);
1342 
1343 	if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY)
1344 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CLR_STUCK_BUSY);
1345 
1346 	if (i == AN_TIMEOUT)
1347 		return(ETIMEDOUT);
1348 
1349 	return(0);
1350 }
1351 
1352 /*
1353  * This reset sequence may look a little strange, but this is the
1354  * most reliable method I've found to really kick the NIC in the
1355  * head and force it to reboot correctly.
1356  */
1357 static void
an_reset(struct an_softc * sc)1358 an_reset(struct an_softc *sc)
1359 {
1360 	if (sc->an_gone)
1361 		return;
1362 
1363 	AN_LOCK_ASSERT(sc);
1364 	an_cmd(sc, AN_CMD_ENABLE, 0);
1365 	an_cmd(sc, AN_CMD_FW_RESTART, 0);
1366 	an_cmd(sc, AN_CMD_NOOP2, 0);
1367 
1368 	if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT)
1369 		device_printf(sc->an_dev, "reset failed\n");
1370 
1371 	an_cmd(sc, AN_CMD_DISABLE, 0);
1372 
1373 	return;
1374 }
1375 
1376 /*
1377  * Read an LTV record from the NIC.
1378  */
1379 static int
an_read_record(struct an_softc * sc,struct an_ltv_gen * ltv)1380 an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv)
1381 {
1382 	struct an_ltv_gen	*an_ltv;
1383 	struct an_card_rid_desc an_rid_desc;
1384 	struct an_command	cmd;
1385 	struct an_reply		reply;
1386 	struct ifnet		*ifp;
1387 	u_int16_t		*ptr;
1388 	u_int8_t		*ptr2;
1389 	int			i, len;
1390 
1391 	AN_LOCK_ASSERT(sc);
1392 	if (ltv->an_len < 4 || ltv->an_type == 0)
1393 		return(EINVAL);
1394 
1395 	ifp = sc->an_ifp;
1396 	if (!sc->mpi350){
1397 		/* Tell the NIC to enter record read mode. */
1398 		if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) {
1399 			if_printf(ifp, "RID access failed\n");
1400 			return(EIO);
1401 		}
1402 
1403 		/* Seek to the record. */
1404 		if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) {
1405 			if_printf(ifp, "seek to record failed\n");
1406 			return(EIO);
1407 		}
1408 
1409 		/*
1410 		 * Read the length and record type and make sure they
1411 		 * match what we expect (this verifies that we have enough
1412 		 * room to hold all of the returned data).
1413 		 * Length includes type but not length.
1414 		 */
1415 		len = CSR_READ_2(sc, AN_DATA1);
1416 		if (len > (ltv->an_len - 2)) {
1417 			if_printf(ifp, "record length mismatch -- expected %d, "
1418 			       "got %d for Rid %x\n",
1419 			       ltv->an_len - 2, len, ltv->an_type);
1420 			len = ltv->an_len - 2;
1421 		} else {
1422 			ltv->an_len = len + 2;
1423 		}
1424 
1425 		/* Now read the data. */
1426 		len -= 2;	/* skip the type */
1427 		ptr = &ltv->an_val;
1428 		for (i = len; i > 1; i -= 2)
1429 			*ptr++ = CSR_READ_2(sc, AN_DATA1);
1430 		if (i) {
1431 			ptr2 = (u_int8_t *)ptr;
1432 			*ptr2 = CSR_READ_1(sc, AN_DATA1);
1433 		}
1434 	} else { /* MPI-350 */
1435 		if (!sc->an_rid_buffer.an_dma_vaddr)
1436 			return(EIO);
1437 		an_rid_desc.an_valid = 1;
1438 		an_rid_desc.an_len = AN_RID_BUFFER_SIZE;
1439 		an_rid_desc.an_rid = 0;
1440 		an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr;
1441 		bzero(sc->an_rid_buffer.an_dma_vaddr, AN_RID_BUFFER_SIZE);
1442 
1443 		bzero(&cmd, sizeof(cmd));
1444 		bzero(&reply, sizeof(reply));
1445 		cmd.an_cmd = AN_CMD_ACCESS|AN_ACCESS_READ;
1446 		cmd.an_parm0 = ltv->an_type;
1447 
1448 		for (i = 0; i < sizeof(an_rid_desc) / 4; i++)
1449 			CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4,
1450 			    ((u_int32_t *)(void *)&an_rid_desc)[i]);
1451 
1452 		if (an_cmd_struct(sc, &cmd, &reply)
1453 		    || reply.an_status & AN_CMD_QUAL_MASK) {
1454 			if_printf(ifp, "failed to read RID %x %x %x %x %x, %d\n",
1455 			       ltv->an_type,
1456 			       reply.an_status,
1457 			       reply.an_resp0,
1458 			       reply.an_resp1,
1459 			       reply.an_resp2,
1460 			       i);
1461 			return(EIO);
1462 		}
1463 
1464 		an_ltv = (struct an_ltv_gen *)sc->an_rid_buffer.an_dma_vaddr;
1465 		if (an_ltv->an_len + 2 < an_rid_desc.an_len) {
1466 			an_rid_desc.an_len = an_ltv->an_len;
1467 		}
1468 
1469 		len = an_rid_desc.an_len;
1470 		if (len > (ltv->an_len - 2)) {
1471 			if_printf(ifp, "record length mismatch -- expected %d, "
1472 			       "got %d for Rid %x\n",
1473 			       ltv->an_len - 2, len, ltv->an_type);
1474 			len = ltv->an_len - 2;
1475 		} else {
1476 			ltv->an_len = len + 2;
1477 		}
1478 		bcopy(&an_ltv->an_type,
1479 		    &ltv->an_val,
1480 		    len);
1481 	}
1482 
1483 	if (an_dump)
1484 		an_dump_record(sc, ltv, "Read");
1485 
1486 	return(0);
1487 }
1488 
1489 /*
1490  * Same as read, except we inject data instead of reading it.
1491  */
1492 static int
an_write_record(struct an_softc * sc,struct an_ltv_gen * ltv)1493 an_write_record(struct an_softc *sc, struct an_ltv_gen *ltv)
1494 {
1495 	struct an_card_rid_desc an_rid_desc;
1496 	struct an_command	cmd;
1497 	struct an_reply		reply;
1498 	u_int16_t		*ptr;
1499 	u_int8_t		*ptr2;
1500 	int			i, len;
1501 
1502 	AN_LOCK_ASSERT(sc);
1503 	if (an_dump)
1504 		an_dump_record(sc, ltv, "Write");
1505 
1506 	if (!sc->mpi350){
1507 		if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type))
1508 			return(EIO);
1509 
1510 		if (an_seek(sc, ltv->an_type, 0, AN_BAP1))
1511 			return(EIO);
1512 
1513 		/*
1514 		 * Length includes type but not length.
1515 		 */
1516 		len = ltv->an_len - 2;
1517 		CSR_WRITE_2(sc, AN_DATA1, len);
1518 
1519 		len -= 2;	/* skip the type */
1520 		ptr = &ltv->an_val;
1521 		for (i = len; i > 1; i -= 2)
1522 			CSR_WRITE_2(sc, AN_DATA1, *ptr++);
1523 		if (i) {
1524 			ptr2 = (u_int8_t *)ptr;
1525 			CSR_WRITE_1(sc, AN_DATA0, *ptr2);
1526 		}
1527 
1528 		if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type))
1529 			return(EIO);
1530 	} else {
1531 		/* MPI-350 */
1532 
1533 		for (i = 0; i != AN_TIMEOUT; i++) {
1534 			if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350))
1535 			    & AN_CMD_BUSY) {
1536 				DELAY(10);
1537 			} else
1538 				break;
1539 		}
1540 		if (i == AN_TIMEOUT) {
1541 			printf("BUSY\n");
1542 		}
1543 
1544 		an_rid_desc.an_valid = 1;
1545 		an_rid_desc.an_len = ltv->an_len - 2;
1546 		an_rid_desc.an_rid = ltv->an_type;
1547 		an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr;
1548 
1549 		bcopy(&ltv->an_type, sc->an_rid_buffer.an_dma_vaddr,
1550 		      an_rid_desc.an_len);
1551 
1552 		bzero(&cmd,sizeof(cmd));
1553 		bzero(&reply,sizeof(reply));
1554 		cmd.an_cmd = AN_CMD_ACCESS|AN_ACCESS_WRITE;
1555 		cmd.an_parm0 = ltv->an_type;
1556 
1557 		for (i = 0; i < sizeof(an_rid_desc) / 4; i++)
1558 			CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4,
1559 			    ((u_int32_t *)(void *)&an_rid_desc)[i]);
1560 
1561 		DELAY(100000);
1562 
1563 		if ((i = an_cmd_struct(sc, &cmd, &reply))) {
1564 			if_printf(sc->an_ifp,
1565 			    "failed to write RID 1 %x %x %x %x %x, %d\n",
1566 			    ltv->an_type,
1567 			    reply.an_status,
1568 			    reply.an_resp0,
1569 			    reply.an_resp1,
1570 			    reply.an_resp2,
1571 			    i);
1572 			return(EIO);
1573 		}
1574 
1575 		if (reply.an_status & AN_CMD_QUAL_MASK) {
1576 			if_printf(sc->an_ifp,
1577 			    "failed to write RID 2 %x %x %x %x %x, %d\n",
1578 			    ltv->an_type,
1579 			    reply.an_status,
1580 			    reply.an_resp0,
1581 			    reply.an_resp1,
1582 			    reply.an_resp2,
1583 			    i);
1584 			return(EIO);
1585 		}
1586 		DELAY(100000);
1587 	}
1588 
1589 	return(0);
1590 }
1591 
1592 static void
an_dump_record(struct an_softc * sc,struct an_ltv_gen * ltv,char * string)1593 an_dump_record(struct an_softc *sc, struct an_ltv_gen *ltv, char *string)
1594 {
1595 	u_int8_t		*ptr2;
1596 	int			len;
1597 	int			i;
1598 	int			count = 0;
1599 	char			buf[17], temp;
1600 
1601 	len = ltv->an_len - 4;
1602 	if_printf(sc->an_ifp, "RID %4x, Length %4d, Mode %s\n",
1603 		ltv->an_type, ltv->an_len - 4, string);
1604 
1605 	if (an_dump == 1 || (an_dump == ltv->an_type)) {
1606 		if_printf(sc->an_ifp, "\t");
1607 		bzero(buf,sizeof(buf));
1608 
1609 		ptr2 = (u_int8_t *)&ltv->an_val;
1610 		for (i = len; i > 0; i--) {
1611 			printf("%02x ", *ptr2);
1612 
1613 			temp = *ptr2++;
1614 			if (isprint(temp))
1615 				buf[count] = temp;
1616 			else
1617 				buf[count] = '.';
1618 			if (++count == 16) {
1619 				count = 0;
1620 				printf("%s\n",buf);
1621 				if_printf(sc->an_ifp, "\t");
1622 				bzero(buf,sizeof(buf));
1623 			}
1624 		}
1625 		for (; count != 16; count++) {
1626 			printf("   ");
1627 		}
1628 		printf(" %s\n",buf);
1629 	}
1630 }
1631 
1632 static int
an_seek(struct an_softc * sc,int id,int off,int chan)1633 an_seek(struct an_softc *sc, int id, int off, int chan)
1634 {
1635 	int			i;
1636 	int			selreg, offreg;
1637 
1638 	switch (chan) {
1639 	case AN_BAP0:
1640 		selreg = AN_SEL0;
1641 		offreg = AN_OFF0;
1642 		break;
1643 	case AN_BAP1:
1644 		selreg = AN_SEL1;
1645 		offreg = AN_OFF1;
1646 		break;
1647 	default:
1648 		if_printf(sc->an_ifp, "invalid data path: %x\n", chan);
1649 		return(EIO);
1650 	}
1651 
1652 	CSR_WRITE_2(sc, selreg, id);
1653 	CSR_WRITE_2(sc, offreg, off);
1654 
1655 	for (i = 0; i < AN_TIMEOUT; i++) {
1656 		if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR)))
1657 			break;
1658 	}
1659 
1660 	if (i == AN_TIMEOUT)
1661 		return(ETIMEDOUT);
1662 
1663 	return(0);
1664 }
1665 
1666 static int
an_read_data(struct an_softc * sc,int id,int off,caddr_t buf,int len)1667 an_read_data(struct an_softc *sc, int id, int off, caddr_t buf, int len)
1668 {
1669 	int			i;
1670 	u_int16_t		*ptr;
1671 	u_int8_t		*ptr2;
1672 
1673 	if (off != -1) {
1674 		if (an_seek(sc, id, off, AN_BAP1))
1675 			return(EIO);
1676 	}
1677 
1678 	ptr = (u_int16_t *)buf;
1679 	for (i = len; i > 1; i -= 2)
1680 		*ptr++ = CSR_READ_2(sc, AN_DATA1);
1681 	if (i) {
1682 		ptr2 = (u_int8_t *)ptr;
1683 		*ptr2 = CSR_READ_1(sc, AN_DATA1);
1684 	}
1685 
1686 	return(0);
1687 }
1688 
1689 static int
an_write_data(struct an_softc * sc,int id,int off,caddr_t buf,int len)1690 an_write_data(struct an_softc *sc, int id, int off, caddr_t buf, int len)
1691 {
1692 	int			i;
1693 	u_int16_t		*ptr;
1694 	u_int8_t		*ptr2;
1695 
1696 	if (off != -1) {
1697 		if (an_seek(sc, id, off, AN_BAP0))
1698 			return(EIO);
1699 	}
1700 
1701 	ptr = (u_int16_t *)buf;
1702 	for (i = len; i > 1; i -= 2)
1703 		CSR_WRITE_2(sc, AN_DATA0, *ptr++);
1704 	if (i) {
1705 		ptr2 = (u_int8_t *)ptr;
1706 		CSR_WRITE_1(sc, AN_DATA0, *ptr2);
1707 	}
1708 
1709 	return(0);
1710 }
1711 
1712 /*
1713  * Allocate a region of memory inside the NIC and zero
1714  * it out.
1715  */
1716 static int
an_alloc_nicmem(struct an_softc * sc,int len,int * id)1717 an_alloc_nicmem(struct an_softc *sc, int len, int *id)
1718 {
1719 	int			i;
1720 
1721 	if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) {
1722 		if_printf(sc->an_ifp, "failed to allocate %d bytes on NIC\n",
1723 		    len);
1724 		return(ENOMEM);
1725 	}
1726 
1727 	for (i = 0; i < AN_TIMEOUT; i++) {
1728 		if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_ALLOC)
1729 			break;
1730 	}
1731 
1732 	if (i == AN_TIMEOUT)
1733 		return(ETIMEDOUT);
1734 
1735 	CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
1736 	*id = CSR_READ_2(sc, AN_ALLOC_FID);
1737 
1738 	if (an_seek(sc, *id, 0, AN_BAP0))
1739 		return(EIO);
1740 
1741 	for (i = 0; i < len / 2; i++)
1742 		CSR_WRITE_2(sc, AN_DATA0, 0);
1743 
1744 	return(0);
1745 }
1746 
1747 static void
an_setdef(struct an_softc * sc,struct an_req * areq)1748 an_setdef(struct an_softc *sc, struct an_req *areq)
1749 {
1750 	struct ifnet		*ifp;
1751 	struct an_ltv_genconfig	*cfg;
1752 	struct an_ltv_ssidlist_new	*ssid;
1753 	struct an_ltv_aplist	*ap;
1754 	struct an_ltv_gen	*sp;
1755 
1756 	ifp = sc->an_ifp;
1757 
1758 	AN_LOCK_ASSERT(sc);
1759 	switch (areq->an_type) {
1760 	case AN_RID_GENCONFIG:
1761 		cfg = (struct an_ltv_genconfig *)areq;
1762 
1763 		bcopy((char *)&cfg->an_macaddr, IF_LLADDR(sc->an_ifp),
1764 		    ETHER_ADDR_LEN);
1765 
1766 		bcopy((char *)cfg, (char *)&sc->an_config,
1767 			sizeof(struct an_ltv_genconfig));
1768 		break;
1769 	case AN_RID_SSIDLIST:
1770 		ssid = (struct an_ltv_ssidlist_new *)areq;
1771 		bcopy((char *)ssid, (char *)&sc->an_ssidlist,
1772 			sizeof(struct an_ltv_ssidlist_new));
1773 		break;
1774 	case AN_RID_APLIST:
1775 		ap = (struct an_ltv_aplist *)areq;
1776 		bcopy((char *)ap, (char *)&sc->an_aplist,
1777 			sizeof(struct an_ltv_aplist));
1778 		break;
1779 	case AN_RID_TX_SPEED:
1780 		sp = (struct an_ltv_gen *)areq;
1781 		sc->an_tx_rate = sp->an_val;
1782 
1783 		/* Read the current configuration */
1784 		sc->an_config.an_type = AN_RID_GENCONFIG;
1785 		sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
1786 		an_read_record(sc, (struct an_ltv_gen *)&sc->an_config);
1787 		cfg = &sc->an_config;
1788 
1789 		/* clear other rates and set the only one we want */
1790 		bzero(cfg->an_rates, sizeof(cfg->an_rates));
1791 		cfg->an_rates[0] = sc->an_tx_rate;
1792 
1793 		/* Save the new rate */
1794 		sc->an_config.an_type = AN_RID_GENCONFIG;
1795 		sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
1796 		break;
1797 	case AN_RID_WEP_TEMP:
1798 		/* Cache the temp keys */
1799 		bcopy(areq,
1800 		    &sc->an_temp_keys[((struct an_ltv_key *)areq)->kindex],
1801 		    sizeof(struct an_ltv_key));
1802 	case AN_RID_WEP_PERM:
1803 	case AN_RID_LEAPUSERNAME:
1804 	case AN_RID_LEAPPASSWORD:
1805 		an_init_locked(sc);
1806 
1807 		/* Disable the MAC. */
1808 		an_cmd(sc, AN_CMD_DISABLE, 0);
1809 
1810 		/* Write the key */
1811 		an_write_record(sc, (struct an_ltv_gen *)areq);
1812 
1813 		/* Turn the MAC back on. */
1814 		an_cmd(sc, AN_CMD_ENABLE, 0);
1815 
1816 		break;
1817 	case AN_RID_MONITOR_MODE:
1818 		cfg = (struct an_ltv_genconfig *)areq;
1819 		bpfdetach(ifp);
1820 		if (ng_ether_detach_p != NULL)
1821 			(*ng_ether_detach_p) (ifp);
1822 		sc->an_monitor = cfg->an_len;
1823 
1824 		if (sc->an_monitor & AN_MONITOR) {
1825 			if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) {
1826 				bpfattach(ifp, DLT_AIRONET_HEADER,
1827 					sizeof(struct ether_header));
1828 			} else {
1829 				bpfattach(ifp, DLT_IEEE802_11,
1830 					sizeof(struct ether_header));
1831 			}
1832 		} else {
1833 			bpfattach(ifp, DLT_EN10MB,
1834 				  sizeof(struct ether_header));
1835 			if (ng_ether_attach_p != NULL)
1836 				(*ng_ether_attach_p) (ifp);
1837 		}
1838 		break;
1839 	default:
1840 		if_printf(ifp, "unknown RID: %x\n", areq->an_type);
1841 		return;
1842 	}
1843 
1844 	/* Reinitialize the card. */
1845 	if (ifp->if_flags)
1846 		an_init_locked(sc);
1847 
1848 	return;
1849 }
1850 
1851 /*
1852  * Derived from Linux driver to enable promiscious mode.
1853  */
1854 
1855 static void
an_promisc(struct an_softc * sc,int promisc)1856 an_promisc(struct an_softc *sc, int promisc)
1857 {
1858 	AN_LOCK_ASSERT(sc);
1859 	if (sc->an_was_monitor) {
1860 		an_reset(sc);
1861 		if (sc->mpi350)
1862 			an_init_mpi350_desc(sc);
1863 	}
1864 	if (sc->an_monitor || sc->an_was_monitor)
1865 		an_init_locked(sc);
1866 
1867 	sc->an_was_monitor = sc->an_monitor;
1868 	an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0);
1869 
1870 	return;
1871 }
1872 
1873 static int
an_ioctl(struct ifnet * ifp,u_long command,caddr_t data)1874 an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1875 {
1876 	int			error = 0;
1877 	int			len;
1878 	int			i, max;
1879 	struct an_softc		*sc;
1880 	struct an_req		*areq;
1881 	struct ifreq		*ifr;
1882 	struct thread		*td = curthread;
1883 	struct ieee80211req	*ireq;
1884 	struct ieee80211_channel	ch;
1885 	u_int8_t		tmpstr[IEEE80211_NWID_LEN*2];
1886 	u_int8_t		*tmpptr;
1887 	struct an_ltv_genconfig	*config;
1888 	struct an_ltv_key	*key;
1889 	struct an_ltv_status	*status;
1890 	struct an_ltv_ssidlist_new	*ssids;
1891 	int			mode;
1892 	struct aironet_ioctl	l_ioctl;
1893 
1894 	sc = ifp->if_softc;
1895 	ifr = (struct ifreq *)data;
1896 	ireq = (struct ieee80211req *)data;
1897 
1898 	config = (struct an_ltv_genconfig *)&sc->areq;
1899 	key = (struct an_ltv_key *)&sc->areq;
1900 	status = (struct an_ltv_status *)&sc->areq;
1901 	ssids = (struct an_ltv_ssidlist_new *)&sc->areq;
1902 
1903 	if (sc->an_gone) {
1904 		error = ENODEV;
1905 		goto out;
1906 	}
1907 
1908 	switch (command) {
1909 	case SIOCSIFFLAGS:
1910 		AN_LOCK(sc);
1911 		if (ifp->if_flags & IFF_UP) {
1912 			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
1913 			    ifp->if_flags & IFF_PROMISC &&
1914 			    !(sc->an_if_flags & IFF_PROMISC)) {
1915 				an_promisc(sc, 1);
1916 			} else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
1917 			    !(ifp->if_flags & IFF_PROMISC) &&
1918 			    sc->an_if_flags & IFF_PROMISC) {
1919 				an_promisc(sc, 0);
1920 			} else
1921 				an_init_locked(sc);
1922 		} else {
1923 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1924 				an_stop(sc);
1925 		}
1926 		sc->an_if_flags = ifp->if_flags;
1927 		AN_UNLOCK(sc);
1928 		error = 0;
1929 		break;
1930 	case SIOCSIFMEDIA:
1931 	case SIOCGIFMEDIA:
1932 		error = ifmedia_ioctl(ifp, ifr, &sc->an_ifmedia, command);
1933 		break;
1934 	case SIOCADDMULTI:
1935 	case SIOCDELMULTI:
1936 		/* The Aironet has no multicast filter. */
1937 		error = 0;
1938 		break;
1939 	case SIOCGAIRONET:
1940 		error = priv_check(td, PRIV_DRIVER);
1941 		if (error)
1942 			break;
1943 		areq = malloc(sizeof(*areq), M_TEMP, M_WAITOK);
1944 		error = copyin(ifr_data_get_ptr(ifr), areq, sizeof(*areq));
1945 		if (error != 0) {
1946 			free(areq, M_TEMP);
1947 			break;
1948 		}
1949 		AN_LOCK(sc);
1950 		memcpy(&sc->areq, areq, sizeof(sc->areq));
1951 #ifdef ANCACHE
1952 		if (sc->areq.an_type == AN_RID_ZERO_CACHE) {
1953 			sc->an_sigitems = sc->an_nextitem = 0;
1954 			free(areq, M_TEMP);
1955 			break;
1956 		} else if (sc->areq.an_type == AN_RID_READ_CACHE) {
1957 			char *pt = (char *)&sc->areq.an_val;
1958 			bcopy((char *)&sc->an_sigitems, (char *)pt,
1959 			    sizeof(int));
1960 			pt += sizeof(int);
1961 			sc->areq.an_len = sizeof(int) / 2;
1962 			bcopy((char *)&sc->an_sigcache, (char *)pt,
1963 			    sizeof(struct an_sigcache) * sc->an_sigitems);
1964 			sc->areq.an_len += ((sizeof(struct an_sigcache) *
1965 			    sc->an_sigitems) / 2) + 1;
1966 		} else
1967 #endif
1968 		if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) {
1969 			AN_UNLOCK(sc);
1970 			free(areq, M_TEMP);
1971 			error = EINVAL;
1972 			break;
1973 		}
1974 		memcpy(areq, &sc->areq, sizeof(*areq));
1975 		AN_UNLOCK(sc);
1976 		error = copyout(areq, ifr_data_get_ptr(ifr), sizeof(*areq));
1977 		free(areq, M_TEMP);
1978 		break;
1979 	case SIOCSAIRONET:
1980 		if ((error = priv_check(td, PRIV_DRIVER)))
1981 			goto out;
1982 		AN_LOCK(sc);
1983 		error = copyin(ifr_data_get_ptr(ifr), &sc->areq,
1984 		    sizeof(sc->areq));
1985 		if (error != 0)
1986 			break;
1987 		an_setdef(sc, &sc->areq);
1988 		AN_UNLOCK(sc);
1989 		break;
1990 	case SIOCGPRIVATE_0:		/* used by Cisco client utility */
1991 		if ((error = priv_check(td, PRIV_DRIVER)))
1992 			goto out;
1993 		error = copyin(ifr_data_get_ptr(ifr), &l_ioctl,
1994 		    sizeof(l_ioctl));
1995 		if (error)
1996 			goto out;
1997 		mode = l_ioctl.command;
1998 
1999 		AN_LOCK(sc);
2000 		if (mode >= AIROGCAP && mode <= AIROGSTATSD32) {
2001 			error = readrids(ifp, &l_ioctl);
2002 		} else if (mode >= AIROPCAP && mode <= AIROPLEAPUSR) {
2003 			error = writerids(ifp, &l_ioctl);
2004 		} else if (mode >= AIROFLSHRST && mode <= AIRORESTART) {
2005 			error = flashcard(ifp, &l_ioctl);
2006 		} else {
2007 			error =-1;
2008 		}
2009 		AN_UNLOCK(sc);
2010 		if (!error) {
2011 			/* copy out the updated command info */
2012 			error = copyout(&l_ioctl, ifr_data_get_ptr(ifr),
2013 			    sizeof(l_ioctl));
2014 		}
2015 		break;
2016 	case SIOCGPRIVATE_1:		/* used by Cisco client utility */
2017 		if ((error = priv_check(td, PRIV_DRIVER)))
2018 			goto out;
2019 		error = copyin(ifr_data_get_ptr(ifr), &l_ioctl,
2020 		    sizeof(l_ioctl));
2021 		if (error)
2022 			goto out;
2023 		l_ioctl.command = 0;
2024 		error = AIROMAGIC;
2025 		(void) copyout(&error, l_ioctl.data, sizeof(error));
2026 		error = 0;
2027 		break;
2028 	case SIOCG80211:
2029 		sc->areq.an_len = sizeof(sc->areq);
2030 		/* was that a good idea DJA we are doing a short-cut */
2031 		switch (ireq->i_type) {
2032 		case IEEE80211_IOC_SSID:
2033 			AN_LOCK(sc);
2034 			if (ireq->i_val == -1) {
2035 				sc->areq.an_type = AN_RID_STATUS;
2036 				if (an_read_record(sc,
2037 				    (struct an_ltv_gen *)&sc->areq)) {
2038 					error = EINVAL;
2039 					AN_UNLOCK(sc);
2040 					break;
2041 				}
2042 				len = status->an_ssidlen;
2043 				tmpptr = status->an_ssid;
2044 			} else if (ireq->i_val >= 0) {
2045 				sc->areq.an_type = AN_RID_SSIDLIST;
2046 				if (an_read_record(sc,
2047 				    (struct an_ltv_gen *)&sc->areq)) {
2048 					error = EINVAL;
2049 					AN_UNLOCK(sc);
2050 					break;
2051 				}
2052 				max = (sc->areq.an_len - 4)
2053 				    / sizeof(struct an_ltv_ssid_entry);
2054 				if ( max > MAX_SSIDS ) {
2055 					printf("To many SSIDs only using "
2056 					    "%d of %d\n",
2057 					    MAX_SSIDS, max);
2058 					max = MAX_SSIDS;
2059 				}
2060 				if (ireq->i_val > max) {
2061 					error = EINVAL;
2062 					AN_UNLOCK(sc);
2063 					break;
2064 				} else {
2065 					len = ssids->an_entry[ireq->i_val].an_len;
2066 					tmpptr = ssids->an_entry[ireq->i_val].an_ssid;
2067 				}
2068 			} else {
2069 				error = EINVAL;
2070 				AN_UNLOCK(sc);
2071 				break;
2072 			}
2073 			if (len > IEEE80211_NWID_LEN) {
2074 				error = EINVAL;
2075 				AN_UNLOCK(sc);
2076 				break;
2077 			}
2078 			AN_UNLOCK(sc);
2079 			ireq->i_len = len;
2080 			bzero(tmpstr, IEEE80211_NWID_LEN);
2081 			bcopy(tmpptr, tmpstr, len);
2082 			error = copyout(tmpstr, ireq->i_data,
2083 			    IEEE80211_NWID_LEN);
2084 			break;
2085 		case IEEE80211_IOC_NUMSSIDS:
2086 			AN_LOCK(sc);
2087 			sc->areq.an_len = sizeof(sc->areq);
2088 			sc->areq.an_type = AN_RID_SSIDLIST;
2089 			if (an_read_record(sc,
2090 			    (struct an_ltv_gen *)&sc->areq)) {
2091 				AN_UNLOCK(sc);
2092 				error = EINVAL;
2093 				break;
2094 			}
2095 			max = (sc->areq.an_len - 4)
2096 			    / sizeof(struct an_ltv_ssid_entry);
2097 			AN_UNLOCK(sc);
2098 			if ( max > MAX_SSIDS ) {
2099 				printf("To many SSIDs only using "
2100 				    "%d of %d\n",
2101 				    MAX_SSIDS, max);
2102 				max = MAX_SSIDS;
2103 			}
2104 			ireq->i_val = max;
2105 			break;
2106 		case IEEE80211_IOC_WEP:
2107 			AN_LOCK(sc);
2108 			sc->areq.an_type = AN_RID_ACTUALCFG;
2109 			if (an_read_record(sc,
2110 			    (struct an_ltv_gen *)&sc->areq)) {
2111 				error = EINVAL;
2112 				AN_UNLOCK(sc);
2113 				break;
2114 			}
2115 			AN_UNLOCK(sc);
2116 			if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) {
2117 				if (config->an_authtype &
2118 				    AN_AUTHTYPE_ALLOW_UNENCRYPTED)
2119 					ireq->i_val = IEEE80211_WEP_MIXED;
2120 				else
2121 					ireq->i_val = IEEE80211_WEP_ON;
2122 			} else {
2123 				ireq->i_val = IEEE80211_WEP_OFF;
2124 			}
2125 			break;
2126 		case IEEE80211_IOC_WEPKEY:
2127 			/*
2128 			 * XXX: I'm not entierly convinced this is
2129 			 * correct, but it's what is implemented in
2130 			 * ancontrol so it will have to do until we get
2131 			 * access to actual Cisco code.
2132 			 */
2133 			if (ireq->i_val < 0 || ireq->i_val > 8) {
2134 				error = EINVAL;
2135 				break;
2136 			}
2137 			len = 0;
2138 			if (ireq->i_val < 5) {
2139 				AN_LOCK(sc);
2140 				sc->areq.an_type = AN_RID_WEP_TEMP;
2141 				for (i = 0; i < 5; i++) {
2142 					if (an_read_record(sc,
2143 					    (struct an_ltv_gen *)&sc->areq)) {
2144 						error = EINVAL;
2145 						break;
2146 					}
2147 					if (key->kindex == 0xffff)
2148 						break;
2149 					if (key->kindex == ireq->i_val)
2150 						len = key->klen;
2151 					/* Required to get next entry */
2152 					sc->areq.an_type = AN_RID_WEP_PERM;
2153 				}
2154 				AN_UNLOCK(sc);
2155 				if (error != 0) {
2156 					break;
2157 				}
2158 			}
2159 			/* We aren't allowed to read the value of the
2160 			 * key from the card so we just output zeros
2161 			 * like we would if we could read the card, but
2162 			 * denied the user access.
2163 			 */
2164 			bzero(tmpstr, len);
2165 			ireq->i_len = len;
2166 			error = copyout(tmpstr, ireq->i_data, len);
2167 			break;
2168 		case IEEE80211_IOC_NUMWEPKEYS:
2169 			ireq->i_val = 9; /* include home key */
2170 			break;
2171 		case IEEE80211_IOC_WEPTXKEY:
2172 			/*
2173 			 * For some strange reason, you have to read all
2174 			 * keys before you can read the txkey.
2175 			 */
2176 			AN_LOCK(sc);
2177 			sc->areq.an_type = AN_RID_WEP_TEMP;
2178 			for (i = 0; i < 5; i++) {
2179 				if (an_read_record(sc,
2180 				    (struct an_ltv_gen *) &sc->areq)) {
2181 					error = EINVAL;
2182 					break;
2183 				}
2184 				if (key->kindex == 0xffff) {
2185 					break;
2186 				}
2187 				/* Required to get next entry */
2188 				sc->areq.an_type = AN_RID_WEP_PERM;
2189 			}
2190 			if (error != 0) {
2191 				AN_UNLOCK(sc);
2192 				break;
2193 			}
2194 
2195 			sc->areq.an_type = AN_RID_WEP_PERM;
2196 			key->kindex = 0xffff;
2197 			if (an_read_record(sc,
2198 			    (struct an_ltv_gen *)&sc->areq)) {
2199 				error = EINVAL;
2200 				AN_UNLOCK(sc);
2201 				break;
2202 			}
2203 			ireq->i_val = key->mac[0];
2204 			/*
2205 			 * Check for home mode.  Map home mode into
2206 			 * 5th key since that is how it is stored on
2207 			 * the card
2208 			 */
2209 			sc->areq.an_len  = sizeof(struct an_ltv_genconfig);
2210 			sc->areq.an_type = AN_RID_GENCONFIG;
2211 			if (an_read_record(sc,
2212 			    (struct an_ltv_gen *)&sc->areq)) {
2213 				error = EINVAL;
2214 				AN_UNLOCK(sc);
2215 				break;
2216 			}
2217 			if (config->an_home_product & AN_HOME_NETWORK)
2218 				ireq->i_val = 4;
2219 			AN_UNLOCK(sc);
2220 			break;
2221 		case IEEE80211_IOC_AUTHMODE:
2222 			AN_LOCK(sc);
2223 			sc->areq.an_type = AN_RID_ACTUALCFG;
2224 			if (an_read_record(sc,
2225 			    (struct an_ltv_gen *)&sc->areq)) {
2226 				error = EINVAL;
2227 				AN_UNLOCK(sc);
2228 				break;
2229 			}
2230 			AN_UNLOCK(sc);
2231 			if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
2232 			    AN_AUTHTYPE_NONE) {
2233 			    ireq->i_val = IEEE80211_AUTH_NONE;
2234 			} else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
2235 			    AN_AUTHTYPE_OPEN) {
2236 			    ireq->i_val = IEEE80211_AUTH_OPEN;
2237 			} else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==
2238 			    AN_AUTHTYPE_SHAREDKEY) {
2239 			    ireq->i_val = IEEE80211_AUTH_SHARED;
2240 			} else
2241 				error = EINVAL;
2242 			break;
2243 		case IEEE80211_IOC_STATIONNAME:
2244 			AN_LOCK(sc);
2245 			sc->areq.an_type = AN_RID_ACTUALCFG;
2246 			if (an_read_record(sc,
2247 			    (struct an_ltv_gen *)&sc->areq)) {
2248 				error = EINVAL;
2249 				AN_UNLOCK(sc);
2250 				break;
2251 			}
2252 			AN_UNLOCK(sc);
2253 			ireq->i_len = sizeof(config->an_nodename);
2254 			tmpptr = config->an_nodename;
2255 			bzero(tmpstr, IEEE80211_NWID_LEN);
2256 			bcopy(tmpptr, tmpstr, ireq->i_len);
2257 			error = copyout(tmpstr, ireq->i_data,
2258 			    IEEE80211_NWID_LEN);
2259 			break;
2260 		case IEEE80211_IOC_CHANNEL:
2261 			AN_LOCK(sc);
2262 			sc->areq.an_type = AN_RID_STATUS;
2263 			if (an_read_record(sc,
2264 			    (struct an_ltv_gen *)&sc->areq)) {
2265 				error = EINVAL;
2266 				AN_UNLOCK(sc);
2267 				break;
2268 			}
2269 			AN_UNLOCK(sc);
2270 			ireq->i_val = status->an_cur_channel;
2271 			break;
2272 		case IEEE80211_IOC_CURCHAN:
2273 			AN_LOCK(sc);
2274 			sc->areq.an_type = AN_RID_STATUS;
2275 			if (an_read_record(sc,
2276 			    (struct an_ltv_gen *)&sc->areq)) {
2277 				error = EINVAL;
2278 				AN_UNLOCK(sc);
2279 				break;
2280 			}
2281 			AN_UNLOCK(sc);
2282 			bzero(&ch, sizeof(ch));
2283 			ch.ic_freq = ieee80211_ieee2mhz(status->an_cur_channel,
2284 			    IEEE80211_CHAN_B);
2285 			ch.ic_flags = IEEE80211_CHAN_B;
2286 			ch.ic_ieee = status->an_cur_channel;
2287 			error = copyout(&ch, ireq->i_data, sizeof(ch));
2288 			break;
2289 		case IEEE80211_IOC_POWERSAVE:
2290 			AN_LOCK(sc);
2291 			sc->areq.an_type = AN_RID_ACTUALCFG;
2292 			if (an_read_record(sc,
2293 			    (struct an_ltv_gen *)&sc->areq)) {
2294 				error = EINVAL;
2295 				AN_UNLOCK(sc);
2296 				break;
2297 			}
2298 			AN_UNLOCK(sc);
2299 			if (config->an_psave_mode == AN_PSAVE_NONE) {
2300 				ireq->i_val = IEEE80211_POWERSAVE_OFF;
2301 			} else if (config->an_psave_mode == AN_PSAVE_CAM) {
2302 				ireq->i_val = IEEE80211_POWERSAVE_CAM;
2303 			} else if (config->an_psave_mode == AN_PSAVE_PSP) {
2304 				ireq->i_val = IEEE80211_POWERSAVE_PSP;
2305 			} else if (config->an_psave_mode == AN_PSAVE_PSP_CAM) {
2306 				ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM;
2307 			} else
2308 				error = EINVAL;
2309 			break;
2310 		case IEEE80211_IOC_POWERSAVESLEEP:
2311 			AN_LOCK(sc);
2312 			sc->areq.an_type = AN_RID_ACTUALCFG;
2313 			if (an_read_record(sc,
2314 			    (struct an_ltv_gen *)&sc->areq)) {
2315 				error = EINVAL;
2316 				AN_UNLOCK(sc);
2317 				break;
2318 			}
2319 			AN_UNLOCK(sc);
2320 			ireq->i_val = config->an_listen_interval;
2321 			break;
2322 		}
2323 		break;
2324 	case SIOCS80211:
2325 		if ((error = priv_check(td, PRIV_NET80211_VAP_MANAGE)))
2326 			goto out;
2327 		AN_LOCK(sc);
2328 		sc->areq.an_len = sizeof(sc->areq);
2329 		/*
2330 		 * We need a config structure for everything but the WEP
2331 		 * key management and SSIDs so we get it now so avoid
2332 		 * duplicating this code every time.
2333 		 */
2334 		if (ireq->i_type != IEEE80211_IOC_SSID &&
2335 		    ireq->i_type != IEEE80211_IOC_WEPKEY &&
2336 		    ireq->i_type != IEEE80211_IOC_WEPTXKEY) {
2337 			sc->areq.an_type = AN_RID_GENCONFIG;
2338 			if (an_read_record(sc,
2339 			    (struct an_ltv_gen *)&sc->areq)) {
2340 				error = EINVAL;
2341 				AN_UNLOCK(sc);
2342 				break;
2343 			}
2344 		}
2345 		switch (ireq->i_type) {
2346 		case IEEE80211_IOC_SSID:
2347 			sc->areq.an_len = sizeof(sc->areq);
2348 			sc->areq.an_type = AN_RID_SSIDLIST;
2349 			if (an_read_record(sc,
2350 			    (struct an_ltv_gen *)&sc->areq)) {
2351 				error = EINVAL;
2352 				AN_UNLOCK(sc);
2353 				break;
2354 			}
2355 			if (ireq->i_len > IEEE80211_NWID_LEN) {
2356 				error = EINVAL;
2357 				AN_UNLOCK(sc);
2358 				break;
2359 			}
2360 			max = (sc->areq.an_len - 4)
2361 			    / sizeof(struct an_ltv_ssid_entry);
2362 			if ( max > MAX_SSIDS ) {
2363 				printf("To many SSIDs only using "
2364 				    "%d of %d\n",
2365 				    MAX_SSIDS, max);
2366 				max = MAX_SSIDS;
2367 			}
2368 			if (ireq->i_val > max) {
2369 				error = EINVAL;
2370 				AN_UNLOCK(sc);
2371 				break;
2372 			} else {
2373 				error = copyin(ireq->i_data,
2374 				    ssids->an_entry[ireq->i_val].an_ssid,
2375 				    ireq->i_len);
2376 				ssids->an_entry[ireq->i_val].an_len
2377 				    = ireq->i_len;
2378 				sc->areq.an_len = sizeof(sc->areq);
2379 				sc->areq.an_type = AN_RID_SSIDLIST;
2380 				an_setdef(sc, &sc->areq);
2381 				AN_UNLOCK(sc);
2382 				break;
2383 			}
2384 			break;
2385 		case IEEE80211_IOC_WEP:
2386 			switch (ireq->i_val) {
2387 			case IEEE80211_WEP_OFF:
2388 				config->an_authtype &=
2389 				    ~(AN_AUTHTYPE_PRIVACY_IN_USE |
2390 				    AN_AUTHTYPE_ALLOW_UNENCRYPTED);
2391 				break;
2392 			case IEEE80211_WEP_ON:
2393 				config->an_authtype |=
2394 				    AN_AUTHTYPE_PRIVACY_IN_USE;
2395 				config->an_authtype &=
2396 				    ~AN_AUTHTYPE_ALLOW_UNENCRYPTED;
2397 				break;
2398 			case IEEE80211_WEP_MIXED:
2399 				config->an_authtype |=
2400 				    AN_AUTHTYPE_PRIVACY_IN_USE |
2401 				    AN_AUTHTYPE_ALLOW_UNENCRYPTED;
2402 				break;
2403 			default:
2404 				error = EINVAL;
2405 				break;
2406 			}
2407 			if (error != EINVAL)
2408 				an_setdef(sc, &sc->areq);
2409 			AN_UNLOCK(sc);
2410 			break;
2411 		case IEEE80211_IOC_WEPKEY:
2412 			if (ireq->i_val < 0 || ireq->i_val > 8 ||
2413 			    ireq->i_len > 13) {
2414 				error = EINVAL;
2415 				AN_UNLOCK(sc);
2416 				break;
2417 			}
2418 			error = copyin(ireq->i_data, tmpstr, 13);
2419 			if (error != 0) {
2420 				AN_UNLOCK(sc);
2421 				break;
2422 			}
2423 			/*
2424 			 * Map the 9th key into the home mode
2425 			 * since that is how it is stored on
2426 			 * the card
2427 			 */
2428 			bzero(&sc->areq, sizeof(struct an_ltv_key));
2429 			sc->areq.an_len = sizeof(struct an_ltv_key);
2430 			key->mac[0] = 1;	/* The others are 0. */
2431 			if (ireq->i_val < 4) {
2432 				sc->areq.an_type = AN_RID_WEP_TEMP;
2433 				key->kindex = ireq->i_val;
2434 			} else {
2435 				sc->areq.an_type = AN_RID_WEP_PERM;
2436 				key->kindex = ireq->i_val - 4;
2437 			}
2438 			key->klen = ireq->i_len;
2439 			bcopy(tmpstr, key->key, key->klen);
2440 			an_setdef(sc, &sc->areq);
2441 			AN_UNLOCK(sc);
2442 			break;
2443 		case IEEE80211_IOC_WEPTXKEY:
2444 			if (ireq->i_val < 0 || ireq->i_val > 4) {
2445 				error = EINVAL;
2446 				AN_UNLOCK(sc);
2447 				break;
2448 			}
2449 
2450 			/*
2451 			 * Map the 5th key into the home mode
2452 			 * since that is how it is stored on
2453 			 * the card
2454 			 */
2455 			sc->areq.an_len  = sizeof(struct an_ltv_genconfig);
2456 			sc->areq.an_type = AN_RID_ACTUALCFG;
2457 			if (an_read_record(sc,
2458 			    (struct an_ltv_gen *)&sc->areq)) {
2459 				error = EINVAL;
2460 				AN_UNLOCK(sc);
2461 				break;
2462 			}
2463 			if (ireq->i_val ==  4) {
2464 				config->an_home_product |= AN_HOME_NETWORK;
2465 				ireq->i_val = 0;
2466 			} else {
2467 				config->an_home_product &= ~AN_HOME_NETWORK;
2468 			}
2469 
2470 			sc->an_config.an_home_product
2471 				= config->an_home_product;
2472 
2473 			/* update configuration */
2474 			an_init_locked(sc);
2475 
2476 			bzero(&sc->areq, sizeof(struct an_ltv_key));
2477 			sc->areq.an_len = sizeof(struct an_ltv_key);
2478 			sc->areq.an_type = AN_RID_WEP_PERM;
2479 			key->kindex = 0xffff;
2480 			key->mac[0] = ireq->i_val;
2481 			an_setdef(sc, &sc->areq);
2482 			AN_UNLOCK(sc);
2483 			break;
2484 		case IEEE80211_IOC_AUTHMODE:
2485 			switch (ireq->i_val) {
2486 			case IEEE80211_AUTH_NONE:
2487 				config->an_authtype = AN_AUTHTYPE_NONE |
2488 				    (config->an_authtype & ~AN_AUTHTYPE_MASK);
2489 				break;
2490 			case IEEE80211_AUTH_OPEN:
2491 				config->an_authtype = AN_AUTHTYPE_OPEN |
2492 				    (config->an_authtype & ~AN_AUTHTYPE_MASK);
2493 				break;
2494 			case IEEE80211_AUTH_SHARED:
2495 				config->an_authtype = AN_AUTHTYPE_SHAREDKEY |
2496 				    (config->an_authtype & ~AN_AUTHTYPE_MASK);
2497 				break;
2498 			default:
2499 				error = EINVAL;
2500 			}
2501 			if (error != EINVAL) {
2502 				an_setdef(sc, &sc->areq);
2503 			}
2504 			AN_UNLOCK(sc);
2505 			break;
2506 		case IEEE80211_IOC_STATIONNAME:
2507 			if (ireq->i_len > 16) {
2508 				error = EINVAL;
2509 				AN_UNLOCK(sc);
2510 				break;
2511 			}
2512 			bzero(config->an_nodename, 16);
2513 			error = copyin(ireq->i_data,
2514 			    config->an_nodename, ireq->i_len);
2515 			an_setdef(sc, &sc->areq);
2516 			AN_UNLOCK(sc);
2517 			break;
2518 		case IEEE80211_IOC_CHANNEL:
2519 			/*
2520 			 * The actual range is 1-14, but if you set it
2521 			 * to 0 you get the default so we let that work
2522 			 * too.
2523 			 */
2524 			if (ireq->i_val < 0 || ireq->i_val >14) {
2525 				error = EINVAL;
2526 				AN_UNLOCK(sc);
2527 				break;
2528 			}
2529 			config->an_ds_channel = ireq->i_val;
2530 			an_setdef(sc, &sc->areq);
2531 			AN_UNLOCK(sc);
2532 			break;
2533 		case IEEE80211_IOC_POWERSAVE:
2534 			switch (ireq->i_val) {
2535 			case IEEE80211_POWERSAVE_OFF:
2536 				config->an_psave_mode = AN_PSAVE_NONE;
2537 				break;
2538 			case IEEE80211_POWERSAVE_CAM:
2539 				config->an_psave_mode = AN_PSAVE_CAM;
2540 				break;
2541 			case IEEE80211_POWERSAVE_PSP:
2542 				config->an_psave_mode = AN_PSAVE_PSP;
2543 				break;
2544 			case IEEE80211_POWERSAVE_PSP_CAM:
2545 				config->an_psave_mode = AN_PSAVE_PSP_CAM;
2546 				break;
2547 			default:
2548 				error = EINVAL;
2549 				break;
2550 			}
2551 			an_setdef(sc, &sc->areq);
2552 			AN_UNLOCK(sc);
2553 			break;
2554 		case IEEE80211_IOC_POWERSAVESLEEP:
2555 			config->an_listen_interval = ireq->i_val;
2556 			an_setdef(sc, &sc->areq);
2557 			AN_UNLOCK(sc);
2558 			break;
2559 		default:
2560 			AN_UNLOCK(sc);
2561 			break;
2562 		}
2563 
2564 		/*
2565 		if (!error) {
2566 			AN_LOCK(sc);
2567 			an_setdef(sc, &sc->areq);
2568 			AN_UNLOCK(sc);
2569 		}
2570 		*/
2571 		break;
2572 	default:
2573 		error = ether_ioctl(ifp, command, data);
2574 		break;
2575 	}
2576 out:
2577 
2578 	return(error != 0);
2579 }
2580 
2581 static int
an_init_tx_ring(struct an_softc * sc)2582 an_init_tx_ring(struct an_softc *sc)
2583 {
2584 	int			i;
2585 	int			id;
2586 
2587 	if (sc->an_gone)
2588 		return (0);
2589 
2590 	if (!sc->mpi350) {
2591 		for (i = 0; i < AN_TX_RING_CNT; i++) {
2592 			if (an_alloc_nicmem(sc, 1518 +
2593 			    0x44, &id))
2594 				return(ENOMEM);
2595 			sc->an_rdata.an_tx_fids[i] = id;
2596 			sc->an_rdata.an_tx_ring[i] = 0;
2597 		}
2598 	}
2599 
2600 	sc->an_rdata.an_tx_prod = 0;
2601 	sc->an_rdata.an_tx_cons = 0;
2602 	sc->an_rdata.an_tx_empty = 1;
2603 
2604 	return(0);
2605 }
2606 
2607 static void
an_init(void * xsc)2608 an_init(void *xsc)
2609 {
2610 	struct an_softc		*sc = xsc;
2611 
2612 	AN_LOCK(sc);
2613 	an_init_locked(sc);
2614 	AN_UNLOCK(sc);
2615 }
2616 
2617 static void
an_init_locked(struct an_softc * sc)2618 an_init_locked(struct an_softc *sc)
2619 {
2620 	struct ifnet *ifp;
2621 
2622 	AN_LOCK_ASSERT(sc);
2623 	ifp = sc->an_ifp;
2624 	if (sc->an_gone)
2625 		return;
2626 
2627 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2628 		an_stop(sc);
2629 
2630 	sc->an_associated = 0;
2631 
2632 	/* Allocate the TX buffers */
2633 	if (an_init_tx_ring(sc)) {
2634 		an_reset(sc);
2635 		if (sc->mpi350)
2636 			an_init_mpi350_desc(sc);
2637 		if (an_init_tx_ring(sc)) {
2638 			if_printf(ifp, "tx buffer allocation failed\n");
2639 			return;
2640 		}
2641 	}
2642 
2643 	/* Set our MAC address. */
2644 	bcopy((char *)IF_LLADDR(sc->an_ifp),
2645 	    (char *)&sc->an_config.an_macaddr, ETHER_ADDR_LEN);
2646 
2647 	if (ifp->if_flags & IFF_BROADCAST)
2648 		sc->an_config.an_rxmode = AN_RXMODE_BC_ADDR;
2649 	else
2650 		sc->an_config.an_rxmode = AN_RXMODE_ADDR;
2651 
2652 	if (ifp->if_flags & IFF_MULTICAST)
2653 		sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR;
2654 
2655 	if (ifp->if_flags & IFF_PROMISC) {
2656 		if (sc->an_monitor & AN_MONITOR) {
2657 			if (sc->an_monitor & AN_MONITOR_ANY_BSS) {
2658 				sc->an_config.an_rxmode |=
2659 				    AN_RXMODE_80211_MONITOR_ANYBSS |
2660 				    AN_RXMODE_NO_8023_HEADER;
2661 			} else {
2662 				sc->an_config.an_rxmode |=
2663 				    AN_RXMODE_80211_MONITOR_CURBSS |
2664 				    AN_RXMODE_NO_8023_HEADER;
2665 			}
2666 		}
2667 	}
2668 
2669 #ifdef ANCACHE
2670 	if (sc->an_have_rssimap)
2671 		sc->an_config.an_rxmode |= AN_RXMODE_NORMALIZED_RSSI;
2672 #endif
2673 
2674 	/* Set the ssid list */
2675 	sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
2676 	sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new);
2677 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
2678 		if_printf(ifp, "failed to set ssid list\n");
2679 		return;
2680 	}
2681 
2682 	/* Set the AP list */
2683 	sc->an_aplist.an_type = AN_RID_APLIST;
2684 	sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
2685 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
2686 		if_printf(ifp, "failed to set AP list\n");
2687 		return;
2688 	}
2689 
2690 	/* Set the configuration in the NIC */
2691 	sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
2692 	sc->an_config.an_type = AN_RID_GENCONFIG;
2693 	if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
2694 		if_printf(ifp, "failed to set configuration\n");
2695 		return;
2696 	}
2697 
2698 	/* Enable the MAC */
2699 	if (an_cmd(sc, AN_CMD_ENABLE, 0)) {
2700 		if_printf(ifp, "failed to enable MAC\n");
2701 		return;
2702 	}
2703 
2704 	if (ifp->if_flags & IFF_PROMISC)
2705 		an_cmd(sc, AN_CMD_SET_MODE, 0xffff);
2706 
2707 	/* enable interrupts */
2708 	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
2709 
2710 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
2711 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2712 
2713 	callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
2714 
2715 	return;
2716 }
2717 
2718 static void
an_start(struct ifnet * ifp)2719 an_start(struct ifnet *ifp)
2720 {
2721 	struct an_softc		*sc;
2722 
2723 	sc = ifp->if_softc;
2724 	AN_LOCK(sc);
2725 	an_start_locked(ifp);
2726 	AN_UNLOCK(sc);
2727 }
2728 
2729 static void
an_start_locked(struct ifnet * ifp)2730 an_start_locked(struct ifnet *ifp)
2731 {
2732 	struct an_softc		*sc;
2733 	struct mbuf		*m0 = NULL;
2734 	struct an_txframe_802_3	tx_frame_802_3;
2735 	struct ether_header	*eh;
2736 	int			id, idx, i;
2737 	unsigned char		txcontrol;
2738 	struct an_card_tx_desc an_tx_desc;
2739 	u_int8_t		*buf;
2740 
2741 	sc = ifp->if_softc;
2742 
2743 	AN_LOCK_ASSERT(sc);
2744 	if (sc->an_gone)
2745 		return;
2746 
2747 	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
2748 		return;
2749 
2750 	if (!sc->an_associated)
2751 		return;
2752 
2753 	/* We can't send in monitor mode so toss any attempts. */
2754 	if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) {
2755 		for (;;) {
2756 			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
2757 			if (m0 == NULL)
2758 				break;
2759 			m_freem(m0);
2760 		}
2761 		return;
2762 	}
2763 
2764 	idx = sc->an_rdata.an_tx_prod;
2765 
2766 	if (!sc->mpi350) {
2767 		bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3));
2768 
2769 		while (sc->an_rdata.an_tx_ring[idx] == 0) {
2770 			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
2771 			if (m0 == NULL)
2772 				break;
2773 
2774 			id = sc->an_rdata.an_tx_fids[idx];
2775 			eh = mtod(m0, struct ether_header *);
2776 
2777 			bcopy((char *)&eh->ether_dhost,
2778 			      (char *)&tx_frame_802_3.an_tx_dst_addr,
2779 			      ETHER_ADDR_LEN);
2780 			bcopy((char *)&eh->ether_shost,
2781 			      (char *)&tx_frame_802_3.an_tx_src_addr,
2782 			      ETHER_ADDR_LEN);
2783 
2784 			/* minus src/dest mac & type */
2785 			tx_frame_802_3.an_tx_802_3_payload_len =
2786 				m0->m_pkthdr.len - 12;
2787 
2788 			m_copydata(m0, sizeof(struct ether_header) - 2 ,
2789 				   tx_frame_802_3.an_tx_802_3_payload_len,
2790 				   (caddr_t)&sc->an_txbuf);
2791 
2792 			txcontrol = AN_TXCTL_8023 | AN_TXCTL_HW(sc->mpi350);
2793 			/* write the txcontrol only */
2794 			an_write_data(sc, id, 0x08, (caddr_t)&txcontrol,
2795 				      sizeof(txcontrol));
2796 
2797 			/* 802_3 header */
2798 			an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3,
2799 				      sizeof(struct an_txframe_802_3));
2800 
2801 			/* in mbuf header type is just before payload */
2802 			an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf,
2803 				      tx_frame_802_3.an_tx_802_3_payload_len);
2804 
2805 			/*
2806 			 * If there's a BPF listner, bounce a copy of
2807 			 * this frame to him.
2808 			 */
2809 			BPF_MTAP(ifp, m0);
2810 
2811 			m_freem(m0);
2812 			m0 = NULL;
2813 
2814 			sc->an_rdata.an_tx_ring[idx] = id;
2815 			if (an_cmd(sc, AN_CMD_TX, id))
2816 				if_printf(ifp, "xmit failed\n");
2817 
2818 			AN_INC(idx, AN_TX_RING_CNT);
2819 
2820 			/*
2821 			 * Set a timeout in case the chip goes out to lunch.
2822 			 */
2823 			sc->an_timer = 5;
2824 		}
2825 	} else { /* MPI-350 */
2826 		/* Disable interrupts. */
2827 		CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
2828 
2829 		while (sc->an_rdata.an_tx_empty ||
2830 		    idx != sc->an_rdata.an_tx_cons) {
2831 			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
2832 			if (m0 == NULL) {
2833 				break;
2834 			}
2835 			buf = sc->an_tx_buffer[idx].an_dma_vaddr;
2836 
2837 			eh = mtod(m0, struct ether_header *);
2838 
2839 			/* DJA optimize this to limit bcopy */
2840 			bcopy((char *)&eh->ether_dhost,
2841 			      (char *)&tx_frame_802_3.an_tx_dst_addr,
2842 			      ETHER_ADDR_LEN);
2843 			bcopy((char *)&eh->ether_shost,
2844 			      (char *)&tx_frame_802_3.an_tx_src_addr,
2845 			      ETHER_ADDR_LEN);
2846 
2847 			/* minus src/dest mac & type */
2848 			tx_frame_802_3.an_tx_802_3_payload_len =
2849 				m0->m_pkthdr.len - 12;
2850 
2851 			m_copydata(m0, sizeof(struct ether_header) - 2 ,
2852 				   tx_frame_802_3.an_tx_802_3_payload_len,
2853 				   (caddr_t)&sc->an_txbuf);
2854 
2855 			txcontrol = AN_TXCTL_8023 | AN_TXCTL_HW(sc->mpi350);
2856 			/* write the txcontrol only */
2857 			bcopy((caddr_t)&txcontrol, &buf[0x08],
2858 			      sizeof(txcontrol));
2859 
2860 			/* 802_3 header */
2861 			bcopy((caddr_t)&tx_frame_802_3, &buf[0x34],
2862 			      sizeof(struct an_txframe_802_3));
2863 
2864 			/* in mbuf header type is just before payload */
2865 			bcopy((caddr_t)&sc->an_txbuf, &buf[0x44],
2866 			      tx_frame_802_3.an_tx_802_3_payload_len);
2867 
2868 			bzero(&an_tx_desc, sizeof(an_tx_desc));
2869 			an_tx_desc.an_offset = 0;
2870 			an_tx_desc.an_eoc = 1;
2871 			an_tx_desc.an_valid = 1;
2872 			an_tx_desc.an_len =  0x44 +
2873 			    tx_frame_802_3.an_tx_802_3_payload_len;
2874 			an_tx_desc.an_phys
2875 			    = sc->an_tx_buffer[idx].an_dma_paddr;
2876 			for (i = sizeof(an_tx_desc) / 4 - 1; i >= 0; i--) {
2877 				CSR_MEM_AUX_WRITE_4(sc, AN_TX_DESC_OFFSET
2878 				    /* zero for now */
2879 				    + (0 * sizeof(an_tx_desc))
2880 				    + (i * 4),
2881 				    ((u_int32_t *)(void *)&an_tx_desc)[i]);
2882 			}
2883 
2884 			/*
2885 			 * If there's a BPF listner, bounce a copy of
2886 			 * this frame to him.
2887 			 */
2888 			BPF_MTAP(ifp, m0);
2889 
2890 			m_freem(m0);
2891 			m0 = NULL;
2892 			AN_INC(idx, AN_MAX_TX_DESC);
2893 			sc->an_rdata.an_tx_empty = 0;
2894 			CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
2895 
2896 			/*
2897 			 * Set a timeout in case the chip goes out to lunch.
2898 			 */
2899 			sc->an_timer = 5;
2900 		}
2901 
2902 		/* Re-enable interrupts. */
2903 		CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
2904 	}
2905 
2906 	if (m0 != NULL)
2907 		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2908 
2909 	sc->an_rdata.an_tx_prod = idx;
2910 
2911 	return;
2912 }
2913 
2914 void
an_stop(struct an_softc * sc)2915 an_stop(struct an_softc *sc)
2916 {
2917 	struct ifnet		*ifp;
2918 	int			i;
2919 
2920 	AN_LOCK_ASSERT(sc);
2921 
2922 	if (sc->an_gone)
2923 		return;
2924 
2925 	ifp = sc->an_ifp;
2926 
2927 	an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0);
2928 	CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
2929 	an_cmd(sc, AN_CMD_DISABLE, 0);
2930 
2931 	for (i = 0; i < AN_TX_RING_CNT; i++)
2932 		an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]);
2933 
2934 	callout_stop(&sc->an_stat_ch);
2935 
2936 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING|IFF_DRV_OACTIVE);
2937 
2938 	if (sc->an_flash_buffer) {
2939 		free(sc->an_flash_buffer, M_DEVBUF);
2940 		sc->an_flash_buffer = NULL;
2941 	}
2942 }
2943 
2944 static void
an_watchdog(struct an_softc * sc)2945 an_watchdog(struct an_softc *sc)
2946 {
2947 	struct ifnet *ifp;
2948 
2949 	AN_LOCK_ASSERT(sc);
2950 
2951 	if (sc->an_gone)
2952 		return;
2953 
2954 	ifp = sc->an_ifp;
2955 	if_printf(ifp, "device timeout\n");
2956 
2957 	an_reset(sc);
2958 	if (sc->mpi350)
2959 		an_init_mpi350_desc(sc);
2960 	an_init_locked(sc);
2961 
2962 	if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
2963 }
2964 
2965 int
an_shutdown(device_t dev)2966 an_shutdown(device_t dev)
2967 {
2968 	struct an_softc		*sc;
2969 
2970 	sc = device_get_softc(dev);
2971 	AN_LOCK(sc);
2972 	an_stop(sc);
2973 	sc->an_gone = 1;
2974 	AN_UNLOCK(sc);
2975 
2976 	return (0);
2977 }
2978 
2979 void
an_resume(device_t dev)2980 an_resume(device_t dev)
2981 {
2982 	struct an_softc		*sc;
2983 	struct ifnet		*ifp;
2984 	int			i;
2985 
2986 	sc = device_get_softc(dev);
2987 	AN_LOCK(sc);
2988 	ifp = sc->an_ifp;
2989 
2990 	sc->an_gone = 0;
2991 	an_reset(sc);
2992 	if (sc->mpi350)
2993 		an_init_mpi350_desc(sc);
2994 	an_init_locked(sc);
2995 
2996 	/* Recovery temporary keys */
2997 	for (i = 0; i < 4; i++) {
2998 		sc->areq.an_type = AN_RID_WEP_TEMP;
2999 		sc->areq.an_len = sizeof(struct an_ltv_key);
3000 		bcopy(&sc->an_temp_keys[i],
3001 		    &sc->areq, sizeof(struct an_ltv_key));
3002 		an_setdef(sc, &sc->areq);
3003 	}
3004 
3005 	if (ifp->if_flags & IFF_UP)
3006 		an_start_locked(ifp);
3007 	AN_UNLOCK(sc);
3008 
3009 	return;
3010 }
3011 
3012 #ifdef ANCACHE
3013 /* Aironet signal strength cache code.
3014  * store signal/noise/quality on per MAC src basis in
3015  * a small fixed cache.  The cache wraps if > MAX slots
3016  * used.  The cache may be zeroed out to start over.
3017  * Two simple filters exist to reduce computation:
3018  * 1. ip only (literally 0x800, ETHERTYPE_IP) which may be used
3019  * to ignore some packets.  It defaults to ip only.
3020  * it could be used to focus on broadcast, non-IP 802.11 beacons.
3021  * 2. multicast/broadcast only.  This may be used to
3022  * ignore unicast packets and only cache signal strength
3023  * for multicast/broadcast packets (beacons); e.g., Mobile-IP
3024  * beacons and not unicast traffic.
3025  *
3026  * The cache stores (MAC src(index), IP src (major clue), signal,
3027  *	quality, noise)
3028  *
3029  * No apologies for storing IP src here.  It's easy and saves much
3030  * trouble elsewhere.  The cache is assumed to be INET dependent,
3031  * although it need not be.
3032  *
3033  * Note: the Aironet only has a single byte of signal strength value
3034  * in the rx frame header, and it's not scaled to anything sensible.
3035  * This is kind of lame, but it's all we've got.
3036  */
3037 
3038 #ifdef documentation
3039 
3040 int an_sigitems;				/* number of cached entries */
3041 struct an_sigcache an_sigcache[MAXANCACHE];	/* array of cache entries */
3042 int an_nextitem;				/* index/# of entries */
3043 
3044 #endif
3045 
3046 /* control variables for cache filtering.  Basic idea is
3047  * to reduce cost (e.g., to only Mobile-IP agent beacons
3048  * which are broadcast or multicast).  Still you might
3049  * want to measure signal strength anth unicast ping packets
3050  * on a pt. to pt. ant. setup.
3051  */
3052 /* set true if you want to limit cache items to broadcast/mcast
3053  * only packets (not unicast).  Useful for mobile-ip beacons which
3054  * are broadcast/multicast at network layer.  Default is all packets
3055  * so ping/unicast anll work say anth pt. to pt. antennae setup.
3056  */
3057 static int an_cache_mcastonly = 0;
3058 SYSCTL_INT(_hw_an, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW,
3059 	&an_cache_mcastonly, 0, "");
3060 
3061 /* set true if you want to limit cache items to IP packets only
3062 */
3063 static int an_cache_iponly = 1;
3064 SYSCTL_INT(_hw_an, OID_AUTO, an_cache_iponly, CTLFLAG_RW,
3065 	&an_cache_iponly, 0, "");
3066 
3067 /*
3068  * an_cache_store, per rx packet store signal
3069  * strength in MAC (src) indexed cache.
3070  */
3071 static void
an_cache_store(struct an_softc * sc,struct ether_header * eh,struct mbuf * m,u_int8_t rx_rssi,u_int8_t rx_quality)3072 an_cache_store(struct an_softc *sc, struct ether_header *eh, struct mbuf *m,
3073     u_int8_t rx_rssi, u_int8_t rx_quality)
3074 {
3075 	struct ip *ip = NULL;
3076 	int i;
3077 	static int cache_slot = 0; 	/* use this cache entry */
3078 	static int wrapindex = 0;	/* next "free" cache entry */
3079 	int type_ipv4 = 0;
3080 
3081 	/* filters:
3082 	 * 1. ip only
3083 	 * 2. configurable filter to throw out unicast packets,
3084 	 * keep multicast only.
3085 	 */
3086 
3087 	if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) {
3088 		type_ipv4 = 1;
3089 	}
3090 
3091 	/* filter for ip packets only
3092 	*/
3093 	if ( an_cache_iponly && !type_ipv4) {
3094 		return;
3095 	}
3096 
3097 	/* filter for broadcast/multicast only
3098 	 */
3099 	if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
3100 		return;
3101 	}
3102 
3103 #ifdef SIGDEBUG
3104 	if_printf(sc->an_ifp, "q value %x (MSB=0x%x, LSB=0x%x) \n",
3105 		rx_rssi & 0xffff, rx_rssi >> 8, rx_rssi & 0xff);
3106 #endif
3107 
3108 	/* find the ip header.  we want to store the ip_src
3109 	 * address.
3110 	 */
3111 	if (type_ipv4) {
3112 		ip = mtod(m, struct ip *);
3113 	}
3114 
3115 	/* do a linear search for a matching MAC address
3116 	 * in the cache table
3117 	 * . MAC address is 6 bytes,
3118 	 * . var w_nextitem holds total number of entries already cached
3119 	 */
3120 	for (i = 0; i < sc->an_nextitem; i++) {
3121 		if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc,  6 )) {
3122 			/* Match!,
3123 			 * so we already have this entry,
3124 			 * update the data
3125 			 */
3126 			break;
3127 		}
3128 	}
3129 
3130 	/* did we find a matching mac address?
3131 	 * if yes, then overwrite a previously existing cache entry
3132 	 */
3133 	if (i < sc->an_nextitem )   {
3134 		cache_slot = i;
3135 	}
3136 	/* else, have a new address entry,so
3137 	 * add this new entry,
3138 	 * if table full, then we need to replace LRU entry
3139 	 */
3140 	else    {
3141 		/* check for space in cache table
3142 		 * note: an_nextitem also holds number of entries
3143 		 * added in the cache table
3144 		 */
3145 		if ( sc->an_nextitem < MAXANCACHE ) {
3146 			cache_slot = sc->an_nextitem;
3147 			sc->an_nextitem++;
3148 			sc->an_sigitems = sc->an_nextitem;
3149 		}
3150 		/* no space found, so simply wrap anth wrap index
3151 		 * and "zap" the next entry
3152 		 */
3153 		else {
3154 			if (wrapindex == MAXANCACHE) {
3155 				wrapindex = 0;
3156 			}
3157 			cache_slot = wrapindex++;
3158 		}
3159 	}
3160 
3161 	/* invariant: cache_slot now points at some slot
3162 	 * in cache.
3163 	 */
3164 	if (cache_slot < 0 || cache_slot >= MAXANCACHE) {
3165 		log(LOG_ERR, "an_cache_store, bad index: %d of "
3166 		    "[0..%d], gross cache error\n",
3167 		    cache_slot, MAXANCACHE);
3168 		return;
3169 	}
3170 
3171 	/*  store items in cache
3172 	 *  .ip source address
3173 	 *  .mac src
3174 	 *  .signal, etc.
3175 	 */
3176 	if (type_ipv4) {
3177 		sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
3178 	}
3179 	bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc,  6);
3180 
3181 	switch (an_cache_mode) {
3182 	case DBM:
3183 		if (sc->an_have_rssimap) {
3184 			sc->an_sigcache[cache_slot].signal =
3185 				- sc->an_rssimap.an_entries[rx_rssi].an_rss_dbm;
3186 			sc->an_sigcache[cache_slot].quality =
3187 				- sc->an_rssimap.an_entries[rx_quality].an_rss_dbm;
3188 		} else {
3189 			sc->an_sigcache[cache_slot].signal = rx_rssi - 100;
3190 			sc->an_sigcache[cache_slot].quality = rx_quality - 100;
3191 		}
3192 		break;
3193 	case PERCENT:
3194 		if (sc->an_have_rssimap) {
3195 			sc->an_sigcache[cache_slot].signal =
3196 				sc->an_rssimap.an_entries[rx_rssi].an_rss_pct;
3197 			sc->an_sigcache[cache_slot].quality =
3198 				sc->an_rssimap.an_entries[rx_quality].an_rss_pct;
3199 		} else {
3200 			if (rx_rssi > 100)
3201 				rx_rssi = 100;
3202 			if (rx_quality > 100)
3203 				rx_quality = 100;
3204 			sc->an_sigcache[cache_slot].signal = rx_rssi;
3205 			sc->an_sigcache[cache_slot].quality = rx_quality;
3206 		}
3207 		break;
3208 	case RAW:
3209 		sc->an_sigcache[cache_slot].signal = rx_rssi;
3210 		sc->an_sigcache[cache_slot].quality = rx_quality;
3211 		break;
3212 	}
3213 
3214 	sc->an_sigcache[cache_slot].noise = 0;
3215 
3216 	return;
3217 }
3218 #endif
3219 
3220 static int
an_media_change(struct ifnet * ifp)3221 an_media_change(struct ifnet *ifp)
3222 {
3223 	struct an_softc *sc = ifp->if_softc;
3224 	struct an_ltv_genconfig	*cfg;
3225 	int otype = sc->an_config.an_opmode;
3226 	int orate = sc->an_tx_rate;
3227 
3228 	AN_LOCK(sc);
3229 	sc->an_tx_rate = ieee80211_media2rate(
3230 		IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media));
3231 	if (sc->an_tx_rate < 0)
3232 		sc->an_tx_rate = 0;
3233 
3234 	if (orate != sc->an_tx_rate) {
3235 		/* Read the current configuration */
3236 		sc->an_config.an_type = AN_RID_GENCONFIG;
3237 		sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
3238 		an_read_record(sc, (struct an_ltv_gen *)&sc->an_config);
3239 		cfg = &sc->an_config;
3240 
3241 		/* clear other rates and set the only one we want */
3242 		bzero(cfg->an_rates, sizeof(cfg->an_rates));
3243 		cfg->an_rates[0] = sc->an_tx_rate;
3244 
3245 		/* Save the new rate */
3246 		sc->an_config.an_type = AN_RID_GENCONFIG;
3247 		sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
3248 	}
3249 
3250 	if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
3251 		sc->an_config.an_opmode &= ~AN_OPMODE_INFRASTRUCTURE_STATION;
3252 	else
3253 		sc->an_config.an_opmode |= AN_OPMODE_INFRASTRUCTURE_STATION;
3254 
3255 	if (otype != sc->an_config.an_opmode ||
3256 	    orate != sc->an_tx_rate)
3257 		an_init_locked(sc);
3258 	AN_UNLOCK(sc);
3259 
3260 	return(0);
3261 }
3262 
3263 static void
an_media_status(struct ifnet * ifp,struct ifmediareq * imr)3264 an_media_status(struct ifnet *ifp, struct ifmediareq *imr)
3265 {
3266 	struct an_ltv_status	status;
3267 	struct an_softc		*sc = ifp->if_softc;
3268 
3269 	imr->ifm_active = IFM_IEEE80211;
3270 
3271 	AN_LOCK(sc);
3272 	status.an_len = sizeof(status);
3273 	status.an_type = AN_RID_STATUS;
3274 	if (an_read_record(sc, (struct an_ltv_gen *)&status)) {
3275 		/* If the status read fails, just lie. */
3276 		imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media;
3277 		imr->ifm_status = IFM_AVALID|IFM_ACTIVE;
3278 	}
3279 
3280 	if (sc->an_tx_rate == 0) {
3281 		imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
3282 	}
3283 
3284 	if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC)
3285 		imr->ifm_active |= IFM_IEEE80211_ADHOC;
3286 	imr->ifm_active |= ieee80211_rate2media(NULL,
3287 		status.an_current_tx_rate, IEEE80211_MODE_AUTO);
3288 	imr->ifm_status = IFM_AVALID;
3289 	if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED)
3290 		imr->ifm_status |= IFM_ACTIVE;
3291 	AN_UNLOCK(sc);
3292 }
3293 
3294 /********************** Cisco utility support routines *************/
3295 
3296 /*
3297  * ReadRids & WriteRids derived from Cisco driver additions to Ben Reed's
3298  * Linux driver
3299  */
3300 
3301 static int
readrids(struct ifnet * ifp,struct aironet_ioctl * l_ioctl)3302 readrids(struct ifnet *ifp, struct aironet_ioctl *l_ioctl)
3303 {
3304 	unsigned short  rid;
3305 	struct an_softc *sc;
3306 	int error;
3307 
3308 	switch (l_ioctl->command) {
3309 	case AIROGCAP:
3310 		rid = AN_RID_CAPABILITIES;
3311 		break;
3312 	case AIROGCFG:
3313 		rid = AN_RID_GENCONFIG;
3314 		break;
3315 	case AIROGSLIST:
3316 		rid = AN_RID_SSIDLIST;
3317 		break;
3318 	case AIROGVLIST:
3319 		rid = AN_RID_APLIST;
3320 		break;
3321 	case AIROGDRVNAM:
3322 		rid = AN_RID_DRVNAME;
3323 		break;
3324 	case AIROGEHTENC:
3325 		rid = AN_RID_ENCAPPROTO;
3326 		break;
3327 	case AIROGWEPKTMP:
3328 		rid = AN_RID_WEP_TEMP;
3329 		break;
3330 	case AIROGWEPKNV:
3331 		rid = AN_RID_WEP_PERM;
3332 		break;
3333 	case AIROGSTAT:
3334 		rid = AN_RID_STATUS;
3335 		break;
3336 	case AIROGSTATSD32:
3337 		rid = AN_RID_32BITS_DELTA;
3338 		break;
3339 	case AIROGSTATSC32:
3340 		rid = AN_RID_32BITS_CUM;
3341 		break;
3342 	default:
3343 		rid = 999;
3344 		break;
3345 	}
3346 
3347 	if (rid == 999)	/* Is bad command */
3348 		return -EINVAL;
3349 
3350 	sc = ifp->if_softc;
3351 	sc->areq.an_len  = AN_MAX_DATALEN;
3352 	sc->areq.an_type = rid;
3353 
3354 	an_read_record(sc, (struct an_ltv_gen *)&sc->areq);
3355 
3356 	l_ioctl->len = sc->areq.an_len - 4;	/* just data */
3357 
3358 	AN_UNLOCK(sc);
3359 	/* the data contains the length at first */
3360 	if (copyout(&(sc->areq.an_len), l_ioctl->data,
3361 		    sizeof(sc->areq.an_len))) {
3362 		error = -EFAULT;
3363 		goto lock_exit;
3364 	}
3365 	/* Just copy the data back */
3366 	if (copyout(&(sc->areq.an_val), l_ioctl->data + 2,
3367 		    l_ioctl->len)) {
3368 		error = -EFAULT;
3369 		goto lock_exit;
3370 	}
3371 	error = 0;
3372 lock_exit:
3373 	AN_LOCK(sc);
3374 	return (error);
3375 }
3376 
3377 static int
writerids(struct ifnet * ifp,struct aironet_ioctl * l_ioctl)3378 writerids(struct ifnet *ifp, struct aironet_ioctl *l_ioctl)
3379 {
3380 	struct an_softc *sc;
3381 	int		rid, command, error;
3382 
3383 	sc = ifp->if_softc;
3384 	AN_LOCK_ASSERT(sc);
3385 	rid = 0;
3386 	command = l_ioctl->command;
3387 
3388 	switch (command) {
3389 	case AIROPSIDS:
3390 		rid = AN_RID_SSIDLIST;
3391 		break;
3392 	case AIROPCAP:
3393 		rid = AN_RID_CAPABILITIES;
3394 		break;
3395 	case AIROPAPLIST:
3396 		rid = AN_RID_APLIST;
3397 		break;
3398 	case AIROPCFG:
3399 		rid = AN_RID_GENCONFIG;
3400 		break;
3401 	case AIROPMACON:
3402 		an_cmd(sc, AN_CMD_ENABLE, 0);
3403 		return 0;
3404 		break;
3405 	case AIROPMACOFF:
3406 		an_cmd(sc, AN_CMD_DISABLE, 0);
3407 		return 0;
3408 		break;
3409 	case AIROPSTCLR:
3410 		/*
3411 		 * This command merely clears the counts does not actually
3412 		 * store any data only reads rid. But as it changes the cards
3413 		 * state, I put it in the writerid routines.
3414 		 */
3415 
3416 		rid = AN_RID_32BITS_DELTACLR;
3417 		sc = ifp->if_softc;
3418 		sc->areq.an_len = AN_MAX_DATALEN;
3419 		sc->areq.an_type = rid;
3420 
3421 		an_read_record(sc, (struct an_ltv_gen *)&sc->areq);
3422 		l_ioctl->len = sc->areq.an_len - 4;	/* just data */
3423 
3424 		AN_UNLOCK(sc);
3425 		/* the data contains the length at first */
3426 		error = copyout(&(sc->areq.an_len), l_ioctl->data,
3427 			    sizeof(sc->areq.an_len));
3428 		if (error) {
3429 			AN_LOCK(sc);
3430 			return -EFAULT;
3431 		}
3432 		/* Just copy the data */
3433 		error = copyout(&(sc->areq.an_val), l_ioctl->data + 2,
3434 			    l_ioctl->len);
3435 		AN_LOCK(sc);
3436 		if (error)
3437 			return -EFAULT;
3438 		return 0;
3439 		break;
3440 	case AIROPWEPKEY:
3441 		rid = AN_RID_WEP_TEMP;
3442 		break;
3443 	case AIROPWEPKEYNV:
3444 		rid = AN_RID_WEP_PERM;
3445 		break;
3446 	case AIROPLEAPUSR:
3447 		rid = AN_RID_LEAPUSERNAME;
3448 		break;
3449 	case AIROPLEAPPWD:
3450 		rid = AN_RID_LEAPPASSWORD;
3451 		break;
3452 	default:
3453 		return -EOPNOTSUPP;
3454 	}
3455 
3456 	if (rid) {
3457 		if (l_ioctl->len > sizeof(sc->areq.an_val) + 4)
3458 			return -EINVAL;
3459 		sc->areq.an_len = l_ioctl->len + 4;	/* add type & length */
3460 		sc->areq.an_type = rid;
3461 
3462 		/* Just copy the data back */
3463 		AN_UNLOCK(sc);
3464 		error = copyin((l_ioctl->data) + 2, &sc->areq.an_val,
3465 		       l_ioctl->len);
3466 		AN_LOCK(sc);
3467 		if (error)
3468 			return -EFAULT;
3469 
3470 		an_cmd(sc, AN_CMD_DISABLE, 0);
3471 		an_write_record(sc, (struct an_ltv_gen *)&sc->areq);
3472 		an_cmd(sc, AN_CMD_ENABLE, 0);
3473 		return 0;
3474 	}
3475 	return -EOPNOTSUPP;
3476 }
3477 
3478 /*
3479  * General Flash utilities derived from Cisco driver additions to Ben Reed's
3480  * Linux driver
3481  */
3482 
3483 #define FLASH_DELAY(_sc, x)	msleep(ifp, &(_sc)->an_mtx, PZERO, \
3484 	"flash", ((x) / hz) + 1);
3485 #define FLASH_COMMAND	0x7e7e
3486 #define FLASH_SIZE	32 * 1024
3487 
3488 static int
unstickbusy(struct ifnet * ifp)3489 unstickbusy(struct ifnet *ifp)
3490 {
3491 	struct an_softc *sc = ifp->if_softc;
3492 
3493 	if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) {
3494 		CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350),
3495 			    AN_EV_CLR_STUCK_BUSY);
3496 		return 1;
3497 	}
3498 	return 0;
3499 }
3500 
3501 /*
3502  * Wait for busy completion from card wait for delay uSec's Return true for
3503  * success meaning command reg is clear
3504  */
3505 
3506 static int
WaitBusy(struct ifnet * ifp,int uSec)3507 WaitBusy(struct ifnet *ifp, int uSec)
3508 {
3509 	int		statword = 0xffff;
3510 	int		delay = 0;
3511 	struct an_softc	*sc = ifp->if_softc;
3512 
3513 	while ((statword & AN_CMD_BUSY) && delay <= (1000 * 100)) {
3514 		FLASH_DELAY(sc, 10);
3515 		delay += 10;
3516 		statword = CSR_READ_2(sc, AN_COMMAND(sc->mpi350));
3517 
3518 		if ((AN_CMD_BUSY & statword) && (delay % 200)) {
3519 			unstickbusy(ifp);
3520 		}
3521 	}
3522 
3523 	return 0 == (AN_CMD_BUSY & statword);
3524 }
3525 
3526 /*
3527  * STEP 1) Disable MAC and do soft reset on card.
3528  */
3529 
3530 static int
cmdreset(struct ifnet * ifp)3531 cmdreset(struct ifnet *ifp)
3532 {
3533 	int		status;
3534 	struct an_softc	*sc = ifp->if_softc;
3535 
3536 	AN_LOCK(sc);
3537 	an_stop(sc);
3538 
3539 	an_cmd(sc, AN_CMD_DISABLE, 0);
3540 
3541 	if (!(status = WaitBusy(ifp, AN_TIMEOUT))) {
3542 		if_printf(ifp, "Waitbusy hang b4 RESET =%d\n", status);
3543 		AN_UNLOCK(sc);
3544 		return -EBUSY;
3545 	}
3546 	CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), AN_CMD_FW_RESTART);
3547 
3548 	FLASH_DELAY(sc, 1000);	/* WAS 600 12/7/00 */
3549 
3550 	if (!(status = WaitBusy(ifp, 100))) {
3551 		if_printf(ifp, "Waitbusy hang AFTER RESET =%d\n", status);
3552 		AN_UNLOCK(sc);
3553 		return -EBUSY;
3554 	}
3555 	AN_UNLOCK(sc);
3556 	return 0;
3557 }
3558 
3559 /*
3560  * STEP 2) Put the card in legendary flash mode
3561  */
3562 
3563 static int
setflashmode(struct ifnet * ifp)3564 setflashmode(struct ifnet *ifp)
3565 {
3566 	int		status;
3567 	struct an_softc	*sc = ifp->if_softc;
3568 
3569 	CSR_WRITE_2(sc, AN_SW0(sc->mpi350), FLASH_COMMAND);
3570 	CSR_WRITE_2(sc, AN_SW1(sc->mpi350), FLASH_COMMAND);
3571 	CSR_WRITE_2(sc, AN_SW0(sc->mpi350), FLASH_COMMAND);
3572 	CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), FLASH_COMMAND);
3573 
3574 	/*
3575 	 * mdelay(500); // 500ms delay
3576 	 */
3577 
3578 	FLASH_DELAY(sc, 500);
3579 
3580 	if (!(status = WaitBusy(ifp, AN_TIMEOUT))) {
3581 		printf("Waitbusy hang after setflash mode\n");
3582 		return -EIO;
3583 	}
3584 	return 0;
3585 }
3586 
3587 /*
3588  * Get a character from the card matching matchbyte Step 3)
3589  */
3590 
3591 static int
flashgchar(struct ifnet * ifp,int matchbyte,int dwelltime)3592 flashgchar(struct ifnet *ifp, int matchbyte, int dwelltime)
3593 {
3594 	int		rchar;
3595 	unsigned char	rbyte = 0;
3596 	int		success = -1;
3597 	struct an_softc	*sc = ifp->if_softc;
3598 
3599 	do {
3600 		rchar = CSR_READ_2(sc, AN_SW1(sc->mpi350));
3601 
3602 		if (dwelltime && !(0x8000 & rchar)) {
3603 			dwelltime -= 10;
3604 			FLASH_DELAY(sc, 10);
3605 			continue;
3606 		}
3607 		rbyte = 0xff & rchar;
3608 
3609 		if ((rbyte == matchbyte) && (0x8000 & rchar)) {
3610 			CSR_WRITE_2(sc, AN_SW1(sc->mpi350), 0);
3611 			success = 1;
3612 			break;
3613 		}
3614 		if (rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
3615 			break;
3616 		CSR_WRITE_2(sc, AN_SW1(sc->mpi350), 0);
3617 
3618 	} while (dwelltime > 0);
3619 	return success;
3620 }
3621 
3622 /*
3623  * Put character to SWS0 wait for dwelltime x 50us for  echo .
3624  */
3625 
3626 static int
flashpchar(struct ifnet * ifp,int byte,int dwelltime)3627 flashpchar(struct ifnet *ifp, int byte, int dwelltime)
3628 {
3629 	int		echo;
3630 	int		pollbusy, waittime;
3631 	struct an_softc	*sc = ifp->if_softc;
3632 
3633 	byte |= 0x8000;
3634 
3635 	if (dwelltime == 0)
3636 		dwelltime = 200;
3637 
3638 	waittime = dwelltime;
3639 
3640 	/*
3641 	 * Wait for busy bit d15 to go false indicating buffer empty
3642 	 */
3643 	do {
3644 		pollbusy = CSR_READ_2(sc, AN_SW0(sc->mpi350));
3645 
3646 		if (pollbusy & 0x8000) {
3647 			FLASH_DELAY(sc, 50);
3648 			waittime -= 50;
3649 			continue;
3650 		} else
3651 			break;
3652 	}
3653 	while (waittime >= 0);
3654 
3655 	/* timeout for busy clear wait */
3656 
3657 	if (waittime <= 0) {
3658 		if_printf(ifp, "flash putchar busywait timeout!\n");
3659 		return -1;
3660 	}
3661 	/*
3662 	 * Port is clear now write byte and wait for it to echo back
3663 	 */
3664 	do {
3665 		CSR_WRITE_2(sc, AN_SW0(sc->mpi350), byte);
3666 		FLASH_DELAY(sc, 50);
3667 		dwelltime -= 50;
3668 		echo = CSR_READ_2(sc, AN_SW1(sc->mpi350));
3669 	} while (dwelltime >= 0 && echo != byte);
3670 
3671 	CSR_WRITE_2(sc, AN_SW1(sc->mpi350), 0);
3672 
3673 	return echo == byte;
3674 }
3675 
3676 /*
3677  * Transfer 32k of firmware data from user buffer to our buffer and send to
3678  * the card
3679  */
3680 
3681 static int
flashputbuf(struct ifnet * ifp)3682 flashputbuf(struct ifnet *ifp)
3683 {
3684 	unsigned short *bufp;
3685 	int		nwords;
3686 	struct an_softc	*sc = ifp->if_softc;
3687 
3688 	/* Write stuff */
3689 
3690 	bufp = sc->an_flash_buffer;
3691 
3692 	if (!sc->mpi350) {
3693 		CSR_WRITE_2(sc, AN_AUX_PAGE, 0x100);
3694 		CSR_WRITE_2(sc, AN_AUX_OFFSET, 0);
3695 
3696 		for (nwords = 0; nwords != FLASH_SIZE / 2; nwords++) {
3697 			CSR_WRITE_2(sc, AN_AUX_DATA, bufp[nwords] & 0xffff);
3698 		}
3699 	} else {
3700 		for (nwords = 0; nwords != FLASH_SIZE / 4; nwords++) {
3701 			CSR_MEM_AUX_WRITE_4(sc, 0x8000,
3702 				((u_int32_t *)bufp)[nwords] & 0xffff);
3703 		}
3704 	}
3705 
3706 	CSR_WRITE_2(sc, AN_SW0(sc->mpi350), 0x8000);
3707 
3708 	return 0;
3709 }
3710 
3711 /*
3712  * After flashing restart the card.
3713  */
3714 
3715 static int
flashrestart(struct ifnet * ifp)3716 flashrestart(struct ifnet *ifp)
3717 {
3718 	int		status = 0;
3719 	struct an_softc	*sc = ifp->if_softc;
3720 
3721 	FLASH_DELAY(sc, 1024);		/* Added 12/7/00 */
3722 
3723 	an_init_locked(sc);
3724 
3725 	FLASH_DELAY(sc, 1024);		/* Added 12/7/00 */
3726 	return status;
3727 }
3728 
3729 /*
3730  * Entry point for flash ioclt.
3731  */
3732 
3733 static int
flashcard(struct ifnet * ifp,struct aironet_ioctl * l_ioctl)3734 flashcard(struct ifnet *ifp, struct aironet_ioctl *l_ioctl)
3735 {
3736 	int		z = 0, status;
3737 	struct an_softc	*sc;
3738 
3739 	sc = ifp->if_softc;
3740 	if (sc->mpi350) {
3741 		if_printf(ifp, "flashing not supported on MPI 350 yet\n");
3742 		return(-1);
3743 	}
3744 	status = l_ioctl->command;
3745 
3746 	switch (l_ioctl->command) {
3747 	case AIROFLSHRST:
3748 		return cmdreset(ifp);
3749 		break;
3750 	case AIROFLSHSTFL:
3751 		if (sc->an_flash_buffer) {
3752 			free(sc->an_flash_buffer, M_DEVBUF);
3753 			sc->an_flash_buffer = NULL;
3754 		}
3755 		sc->an_flash_buffer = malloc(FLASH_SIZE, M_DEVBUF, M_WAITOK);
3756 		if (sc->an_flash_buffer)
3757 			return setflashmode(ifp);
3758 		else
3759 			return ENOBUFS;
3760 		break;
3761 	case AIROFLSHGCHR:	/* Get char from aux */
3762 		if (l_ioctl->len > sizeof(sc->areq)) {
3763 			return -EINVAL;
3764 		}
3765 		AN_UNLOCK(sc);
3766 		status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len);
3767 		AN_LOCK(sc);
3768 		if (status)
3769 			return status;
3770 		z = *(int *)&sc->areq;
3771 		if ((status = flashgchar(ifp, z, 8000)) == 1)
3772 			return 0;
3773 		else
3774 			return -1;
3775 	case AIROFLSHPCHR:	/* Send char to card. */
3776 		if (l_ioctl->len > sizeof(sc->areq)) {
3777 			return -EINVAL;
3778 		}
3779 		AN_UNLOCK(sc);
3780 		status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len);
3781 		AN_LOCK(sc);
3782 		if (status)
3783 			return status;
3784 		z = *(int *)&sc->areq;
3785 		if ((status = flashpchar(ifp, z, 8000)) == -1)
3786 			return -EIO;
3787 		else
3788 			return 0;
3789 		break;
3790 	case AIROFLPUTBUF:	/* Send 32k to card */
3791 		if (l_ioctl->len > FLASH_SIZE) {
3792 			if_printf(ifp, "Buffer to big, %x %x\n",
3793 			       l_ioctl->len, FLASH_SIZE);
3794 			return -EINVAL;
3795 		}
3796 		AN_UNLOCK(sc);
3797 		status = copyin(l_ioctl->data, sc->an_flash_buffer, l_ioctl->len);
3798 		AN_LOCK(sc);
3799 		if (status)
3800 			return status;
3801 
3802 		if ((status = flashputbuf(ifp)) != 0)
3803 			return -EIO;
3804 		else
3805 			return 0;
3806 		break;
3807 	case AIRORESTART:
3808 		if ((status = flashrestart(ifp)) != 0) {
3809 			if_printf(ifp, "FLASHRESTART returned %d\n", status);
3810 			return -EIO;
3811 		} else
3812 			return 0;
3813 
3814 		break;
3815 	default:
3816 		return -EINVAL;
3817 	}
3818 
3819 	return -EINVAL;
3820 }
3821