if_wi.c (53356) | if_wi.c (53702) |
---|---|
1/* 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * | 1/* 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * |
32 * $FreeBSD: head/sys/dev/wi/if_wi.c 53356 1999-11-18 08:39:02Z peter $ | 32 * $FreeBSD: head/sys/dev/wi/if_wi.c 53702 1999-11-25 20:45:49Z wpaul $ |
33 */ 34 35/* 36 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD. 37 * 38 * Written by Bill Paul <wpaul@ctr.columbia.edu> 39 * Electrical Engineering Department 40 * Columbia University, New York City --- 20 unchanged lines hidden (view full) --- 61 * anything of the sort: it's actually a PCMCIA bridge adapter 62 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is 63 * inserted. Consequently, you need to use the pccard support for 64 * both the ISA and PCMCIA adapters. 65 */ 66 67#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ 68#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ | 33 */ 34 35/* 36 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD. 37 * 38 * Written by Bill Paul <wpaul@ctr.columbia.edu> 39 * Electrical Engineering Department 40 * Columbia University, New York City --- 20 unchanged lines hidden (view full) --- 61 * anything of the sort: it's actually a PCMCIA bridge adapter 62 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is 63 * inserted. Consequently, you need to use the pccard support for 64 * both the ISA and PCMCIA adapters. 65 */ 66 67#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ 68#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ |
69#define WICACHE /* turn on signal strength cache code */ |
|
69 | 70 |
70#include "card.h" 71#undef NCARD 72#define NCARD 0 73#include "wi.h" 74 | |
75#include <sys/param.h> 76#include <sys/systm.h> | 71#include <sys/param.h> 72#include <sys/systm.h> |
77#include <sys/eventhandler.h> | |
78#include <sys/sockio.h> 79#include <sys/mbuf.h> 80#include <sys/malloc.h> 81#include <sys/kernel.h> 82#include <sys/socket.h> | 73#include <sys/sockio.h> 74#include <sys/mbuf.h> 75#include <sys/malloc.h> 76#include <sys/kernel.h> 77#include <sys/socket.h> |
78#include <sys/module.h> 79#include <sys/bus.h> 80#include <sys/syslog.h> 81#include <sys/sysctl.h> |
|
83 | 82 |
83#include <machine/bus.h> 84#include <machine/resource.h> 85#include <machine/clock.h> 86#include <machine/md_var.h> 87#include <machine/bus_pio.h> 88#include <sys/rman.h> 89 |
|
84#include <net/if.h> 85#include <net/if_arp.h> 86#include <net/ethernet.h> 87#include <net/if_dl.h> 88#include <net/if_media.h> 89#include <net/if_types.h> 90 | 90#include <net/if.h> 91#include <net/if_arp.h> 92#include <net/ethernet.h> 93#include <net/if_dl.h> 94#include <net/if_media.h> 95#include <net/if_types.h> 96 |
91#ifdef INET | |
92#include <netinet/in.h> 93#include <netinet/in_systm.h> 94#include <netinet/in_var.h> 95#include <netinet/ip.h> 96#include <netinet/if_ether.h> | 97#include <netinet/in.h> 98#include <netinet/in_systm.h> 99#include <netinet/in_var.h> 100#include <netinet/ip.h> 101#include <netinet/if_ether.h> |
97#endif | |
98 99#include <net/bpf.h> 100 | 102 103#include <net/bpf.h> 104 |
101#include <machine/clock.h> 102#include <machine/md_var.h> 103#include <machine/bus_pio.h> 104#include <machine/bus.h> 105 106#include <i386/isa/isa_device.h> 107#include <i386/isa/icu.h> 108#include <i386/isa/if_wireg.h> | |
109#include <machine/if_wavelan_ieee.h> | 105#include <machine/if_wavelan_ieee.h> |
106#include <i386/isa/if_wireg.h> |
|
110 | 107 |
111#if NCARD > 0 112#include <sys/select.h> 113#include <pccard/cardinfo.h> 114#include <pccard/slot.h> 115#endif 116 | |
117#if !defined(lint) 118static const char rcsid[] = | 108#if !defined(lint) 109static const char rcsid[] = |
119 "$FreeBSD: head/sys/dev/wi/if_wi.c 53356 1999-11-18 08:39:02Z peter $"; | 110 "$FreeBSD: head/sys/dev/wi/if_wi.c 53702 1999-11-25 20:45:49Z wpaul $"; |
120#endif 121 | 111#endif 112 |
122static struct wi_softc wi_softc[NWI]; 123 | |
124#ifdef foo 125static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 }; 126#endif 127 | 113#ifdef foo 114static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 }; 115#endif 116 |
128static int wi_probe __P((struct isa_device *)); 129static int wi_attach __P((struct isa_device *)); 130ointhand2_t wi_intr; | 117static void wi_intr __P((void *)); |
131static void wi_reset __P((struct wi_softc *)); 132static int wi_ioctl __P((struct ifnet *, u_long, caddr_t)); 133static void wi_init __P((void *)); 134static void wi_start __P((struct ifnet *)); 135static void wi_stop __P((struct wi_softc *)); 136static void wi_watchdog __P((struct ifnet *)); | 118static void wi_reset __P((struct wi_softc *)); 119static int wi_ioctl __P((struct ifnet *, u_long, caddr_t)); 120static void wi_init __P((void *)); 121static void wi_start __P((struct ifnet *)); 122static void wi_stop __P((struct wi_softc *)); 123static void wi_watchdog __P((struct ifnet *)); |
137static void wi_shutdown __P((void *, int)); | |
138static void wi_rxeof __P((struct wi_softc *)); 139static void wi_txeof __P((struct wi_softc *, int)); 140static void wi_update_stats __P((struct wi_softc *)); 141static void wi_setmulti __P((struct wi_softc *)); 142 143static int wi_cmd __P((struct wi_softc *, int, int)); 144static int wi_read_record __P((struct wi_softc *, struct wi_ltv_gen *)); 145static int wi_write_record __P((struct wi_softc *, struct wi_ltv_gen *)); 146static int wi_read_data __P((struct wi_softc *, int, 147 int, caddr_t, int)); 148static int wi_write_data __P((struct wi_softc *, int, 149 int, caddr_t, int)); 150static int wi_seek __P((struct wi_softc *, int, int, int)); 151static int wi_alloc_nicmem __P((struct wi_softc *, int, int *)); 152static void wi_inquire __P((void *)); 153static void wi_setdef __P((struct wi_softc *, struct wi_req *)); 154static int wi_mgmt_xmit __P((struct wi_softc *, caddr_t, int)); 155 | 124static void wi_rxeof __P((struct wi_softc *)); 125static void wi_txeof __P((struct wi_softc *, int)); 126static void wi_update_stats __P((struct wi_softc *)); 127static void wi_setmulti __P((struct wi_softc *)); 128 129static int wi_cmd __P((struct wi_softc *, int, int)); 130static int wi_read_record __P((struct wi_softc *, struct wi_ltv_gen *)); 131static int wi_write_record __P((struct wi_softc *, struct wi_ltv_gen *)); 132static int wi_read_data __P((struct wi_softc *, int, 133 int, caddr_t, int)); 134static int wi_write_data __P((struct wi_softc *, int, 135 int, caddr_t, int)); 136static int wi_seek __P((struct wi_softc *, int, int, int)); 137static int wi_alloc_nicmem __P((struct wi_softc *, int, int *)); 138static void wi_inquire __P((void *)); 139static void wi_setdef __P((struct wi_softc *, struct wi_req *)); 140static int wi_mgmt_xmit __P((struct wi_softc *, caddr_t, int)); 141 |
156struct isa_driver widriver = { 157 wi_probe, 158 wi_attach, 159 "wi", 160 1 161}; | 142#ifdef WICACHE 143static 144void wi_cache_store __P((struct wi_softc *, struct ether_header *, 145 struct mbuf *, unsigned short)); 146#endif |
162 | 147 |
163#if NCARD > 0 164static int wi_pccard_init __P((struct pccard_devinfo *)); 165static void wi_pccard_unload __P((struct pccard_devinfo *)); 166static int wi_pccard_intr __P((struct pccard_devinfo *)); | 148static int wi_pccard_probe __P((device_t)); 149static int wi_pccard_attach __P((device_t)); 150static int wi_pccard_detach __P((device_t)); 151static void wi_shutdown __P((device_t)); |
167 | 152 |
168#ifdef PCCARD_MODULE 169PCCARD_MODULE(wi, wi_pccard_init, wi_pccard_unload, 170 wi_pccard_intr, 0, net_imask); 171#else 172static struct pccard_device wi_info = { | 153static int wi_alloc __P((device_t)); 154static void wi_free __P((device_t)); 155 156static device_method_t wi_pccard_methods[] = { 157 /* Device interface */ 158 DEVMETHOD(device_probe, wi_pccard_probe), 159 DEVMETHOD(device_attach, wi_pccard_attach), 160 DEVMETHOD(device_detach, wi_pccard_detach), 161 DEVMETHOD(device_shutdown, wi_shutdown), 162 163 { 0, 0 } 164}; 165 166static driver_t wi_pccard_driver = { |
173 "wi", | 167 "wi", |
174 wi_pccard_init, 175 wi_pccard_unload, 176 wi_pccard_intr, 177 0, /* Attributes - presently unused */ 178 &net_imask /* Interrupt mask for device */ 179 /* XXX - Should this also include net_imask? */ | 168 wi_pccard_methods, 169 sizeof(struct wi_softc) |
180}; 181 | 170}; 171 |
182DATA_SET(pccarddrv_set, wi_info); 183#endif | 172static devclass_t wi_pccard_devclass; |
184 | 173 |
185/* Initialize the PCCARD. */ 186static int wi_pccard_init(sc_p) 187 struct pccard_devinfo *sc_p; | 174DRIVER_MODULE(if_wi, pccard, wi_pccard_driver, wi_pccard_devclass, 0, 0); 175 176static int wi_pccard_probe(dev) 177 device_t dev; |
188{ | 178{ |
189 struct wi_softc *sc; 190 int i; 191 u_int32_t irq; | 179 struct wi_softc *sc; 180 int error; |
192 | 181 |
193 if (sc_p->isahd.id_unit >= NWI) 194 return(ENODEV); 195 196 sc = &wi_softc[sc_p->isahd.id_unit]; | 182 sc = device_get_softc(dev); |
197 sc->wi_gone = 0; | 183 sc->wi_gone = 0; |
198 sc->wi_unit = sc_p->isahd.id_unit; 199 sc->wi_bhandle = sc_p->isahd.id_iobase; 200 sc->wi_btag = I386_BUS_SPACE_IO; | |
201 | 184 |
185 error = wi_alloc(dev); 186 if (error) 187 return (error); 188 189 device_set_desc(dev, "WaveLAN/IEEE 802.11"); 190 wi_free(dev); 191 |
|
202 /* Make sure interrupts are disabled. */ 203 CSR_WRITE_2(sc, WI_INT_EN, 0); 204 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 205 | 192 /* Make sure interrupts are disabled. */ 193 CSR_WRITE_2(sc, WI_INT_EN, 0); 194 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 195 |
206 /* Grr. IRQ is encoded as a bitmask. */ 207 irq = sc_p->isahd.id_irq; 208 for (i = 0; i < 32; i++) { 209 if (irq & 0x1) 210 break; 211 irq >>= 1; 212 } 213 214 /* 215 * Print a nice probe message to let the operator 216 * know something interesting is happening. 217 */ 218 printf("wi%d: <WaveLAN/IEEE 802.11> at 0x%x-0x%x irq %d on isa\n", 219 sc_p->isahd.id_unit, sc_p->isahd.id_iobase, 220 sc_p->isahd.id_iobase + WI_IOSIZ - 1, i); 221 222 if (wi_attach(&sc_p->isahd)) 223 return(ENXIO); 224 225 return(0); | 196 return (0); |
226} 227 | 197} 198 |
228static void wi_pccard_unload(sc_p) 229 struct pccard_devinfo *sc_p; | 199static int wi_pccard_detach(dev) 200 device_t dev; |
230{ 231 struct wi_softc *sc; 232 struct ifnet *ifp; | 201{ 202 struct wi_softc *sc; 203 struct ifnet *ifp; |
204 int s; |
|
233 | 205 |
234 sc = &wi_softc[sc_p->isahd.id_unit]; | 206 s = splimp(); 207 208 sc = device_get_softc(dev); |
235 ifp = &sc->arpcom.ac_if; 236 237 if (sc->wi_gone) { | 209 ifp = &sc->arpcom.ac_if; 210 211 if (sc->wi_gone) { |
238 printf("wi%d: already unloaded\n", sc_p->isahd.id_unit); 239 return; | 212 device_printf(dev, "already unloaded\n"); 213 return(ENODEV); |
240 } 241 | 214 } 215 |
242 ifp->if_flags &= ~IFF_RUNNING; 243 if_down(ifp); | 216 wi_stop(sc); 217 if_detach(ifp); 218 bus_teardown_intr(dev, sc->irq, &sc->wi_intrhand); 219 wi_free(dev); |
244 sc->wi_gone = 1; | 220 sc->wi_gone = 1; |
245 printf("wi%d: unloaded\n", sc_p->isahd.id_unit); | |
246 | 221 |
247 return; 248} | 222 splx(s); 223 device_printf(dev, "unload\n"); |
249 | 224 |
250static int wi_pccard_intr(sc_p) 251 struct pccard_devinfo *sc_p; 252{ 253 wi_intr(sc_p->isahd.id_unit); 254 return(1); 255} 256#endif 257 258static int wi_probe(isa_dev) 259 struct isa_device *isa_dev; 260{ 261 /* 262 * The ISA WaveLAN/IEEE card is actually not an ISA card: 263 * it's a PCMCIA card plugged into a PCMCIA bridge adapter 264 * that fits into an ISA slot. Consequently, we will always 265 * be using the pccard support to probe and attach these 266 * devices, so we can never actually probe one from here. 267 */ | |
268 return(0); 269} 270 | 225 return(0); 226} 227 |
271static int wi_attach(isa_dev) 272 struct isa_device *isa_dev; | 228static int wi_pccard_attach(device_t dev) |
273{ 274 struct wi_softc *sc; 275 struct wi_ltv_macaddr mac; 276 struct wi_ltv_gen gen; 277 struct ifnet *ifp; | 229{ 230 struct wi_softc *sc; 231 struct wi_ltv_macaddr mac; 232 struct wi_ltv_gen gen; 233 struct ifnet *ifp; |
278 char ifname[IFNAMSIZ]; | 234 int error; |
279 | 235 |
280#ifdef PCCARD_MODULE 281 isa_dev->id_ointr = wi_intr; 282#endif 283 sc = &wi_softc[isa_dev->id_unit]; | 236 sc = device_get_softc(dev); |
284 ifp = &sc->arpcom.ac_if; 285 | 237 ifp = &sc->arpcom.ac_if; 238 |
239 error = wi_alloc(dev); 240 if (error) { 241 device_printf(dev, "wi_alloc() failed! (%d)\n", error); 242 return (error); 243 } 244 245 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, 246 wi_intr, sc, &sc->wi_intrhand); 247 248 if (error) { 249 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); 250 wi_free(dev); 251 return (error); 252 } 253 |
|
286 /* Reset the NIC. */ 287 wi_reset(sc); 288 289 /* Read the station address. */ 290 mac.wi_type = WI_RID_MAC_NODE; 291 mac.wi_len = 4; 292 wi_read_record(sc, (struct wi_ltv_gen *)&mac); 293 bcopy((char *)&mac.wi_mac_addr, 294 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 295 | 254 /* Reset the NIC. */ 255 wi_reset(sc); 256 257 /* Read the station address. */ 258 mac.wi_type = WI_RID_MAC_NODE; 259 mac.wi_len = 4; 260 wi_read_record(sc, (struct wi_ltv_gen *)&mac); 261 bcopy((char *)&mac.wi_mac_addr, 262 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 263 |
296 printf("wi%d: Ethernet address: %6D\n", sc->wi_unit, | 264 device_printf(dev, "Ethernet address: %6D\n", |
297 sc->arpcom.ac_enaddr, ":"); 298 299 ifp->if_softc = sc; 300 ifp->if_unit = sc->wi_unit; 301 ifp->if_name = "wi"; 302 ifp->if_mtu = ETHERMTU; 303 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 304 ifp->if_ioctl = wi_ioctl; --- 38 unchanged lines hidden (view full) --- 343 sc->wi_channel = gen.wi_val; 344 345 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); 346 347 wi_init(sc); 348 wi_stop(sc); 349 350 /* | 265 sc->arpcom.ac_enaddr, ":"); 266 267 ifp->if_softc = sc; 268 ifp->if_unit = sc->wi_unit; 269 ifp->if_name = "wi"; 270 ifp->if_mtu = ETHERMTU; 271 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 272 ifp->if_ioctl = wi_ioctl; --- 38 unchanged lines hidden (view full) --- 311 sc->wi_channel = gen.wi_val; 312 313 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); 314 315 wi_init(sc); 316 wi_stop(sc); 317 318 /* |
351 * If this logical interface has already been attached, 352 * don't attach it again or chaos will ensue. | 319 * Call MI attach routines. |
353 */ | 320 */ |
354 sprintf(ifname, "wi%d", sc->wi_unit); | 321 if_attach(ifp); 322 ether_ifattach(ifp); 323 callout_handle_init(&sc->wi_stat_ch); 324 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); |
355 | 325 |
356 if (ifunit(ifname) == NULL) { 357 callout_handle_init(&sc->wi_stat_ch); 358 /* 359 * Call MI attach routines. 360 */ 361 if_attach(ifp); 362 ether_ifattach(ifp); 363 364 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); 365 366 EVENTHANDLER_REGISTER(shutdown_post_sync, wi_shutdown, sc, 367 SHUTDOWN_PRI_DEFAULT); 368 } 369 | |
370 return(0); 371} 372 373static void wi_rxeof(sc) 374 struct wi_softc *sc; 375{ 376 struct ifnet *ifp; 377 struct ether_header *eh; --- 30 unchanged lines hidden (view full) --- 408 409 eh = mtod(m, struct ether_header *); 410 m->m_pkthdr.rcvif = ifp; 411 412 if (rx_frame.wi_status == WI_STAT_1042 || 413 rx_frame.wi_status == WI_STAT_TUNNEL || 414 rx_frame.wi_status == WI_STAT_WMP_MSG) { 415 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) { | 326 return(0); 327} 328 329static void wi_rxeof(sc) 330 struct wi_softc *sc; 331{ 332 struct ifnet *ifp; 333 struct ether_header *eh; --- 30 unchanged lines hidden (view full) --- 364 365 eh = mtod(m, struct ether_header *); 366 m->m_pkthdr.rcvif = ifp; 367 368 if (rx_frame.wi_status == WI_STAT_1042 || 369 rx_frame.wi_status == WI_STAT_TUNNEL || 370 rx_frame.wi_status == WI_STAT_WMP_MSG) { 371 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) { |
416 printf("wi%d: oversized packet received " 417 "(wi_dat_len=%d, wi_status=0x%x)\n", sc->wi_unit, | 372 device_printf(sc->dev, "oversized packet received " 373 "(wi_dat_len=%d, wi_status=0x%x)\n", |
418 rx_frame.wi_dat_len, rx_frame.wi_status); 419 m_freem(m); 420 ifp->if_ierrors++; 421 return; 422 } 423 m->m_pkthdr.len = m->m_len = 424 rx_frame.wi_dat_len + WI_SNAPHDR_LEN; 425 --- 9 unchanged lines hidden (view full) --- 435 m->m_len + 2)) { 436 m_freem(m); 437 ifp->if_ierrors++; 438 return; 439 } 440 } else { 441 if((rx_frame.wi_dat_len + 442 sizeof(struct ether_header)) > MCLBYTES) { | 374 rx_frame.wi_dat_len, rx_frame.wi_status); 375 m_freem(m); 376 ifp->if_ierrors++; 377 return; 378 } 379 m->m_pkthdr.len = m->m_len = 380 rx_frame.wi_dat_len + WI_SNAPHDR_LEN; 381 --- 9 unchanged lines hidden (view full) --- 391 m->m_len + 2)) { 392 m_freem(m); 393 ifp->if_ierrors++; 394 return; 395 } 396 } else { 397 if((rx_frame.wi_dat_len + 398 sizeof(struct ether_header)) > MCLBYTES) { |
443 printf("wi%d: oversized packet received " 444 "(wi_dat_len=%d, wi_status=0x%x)\n", sc->wi_unit, | 399 device_printf(sc->dev, "oversized packet received " 400 "(wi_dat_len=%d, wi_status=0x%x)\n", |
445 rx_frame.wi_dat_len, rx_frame.wi_status); 446 m_freem(m); 447 ifp->if_ierrors++; 448 return; 449 } 450 m->m_pkthdr.len = m->m_len = 451 rx_frame.wi_dat_len + sizeof(struct ether_header); 452 --- 15 unchanged lines hidden (view full) --- 468 ETHER_ADDR_LEN) && (eh->ether_dhost[0] & 1) == 0)) { 469 m_freem(m); 470 return; 471 } 472 } 473 474 /* Receive packet. */ 475 m_adj(m, sizeof(struct ether_header)); | 401 rx_frame.wi_dat_len, rx_frame.wi_status); 402 m_freem(m); 403 ifp->if_ierrors++; 404 return; 405 } 406 m->m_pkthdr.len = m->m_len = 407 rx_frame.wi_dat_len + sizeof(struct ether_header); 408 --- 15 unchanged lines hidden (view full) --- 424 ETHER_ADDR_LEN) && (eh->ether_dhost[0] & 1) == 0)) { 425 m_freem(m); 426 return; 427 } 428 } 429 430 /* Receive packet. */ 431 m_adj(m, sizeof(struct ether_header)); |
432#ifdef WICACHE 433 wi_cache_store(sc, eh, m, rx_frame.wi_q_info); 434#endif |
|
476 ether_input(ifp, eh, m); 477 478 return; 479} 480 481static void wi_txeof(sc, status) 482 struct wi_softc *sc; 483 int status; --- 66 unchanged lines hidden (view full) --- 550 551 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries + 552 sc->wi_stats.wi_tx_multi_retries + 553 sc->wi_stats.wi_tx_retry_limit; 554 555 return; 556} 557 | 435 ether_input(ifp, eh, m); 436 437 return; 438} 439 440static void wi_txeof(sc, status) 441 struct wi_softc *sc; 442 int status; --- 66 unchanged lines hidden (view full) --- 509 510 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries + 511 sc->wi_stats.wi_tx_multi_retries + 512 sc->wi_stats.wi_tx_retry_limit; 513 514 return; 515} 516 |
558void wi_intr(unit) 559 int unit; | 517static void wi_intr(xsc) 518 void *xsc; |
560{ | 519{ |
561 struct wi_softc *sc; | 520 struct wi_softc *sc = xsc; |
562 struct ifnet *ifp; 563 u_int16_t status; 564 | 521 struct ifnet *ifp; 522 u_int16_t status; 523 |
565 sc = &wi_softc[unit]; | |
566 ifp = &sc->arpcom.ac_if; 567 568 if (!(ifp->if_flags & IFF_UP)) { 569 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 570 CSR_WRITE_2(sc, WI_INT_EN, 0); 571 return; 572 } 573 --- 78 unchanged lines hidden (view full) --- 652 return(ETIMEDOUT); 653 654 return(0); 655} 656 657static void wi_reset(sc) 658 struct wi_softc *sc; 659{ | 524 ifp = &sc->arpcom.ac_if; 525 526 if (!(ifp->if_flags & IFF_UP)) { 527 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 528 CSR_WRITE_2(sc, WI_INT_EN, 0); 529 return; 530 } 531 --- 78 unchanged lines hidden (view full) --- 610 return(ETIMEDOUT); 611 612 return(0); 613} 614 615static void wi_reset(sc) 616 struct wi_softc *sc; 617{ |
618 wi_cmd(sc, WI_CMD_INI, 0); 619 DELAY(100000); 620 wi_cmd(sc, WI_CMD_INI, 0); 621 DELAY(100000); 622#ifdef foo |
|
660 if (wi_cmd(sc, WI_CMD_INI, 0)) | 623 if (wi_cmd(sc, WI_CMD_INI, 0)) |
661 printf("wi%d: init failed\n", sc->wi_unit); | 624 device_printf(sc->dev, "init failed\n"); |
662 CSR_WRITE_2(sc, WI_INT_EN, 0); 663 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 664 665 /* Calibrate timer. */ 666 WI_SETVAL(WI_RID_TICK_TIME, 8); | 625 CSR_WRITE_2(sc, WI_INT_EN, 0); 626 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 627 628 /* Calibrate timer. */ 629 WI_SETVAL(WI_RID_TICK_TIME, 8); |
667 | 630#endif |
668 return; 669} 670 671/* 672 * Read an LTV record from the NIC. 673 */ 674static int wi_read_record(sc, ltv) 675 struct wi_softc *sc; --- 71 unchanged lines hidden (view full) --- 747 selreg = WI_SEL0; 748 offreg = WI_OFF0; 749 break; 750 case WI_BAP1: 751 selreg = WI_SEL1; 752 offreg = WI_OFF1; 753 break; 754 default: | 631 return; 632} 633 634/* 635 * Read an LTV record from the NIC. 636 */ 637static int wi_read_record(sc, ltv) 638 struct wi_softc *sc; --- 71 unchanged lines hidden (view full) --- 710 selreg = WI_SEL0; 711 offreg = WI_OFF0; 712 break; 713 case WI_BAP1: 714 selreg = WI_SEL1; 715 offreg = WI_OFF1; 716 break; 717 default: |
755 printf("wi%d: invalid data path: %x\n", sc->wi_unit, chan); | 718 device_printf(sc->dev, "invalid data path: %x\n", chan); |
756 return(EIO); 757 } 758 759 CSR_WRITE_2(sc, selreg, id); 760 CSR_WRITE_2(sc, offreg, off); 761 762 for (i = 0; i < WI_TIMEOUT; i++) { 763 if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR))) --- 79 unchanged lines hidden (view full) --- 843static int wi_alloc_nicmem(sc, len, id) 844 struct wi_softc *sc; 845 int len; 846 int *id; 847{ 848 int i; 849 850 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) { | 719 return(EIO); 720 } 721 722 CSR_WRITE_2(sc, selreg, id); 723 CSR_WRITE_2(sc, offreg, off); 724 725 for (i = 0; i < WI_TIMEOUT; i++) { 726 if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR))) --- 79 unchanged lines hidden (view full) --- 806static int wi_alloc_nicmem(sc, len, id) 807 struct wi_softc *sc; 808 int len; 809 int *id; 810{ 811 int i; 812 813 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) { |
851 printf("wi%d: failed to allocate %d bytes on NIC\n", 852 sc->wi_unit, len); | 814 device_printf(sc->dev, "failed to allocate %d bytes on NIC\n", len); |
853 return(ENOMEM); 854 } 855 856 for (i = 0; i < WI_TIMEOUT; i++) { 857 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) 858 break; 859 } 860 --- 171 unchanged lines hidden (view full) --- 1032 case SIOCGWAVELAN: 1033 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 1034 if (error) 1035 break; 1036 if (wreq.wi_type == WI_RID_IFACE_STATS) { 1037 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val, 1038 sizeof(sc->wi_stats)); 1039 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1; | 815 return(ENOMEM); 816 } 817 818 for (i = 0; i < WI_TIMEOUT; i++) { 819 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) 820 break; 821 } 822 --- 171 unchanged lines hidden (view full) --- 994 case SIOCGWAVELAN: 995 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 996 if (error) 997 break; 998 if (wreq.wi_type == WI_RID_IFACE_STATS) { 999 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val, 1000 sizeof(sc->wi_stats)); 1001 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1; |
1040 } else { | 1002 } 1003#ifdef WICACHE 1004 else if (wreq.wi_type == WI_RID_ZERO_CACHE) { 1005 sc->wi_sigitems = sc->wi_nextitem = 0; 1006 } else if (wreq.wi_type == WI_RID_READ_CACHE) { 1007 char *pt = (char *)&wreq.wi_val; 1008 bcopy((char *)&sc->wi_sigitems, 1009 (char *)pt, sizeof(int)); 1010 pt += (sizeof (int)); 1011 wreq.wi_len = sizeof(int) / 2; 1012 bcopy((char *)&sc->wi_sigcache, (char *)pt, 1013 sizeof(struct wi_sigcache) * sc->wi_sigitems); 1014 wreq.wi_len += ((sizeof(struct wi_sigcache) * 1015 sc->wi_sigitems) / 2) + 1; 1016 } 1017#endif 1018 else { |
1041 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) { 1042 error = EINVAL; 1043 break; 1044 } 1045 } 1046 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1047 break; 1048 case SIOCSWAVELAN: --- 93 unchanged lines hidden (view full) --- 1142 1143 /* Set multicast filter. */ 1144 wi_setmulti(sc); 1145 1146 /* Enable desired port */ 1147 wi_cmd(sc, WI_CMD_ENABLE|sc->wi_portnum, 0); 1148 1149 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id)) | 1019 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) { 1020 error = EINVAL; 1021 break; 1022 } 1023 } 1024 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 1025 break; 1026 case SIOCSWAVELAN: --- 93 unchanged lines hidden (view full) --- 1120 1121 /* Set multicast filter. */ 1122 wi_setmulti(sc); 1123 1124 /* Enable desired port */ 1125 wi_cmd(sc, WI_CMD_ENABLE|sc->wi_portnum, 0); 1126 1127 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id)) |
1150 printf("wi%d: tx buffer allocation failed\n", sc->wi_unit); | 1128 device_printf(sc->dev, "tx buffer allocation failed\n"); |
1151 sc->wi_tx_data_id = id; 1152 1153 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id)) | 1129 sc->wi_tx_data_id = id; 1130 1131 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id)) |
1154 printf("wi%d: mgmt. buffer allocation failed\n", sc->wi_unit); | 1132 device_printf(sc->dev, "mgmt. buffer allocation failed\n"); |
1155 sc->wi_tx_mgmt_id = id; 1156 1157 /* enable interrupts */ 1158 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 1159 1160 splx(s); 1161 1162 ifp->if_flags |= IFF_RUNNING; --- 76 unchanged lines hidden (view full) --- 1239 * this frame to him. 1240 */ 1241 if (ifp->if_bpf) 1242 bpf_mtap(ifp, m0); 1243 1244 m_freem(m0); 1245 1246 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) | 1133 sc->wi_tx_mgmt_id = id; 1134 1135 /* enable interrupts */ 1136 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 1137 1138 splx(s); 1139 1140 ifp->if_flags |= IFF_RUNNING; --- 76 unchanged lines hidden (view full) --- 1217 * this frame to him. 1218 */ 1219 if (ifp->if_bpf) 1220 bpf_mtap(ifp, m0); 1221 1222 m_freem(m0); 1223 1224 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) |
1247 printf("wi%d: xmit failed\n", sc->wi_unit); | 1225 device_printf(sc->dev, "xmit failed\n"); |
1248 1249 ifp->if_flags |= IFF_OACTIVE; 1250 1251 /* 1252 * Set a timeout in case the chip goes out to lunch. 1253 */ 1254 ifp->if_timer = 5; 1255 --- 25 unchanged lines hidden (view full) --- 1281 tx_frame.wi_dat_len = len - WI_SNAPHDR_LEN; 1282 tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN); 1283 1284 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame)); 1285 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr, 1286 (len - sizeof(struct wi_80211_hdr)) + 2); 1287 1288 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) { | 1226 1227 ifp->if_flags |= IFF_OACTIVE; 1228 1229 /* 1230 * Set a timeout in case the chip goes out to lunch. 1231 */ 1232 ifp->if_timer = 5; 1233 --- 25 unchanged lines hidden (view full) --- 1259 tx_frame.wi_dat_len = len - WI_SNAPHDR_LEN; 1260 tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN); 1261 1262 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame)); 1263 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr, 1264 (len - sizeof(struct wi_80211_hdr)) + 2); 1265 1266 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) { |
1289 printf("wi%d: xmit failed\n", sc->wi_unit); | 1267 device_printf(sc->dev, "xmit failed\n"); |
1290 return(EIO); 1291 } 1292 1293 return(0); 1294} 1295 1296static void wi_stop(sc) 1297 struct wi_softc *sc; --- 17 unchanged lines hidden (view full) --- 1315 1316static void wi_watchdog(ifp) 1317 struct ifnet *ifp; 1318{ 1319 struct wi_softc *sc; 1320 1321 sc = ifp->if_softc; 1322 | 1268 return(EIO); 1269 } 1270 1271 return(0); 1272} 1273 1274static void wi_stop(sc) 1275 struct wi_softc *sc; --- 17 unchanged lines hidden (view full) --- 1293 1294static void wi_watchdog(ifp) 1295 struct ifnet *ifp; 1296{ 1297 struct wi_softc *sc; 1298 1299 sc = ifp->if_softc; 1300 |
1323 printf("wi%d: device timeout\n", sc->wi_unit); | 1301 device_printf(sc->dev,"device timeout\n"); |
1324 1325 wi_init(sc); 1326 1327 ifp->if_oerrors++; 1328 1329 return; 1330} 1331 | 1302 1303 wi_init(sc); 1304 1305 ifp->if_oerrors++; 1306 1307 return; 1308} 1309 |
1332static void wi_shutdown(arg, howto) 1333 void *arg; 1334 int howto; | 1310static int wi_alloc(dev) 1311 device_t dev; |
1335{ | 1312{ |
1313 struct wi_softc *sc = device_get_softc(dev); 1314 int rid; 1315 1316 rid = 0; 1317 sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 1318 0, ~0, 1, RF_ACTIVE); 1319 if (!sc->iobase) { 1320 device_printf(dev, "No I/O space?!\n"); 1321 return (ENXIO); 1322 } 1323 1324 rid = 0; 1325 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1326 0, ~0, 1, RF_ACTIVE); 1327 if (!sc->irq) { 1328 device_printf(dev, "No irq?!\n"); 1329 return (ENXIO); 1330 } 1331 1332 sc->dev = dev; 1333 sc->wi_unit = device_get_unit(dev); 1334 sc->wi_io_addr = rman_get_start(sc->iobase); 1335 sc->wi_btag = rman_get_bustag(sc->iobase); 1336 sc->wi_bhandle = rman_get_bushandle(sc->iobase); 1337 1338 return (0); 1339} 1340 1341static void wi_free(dev) 1342 device_t dev; 1343{ 1344 struct wi_softc *sc = device_get_softc(dev); 1345 1346 if (sc->iobase != NULL) 1347 bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->iobase); 1348 if (sc->irq != NULL) 1349 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); 1350 1351 return; 1352} 1353 1354static void wi_shutdown(dev) 1355 device_t dev; 1356{ |
|
1336 struct wi_softc *sc; 1337 | 1357 struct wi_softc *sc; 1358 |
1338 sc = arg; | 1359 sc = device_get_softc(dev); |
1339 wi_stop(sc); 1340 1341 return; 1342} | 1360 wi_stop(sc); 1361 1362 return; 1363} |
1364 1365#ifdef WICACHE 1366/* wavelan signal strength cache code. 1367 * store signal/noise/quality on per MAC src basis in 1368 * a small fixed cache. The cache wraps if > MAX slots 1369 * used. The cache may be zeroed out to start over. 1370 * Two simple filters exist to reduce computation: 1371 * 1. ip only (literally 0x800) which may be used 1372 * to ignore some packets. It defaults to ip only. 1373 * it could be used to focus on broadcast, non-IP 802.11 beacons. 1374 * 2. multicast/broadcast only. This may be used to 1375 * ignore unicast packets and only cache signal strength 1376 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 1377 * beacons and not unicast traffic. 1378 * 1379 * The cache stores (MAC src(index), IP src (major clue), signal, 1380 * quality, noise) 1381 * 1382 * No apologies for storing IP src here. It's easy and saves much 1383 * trouble elsewhere. The cache is assumed to be INET dependent, 1384 * although it need not be. 1385 */ 1386 1387#ifdef documentation 1388 1389int wi_sigitems; /* number of cached entries */ 1390struct wi_sigcache wi_sigcache[MAXWICACHE]; /* array of cache entries */ 1391int wi_nextitem; /* index/# of entries */ 1392 1393 1394#endif 1395 1396/* control variables for cache filtering. Basic idea is 1397 * to reduce cost (e.g., to only Mobile-IP agent beacons 1398 * which are broadcast or multicast). Still you might 1399 * want to measure signal strength with unicast ping packets 1400 * on a pt. to pt. ant. setup. 1401 */ 1402/* set true if you want to limit cache items to broadcast/mcast 1403 * only packets (not unicast). Useful for mobile-ip beacons which 1404 * are broadcast/multicast at network layer. Default is all packets 1405 * so ping/unicast will work say with pt. to pt. antennae setup. 1406 */ 1407static int wi_cache_mcastonly = 0; 1408SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW, 1409 &wi_cache_mcastonly, 0, ""); 1410 1411/* set true if you want to limit cache items to IP packets only 1412*/ 1413static int wi_cache_iponly = 1; 1414SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW, 1415 &wi_cache_iponly, 0, ""); 1416 1417/* 1418 * Original comments: 1419 * ----------------- 1420 * wi_cache_store, per rx packet store signal 1421 * strength in MAC (src) indexed cache. 1422 * 1423 * follows linux driver in how signal strength is computed. 1424 * In ad hoc mode, we use the rx_quality field. 1425 * signal and noise are trimmed to fit in the range from 47..138. 1426 * rx_quality field MSB is signal strength. 1427 * rx_quality field LSB is noise. 1428 * "quality" is (signal - noise) as is log value. 1429 * note: quality CAN be negative. 1430 * 1431 * In BSS mode, we use the RID for communication quality. 1432 * TBD: BSS mode is currently untested. 1433 * 1434 * Bill's comments: 1435 * --------------- 1436 * Actually, we use the rx_quality field all the time for both "ad-hoc" 1437 * and BSS modes. Why? Because reading an RID is really, really expensive: 1438 * there's a bunch of PIO operations that have to be done to read a record 1439 * from the NIC, and reading the comms quality RID each time a packet is 1440 * received can really hurt performance. We don't have to do this anyway: 1441 * the comms quality field only reflects the values in the rx_quality field 1442 * anyway. The comms quality RID is only meaningful in infrastructure mode, 1443 * but the values it contains are updated based on the rx_quality from 1444 * frames received from the access point. 1445 * 1446 * Also, according to Lucent, the signal strength and noise level values 1447 * can be converted to dBms by subtracting 149, so I've modified the code 1448 * to do that instead of the scaling it did originally. 1449 */ 1450static 1451void wi_cache_store (struct wi_softc *sc, struct ether_header *eh, 1452 struct mbuf *m, unsigned short rx_quality) 1453{ 1454 struct ip *ip = 0; 1455 int i; 1456 static int cache_slot = 0; /* use this cache entry */ 1457 static int wrapindex = 0; /* next "free" cache entry */ 1458 int sig, noise; 1459 int sawip=0; 1460 1461 /* filters: 1462 * 1. ip only 1463 * 2. configurable filter to throw out unicast packets, 1464 * keep multicast only. 1465 */ 1466 1467 if ((ntohs(eh->ether_type) == 0x800)) { 1468 sawip = 1; 1469 } 1470 1471 /* filter for ip packets only 1472 */ 1473 if (wi_cache_iponly && !sawip) { 1474 return; 1475 } 1476 1477 /* filter for broadcast/multicast only 1478 */ 1479 if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 1480 return; 1481 } 1482 1483#ifdef SIGDEBUG 1484 printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit, 1485 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 1486#endif 1487 1488 /* find the ip header. we want to store the ip_src 1489 * address. 1490 */ 1491 if (sawip) { 1492 ip = mtod(m, struct ip *); 1493 } 1494 1495 /* do a linear search for a matching MAC address 1496 * in the cache table 1497 * . MAC address is 6 bytes, 1498 * . var w_nextitem holds total number of entries already cached 1499 */ 1500 for(i = 0; i < sc->wi_nextitem; i++) { 1501 if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc, 6 )) { 1502 /* Match!, 1503 * so we already have this entry, 1504 * update the data 1505 */ 1506 break; 1507 } 1508 } 1509 1510 /* did we find a matching mac address? 1511 * if yes, then overwrite a previously existing cache entry 1512 */ 1513 if (i < sc->wi_nextitem ) { 1514 cache_slot = i; 1515 } 1516 /* else, have a new address entry,so 1517 * add this new entry, 1518 * if table full, then we need to replace LRU entry 1519 */ 1520 else { 1521 1522 /* check for space in cache table 1523 * note: wi_nextitem also holds number of entries 1524 * added in the cache table 1525 */ 1526 if ( sc->wi_nextitem < MAXWICACHE ) { 1527 cache_slot = sc->wi_nextitem; 1528 sc->wi_nextitem++; 1529 sc->wi_sigitems = sc->wi_nextitem; 1530 } 1531 /* no space found, so simply wrap with wrap index 1532 * and "zap" the next entry 1533 */ 1534 else { 1535 if (wrapindex == MAXWICACHE) { 1536 wrapindex = 0; 1537 } 1538 cache_slot = wrapindex++; 1539 } 1540 } 1541 1542 /* invariant: cache_slot now points at some slot 1543 * in cache. 1544 */ 1545 if (cache_slot < 0 || cache_slot >= MAXWICACHE) { 1546 log(LOG_ERR, "wi_cache_store, bad index: %d of " 1547 "[0..%d], gross cache error\n", 1548 cache_slot, MAXWICACHE); 1549 return; 1550 } 1551 1552 /* store items in cache 1553 * .ip source address 1554 * .mac src 1555 * .signal, etc. 1556 */ 1557 if (sawip) { 1558 sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr; 1559 } 1560 bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc, 6); 1561 1562 sig = (rx_quality >> 8) & 0xFF; 1563 noise = rx_quality & 0xFF; 1564 sc->wi_sigcache[cache_slot].signal = sig - 149; 1565 sc->wi_sigcache[cache_slot].noise = noise - 149; 1566 sc->wi_sigcache[cache_slot].quality = sig - noise; 1567 1568 return; 1569} 1570#endif |
|