if_an.c (83269) | if_an.c (83270) |
---|---|
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/an/if_an.c 83269 2001-09-10 02:05:10Z brooks $ | 32 * $FreeBSD: head/sys/dev/an/if_an.c 83270 2001-09-10 02:36:18Z brooks $ |
33 */ 34 35/* 36 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD. 37 * 38 * Written by Bill Paul <wpaul@ctr.columbia.edu> 39 * Electrical Engineering Department 40 * Columbia University, New York City --- 29 unchanged lines hidden (view full) --- 70 * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages, 71 * which leaves the card in ISA/PCI mode, which prevents it from 72 * being activated as an PCMCIA device. Consequently, /sys/pccard/pccard.c 73 * has to be patched slightly in order to enable the Vpp voltages in 74 * order to make the Aironet PCMCIA cards work. 75 * 76 * Note that some PCMCIA controller software packages for Windows NT 77 * fail to set the voltages as well. | 33 */ 34 35/* 36 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD. 37 * 38 * Written by Bill Paul <wpaul@ctr.columbia.edu> 39 * Electrical Engineering Department 40 * Columbia University, New York City --- 29 unchanged lines hidden (view full) --- 70 * set to 5 volts. FreeBSD by default doesn't set the Vpp voltages, 71 * which leaves the card in ISA/PCI mode, which prevents it from 72 * being activated as an PCMCIA device. Consequently, /sys/pccard/pccard.c 73 * has to be patched slightly in order to enable the Vpp voltages in 74 * order to make the Aironet PCMCIA cards work. 75 * 76 * Note that some PCMCIA controller software packages for Windows NT 77 * fail to set the voltages as well. |
78 * | 78 * |
79 * The Aironet devices can operate in both station mode and access point 80 * mode. Typically, when programmed for station mode, the card can be set 81 * to automatically perform encapsulation/decapsulation of Ethernet II 82 * and 802.3 frames within 802.11 frames so that the host doesn't have 83 * to do it itself. This driver doesn't program the card that way: the 84 * driver handles all of the encapsulation/decapsulation itself. 85 */ 86 --- 41 unchanged lines hidden (view full) --- 128 129#include <machine/md_var.h> 130 131#include <dev/an/if_aironet_ieee.h> 132#include <dev/an/if_anreg.h> 133 134#if !defined(lint) 135static const char rcsid[] = | 79 * The Aironet devices can operate in both station mode and access point 80 * mode. Typically, when programmed for station mode, the card can be set 81 * to automatically perform encapsulation/decapsulation of Ethernet II 82 * and 802.3 frames within 802.11 frames so that the host doesn't have 83 * to do it itself. This driver doesn't program the card that way: the 84 * driver handles all of the encapsulation/decapsulation itself. 85 */ 86 --- 41 unchanged lines hidden (view full) --- 128 129#include <machine/md_var.h> 130 131#include <dev/an/if_aironet_ieee.h> 132#include <dev/an/if_anreg.h> 133 134#if !defined(lint) 135static const char rcsid[] = |
136 "$FreeBSD: head/sys/dev/an/if_an.c 83269 2001-09-10 02:05:10Z brooks $"; | 136 "$FreeBSD: head/sys/dev/an/if_an.c 83270 2001-09-10 02:36:18Z brooks $"; |
137#endif 138 139/* These are global because we need them in sys/pci/if_an_p.c. */ 140static void an_reset __P((struct an_softc *)); 141static int an_ioctl __P((struct ifnet *, u_long, caddr_t)); 142static void an_init __P((void *)); 143static int an_init_tx_ring __P((struct an_softc *)); 144static void an_start __P((struct ifnet *)); --- 30 unchanged lines hidden (view full) --- 175/* sysctl vars */ 176SYSCTL_NODE(_machdep, OID_AUTO, an, CTLFLAG_RD, 0, "dump RID"); 177 178static int 179sysctl_an_dump(SYSCTL_HANDLER_ARGS) 180{ 181 int error, r, last; 182 char *s = an_conf; | 137#endif 138 139/* These are global because we need them in sys/pci/if_an_p.c. */ 140static void an_reset __P((struct an_softc *)); 141static int an_ioctl __P((struct ifnet *, u_long, caddr_t)); 142static void an_init __P((void *)); 143static int an_init_tx_ring __P((struct an_softc *)); 144static void an_start __P((struct ifnet *)); --- 30 unchanged lines hidden (view full) --- 175/* sysctl vars */ 176SYSCTL_NODE(_machdep, OID_AUTO, an, CTLFLAG_RD, 0, "dump RID"); 177 178static int 179sysctl_an_dump(SYSCTL_HANDLER_ARGS) 180{ 181 int error, r, last; 182 char *s = an_conf; |
183 | 183 |
184 last = an_dump; 185 bzero(an_conf, sizeof(an_conf)); 186 | 184 last = an_dump; 185 bzero(an_conf, sizeof(an_conf)); 186 |
187 switch (an_dump){ | 187 switch (an_dump) { |
188 case 0: 189 strcat(an_conf, "off"); 190 break; 191 case 1: 192 strcat(an_conf, "type"); 193 break; 194 case 2: 195 strcat(an_conf, "dump"); 196 break; 197 default: 198 snprintf(an_conf, 5, "%x", an_dump); 199 break; 200 } 201 202 error = sysctl_handle_string(oidp, an_conf, sizeof(an_conf), req); 203 | 188 case 0: 189 strcat(an_conf, "off"); 190 break; 191 case 1: 192 strcat(an_conf, "type"); 193 break; 194 case 2: 195 strcat(an_conf, "dump"); 196 break; 197 default: 198 snprintf(an_conf, 5, "%x", an_dump); 199 break; 200 } 201 202 error = sysctl_handle_string(oidp, an_conf, sizeof(an_conf), req); 203 |
204 if (strncmp(an_conf,"off", 4) == 0){ | 204 if (strncmp(an_conf,"off", 4) == 0) { |
205 an_dump = 0; 206 } | 205 an_dump = 0; 206 } |
207 if (strncmp(an_conf,"dump", 4) == 0){ | 207 if (strncmp(an_conf,"dump", 4) == 0) { |
208 an_dump = 1; 209 } | 208 an_dump = 1; 209 } |
210 if (strncmp(an_conf,"type", 4) == 0){ | 210 if (strncmp(an_conf,"type", 4) == 0) { |
211 an_dump = 2; 212 } | 211 an_dump = 2; 212 } |
213 if (*s == 'f'){ | 213 if (*s == 'f') { |
214 r = 0; | 214 r = 0; |
215 for(;;s++){ 216 if((*s >= '0') && (*s <= '9')){ | 215 for (;;s++) { 216 if ((*s >= '0') && (*s <= '9')) { |
217 r = r * 16 + (*s - '0'); | 217 r = r * 16 + (*s - '0'); |
218 }else if ((*s >= 'a') && (*s <= 'f')) { | 218 } else if ((*s >= 'a') && (*s <= 'f')) { |
219 r = r * 16 + (*s - 'a' + 10); | 219 r = r * 16 + (*s - 'a' + 10); |
220 }else{ 221 break; | 220 } else { 221 break; |
222 } 223 } 224 an_dump = r; 225 } 226 if (an_dump != last) 227 printf("Sysctl changed for Aironet driver\n"); 228 229 return error; 230} 231 232SYSCTL_PROC(_machdep, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW, 233 0, sizeof(an_conf), sysctl_an_dump, "A", ""); 234 | 222 } 223 } 224 an_dump = r; 225 } 226 if (an_dump != last) 227 printf("Sysctl changed for Aironet driver\n"); 228 229 return error; 230} 231 232SYSCTL_PROC(_machdep, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW, 233 0, sizeof(an_conf), sysctl_an_dump, "A", ""); 234 |
235/* | 235/* |
236 * We probe for an Aironet 4500/4800 card by attempting to 237 * read the default SSID list. On reset, the first entry in 238 * the SSID list will contain the name "tsunami." If we don't 239 * find this, then there's no card present. 240 */ | 236 * We probe for an Aironet 4500/4800 card by attempting to 237 * read the default SSID list. On reset, the first entry in 238 * the SSID list will contain the name "tsunami." If we don't 239 * find this, then there's no card present. 240 */ |
241int an_probe(dev) | 241int 242an_probe(dev) |
242 device_t dev; 243{ 244 struct an_softc *sc = device_get_softc(dev); 245 struct an_ltv_ssidlist ssid; 246 int error; 247 248 bzero((char *)&ssid, sizeof(ssid)); 249 --- 27 unchanged lines hidden (view full) --- 277 return(0); 278 279 if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) 280 return(0); 281 282 /* See if the ssid matches what we expect ... but doesn't have to */ 283 if (strcmp(ssid.an_ssid1, AN_DEF_SSID)) 284 return(0); | 243 device_t dev; 244{ 245 struct an_softc *sc = device_get_softc(dev); 246 struct an_ltv_ssidlist ssid; 247 int error; 248 249 bzero((char *)&ssid, sizeof(ssid)); 250 --- 27 unchanged lines hidden (view full) --- 278 return(0); 279 280 if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) 281 return(0); 282 283 /* See if the ssid matches what we expect ... but doesn't have to */ 284 if (strcmp(ssid.an_ssid1, AN_DEF_SSID)) 285 return(0); |
285 | 286 |
286 return(AN_IOSIZ); 287} 288 289/* 290 * Allocate a port resource with the given resource id. 291 */ 292int 293an_alloc_port(dev, rid, size) --- 54 unchanged lines hidden (view full) --- 348 } 349 if (sc->irq_res) { 350 bus_release_resource(dev, SYS_RES_IRQ, 351 sc->irq_rid, sc->irq_res); 352 sc->irq_res = 0; 353 } 354} 355 | 287 return(AN_IOSIZ); 288} 289 290/* 291 * Allocate a port resource with the given resource id. 292 */ 293int 294an_alloc_port(dev, rid, size) --- 54 unchanged lines hidden (view full) --- 349 } 350 if (sc->irq_res) { 351 bus_release_resource(dev, SYS_RES_IRQ, 352 sc->irq_rid, sc->irq_res); 353 sc->irq_res = 0; 354 } 355} 356 |
356int an_attach(sc, unit, flags) | 357int 358an_attach(sc, unit, flags) |
357 struct an_softc *sc; 358 int unit; 359 int flags; 360{ 361 struct ifnet *ifp = &sc->arpcom.ac_if; 362 363 mtx_init(&sc->an_mtx, device_get_nameunit(sc->an_dev), MTX_DEF | 364 MTX_RECURSE); --- 119 unchanged lines hidden (view full) --- 484 */ 485 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 486 callout_handle_init(&sc->an_stat_ch); 487 AN_UNLOCK(sc); 488 489 return(0); 490} 491 | 359 struct an_softc *sc; 360 int unit; 361 int flags; 362{ 363 struct ifnet *ifp = &sc->arpcom.ac_if; 364 365 mtx_init(&sc->an_mtx, device_get_nameunit(sc->an_dev), MTX_DEF | 366 MTX_RECURSE); --- 119 unchanged lines hidden (view full) --- 486 */ 487 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 488 callout_handle_init(&sc->an_stat_ch); 489 AN_UNLOCK(sc); 490 491 return(0); 492} 493 |
492static void | 494static void |
493an_rxeof(sc) 494 struct an_softc *sc; 495{ 496 struct ifnet *ifp; 497 struct ether_header *eh; 498 struct ieee80211_frame *ih; 499 struct an_rxframe rx_frame; 500 struct an_rxframe_802_3 rx_frame_802_3; --- 13 unchanged lines hidden (view full) --- 514 515 /* read header */ 516 if (an_read_data(sc, id, 0x0, (caddr_t)&rx_frame, 517 sizeof(rx_frame))) { 518 ifp->if_ierrors++; 519 return; 520 } 521 | 495an_rxeof(sc) 496 struct an_softc *sc; 497{ 498 struct ifnet *ifp; 499 struct ether_header *eh; 500 struct ieee80211_frame *ih; 501 struct an_rxframe rx_frame; 502 struct an_rxframe_802_3 rx_frame_802_3; --- 13 unchanged lines hidden (view full) --- 516 517 /* read header */ 518 if (an_read_data(sc, id, 0x0, (caddr_t)&rx_frame, 519 sizeof(rx_frame))) { 520 ifp->if_ierrors++; 521 return; 522 } 523 |
522 /* 523 * skip beacon by default since this increases the | 524 /* 525 * skip beacon by default since this increases the |
524 * system load a lot 525 */ | 526 * system load a lot 527 */ |
526 527 if(!(sc->an_monitor & AN_MONITOR_INCLUDE_BEACON) && 528 (rx_frame.an_frame_ctl & IEEE80211_FC0_SUBTYPE_BEACON)){ | 528 529 if (!(sc->an_monitor & AN_MONITOR_INCLUDE_BEACON) && 530 (rx_frame.an_frame_ctl & IEEE80211_FC0_SUBTYPE_BEACON)) { |
529 return; 530 } 531 | 531 return; 532 } 533 |
532 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER){ 533 len = rx_frame.an_rx_payload_len | 534 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) { 535 len = rx_frame.an_rx_payload_len |
534 + sizeof(rx_frame); 535 /* Check for insane frame length */ 536 if (len > sizeof(sc->buf_802_11)) { 537 printf("an%d: oversized packet received (%d, %d)\n", 538 sc->an_unit, len, MCLBYTES); 539 ifp->if_ierrors++; 540 return; 541 } 542 543 bcopy((char *)&rx_frame, 544 bpf_buf, sizeof(rx_frame)); 545 546 error = an_read_data(sc, id, sizeof(rx_frame), 547 (caddr_t)bpf_buf+sizeof(rx_frame), 548 rx_frame.an_rx_payload_len); | 536 + sizeof(rx_frame); 537 /* Check for insane frame length */ 538 if (len > sizeof(sc->buf_802_11)) { 539 printf("an%d: oversized packet received (%d, %d)\n", 540 sc->an_unit, len, MCLBYTES); 541 ifp->if_ierrors++; 542 return; 543 } 544 545 bcopy((char *)&rx_frame, 546 bpf_buf, sizeof(rx_frame)); 547 548 error = an_read_data(sc, id, sizeof(rx_frame), 549 (caddr_t)bpf_buf+sizeof(rx_frame), 550 rx_frame.an_rx_payload_len); |
549 }else{ | 551 } else { |
550 fc1=rx_frame.an_frame_ctl >> 8; 551 ieee80211_header_len = sizeof(struct ieee80211_frame); 552 if ((fc1 & IEEE80211_FC1_DIR_TODS) && 553 (fc1 & IEEE80211_FC1_DIR_FROMDS)) { 554 ieee80211_header_len += ETHER_ADDR_LEN; 555 } 556 | 552 fc1=rx_frame.an_frame_ctl >> 8; 553 ieee80211_header_len = sizeof(struct ieee80211_frame); 554 if ((fc1 & IEEE80211_FC1_DIR_TODS) && 555 (fc1 & IEEE80211_FC1_DIR_FROMDS)) { 556 ieee80211_header_len += ETHER_ADDR_LEN; 557 } 558 |
557 len = rx_frame.an_rx_payload_len | 559 len = rx_frame.an_rx_payload_len |
558 + ieee80211_header_len; 559 /* Check for insane frame length */ 560 if (len > sizeof(sc->buf_802_11)) { 561 printf("an%d: oversized packet received (%d, %d)\n", 562 sc->an_unit, len, MCLBYTES); 563 ifp->if_ierrors++; 564 return; 565 } 566 567 ih = (struct ieee80211_frame *)bpf_buf; 568 569 bcopy((char *)&rx_frame.an_frame_ctl, 570 (char *)ih, ieee80211_header_len); 571 | 560 + ieee80211_header_len; 561 /* Check for insane frame length */ 562 if (len > sizeof(sc->buf_802_11)) { 563 printf("an%d: oversized packet received (%d, %d)\n", 564 sc->an_unit, len, MCLBYTES); 565 ifp->if_ierrors++; 566 return; 567 } 568 569 ih = (struct ieee80211_frame *)bpf_buf; 570 571 bcopy((char *)&rx_frame.an_frame_ctl, 572 (char *)ih, ieee80211_header_len); 573 |
572 error = an_read_data(sc, id, sizeof(rx_frame) + | 574 error = an_read_data(sc, id, sizeof(rx_frame) + |
573 rx_frame.an_gaplen, 574 (caddr_t)ih +ieee80211_header_len, 575 rx_frame.an_rx_payload_len); 576 } 577 /* dump raw 802.11 packet to bpf and skip ip stack */ 578 if (ifp->if_bpf != NULL) { 579 bpf_tap(ifp, bpf_buf, len); 580 } --- 59 unchanged lines hidden (view full) --- 640 m_adj(m, sizeof(struct ether_header)); 641#ifdef ANCACHE 642 an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength); 643#endif 644 ether_input(ifp, eh, m); 645 } 646} 647 | 575 rx_frame.an_gaplen, 576 (caddr_t)ih +ieee80211_header_len, 577 rx_frame.an_rx_payload_len); 578 } 579 /* dump raw 802.11 packet to bpf and skip ip stack */ 580 if (ifp->if_bpf != NULL) { 581 bpf_tap(ifp, bpf_buf, len); 582 } --- 59 unchanged lines hidden (view full) --- 642 m_adj(m, sizeof(struct ether_header)); 643#ifdef ANCACHE 644 an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength); 645#endif 646 ether_input(ifp, eh, m); 647 } 648} 649 |
648static void an_txeof(sc, status) | 650static void 651an_txeof(sc, status) |
649 struct an_softc *sc; 650 int status; 651{ 652 struct ifnet *ifp; 653 int id, i; 654 655 ifp = &sc->arpcom.ac_if; 656 --- 20 unchanged lines hidden (view full) --- 677} 678 679/* 680 * We abuse the stats updater to check the current NIC status. This 681 * is important because we don't want to allow transmissions until 682 * the NIC has synchronized to the current cell (either as the master 683 * in an ad-hoc group, or as a station connected to an access point). 684 */ | 652 struct an_softc *sc; 653 int status; 654{ 655 struct ifnet *ifp; 656 int id, i; 657 658 ifp = &sc->arpcom.ac_if; 659 --- 20 unchanged lines hidden (view full) --- 680} 681 682/* 683 * We abuse the stats updater to check the current NIC status. This 684 * is important because we don't want to allow transmissions until 685 * the NIC has synchronized to the current cell (either as the master 686 * in an ad-hoc group, or as a station connected to an access point). 687 */ |
685void an_stats_update(xsc) | 688void 689an_stats_update(xsc) |
686 void *xsc; 687{ 688 struct an_softc *sc; 689 struct ifnet *ifp; 690 691 sc = xsc; 692 AN_LOCK(sc); 693 ifp = &sc->arpcom.ac_if; --- 19 unchanged lines hidden (view full) --- 713 an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len); 714 715 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 716 AN_UNLOCK(sc); 717 718 return; 719} 720 | 690 void *xsc; 691{ 692 struct an_softc *sc; 693 struct ifnet *ifp; 694 695 sc = xsc; 696 AN_LOCK(sc); 697 ifp = &sc->arpcom.ac_if; --- 19 unchanged lines hidden (view full) --- 717 an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len); 718 719 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 720 AN_UNLOCK(sc); 721 722 return; 723} 724 |
721void an_intr(xsc) | 725void 726an_intr(xsc) |
722 void *xsc; 723{ 724 struct an_softc *sc; 725 struct ifnet *ifp; 726 u_int16_t status; 727 728 sc = (struct an_softc*)xsc; 729 --- 48 unchanged lines hidden (view full) --- 778 if ((ifp->if_flags & IFF_UP) && (ifp->if_snd.ifq_head != NULL)) 779 an_start(ifp); 780 781 AN_UNLOCK(sc); 782 783 return; 784} 785 | 727 void *xsc; 728{ 729 struct an_softc *sc; 730 struct ifnet *ifp; 731 u_int16_t status; 732 733 sc = (struct an_softc*)xsc; 734 --- 48 unchanged lines hidden (view full) --- 783 if ((ifp->if_flags & IFF_UP) && (ifp->if_snd.ifq_head != NULL)) 784 an_start(ifp); 785 786 AN_UNLOCK(sc); 787 788 return; 789} 790 |
786static int an_cmd(sc, cmd, val) | 791static int 792an_cmd(sc, cmd, val) |
787 struct an_softc *sc; 788 int cmd; 789 int val; 790{ 791 int i, s = 0; 792 793 CSR_WRITE_2(sc, AN_PARAM0, val); 794 CSR_WRITE_2(sc, AN_PARAM1, 0); --- 30 unchanged lines hidden (view full) --- 825 return(0); 826} 827 828/* 829 * This reset sequence may look a little strange, but this is the 830 * most reliable method I've found to really kick the NIC in the 831 * head and force it to reboot correctly. 832 */ | 793 struct an_softc *sc; 794 int cmd; 795 int val; 796{ 797 int i, s = 0; 798 799 CSR_WRITE_2(sc, AN_PARAM0, val); 800 CSR_WRITE_2(sc, AN_PARAM1, 0); --- 30 unchanged lines hidden (view full) --- 831 return(0); 832} 833 834/* 835 * This reset sequence may look a little strange, but this is the 836 * most reliable method I've found to really kick the NIC in the 837 * head and force it to reboot correctly. 838 */ |
833static void an_reset(sc) | 839static void 840an_reset(sc) |
834 struct an_softc *sc; 835{ 836 if (sc->an_gone) 837 return; | 841 struct an_softc *sc; 842{ 843 if (sc->an_gone) 844 return; |
838 | 845 |
839 an_cmd(sc, AN_CMD_ENABLE, 0); 840 an_cmd(sc, AN_CMD_FW_RESTART, 0); 841 an_cmd(sc, AN_CMD_NOOP2, 0); 842 843 if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT) 844 printf("an%d: reset failed\n", sc->an_unit); 845 846 an_cmd(sc, AN_CMD_DISABLE, 0); 847 848 return; 849} 850 851/* 852 * Read an LTV record from the NIC. 853 */ | 846 an_cmd(sc, AN_CMD_ENABLE, 0); 847 an_cmd(sc, AN_CMD_FW_RESTART, 0); 848 an_cmd(sc, AN_CMD_NOOP2, 0); 849 850 if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT) 851 printf("an%d: reset failed\n", sc->an_unit); 852 853 an_cmd(sc, AN_CMD_DISABLE, 0); 854 855 return; 856} 857 858/* 859 * Read an LTV record from the NIC. 860 */ |
854static int an_read_record(sc, ltv) | 861static int 862an_read_record(sc, ltv) |
855 struct an_softc *sc; 856 struct an_ltv_gen *ltv; 857{ 858 u_int16_t *ptr; 859 u_int8_t *ptr2; 860 int i, len; 861 862 if (ltv->an_len < 4 || ltv->an_type == 0) --- 40 unchanged lines hidden (view full) --- 903 an_dump_record(sc, ltv, "Read"); 904 905 return(0); 906} 907 908/* 909 * Same as read, except we inject data instead of reading it. 910 */ | 863 struct an_softc *sc; 864 struct an_ltv_gen *ltv; 865{ 866 u_int16_t *ptr; 867 u_int8_t *ptr2; 868 int i, len; 869 870 if (ltv->an_len < 4 || ltv->an_type == 0) --- 40 unchanged lines hidden (view full) --- 911 an_dump_record(sc, ltv, "Read"); 912 913 return(0); 914} 915 916/* 917 * Same as read, except we inject data instead of reading it. 918 */ |
911static int an_write_record(sc, ltv) | 919static int 920an_write_record(sc, ltv) |
912 struct an_softc *sc; 913 struct an_ltv_gen *ltv; 914{ 915 u_int16_t *ptr; 916 u_int8_t *ptr2; 917 int i, len; 918 919 if (an_dump) 920 an_dump_record(sc, ltv, "Write"); 921 922 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) 923 return(EIO); | 921 struct an_softc *sc; 922 struct an_ltv_gen *ltv; 923{ 924 u_int16_t *ptr; 925 u_int8_t *ptr2; 926 int i, len; 927 928 if (an_dump) 929 an_dump_record(sc, ltv, "Write"); 930 931 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) 932 return(EIO); |
924 | 933 |
925 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) 926 return(EIO); 927 928 /* 929 * Length includes type but not length. 930 */ 931 len = ltv->an_len - 2; 932 CSR_WRITE_2(sc, AN_DATA1, len); | 934 if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) 935 return(EIO); 936 937 /* 938 * Length includes type but not length. 939 */ 940 len = ltv->an_len - 2; 941 CSR_WRITE_2(sc, AN_DATA1, len); |
933 | 942 |
934 len -= 2; /* skip the type */ 935 ptr = <v->an_val; 936 for (i = len; i > 1; i -= 2) 937 CSR_WRITE_2(sc, AN_DATA1, *ptr++); 938 if (i) { 939 ptr2 = (u_int8_t *)ptr; 940 CSR_WRITE_1(sc, AN_DATA0, *ptr2); 941 } 942 943 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type)) 944 return(EIO); 945 946 return(0); 947} 948 | 943 len -= 2; /* skip the type */ 944 ptr = <v->an_val; 945 for (i = len; i > 1; i -= 2) 946 CSR_WRITE_2(sc, AN_DATA1, *ptr++); 947 if (i) { 948 ptr2 = (u_int8_t *)ptr; 949 CSR_WRITE_1(sc, AN_DATA0, *ptr2); 950 } 951 952 if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type)) 953 return(EIO); 954 955 return(0); 956} 957 |
949static void an_dump_record(sc, ltv, string) | 958static void 959an_dump_record(sc, ltv, string) |
950 struct an_softc *sc; 951 struct an_ltv_gen *ltv; 952 char *string; 953{ 954 u_int8_t *ptr2; 955 int len; 956 int i; 957 int count = 0; 958 char buf[17], temp; 959 960 len = ltv->an_len - 4; | 960 struct an_softc *sc; 961 struct an_ltv_gen *ltv; 962 char *string; 963{ 964 u_int8_t *ptr2; 965 int len; 966 int i; 967 int count = 0; 968 char buf[17], temp; 969 970 len = ltv->an_len - 4; |
961 printf("an%d: RID %4x, Length %4d, Mode %s\n", | 971 printf("an%d: RID %4x, Length %4d, Mode %s\n", |
962 sc->an_unit, ltv->an_type, ltv->an_len - 4, string); 963 964 if (an_dump == 1 || (an_dump == ltv->an_type)) { 965 printf("an%d:\t", sc->an_unit); 966 bzero(buf,sizeof(buf)); 967 968 ptr2 = (u_int8_t *)<v->an_val; 969 for (i = len; i > 0; i--) { --- 15 unchanged lines hidden (view full) --- 985 } 986 for (; count != 16; count++) { 987 printf(" "); 988 } 989 printf(" %s\n",buf); 990 } 991} 992 | 972 sc->an_unit, ltv->an_type, ltv->an_len - 4, string); 973 974 if (an_dump == 1 || (an_dump == ltv->an_type)) { 975 printf("an%d:\t", sc->an_unit); 976 bzero(buf,sizeof(buf)); 977 978 ptr2 = (u_int8_t *)<v->an_val; 979 for (i = len; i > 0; i--) { --- 15 unchanged lines hidden (view full) --- 995 } 996 for (; count != 16; count++) { 997 printf(" "); 998 } 999 printf(" %s\n",buf); 1000 } 1001} 1002 |
993static int an_seek(sc, id, off, chan) | 1003static int 1004an_seek(sc, id, off, chan) |
994 struct an_softc *sc; 995 int id, off, chan; 996{ 997 int i; 998 int selreg, offreg; 999 1000 switch (chan) { 1001 case AN_BAP0: --- 18 unchanged lines hidden (view full) --- 1020 } 1021 1022 if (i == AN_TIMEOUT) 1023 return(ETIMEDOUT); 1024 1025 return(0); 1026} 1027 | 1005 struct an_softc *sc; 1006 int id, off, chan; 1007{ 1008 int i; 1009 int selreg, offreg; 1010 1011 switch (chan) { 1012 case AN_BAP0: --- 18 unchanged lines hidden (view full) --- 1031 } 1032 1033 if (i == AN_TIMEOUT) 1034 return(ETIMEDOUT); 1035 1036 return(0); 1037} 1038 |
1028static int an_read_data(sc, id, off, buf, len) | 1039static int 1040an_read_data(sc, id, off, buf, len) |
1029 struct an_softc *sc; 1030 int id, off; 1031 caddr_t buf; 1032 int len; 1033{ 1034 int i; 1035 u_int16_t *ptr; 1036 u_int8_t *ptr2; --- 9 unchanged lines hidden (view full) --- 1046 if (i) { 1047 ptr2 = (u_int8_t *)ptr; 1048 *ptr2 = CSR_READ_1(sc, AN_DATA1); 1049 } 1050 1051 return(0); 1052} 1053 | 1041 struct an_softc *sc; 1042 int id, off; 1043 caddr_t buf; 1044 int len; 1045{ 1046 int i; 1047 u_int16_t *ptr; 1048 u_int8_t *ptr2; --- 9 unchanged lines hidden (view full) --- 1058 if (i) { 1059 ptr2 = (u_int8_t *)ptr; 1060 *ptr2 = CSR_READ_1(sc, AN_DATA1); 1061 } 1062 1063 return(0); 1064} 1065 |
1054static int an_write_data(sc, id, off, buf, len) | 1066static int 1067an_write_data(sc, id, off, buf, len) |
1055 struct an_softc *sc; 1056 int id, off; 1057 caddr_t buf; 1058 int len; 1059{ 1060 int i; 1061 u_int16_t *ptr; 1062 u_int8_t *ptr2; --- 13 unchanged lines hidden (view full) --- 1076 1077 return(0); 1078} 1079 1080/* 1081 * Allocate a region of memory inside the NIC and zero 1082 * it out. 1083 */ | 1068 struct an_softc *sc; 1069 int id, off; 1070 caddr_t buf; 1071 int len; 1072{ 1073 int i; 1074 u_int16_t *ptr; 1075 u_int8_t *ptr2; --- 13 unchanged lines hidden (view full) --- 1089 1090 return(0); 1091} 1092 1093/* 1094 * Allocate a region of memory inside the NIC and zero 1095 * it out. 1096 */ |
1084static int an_alloc_nicmem(sc, len, id) | 1097static int 1098an_alloc_nicmem(sc, len, id) |
1085 struct an_softc *sc; 1086 int len; 1087 int *id; 1088{ 1089 int i; 1090 1091 if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) { 1092 printf("an%d: failed to allocate %d bytes on NIC\n", --- 16 unchanged lines hidden (view full) --- 1109 return(EIO); 1110 1111 for (i = 0; i < len / 2; i++) 1112 CSR_WRITE_2(sc, AN_DATA0, 0); 1113 1114 return(0); 1115} 1116 | 1099 struct an_softc *sc; 1100 int len; 1101 int *id; 1102{ 1103 int i; 1104 1105 if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) { 1106 printf("an%d: failed to allocate %d bytes on NIC\n", --- 16 unchanged lines hidden (view full) --- 1123 return(EIO); 1124 1125 for (i = 0; i < len / 2; i++) 1126 CSR_WRITE_2(sc, AN_DATA0, 0); 1127 1128 return(0); 1129} 1130 |
1117static void an_setdef(sc, areq) | 1131static void 1132an_setdef(sc, areq) |
1118 struct an_softc *sc; 1119 struct an_req *areq; 1120{ 1121 struct sockaddr_dl *sdl; 1122 struct ifaddr *ifa; 1123 struct ifnet *ifp; 1124 struct an_ltv_genconfig *cfg; 1125 struct an_ltv_ssidlist *ssid; --- 28 unchanged lines hidden (view full) --- 1154 case AN_RID_TX_SPEED: 1155 sp = (struct an_ltv_gen *)areq; 1156 sc->an_tx_rate = sp->an_val; 1157 break; 1158 case AN_RID_WEP_TEMP: 1159 case AN_RID_WEP_PERM: 1160 /* Disable the MAC. */ 1161 an_cmd(sc, AN_CMD_DISABLE, 0); | 1133 struct an_softc *sc; 1134 struct an_req *areq; 1135{ 1136 struct sockaddr_dl *sdl; 1137 struct ifaddr *ifa; 1138 struct ifnet *ifp; 1139 struct an_ltv_genconfig *cfg; 1140 struct an_ltv_ssidlist *ssid; --- 28 unchanged lines hidden (view full) --- 1169 case AN_RID_TX_SPEED: 1170 sp = (struct an_ltv_gen *)areq; 1171 sc->an_tx_rate = sp->an_val; 1172 break; 1173 case AN_RID_WEP_TEMP: 1174 case AN_RID_WEP_PERM: 1175 /* Disable the MAC. */ 1176 an_cmd(sc, AN_CMD_DISABLE, 0); |
1162 | 1177 |
1163 /* Write the key */ 1164 an_write_record(sc, (struct an_ltv_gen *)areq); | 1178 /* Write the key */ 1179 an_write_record(sc, (struct an_ltv_gen *)areq); |
1165 1166 /* Turn the MAC back on. */ | 1180 1181 /* Turn the MAC back on. */ |
1167 an_cmd(sc, AN_CMD_ENABLE, 0); | 1182 an_cmd(sc, AN_CMD_ENABLE, 0); |
1168 | 1183 |
1169 break; 1170 case AN_RID_MONITOR_MODE: 1171 cfg = (struct an_ltv_genconfig *)areq; 1172 bpfdetach(ifp); 1173 if (ng_ether_detach_p != NULL) 1174 (*ng_ether_detach_p) (ifp); 1175 sc->an_monitor = cfg->an_len; 1176 | 1184 break; 1185 case AN_RID_MONITOR_MODE: 1186 cfg = (struct an_ltv_genconfig *)areq; 1187 bpfdetach(ifp); 1188 if (ng_ether_detach_p != NULL) 1189 (*ng_ether_detach_p) (ifp); 1190 sc->an_monitor = cfg->an_len; 1191 |
1177 if (sc->an_monitor & AN_MONITOR){ 1178 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER){ 1179 bpfattach(ifp, DLT_AIRONET_HEADER, | 1192 if (sc->an_monitor & AN_MONITOR) { 1193 if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) { 1194 bpfattach(ifp, DLT_AIRONET_HEADER, |
1180 sizeof(struct ether_header)); 1181 } else { | 1195 sizeof(struct ether_header)); 1196 } else { |
1182 bpfattach(ifp, DLT_IEEE802_11, | 1197 bpfattach(ifp, DLT_IEEE802_11, |
1183 sizeof(struct ether_header)); 1184 } 1185 } else { | 1198 sizeof(struct ether_header)); 1199 } 1200 } else { |
1186 bpfattach(ifp, DLT_EN10MB, | 1201 bpfattach(ifp, DLT_EN10MB, |
1187 sizeof(struct ether_header)); 1188 if (ng_ether_attach_p != NULL) 1189 (*ng_ether_attach_p) (ifp); 1190 } 1191 break; 1192 default: 1193 printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type); 1194 return; --- 7 unchanged lines hidden (view full) --- 1202 1203 return; 1204} 1205 1206/* 1207 * Derived from Linux driver to enable promiscious mode. 1208 */ 1209 | 1202 sizeof(struct ether_header)); 1203 if (ng_ether_attach_p != NULL) 1204 (*ng_ether_attach_p) (ifp); 1205 } 1206 break; 1207 default: 1208 printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type); 1209 return; --- 7 unchanged lines hidden (view full) --- 1217 1218 return; 1219} 1220 1221/* 1222 * Derived from Linux driver to enable promiscious mode. 1223 */ 1224 |
1210static void an_promisc(sc, promisc) | 1225static void 1226an_promisc(sc, promisc) |
1211 struct an_softc *sc; 1212 int promisc; 1213{ | 1227 struct an_softc *sc; 1228 int promisc; 1229{ |
1214 if(sc->an_was_monitor) | 1230 if (sc->an_was_monitor) |
1215 an_reset(sc); | 1231 an_reset(sc); |
1216 if (sc->an_monitor ||sc->an_was_monitor ) | 1232 if (sc->an_monitor || sc->an_was_monitor) |
1217 an_init(sc); 1218 1219 sc->an_was_monitor = sc->an_monitor; 1220 an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0); | 1233 an_init(sc); 1234 1235 sc->an_was_monitor = sc->an_monitor; 1236 an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0); |
1221 | 1237 |
1222 return; 1223} 1224 | 1238 return; 1239} 1240 |
1225static int an_ioctl(ifp, command, data) | 1241static int 1242an_ioctl(ifp, command, data) |
1226 struct ifnet *ifp; 1227 u_long command; 1228 caddr_t data; 1229{ 1230 int error = 0; 1231 int len; 1232 int i; 1233 struct an_softc *sc; --- 18 unchanged lines hidden (view full) --- 1252 status = (struct an_ltv_status *)&areq; 1253 ssids = (struct an_ltv_ssidlist *)&areq; 1254 1255 if (sc->an_gone) { 1256 error = ENODEV; 1257 goto out; 1258 } 1259 | 1243 struct ifnet *ifp; 1244 u_long command; 1245 caddr_t data; 1246{ 1247 int error = 0; 1248 int len; 1249 int i; 1250 struct an_softc *sc; --- 18 unchanged lines hidden (view full) --- 1269 status = (struct an_ltv_status *)&areq; 1270 ssids = (struct an_ltv_ssidlist *)&areq; 1271 1272 if (sc->an_gone) { 1273 error = ENODEV; 1274 goto out; 1275 } 1276 |
1260 switch(command) { | 1277 switch (command) { |
1261 case SIOCSIFADDR: 1262 case SIOCGIFADDR: 1263 case SIOCSIFMTU: 1264 error = ether_ioctl(ifp, command, data); 1265 break; 1266 case SIOCSIFFLAGS: 1267 if (ifp->if_flags & IFF_UP) { 1268 if (ifp->if_flags & IFF_RUNNING && --- 53 unchanged lines hidden (view full) --- 1322 goto out; 1323 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1324 if (error != 0) 1325 break; 1326 an_setdef(sc, &areq); 1327 break; 1328 case SIOCG80211: 1329 areq.an_len = sizeof(areq); | 1278 case SIOCSIFADDR: 1279 case SIOCGIFADDR: 1280 case SIOCSIFMTU: 1281 error = ether_ioctl(ifp, command, data); 1282 break; 1283 case SIOCSIFFLAGS: 1284 if (ifp->if_flags & IFF_UP) { 1285 if (ifp->if_flags & IFF_RUNNING && --- 53 unchanged lines hidden (view full) --- 1339 goto out; 1340 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1341 if (error != 0) 1342 break; 1343 an_setdef(sc, &areq); 1344 break; 1345 case SIOCG80211: 1346 areq.an_len = sizeof(areq); |
1330 switch(ireq->i_type) { | 1347 switch (ireq->i_type) { |
1331 case IEEE80211_IOC_SSID: 1332 if (ireq->i_val == -1) { 1333 areq.an_type = AN_RID_STATUS; 1334 if (an_read_record(sc, 1335 (struct an_ltv_gen *)&areq)) { 1336 error = EINVAL; 1337 break; 1338 } --- 44 unchanged lines hidden (view full) --- 1383 break; 1384 } 1385 if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) { 1386 if (config->an_authtype & 1387 AN_AUTHTYPE_ALLOW_UNENCRYPTED) 1388 ireq->i_val = IEEE80211_WEP_MIXED; 1389 else 1390 ireq->i_val = IEEE80211_WEP_ON; | 1348 case IEEE80211_IOC_SSID: 1349 if (ireq->i_val == -1) { 1350 areq.an_type = AN_RID_STATUS; 1351 if (an_read_record(sc, 1352 (struct an_ltv_gen *)&areq)) { 1353 error = EINVAL; 1354 break; 1355 } --- 44 unchanged lines hidden (view full) --- 1400 break; 1401 } 1402 if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) { 1403 if (config->an_authtype & 1404 AN_AUTHTYPE_ALLOW_UNENCRYPTED) 1405 ireq->i_val = IEEE80211_WEP_MIXED; 1406 else 1407 ireq->i_val = IEEE80211_WEP_ON; |
1391 | |
1392 } else { 1393 ireq->i_val = IEEE80211_WEP_OFF; 1394 } 1395 break; 1396 case IEEE80211_IOC_WEPKEY: 1397 /* 1398 * XXX: I'm not entierly convinced this is 1399 * correct, but it's what is implemented in --- 128 unchanged lines hidden (view full) --- 1528 areq.an_type = AN_RID_ACTUALCFG; 1529 if (an_read_record(sc, 1530 (struct an_ltv_gen *)&areq)) { 1531 error = EINVAL; 1532 break; 1533 } 1534 ireq->i_val = config->an_listen_interval; 1535 break; | 1408 } else { 1409 ireq->i_val = IEEE80211_WEP_OFF; 1410 } 1411 break; 1412 case IEEE80211_IOC_WEPKEY: 1413 /* 1414 * XXX: I'm not entierly convinced this is 1415 * correct, but it's what is implemented in --- 128 unchanged lines hidden (view full) --- 1544 areq.an_type = AN_RID_ACTUALCFG; 1545 if (an_read_record(sc, 1546 (struct an_ltv_gen *)&areq)) { 1547 error = EINVAL; 1548 break; 1549 } 1550 ireq->i_val = config->an_listen_interval; 1551 break; |
1536 } | 1552 } |
1537 break; 1538 case SIOCS80211: 1539 if ((error = suser(p))) 1540 goto out; 1541 areq.an_len = sizeof(areq); 1542 /* 1543 * We need a config structure for everything but the WEP 1544 * key management and SSIDs so we get it now so avoid --- 4 unchanged lines hidden (view full) --- 1549 ireq->i_type != IEEE80211_IOC_WEPTXKEY) { 1550 areq.an_type = AN_RID_GENCONFIG; 1551 if (an_read_record(sc, 1552 (struct an_ltv_gen *)&areq)) { 1553 error = EINVAL; 1554 break; 1555 } 1556 } | 1553 break; 1554 case SIOCS80211: 1555 if ((error = suser(p))) 1556 goto out; 1557 areq.an_len = sizeof(areq); 1558 /* 1559 * We need a config structure for everything but the WEP 1560 * key management and SSIDs so we get it now so avoid --- 4 unchanged lines hidden (view full) --- 1565 ireq->i_type != IEEE80211_IOC_WEPTXKEY) { 1566 areq.an_type = AN_RID_GENCONFIG; 1567 if (an_read_record(sc, 1568 (struct an_ltv_gen *)&areq)) { 1569 error = EINVAL; 1570 break; 1571 } 1572 } |
1557 switch(ireq->i_type) { | 1573 switch (ireq->i_type) { |
1558 case IEEE80211_IOC_SSID: 1559 areq.an_type = AN_RID_SSIDLIST; 1560 if (an_read_record(sc, 1561 (struct an_ltv_gen *)&areq)) { 1562 error = EINVAL; 1563 break; 1564 } 1565 if (ireq->i_len > IEEE80211_NWID_LEN) { --- 146 unchanged lines hidden (view full) --- 1712 break; 1713 } 1714out: 1715 AN_UNLOCK(sc); 1716 1717 return(error != 0); 1718} 1719 | 1574 case IEEE80211_IOC_SSID: 1575 areq.an_type = AN_RID_SSIDLIST; 1576 if (an_read_record(sc, 1577 (struct an_ltv_gen *)&areq)) { 1578 error = EINVAL; 1579 break; 1580 } 1581 if (ireq->i_len > IEEE80211_NWID_LEN) { --- 146 unchanged lines hidden (view full) --- 1728 break; 1729 } 1730out: 1731 AN_UNLOCK(sc); 1732 1733 return(error != 0); 1734} 1735 |
1720static int an_init_tx_ring(sc) | 1736static int 1737an_init_tx_ring(sc) |
1721 struct an_softc *sc; 1722{ 1723 int i; 1724 int id; 1725 1726 if (sc->an_gone) 1727 return (0); 1728 --- 6 unchanged lines hidden (view full) --- 1735 } 1736 1737 sc->an_rdata.an_tx_prod = 0; 1738 sc->an_rdata.an_tx_cons = 0; 1739 1740 return(0); 1741} 1742 | 1738 struct an_softc *sc; 1739{ 1740 int i; 1741 int id; 1742 1743 if (sc->an_gone) 1744 return (0); 1745 --- 6 unchanged lines hidden (view full) --- 1752 } 1753 1754 sc->an_rdata.an_tx_prod = 0; 1755 sc->an_rdata.an_tx_cons = 0; 1756 1757 return(0); 1758} 1759 |
1743static void an_init(xsc) | 1760static void 1761an_init(xsc) |
1744 void *xsc; 1745{ 1746 struct an_softc *sc = xsc; 1747 struct ifnet *ifp = &sc->arpcom.ac_if; 1748 1749 AN_LOCK(sc); 1750 1751 if (sc->an_gone) { --- 87 unchanged lines hidden (view full) --- 1839 ifp->if_flags &= ~IFF_OACTIVE; 1840 1841 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 1842 AN_UNLOCK(sc); 1843 1844 return; 1845} 1846 | 1762 void *xsc; 1763{ 1764 struct an_softc *sc = xsc; 1765 struct ifnet *ifp = &sc->arpcom.ac_if; 1766 1767 AN_LOCK(sc); 1768 1769 if (sc->an_gone) { --- 87 unchanged lines hidden (view full) --- 1857 ifp->if_flags &= ~IFF_OACTIVE; 1858 1859 sc->an_stat_ch = timeout(an_stats_update, sc, hz); 1860 AN_UNLOCK(sc); 1861 1862 return; 1863} 1864 |
1847static void an_start(ifp) | 1865static void 1866an_start(ifp) |
1848 struct ifnet *ifp; 1849{ 1850 struct an_softc *sc; 1851 struct mbuf *m0 = NULL; 1852 struct an_txframe_802_3 tx_frame_802_3; 1853 struct ether_header *eh; 1854 int id; 1855 int idx; --- 6 unchanged lines hidden (view full) --- 1862 1863 if (ifp->if_flags & IFF_OACTIVE) 1864 return; 1865 1866 if (!sc->an_associated) 1867 return; 1868 1869 if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { | 1867 struct ifnet *ifp; 1868{ 1869 struct an_softc *sc; 1870 struct mbuf *m0 = NULL; 1871 struct an_txframe_802_3 tx_frame_802_3; 1872 struct ether_header *eh; 1873 int id; 1874 int idx; --- 6 unchanged lines hidden (view full) --- 1881 1882 if (ifp->if_flags & IFF_OACTIVE) 1883 return; 1884 1885 if (!sc->an_associated) 1886 return; 1887 1888 if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) { |
1870 for(;;) { | 1889 for (;;) { |
1871 IF_DEQUEUE(&ifp->if_snd, m0); 1872 if (m0 == NULL) 1873 break; 1874 } 1875 return; 1876 } 1877 1878 idx = sc->an_rdata.an_tx_prod; 1879 bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3)); 1880 | 1890 IF_DEQUEUE(&ifp->if_snd, m0); 1891 if (m0 == NULL) 1892 break; 1893 } 1894 return; 1895 } 1896 1897 idx = sc->an_rdata.an_tx_prod; 1898 bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3)); 1899 |
1881 while(sc->an_rdata.an_tx_ring[idx] == 0) { | 1900 while (sc->an_rdata.an_tx_ring[idx] == 0) { |
1882 IF_DEQUEUE(&ifp->if_snd, m0); 1883 if (m0 == NULL) 1884 break; 1885 1886 id = sc->an_rdata.an_tx_fids[idx]; 1887 eh = mtod(m0, struct ether_header *); 1888 1889 bcopy((char *)&eh->ether_dhost, 1890 (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN); 1891 bcopy((char *)&eh->ether_shost, 1892 (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN); | 1901 IF_DEQUEUE(&ifp->if_snd, m0); 1902 if (m0 == NULL) 1903 break; 1904 1905 id = sc->an_rdata.an_tx_fids[idx]; 1906 eh = mtod(m0, struct ether_header *); 1907 1908 bcopy((char *)&eh->ether_dhost, 1909 (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN); 1910 bcopy((char *)&eh->ether_shost, 1911 (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN); |
1893 | 1912 |
1894 tx_frame_802_3.an_tx_802_3_payload_len = 1895 m0->m_pkthdr.len - 12; /* minus src/dest mac & type */ 1896 1897 m_copydata(m0, sizeof(struct ether_header) - 2 , 1898 tx_frame_802_3.an_tx_802_3_payload_len, 1899 (caddr_t)&sc->an_txbuf); 1900 1901 txcontrol = AN_TXCTL_8023; 1902 /* write the txcontrol only */ 1903 an_write_data(sc, id, 0x08, (caddr_t)&txcontrol, 1904 sizeof(txcontrol)); | 1913 tx_frame_802_3.an_tx_802_3_payload_len = 1914 m0->m_pkthdr.len - 12; /* minus src/dest mac & type */ 1915 1916 m_copydata(m0, sizeof(struct ether_header) - 2 , 1917 tx_frame_802_3.an_tx_802_3_payload_len, 1918 (caddr_t)&sc->an_txbuf); 1919 1920 txcontrol = AN_TXCTL_8023; 1921 /* write the txcontrol only */ 1922 an_write_data(sc, id, 0x08, (caddr_t)&txcontrol, 1923 sizeof(txcontrol)); |
1905 | 1924 |
1906 /* 802_3 header */ 1907 an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3, 1908 sizeof(struct an_txframe_802_3)); | 1925 /* 802_3 header */ 1926 an_write_data(sc, id, 0x34, (caddr_t)&tx_frame_802_3, 1927 sizeof(struct an_txframe_802_3)); |
1909 | 1928 |
1910 /* in mbuf header type is just before payload */ 1911 an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf, 1912 tx_frame_802_3.an_tx_802_3_payload_len); | 1929 /* in mbuf header type is just before payload */ 1930 an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf, 1931 tx_frame_802_3.an_tx_802_3_payload_len); |
1913 | 1932 |
1914 /* 1915 * If there's a BPF listner, bounce a copy of 1916 * this frame to him. 1917 */ 1918 if (ifp->if_bpf) 1919 bpf_mtap(ifp, m0); 1920 1921 m_freem(m0); --- 14 unchanged lines hidden (view full) --- 1936 /* 1937 * Set a timeout in case the chip goes out to lunch. 1938 */ 1939 ifp->if_timer = 5; 1940 1941 return; 1942} 1943 | 1933 /* 1934 * If there's a BPF listner, bounce a copy of 1935 * this frame to him. 1936 */ 1937 if (ifp->if_bpf) 1938 bpf_mtap(ifp, m0); 1939 1940 m_freem(m0); --- 14 unchanged lines hidden (view full) --- 1955 /* 1956 * Set a timeout in case the chip goes out to lunch. 1957 */ 1958 ifp->if_timer = 5; 1959 1960 return; 1961} 1962 |
1944void an_stop(sc) | 1963void 1964an_stop(sc) |
1945 struct an_softc *sc; 1946{ 1947 struct ifnet *ifp; 1948 int i; 1949 1950 AN_LOCK(sc); 1951 1952 if (sc->an_gone) { --- 14 unchanged lines hidden (view full) --- 1967 1968 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 1969 1970 AN_UNLOCK(sc); 1971 1972 return; 1973} 1974 | 1965 struct an_softc *sc; 1966{ 1967 struct ifnet *ifp; 1968 int i; 1969 1970 AN_LOCK(sc); 1971 1972 if (sc->an_gone) { --- 14 unchanged lines hidden (view full) --- 1987 1988 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 1989 1990 AN_UNLOCK(sc); 1991 1992 return; 1993} 1994 |
1975static void an_watchdog(ifp) | 1995static void 1996an_watchdog(ifp) |
1976 struct ifnet *ifp; 1977{ 1978 struct an_softc *sc; 1979 1980 sc = ifp->if_softc; 1981 AN_LOCK(sc); 1982 1983 if (sc->an_gone) { --- 7 unchanged lines hidden (view full) --- 1991 an_init(sc); 1992 1993 ifp->if_oerrors++; 1994 AN_UNLOCK(sc); 1995 1996 return; 1997} 1998 | 1997 struct ifnet *ifp; 1998{ 1999 struct an_softc *sc; 2000 2001 sc = ifp->if_softc; 2002 AN_LOCK(sc); 2003 2004 if (sc->an_gone) { --- 7 unchanged lines hidden (view full) --- 2012 an_init(sc); 2013 2014 ifp->if_oerrors++; 2015 AN_UNLOCK(sc); 2016 2017 return; 2018} 2019 |
1999void an_shutdown(dev) | 2020void 2021an_shutdown(dev) |
2000 device_t dev; 2001{ 2002 struct an_softc *sc; 2003 2004 sc = device_get_softc(dev); 2005 an_stop(sc); 2006 2007 return; --- 12 unchanged lines hidden (view full) --- 2020 * ignore unicast packets and only cache signal strength 2021 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 2022 * beacons and not unicast traffic. 2023 * 2024 * The cache stores (MAC src(index), IP src (major clue), signal, 2025 * quality, noise) 2026 * 2027 * No apologies for storing IP src here. It's easy and saves much | 2022 device_t dev; 2023{ 2024 struct an_softc *sc; 2025 2026 sc = device_get_softc(dev); 2027 an_stop(sc); 2028 2029 return; --- 12 unchanged lines hidden (view full) --- 2042 * ignore unicast packets and only cache signal strength 2043 * for multicast/broadcast packets (beacons); e.g., Mobile-IP 2044 * beacons and not unicast traffic. 2045 * 2046 * The cache stores (MAC src(index), IP src (major clue), signal, 2047 * quality, noise) 2048 * 2049 * No apologies for storing IP src here. It's easy and saves much |
2028 * trouble elsewhere. The cache is assumed to be INET dependent, | 2050 * trouble elsewhere. The cache is assumed to be INET dependent, |
2029 * although it need not be. 2030 * 2031 * Note: the Aironet only has a single byte of signal strength value 2032 * in the rx frame header, and it's not scaled to anything sensible. 2033 * This is kind of lame, but it's all we've got. 2034 */ 2035 2036#ifdef documentation --- 6 unchanged lines hidden (view full) --- 2043#endif 2044 2045/* control variables for cache filtering. Basic idea is 2046 * to reduce cost (e.g., to only Mobile-IP agent beacons 2047 * which are broadcast or multicast). Still you might 2048 * want to measure signal strength anth unicast ping packets 2049 * on a pt. to pt. ant. setup. 2050 */ | 2051 * although it need not be. 2052 * 2053 * Note: the Aironet only has a single byte of signal strength value 2054 * in the rx frame header, and it's not scaled to anything sensible. 2055 * This is kind of lame, but it's all we've got. 2056 */ 2057 2058#ifdef documentation --- 6 unchanged lines hidden (view full) --- 2065#endif 2066 2067/* control variables for cache filtering. Basic idea is 2068 * to reduce cost (e.g., to only Mobile-IP agent beacons 2069 * which are broadcast or multicast). Still you might 2070 * want to measure signal strength anth unicast ping packets 2071 * on a pt. to pt. ant. setup. 2072 */ |
2051/* set true if you want to limit cache items to broadcast/mcast | 2073/* set true if you want to limit cache items to broadcast/mcast |
2052 * only packets (not unicast). Useful for mobile-ip beacons which 2053 * are broadcast/multicast at network layer. Default is all packets 2054 * so ping/unicast anll work say anth pt. to pt. antennae setup. 2055 */ 2056static int an_cache_mcastonly = 0; | 2074 * only packets (not unicast). Useful for mobile-ip beacons which 2075 * are broadcast/multicast at network layer. Default is all packets 2076 * so ping/unicast anll work say anth pt. to pt. antennae setup. 2077 */ 2078static int an_cache_mcastonly = 0; |
2057SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW, | 2079SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW, |
2058 &an_cache_mcastonly, 0, ""); 2059 2060/* set true if you want to limit cache items to IP packets only 2061*/ 2062static int an_cache_iponly = 1; | 2080 &an_cache_mcastonly, 0, ""); 2081 2082/* set true if you want to limit cache items to IP packets only 2083*/ 2084static int an_cache_iponly = 1; |
2063SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW, | 2085SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW, |
2064 &an_cache_iponly, 0, ""); 2065 2066/* 2067 * an_cache_store, per rx packet store signal 2068 * strength in MAC (src) indexed cache. 2069 */ | 2086 &an_cache_iponly, 0, ""); 2087 2088/* 2089 * an_cache_store, per rx packet store signal 2090 * strength in MAC (src) indexed cache. 2091 */ |
2070static 2071void an_cache_store (sc, eh, m, rx_quality) | 2092static void 2093an_cache_store (sc, eh, m, rx_quality) |
2072 struct an_softc *sc; 2073 struct ether_header *eh; 2074 struct mbuf *m; 2075 unsigned short rx_quality; 2076{ | 2094 struct an_softc *sc; 2095 struct ether_header *eh; 2096 struct mbuf *m; 2097 unsigned short rx_quality; 2098{ |
2077 struct ip *ip = 0; | 2099 struct ip *ip = 0; |
2078 int i; 2079 static int cache_slot = 0; /* use this cache entry */ 2080 static int wrapindex = 0; /* next "free" cache entry */ 2081 int saanp = 0; 2082 2083 /* filters: 2084 * 1. ip only 2085 * 2. configurable filter to throw out unicast packets, 2086 * keep multicast only. 2087 */ | 2100 int i; 2101 static int cache_slot = 0; /* use this cache entry */ 2102 static int wrapindex = 0; /* next "free" cache entry */ 2103 int saanp = 0; 2104 2105 /* filters: 2106 * 1. ip only 2107 * 2. configurable filter to throw out unicast packets, 2108 * keep multicast only. 2109 */ |
2088 | 2110 |
2089 if ((ntohs(eh->ether_type) == 0x800)) { 2090 saanp = 1; 2091 } 2092 | 2111 if ((ntohs(eh->ether_type) == 0x800)) { 2112 saanp = 1; 2113 } 2114 |
2093 /* filter for ip packets only | 2115 /* filter for ip packets only |
2094 */ 2095 if ( an_cache_iponly && !saanp) { 2096 return; 2097 } 2098 2099 /* filter for broadcast/multicast only 2100 */ 2101 if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 2102 return; 2103 } 2104 2105#ifdef SIGDEBUG 2106 printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n", 2107 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 2108#endif 2109 2110 /* find the ip header. we want to store the ip_src | 2116 */ 2117 if ( an_cache_iponly && !saanp) { 2118 return; 2119 } 2120 2121 /* filter for broadcast/multicast only 2122 */ 2123 if (an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) { 2124 return; 2125 } 2126 2127#ifdef SIGDEBUG 2128 printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n", 2129 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff); 2130#endif 2131 2132 /* find the ip header. we want to store the ip_src |
2111 * address. | 2133 * address. |
2112 */ 2113 if (saanp) { 2114 ip = mtod(m, struct ip *); 2115 } | 2134 */ 2135 if (saanp) { 2136 ip = mtod(m, struct ip *); 2137 } |
2116 2117 /* do a linear search for a matching MAC address | 2138 2139 /* do a linear search for a matching MAC address |
2118 * in the cache table 2119 * . MAC address is 6 bytes, 2120 * . var w_nextitem holds total number of entries already cached 2121 */ 2122 for (i = 0; i < sc->an_nextitem; i++) { 2123 if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6 )) { 2124 /* Match!, 2125 * so we already have this entry, 2126 * update the data 2127 */ | 2140 * in the cache table 2141 * . MAC address is 6 bytes, 2142 * . var w_nextitem holds total number of entries already cached 2143 */ 2144 for (i = 0; i < sc->an_nextitem; i++) { 2145 if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6 )) { 2146 /* Match!, 2147 * so we already have this entry, 2148 * update the data 2149 */ |
2128 break; | 2150 break; |
2129 } 2130 } 2131 2132 /* did we find a matching mac address? 2133 * if yes, then overwrite a previously existing cache entry 2134 */ 2135 if (i < sc->an_nextitem ) { | 2151 } 2152 } 2153 2154 /* did we find a matching mac address? 2155 * if yes, then overwrite a previously existing cache entry 2156 */ 2157 if (i < sc->an_nextitem ) { |
2136 cache_slot = i; | 2158 cache_slot = i; |
2137 } 2138 /* else, have a new address entry,so 2139 * add this new entry, 2140 * if table full, then we need to replace LRU entry 2141 */ | 2159 } 2160 /* else, have a new address entry,so 2161 * add this new entry, 2162 * if table full, then we need to replace LRU entry 2163 */ |
2142 else { | 2164 else { |
2143 | 2165 |
2144 /* check for space in cache table | 2166 /* check for space in cache table |
2145 * note: an_nextitem also holds number of entries | 2167 * note: an_nextitem also holds number of entries |
2146 * added in the cache table | 2168 * added in the cache table |
2147 */ 2148 if ( sc->an_nextitem < MAXANCACHE ) { 2149 cache_slot = sc->an_nextitem; | 2169 */ 2170 if ( sc->an_nextitem < MAXANCACHE ) { 2171 cache_slot = sc->an_nextitem; |
2150 sc->an_nextitem++; | 2172 sc->an_nextitem++; |
2151 sc->an_sigitems = sc->an_nextitem; 2152 } 2153 /* no space found, so simply wrap anth wrap index 2154 * and "zap" the next entry 2155 */ 2156 else { 2157 if (wrapindex == MAXANCACHE) { 2158 wrapindex = 0; --- 23 unchanged lines hidden (view full) --- 2182 bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6); 2183 2184 sc->an_sigcache[cache_slot].signal = rx_quality; 2185 2186 return; 2187} 2188#endif 2189 | 2173 sc->an_sigitems = sc->an_nextitem; 2174 } 2175 /* no space found, so simply wrap anth wrap index 2176 * and "zap" the next entry 2177 */ 2178 else { 2179 if (wrapindex == MAXANCACHE) { 2180 wrapindex = 0; --- 23 unchanged lines hidden (view full) --- 2204 bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6); 2205 2206 sc->an_sigcache[cache_slot].signal = rx_quality; 2207 2208 return; 2209} 2210#endif 2211 |
2190static int an_media_change(ifp) | 2212static int 2213an_media_change(ifp) |
2191 struct ifnet *ifp; 2192{ 2193 struct an_softc *sc = ifp->if_softc; 2194 int otype = sc->an_config.an_opmode; 2195 int orate = sc->an_tx_rate; 2196 2197 if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 2198 sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC; --- 20 unchanged lines hidden (view full) --- 2219 2220 if (otype != sc->an_config.an_opmode || 2221 orate != sc->an_tx_rate) 2222 an_init(sc); 2223 2224 return(0); 2225} 2226 | 2214 struct ifnet *ifp; 2215{ 2216 struct an_softc *sc = ifp->if_softc; 2217 int otype = sc->an_config.an_opmode; 2218 int orate = sc->an_tx_rate; 2219 2220 if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 2221 sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC; --- 20 unchanged lines hidden (view full) --- 2242 2243 if (otype != sc->an_config.an_opmode || 2244 orate != sc->an_tx_rate) 2245 an_init(sc); 2246 2247 return(0); 2248} 2249 |
2227static void an_media_status(ifp, imr) | 2250static void 2251an_media_status(ifp, imr) |
2228 struct ifnet *ifp; 2229 struct ifmediareq *imr; 2230{ 2231 struct an_ltv_status status; 2232 struct an_softc *sc = ifp->if_softc; 2233 2234 status.an_len = sizeof(status); 2235 status.an_type = AN_RID_STATUS; 2236 if (an_read_record(sc, (struct an_ltv_gen *)&status)) { 2237 /* If the status read fails, just lie. */ 2238 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 2239 imr->ifm_status = IFM_AVALID|IFM_ACTIVE; 2240 } 2241 2242 if (sc->an_tx_rate == 0) { 2243 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 2244 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 2245 imr->ifm_active |= IFM_IEEE80211_ADHOC; | 2252 struct ifnet *ifp; 2253 struct ifmediareq *imr; 2254{ 2255 struct an_ltv_status status; 2256 struct an_softc *sc = ifp->if_softc; 2257 2258 status.an_len = sizeof(status); 2259 status.an_type = AN_RID_STATUS; 2260 if (an_read_record(sc, (struct an_ltv_gen *)&status)) { 2261 /* If the status read fails, just lie. */ 2262 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 2263 imr->ifm_status = IFM_AVALID|IFM_ACTIVE; 2264 } 2265 2266 if (sc->an_tx_rate == 0) { 2267 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 2268 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 2269 imr->ifm_active |= IFM_IEEE80211_ADHOC; |
2246 switch(status.an_current_tx_rate) { | 2270 switch (status.an_current_tx_rate) { |
2247 case AN_RATE_1MBPS: 2248 imr->ifm_active |= IFM_IEEE80211_DS1; 2249 break; 2250 case AN_RATE_2MBPS: 2251 imr->ifm_active |= IFM_IEEE80211_DS2; 2252 break; 2253 case AN_RATE_5_5MBPS: 2254 imr->ifm_active |= IFM_IEEE80211_DS5; --- 15 unchanged lines hidden --- | 2271 case AN_RATE_1MBPS: 2272 imr->ifm_active |= IFM_IEEE80211_DS1; 2273 break; 2274 case AN_RATE_2MBPS: 2275 imr->ifm_active |= IFM_IEEE80211_DS2; 2276 break; 2277 case AN_RATE_5_5MBPS: 2278 imr->ifm_active |= IFM_IEEE80211_DS5; --- 15 unchanged lines hidden --- |