if_ipw.c (191207) | if_ipw.c (191746) |
---|---|
1/* $FreeBSD: head/sys/dev/ipw/if_ipw.c 191207 2009-04-17 16:07:13Z thompsa $ */ | 1/* $FreeBSD: head/sys/dev/ipw/if_ipw.c 191746 2009-05-02 15:14:18Z thompsa $ */ |
2 3/*- 4 * Copyright (c) 2004-2006 5 * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. 6 * Copyright (c) 2006 Sam Leffler, Errno Consulting 7 * Copyright (c) 2007 Andrew Thompson <thompsa@FreeBSD.org> 8 * 9 * Redistribution and use in source and binary forms, with or without --- 15 unchanged lines hidden (view full) --- 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> | 2 3/*- 4 * Copyright (c) 2004-2006 5 * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. 6 * Copyright (c) 2006 Sam Leffler, Errno Consulting 7 * Copyright (c) 2007 Andrew Thompson <thompsa@FreeBSD.org> 8 * 9 * Redistribution and use in source and binary forms, with or without --- 15 unchanged lines hidden (view full) --- 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/dev/ipw/if_ipw.c 191207 2009-04-17 16:07:13Z thompsa $"); | 33__FBSDID("$FreeBSD: head/sys/dev/ipw/if_ipw.c 191746 2009-05-02 15:14:18Z thompsa $"); |
34 35/*- 36 * Intel(R) PRO/Wireless 2100 MiniPCI driver 37 * http://www.intel.com/network/connectivity/products/wireless/prowireless_mobile.htm 38 */ 39 40#include <sys/param.h> 41#include <sys/sysctl.h> --- 71 unchanged lines hidden (view full) --- 113 const uint8_t mac[IEEE80211_ADDR_LEN]); 114static void ipw_vap_delete(struct ieee80211vap *); 115static int ipw_dma_alloc(struct ipw_softc *); 116static void ipw_release(struct ipw_softc *); 117static void ipw_media_status(struct ifnet *, struct ifmediareq *); 118static int ipw_newstate(struct ieee80211vap *, enum ieee80211_state, int); 119static uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t); 120static void ipw_rx_cmd_intr(struct ipw_softc *, struct ipw_soft_buf *); | 34 35/*- 36 * Intel(R) PRO/Wireless 2100 MiniPCI driver 37 * http://www.intel.com/network/connectivity/products/wireless/prowireless_mobile.htm 38 */ 39 40#include <sys/param.h> 41#include <sys/sysctl.h> --- 71 unchanged lines hidden (view full) --- 113 const uint8_t mac[IEEE80211_ADDR_LEN]); 114static void ipw_vap_delete(struct ieee80211vap *); 115static int ipw_dma_alloc(struct ipw_softc *); 116static void ipw_release(struct ipw_softc *); 117static void ipw_media_status(struct ifnet *, struct ifmediareq *); 118static int ipw_newstate(struct ieee80211vap *, enum ieee80211_state, int); 119static uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t); 120static void ipw_rx_cmd_intr(struct ipw_softc *, struct ipw_soft_buf *); |
121static void ipw_assocsuccess(void *, int); 122static void ipw_assocfailed(void *, int); 123static void ipw_scandone(void *, int); 124static void ipw_bmiss(void *, int); | |
125static void ipw_rx_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *); 126static void ipw_rx_data_intr(struct ipw_softc *, struct ipw_status *, 127 struct ipw_soft_bd *, struct ipw_soft_buf *); 128static void ipw_rx_intr(struct ipw_softc *); 129static void ipw_release_sbd(struct ipw_softc *, struct ipw_soft_bd *); 130static void ipw_tx_intr(struct ipw_softc *); 131static void ipw_intr(void *); 132static void ipw_dma_map_addr(void *, bus_dma_segment_t *, int, int); --- 9 unchanged lines hidden (view full) --- 142static int ipw_ioctl(struct ifnet *, u_long, caddr_t); 143static void ipw_stop_master(struct ipw_softc *); 144static int ipw_enable(struct ipw_softc *); 145static int ipw_disable(struct ipw_softc *); 146static int ipw_reset(struct ipw_softc *); 147static int ipw_load_ucode(struct ipw_softc *, const char *, int); 148static int ipw_load_firmware(struct ipw_softc *, const char *, int); 149static int ipw_config(struct ipw_softc *); | 121static void ipw_rx_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *); 122static void ipw_rx_data_intr(struct ipw_softc *, struct ipw_status *, 123 struct ipw_soft_bd *, struct ipw_soft_buf *); 124static void ipw_rx_intr(struct ipw_softc *); 125static void ipw_release_sbd(struct ipw_softc *, struct ipw_soft_bd *); 126static void ipw_tx_intr(struct ipw_softc *); 127static void ipw_intr(void *); 128static void ipw_dma_map_addr(void *, bus_dma_segment_t *, int, int); --- 9 unchanged lines hidden (view full) --- 138static int ipw_ioctl(struct ifnet *, u_long, caddr_t); 139static void ipw_stop_master(struct ipw_softc *); 140static int ipw_enable(struct ipw_softc *); 141static int ipw_disable(struct ipw_softc *); 142static int ipw_reset(struct ipw_softc *); 143static int ipw_load_ucode(struct ipw_softc *, const char *, int); 144static int ipw_load_firmware(struct ipw_softc *, const char *, int); 145static int ipw_config(struct ipw_softc *); |
150static void ipw_assoc_task(void *, int); 151static void ipw_disassoc_task(void *, int); | 146static void ipw_assoc(struct ieee80211com *, struct ieee80211vap *); 147static void ipw_disassoc(struct ieee80211com *, struct ieee80211vap *); |
152static void ipw_init_task(void *, int); 153static void ipw_init(void *); 154static void ipw_init_locked(struct ipw_softc *); 155static void ipw_stop(void *); 156static void ipw_stop_locked(struct ipw_softc *); 157static int ipw_sysctl_stats(SYSCTL_HANDLER_ARGS); 158static int ipw_sysctl_radio(SYSCTL_HANDLER_ARGS); 159static uint32_t ipw_read_table1(struct ipw_softc *, uint32_t); 160static void ipw_write_table1(struct ipw_softc *, uint32_t, uint32_t); 161#if 0 162static int ipw_read_table2(struct ipw_softc *, uint32_t, void *, 163 uint32_t *); 164static void ipw_read_mem_1(struct ipw_softc *, bus_size_t, uint8_t *, 165 bus_size_t); 166#endif 167static void ipw_write_mem_1(struct ipw_softc *, bus_size_t, 168 const uint8_t *, bus_size_t); | 148static void ipw_init_task(void *, int); 149static void ipw_init(void *); 150static void ipw_init_locked(struct ipw_softc *); 151static void ipw_stop(void *); 152static void ipw_stop_locked(struct ipw_softc *); 153static int ipw_sysctl_stats(SYSCTL_HANDLER_ARGS); 154static int ipw_sysctl_radio(SYSCTL_HANDLER_ARGS); 155static uint32_t ipw_read_table1(struct ipw_softc *, uint32_t); 156static void ipw_write_table1(struct ipw_softc *, uint32_t, uint32_t); 157#if 0 158static int ipw_read_table2(struct ipw_softc *, uint32_t, void *, 159 uint32_t *); 160static void ipw_read_mem_1(struct ipw_softc *, bus_size_t, uint8_t *, 161 bus_size_t); 162#endif 163static void ipw_write_mem_1(struct ipw_softc *, bus_size_t, 164 const uint8_t *, bus_size_t); |
169static void ipw_scan_task(void *, int); | |
170static int ipw_scan(struct ipw_softc *); 171static void ipw_scan_start(struct ieee80211com *); 172static void ipw_scan_end(struct ieee80211com *); 173static void ipw_set_channel(struct ieee80211com *); 174static void ipw_scan_curchan(struct ieee80211_scan_state *, 175 unsigned long maxdwell); 176static void ipw_scan_mindwell(struct ieee80211_scan_state *); 177 --- 56 unchanged lines hidden (view full) --- 234 uint8_t macaddr[IEEE80211_ADDR_LEN]; 235 236 sc->sc_dev = dev; 237 238 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 239 MTX_DEF | MTX_RECURSE); 240 241 TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc); | 165static int ipw_scan(struct ipw_softc *); 166static void ipw_scan_start(struct ieee80211com *); 167static void ipw_scan_end(struct ieee80211com *); 168static void ipw_set_channel(struct ieee80211com *); 169static void ipw_scan_curchan(struct ieee80211_scan_state *, 170 unsigned long maxdwell); 171static void ipw_scan_mindwell(struct ieee80211_scan_state *); 172 --- 56 unchanged lines hidden (view full) --- 229 uint8_t macaddr[IEEE80211_ADDR_LEN]; 230 231 sc->sc_dev = dev; 232 233 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 234 MTX_DEF | MTX_RECURSE); 235 236 TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc); |
242 TASK_INIT(&sc->sc_scan_task, 0, ipw_scan_task, sc); 243 TASK_INIT(&sc->sc_bmiss_task, 0, ipw_bmiss, sc); | |
244 callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); 245 246 if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { 247 device_printf(dev, "chip is in D%d power mode " 248 "-- setting to D0\n", pci_get_powerstate(dev)); 249 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 250 } 251 --- 160 unchanged lines hidden (view full) --- 412 struct ieee80211com *ic = ifp->if_l2com; 413 414 ipw_stop(sc); 415 416 bpfdetach(ifp); 417 ieee80211_ifdetach(ic); 418 419 callout_drain(&sc->sc_wdtimer); | 237 callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); 238 239 if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { 240 device_printf(dev, "chip is in D%d power mode " 241 "-- setting to D0\n", pci_get_powerstate(dev)); 242 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 243 } 244 --- 160 unchanged lines hidden (view full) --- 405 struct ieee80211com *ic = ifp->if_l2com; 406 407 ipw_stop(sc); 408 409 bpfdetach(ifp); 410 ieee80211_ifdetach(ic); 411 412 callout_drain(&sc->sc_wdtimer); |
420 taskqueue_drain(taskqueue_swi, &sc->sc_init_task); 421 taskqueue_drain(taskqueue_swi, &sc->sc_scan_task); 422 taskqueue_drain(taskqueue_swi, &sc->sc_bmiss_task); | 413 ieee80211_draintask(ic, &sc->sc_init_task); |
423 424 ipw_release(sc); 425 426 bus_teardown_intr(dev, sc->irq, sc->sc_ih); 427 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); 428 429 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); 430 --- 75 unchanged lines hidden (view full) --- 506 } 507 508 ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap), 509 M_80211_VAP, M_NOWAIT | M_ZERO); 510 if (ivp == NULL) 511 return NULL; 512 vap = &ivp->vap; 513 | 414 415 ipw_release(sc); 416 417 bus_teardown_intr(dev, sc->irq, sc->sc_ih); 418 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); 419 420 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); 421 --- 75 unchanged lines hidden (view full) --- 497 } 498 499 ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap), 500 M_80211_VAP, M_NOWAIT | M_ZERO); 501 if (ivp == NULL) 502 return NULL; 503 vap = &ivp->vap; 504 |
514 TASK_INIT(&ivp->assoc_task, 0, ipw_assoc_task, vap); 515 TASK_INIT(&ivp->disassoc_task, 0, ipw_disassoc_task, vap); 516 TASK_INIT(&ivp->assoc_success_task, 0, ipw_assocsuccess, vap); 517 TASK_INIT(&ivp->assoc_failed_task, 0, ipw_assocfailed, vap); 518 TASK_INIT(&ivp->scandone_task, 0, ipw_scandone, vap); 519 | |
520 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 521 /* override with driver methods */ 522 ivp->newstate = vap->iv_newstate; 523 vap->iv_newstate = ipw_newstate; 524 525 /* complete setup */ 526 ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status); 527 ic->ic_opmode = opmode; --- 361 unchanged lines hidden (view full) --- 889 890static int 891ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 892{ 893 struct ipw_vap *ivp = IPW_VAP(vap); 894 struct ieee80211com *ic = vap->iv_ic; 895 struct ifnet *ifp = ic->ic_ifp; 896 struct ipw_softc *sc = ifp->if_softc; | 505 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 506 /* override with driver methods */ 507 ivp->newstate = vap->iv_newstate; 508 vap->iv_newstate = ipw_newstate; 509 510 /* complete setup */ 511 ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status); 512 ic->ic_opmode = opmode; --- 361 unchanged lines hidden (view full) --- 874 875static int 876ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 877{ 878 struct ipw_vap *ivp = IPW_VAP(vap); 879 struct ieee80211com *ic = vap->iv_ic; 880 struct ifnet *ifp = ic->ic_ifp; 881 struct ipw_softc *sc = ifp->if_softc; |
882 enum ieee80211_state ostate; |
|
897 898 DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, 899 ieee80211_state_name[vap->iv_state], 900 ieee80211_state_name[nstate], sc->flags)); 901 | 883 884 DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, 885 ieee80211_state_name[vap->iv_state], 886 ieee80211_state_name[nstate], sc->flags)); 887 |
888 ostate = vap->iv_state; 889 IEEE80211_UNLOCK(ic); 890 |
|
902 switch (nstate) { 903 case IEEE80211_S_RUN: 904 if (ic->ic_opmode == IEEE80211_M_IBSS) { 905 /* 906 * XXX when joining an ibss network we are called 907 * with a SCAN -> RUN transition on scan complete. 908 * Use that to call ipw_auth_and_assoc. On completing 909 * the join we are then called again with an 910 * AUTH -> RUN transition and we want to do nothing. 911 * This is all totally bogus and needs to be redone. 912 */ | 891 switch (nstate) { 892 case IEEE80211_S_RUN: 893 if (ic->ic_opmode == IEEE80211_M_IBSS) { 894 /* 895 * XXX when joining an ibss network we are called 896 * with a SCAN -> RUN transition on scan complete. 897 * Use that to call ipw_auth_and_assoc. On completing 898 * the join we are then called again with an 899 * AUTH -> RUN transition and we want to do nothing. 900 * This is all totally bogus and needs to be redone. 901 */ |
913 if (vap->iv_state == IEEE80211_S_SCAN) { 914 taskqueue_enqueue(taskqueue_swi, 915 &IPW_VAP(vap)->assoc_task); 916 return EINPROGRESS; 917 } | 902 if (ostate == IEEE80211_S_SCAN) 903 ipw_assoc(ic, vap); |
918 } 919 break; 920 921 case IEEE80211_S_INIT: 922 if (sc->flags & IPW_FLAG_ASSOCIATED) | 904 } 905 break; 906 907 case IEEE80211_S_INIT: 908 if (sc->flags & IPW_FLAG_ASSOCIATED) |
923 taskqueue_enqueue(taskqueue_swi, 924 &IPW_VAP(vap)->disassoc_task); | 909 ipw_disassoc(ic, vap); |
925 break; 926 927 case IEEE80211_S_AUTH: | 910 break; 911 912 case IEEE80211_S_AUTH: |
928 taskqueue_enqueue(taskqueue_swi, &IPW_VAP(vap)->assoc_task); 929 return EINPROGRESS; | 913 ipw_assoc(ic, vap); 914 break; |
930 931 case IEEE80211_S_ASSOC: 932 /* 933 * If we are not transitioning from AUTH the resend the 934 * association request. 935 */ | 915 916 case IEEE80211_S_ASSOC: 917 /* 918 * If we are not transitioning from AUTH the resend the 919 * association request. 920 */ |
936 if (vap->iv_state != IEEE80211_S_AUTH) { 937 taskqueue_enqueue(taskqueue_swi, 938 &IPW_VAP(vap)->assoc_task); 939 return EINPROGRESS; 940 } | 921 if (ostate != IEEE80211_S_AUTH) 922 ipw_assoc(ic, vap); |
941 break; 942 943 default: 944 break; 945 } | 923 break; 924 925 default: 926 break; 927 } |
928 IEEE80211_LOCK(ic); |
|
946 return ivp->newstate(vap, nstate, arg); 947} 948 949/* 950 * Read 16 bits at address 'addr' from the serial EEPROM. 951 */ 952static uint16_t 953ipw_read_prom_word(struct ipw_softc *sc, uint8_t addr) --- 61 unchanged lines hidden (view full) --- 1015 le32toh(cmd->subtype), le32toh(cmd->seq), le32toh(cmd->len), 1016 le32toh(cmd->status))); 1017 1018 sc->flags &= ~IPW_FLAG_BUSY; 1019 wakeup(sc); 1020} 1021 1022static void | 929 return ivp->newstate(vap, nstate, arg); 930} 931 932/* 933 * Read 16 bits at address 'addr' from the serial EEPROM. 934 */ 935static uint16_t 936ipw_read_prom_word(struct ipw_softc *sc, uint8_t addr) --- 61 unchanged lines hidden (view full) --- 998 le32toh(cmd->subtype), le32toh(cmd->seq), le32toh(cmd->len), 999 le32toh(cmd->status))); 1000 1001 sc->flags &= ~IPW_FLAG_BUSY; 1002 wakeup(sc); 1003} 1004 1005static void |
1023ipw_assocsuccess(void *arg, int npending) 1024{ 1025 struct ieee80211vap *vap = arg; 1026 1027 ieee80211_new_state(vap, IEEE80211_S_RUN, -1); 1028} 1029 1030static void 1031ipw_assocfailed(void *arg, int npending) 1032{ 1033 struct ieee80211vap *vap = arg; 1034 1035 ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); 1036} 1037 1038static void 1039ipw_scandone(void *arg, int npending) 1040{ 1041 struct ieee80211vap *vap = arg; 1042 1043 ieee80211_scan_done(vap); 1044} 1045 1046static void 1047ipw_bmiss(void *arg, int npending) 1048{ 1049 struct ieee80211com *ic = arg; 1050 1051 ieee80211_beacon_miss(ic); 1052} 1053 1054static void | |
1055ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) 1056{ 1057#define IEEESTATE(vap) ieee80211_state_name[vap->iv_state] 1058 struct ifnet *ifp = sc->sc_ifp; 1059 struct ieee80211com *ic = ifp->if_l2com; 1060 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1061 uint32_t state; 1062 --- 8 unchanged lines hidden (view full) --- 1071 /* XXX suppress state change in case the fw auto-associates */ 1072 if ((sc->flags & IPW_FLAG_ASSOCIATING) == 0) { 1073 DPRINTF(("Unexpected association (%s, flags 0x%x)\n", 1074 IEEESTATE(vap), sc->flags)); 1075 break; 1076 } 1077 sc->flags &= ~IPW_FLAG_ASSOCIATING; 1078 sc->flags |= IPW_FLAG_ASSOCIATED; | 1006ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) 1007{ 1008#define IEEESTATE(vap) ieee80211_state_name[vap->iv_state] 1009 struct ifnet *ifp = sc->sc_ifp; 1010 struct ieee80211com *ic = ifp->if_l2com; 1011 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1012 uint32_t state; 1013 --- 8 unchanged lines hidden (view full) --- 1022 /* XXX suppress state change in case the fw auto-associates */ 1023 if ((sc->flags & IPW_FLAG_ASSOCIATING) == 0) { 1024 DPRINTF(("Unexpected association (%s, flags 0x%x)\n", 1025 IEEESTATE(vap), sc->flags)); 1026 break; 1027 } 1028 sc->flags &= ~IPW_FLAG_ASSOCIATING; 1029 sc->flags |= IPW_FLAG_ASSOCIATED; |
1079 taskqueue_enqueue(taskqueue_swi, 1080 &IPW_VAP(vap)->assoc_success_task); | 1030 ieee80211_new_state(vap, IEEE80211_S_RUN, -1); |
1081 break; 1082 1083 case IPW_STATE_SCANNING: 1084 DPRINTFN(3, ("Scanning (%s flags 0x%x)\n", 1085 IEEESTATE(vap), sc->flags)); 1086 /* 1087 * NB: Check driver state for association on assoc 1088 * loss as the firmware will immediately start to 1089 * scan and we would treat it as a beacon miss if 1090 * we checked the 802.11 layer state. 1091 */ 1092 if (sc->flags & IPW_FLAG_ASSOCIATED) { 1093 /* XXX probably need to issue disassoc to fw */ | 1031 break; 1032 1033 case IPW_STATE_SCANNING: 1034 DPRINTFN(3, ("Scanning (%s flags 0x%x)\n", 1035 IEEESTATE(vap), sc->flags)); 1036 /* 1037 * NB: Check driver state for association on assoc 1038 * loss as the firmware will immediately start to 1039 * scan and we would treat it as a beacon miss if 1040 * we checked the 802.11 layer state. 1041 */ 1042 if (sc->flags & IPW_FLAG_ASSOCIATED) { 1043 /* XXX probably need to issue disassoc to fw */ |
1094 taskqueue_enqueue(taskqueue_swi, &sc->sc_bmiss_task); | 1044 ieee80211_beacon_miss(ic); |
1095 } 1096 break; 1097 1098 case IPW_STATE_SCAN_COMPLETE: 1099 /* 1100 * XXX For some reason scan requests generate scan 1101 * started + scan done events before any traffic is 1102 * received (e.g. probe response frames). We work 1103 * around this by marking the HACK flag and skipping 1104 * the first scan complete event. 1105 */ 1106 DPRINTFN(3, ("Scan complete (%s flags 0x%x)\n", 1107 IEEESTATE(vap), sc->flags)); 1108 if (sc->flags & IPW_FLAG_HACK) { 1109 sc->flags &= ~IPW_FLAG_HACK; 1110 break; 1111 } 1112 if (sc->flags & IPW_FLAG_SCANNING) { | 1045 } 1046 break; 1047 1048 case IPW_STATE_SCAN_COMPLETE: 1049 /* 1050 * XXX For some reason scan requests generate scan 1051 * started + scan done events before any traffic is 1052 * received (e.g. probe response frames). We work 1053 * around this by marking the HACK flag and skipping 1054 * the first scan complete event. 1055 */ 1056 DPRINTFN(3, ("Scan complete (%s flags 0x%x)\n", 1057 IEEESTATE(vap), sc->flags)); 1058 if (sc->flags & IPW_FLAG_HACK) { 1059 sc->flags &= ~IPW_FLAG_HACK; 1060 break; 1061 } 1062 if (sc->flags & IPW_FLAG_SCANNING) { |
1113 taskqueue_enqueue(taskqueue_swi, 1114 &IPW_VAP(vap)->scandone_task); | 1063 ieee80211_scan_done(vap); |
1115 sc->flags &= ~IPW_FLAG_SCANNING; 1116 sc->sc_scan_timer = 0; 1117 } 1118 break; 1119 1120 case IPW_STATE_ASSOCIATION_LOST: 1121 DPRINTFN(2, ("Association lost (%s flags 0x%x)\n", 1122 IEEESTATE(vap), sc->flags)); 1123 sc->flags &= ~(IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED); 1124 if (vap->iv_state == IEEE80211_S_RUN) | 1064 sc->flags &= ~IPW_FLAG_SCANNING; 1065 sc->sc_scan_timer = 0; 1066 } 1067 break; 1068 1069 case IPW_STATE_ASSOCIATION_LOST: 1070 DPRINTFN(2, ("Association lost (%s flags 0x%x)\n", 1071 IEEESTATE(vap), sc->flags)); 1072 sc->flags &= ~(IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED); 1073 if (vap->iv_state == IEEE80211_S_RUN) |
1125 taskqueue_enqueue(taskqueue_swi, 1126 &IPW_VAP(vap)->assoc_failed_task); | 1074 ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); |
1127 break; 1128 1129 case IPW_STATE_DISABLED: 1130 /* XXX? is this right? */ 1131 sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING | 1132 IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED); 1133 DPRINTFN(2, ("Firmware disabled (%s flags 0x%x)\n", 1134 IEEESTATE(vap), sc->flags)); --- 292 unchanged lines hidden (view full) --- 1427 /* remember what the firmware has processed */ 1428 sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1; 1429 1430 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1431 ipw_start_locked(ifp); 1432} 1433 1434static void | 1075 break; 1076 1077 case IPW_STATE_DISABLED: 1078 /* XXX? is this right? */ 1079 sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING | 1080 IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED); 1081 DPRINTFN(2, ("Firmware disabled (%s flags 0x%x)\n", 1082 IEEESTATE(vap), sc->flags)); --- 292 unchanged lines hidden (view full) --- 1375 /* remember what the firmware has processed */ 1376 sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1; 1377 1378 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1379 ipw_start_locked(ifp); 1380} 1381 1382static void |
1383ipw_fatal_error_intr(struct ipw_softc *sc) 1384{ 1385 struct ifnet *ifp = sc->sc_ifp; 1386 struct ieee80211com *ic = ifp->if_l2com; 1387 1388 device_printf(sc->sc_dev, "firmware error\n"); 1389 ieee80211_runtask(ic, &sc->sc_init_task); 1390} 1391 1392static void |
|
1435ipw_intr(void *arg) 1436{ 1437 struct ipw_softc *sc = arg; 1438 uint32_t r; 1439 IPW_LOCK_DECL; 1440 1441 IPW_LOCK(sc); 1442 | 1393ipw_intr(void *arg) 1394{ 1395 struct ipw_softc *sc = arg; 1396 uint32_t r; 1397 IPW_LOCK_DECL; 1398 1399 IPW_LOCK(sc); 1400 |
1443 if ((r = CSR_READ_4(sc, IPW_CSR_INTR)) == 0 || r == 0xffffffff) { 1444 IPW_UNLOCK(sc); 1445 return; 1446 } | 1401 r = CSR_READ_4(sc, IPW_CSR_INTR); 1402 if (r == 0 || r == 0xffffffff) 1403 goto done; |
1447 1448 /* disable interrupts */ 1449 CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0); 1450 1451 /* acknowledge all interrupts */ 1452 CSR_WRITE_4(sc, IPW_CSR_INTR, r); 1453 1454 if (r & (IPW_INTR_FATAL_ERROR | IPW_INTR_PARITY_ERROR)) { | 1404 1405 /* disable interrupts */ 1406 CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0); 1407 1408 /* acknowledge all interrupts */ 1409 CSR_WRITE_4(sc, IPW_CSR_INTR, r); 1410 1411 if (r & (IPW_INTR_FATAL_ERROR | IPW_INTR_PARITY_ERROR)) { |
1455 device_printf(sc->sc_dev, "firmware error\n"); 1456 taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task); 1457 r = 0; /* don't process more interrupts */ | 1412 ipw_fatal_error_intr(sc); 1413 goto done; |
1458 } 1459 1460 if (r & IPW_INTR_FW_INIT_DONE) 1461 wakeup(sc); 1462 1463 if (r & IPW_INTR_RX_TRANSFER) 1464 ipw_rx_intr(sc); 1465 1466 if (r & IPW_INTR_TX_TRANSFER) 1467 ipw_tx_intr(sc); 1468 1469 /* re-enable interrupts */ 1470 CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, IPW_INTR_MASK); | 1414 } 1415 1416 if (r & IPW_INTR_FW_INIT_DONE) 1417 wakeup(sc); 1418 1419 if (r & IPW_INTR_RX_TRANSFER) 1420 ipw_rx_intr(sc); 1421 1422 if (r & IPW_INTR_TX_TRANSFER) 1423 ipw_tx_intr(sc); 1424 1425 /* re-enable interrupts */ 1426 CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, IPW_INTR_MASK); |
1471 | 1427done: |
1472 IPW_UNLOCK(sc); 1473} 1474 1475static void 1476ipw_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1477{ 1478 if (error != 0) 1479 return; --- 696 unchanged lines hidden (view full) --- 2176 struct ipw_scan_options opts; 2177 2178 DPRINTF(("Scan options: mask 0x%x flags 0x%x\n", chanmask, flags)); 2179 opts.channels = htole32(chanmask); 2180 opts.flags = htole32(flags); 2181 return ipw_cmd(sc, IPW_CMD_SET_SCAN_OPTIONS, &opts, sizeof(opts)); 2182} 2183 | 1428 IPW_UNLOCK(sc); 1429} 1430 1431static void 1432ipw_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1433{ 1434 if (error != 0) 1435 return; --- 696 unchanged lines hidden (view full) --- 2132 struct ipw_scan_options opts; 2133 2134 DPRINTF(("Scan options: mask 0x%x flags 0x%x\n", chanmask, flags)); 2135 opts.channels = htole32(chanmask); 2136 opts.flags = htole32(flags); 2137 return ipw_cmd(sc, IPW_CMD_SET_SCAN_OPTIONS, &opts, sizeof(opts)); 2138} 2139 |
2184/* 2185 * Handler for sc_scan_task. This is a simple wrapper around ipw_scan(). 2186 */ 2187static void 2188ipw_scan_task(void *context, int pending) 2189{ 2190 struct ipw_softc *sc = context; 2191 IPW_LOCK_DECL; 2192 2193 IPW_LOCK(sc); 2194 ipw_scan(sc); 2195 IPW_UNLOCK(sc); 2196} 2197 | |
2198static int 2199ipw_scan(struct ipw_softc *sc) 2200{ 2201 uint32_t params; 2202 int error; 2203 2204 DPRINTF(("%s: flags 0x%x\n", __func__, sc->flags)); 2205 --- 47 unchanged lines hidden (view full) --- 2253 DPRINTF(("Setting channel to %u\n", le32toh(data))); 2254 error = ipw_cmd(sc, IPW_CMD_SET_CHANNEL, &data, sizeof data); 2255 if (error == 0) 2256 ipw_setcurchan(sc, chan); 2257 return error; 2258} 2259 2260static void | 2140static int 2141ipw_scan(struct ipw_softc *sc) 2142{ 2143 uint32_t params; 2144 int error; 2145 2146 DPRINTF(("%s: flags 0x%x\n", __func__, sc->flags)); 2147 --- 47 unchanged lines hidden (view full) --- 2195 DPRINTF(("Setting channel to %u\n", le32toh(data))); 2196 error = ipw_cmd(sc, IPW_CMD_SET_CHANNEL, &data, sizeof data); 2197 if (error == 0) 2198 ipw_setcurchan(sc, chan); 2199 return error; 2200} 2201 2202static void |
2261ipw_assoc_task(void *context, int pending) | 2203ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap) |
2262{ | 2204{ |
2263 struct ieee80211vap *vap = context; | |
2264 struct ifnet *ifp = vap->iv_ic->ic_ifp; | 2205 struct ifnet *ifp = vap->iv_ic->ic_ifp; |
2265 struct ieee80211com *ic = ifp->if_l2com; | |
2266 struct ipw_softc *sc = ifp->if_softc; 2267 struct ieee80211_node *ni = vap->iv_bss; 2268 struct ipw_security security; 2269 uint32_t data; 2270 int error; 2271 IPW_LOCK_DECL; 2272 2273 IPW_LOCK(sc); --- 74 unchanged lines hidden (view full) --- 2348 error = ipw_enable(sc); /* finally, enable adapter */ 2349 if (error == 0) 2350 sc->flags |= IPW_FLAG_ASSOCIATING; 2351done: 2352 IPW_UNLOCK(sc); 2353} 2354 2355static void | 2206 struct ipw_softc *sc = ifp->if_softc; 2207 struct ieee80211_node *ni = vap->iv_bss; 2208 struct ipw_security security; 2209 uint32_t data; 2210 int error; 2211 IPW_LOCK_DECL; 2212 2213 IPW_LOCK(sc); --- 74 unchanged lines hidden (view full) --- 2288 error = ipw_enable(sc); /* finally, enable adapter */ 2289 if (error == 0) 2290 sc->flags |= IPW_FLAG_ASSOCIATING; 2291done: 2292 IPW_UNLOCK(sc); 2293} 2294 2295static void |
2356ipw_disassoc_task(void *context, int pending) | 2296ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap) |
2357{ | 2297{ |
2358 struct ieee80211vap *vap = context; | |
2359 struct ifnet *ifp = vap->iv_ic->ic_ifp; 2360 struct ieee80211_node *ni = vap->iv_bss; 2361 struct ipw_softc *sc = ifp->if_softc; 2362 IPW_LOCK_DECL; 2363 2364 IPW_LOCK(sc); 2365 DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":")); 2366 /* --- 357 unchanged lines hidden (view full) --- 2724static void 2725ipw_scan_start(struct ieee80211com *ic) 2726{ 2727 struct ifnet *ifp = ic->ic_ifp; 2728 struct ipw_softc *sc = ifp->if_softc; 2729 IPW_LOCK_DECL; 2730 2731 IPW_LOCK(sc); | 2298 struct ifnet *ifp = vap->iv_ic->ic_ifp; 2299 struct ieee80211_node *ni = vap->iv_bss; 2300 struct ipw_softc *sc = ifp->if_softc; 2301 IPW_LOCK_DECL; 2302 2303 IPW_LOCK(sc); 2304 DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":")); 2305 /* --- 357 unchanged lines hidden (view full) --- 2663static void 2664ipw_scan_start(struct ieee80211com *ic) 2665{ 2666 struct ifnet *ifp = ic->ic_ifp; 2667 struct ipw_softc *sc = ifp->if_softc; 2668 IPW_LOCK_DECL; 2669 2670 IPW_LOCK(sc); |
2732 if (!(sc->flags & IPW_FLAG_SCANNING)) 2733 taskqueue_enqueue(taskqueue_swi, &sc->sc_scan_task); | 2671 ipw_scan(sc); |
2734 IPW_UNLOCK(sc); 2735} 2736 2737static void 2738ipw_set_channel(struct ieee80211com *ic) 2739{ 2740 struct ifnet *ifp = ic->ic_ifp; 2741 struct ipw_softc *sc = ifp->if_softc; --- 34 unchanged lines hidden --- | 2672 IPW_UNLOCK(sc); 2673} 2674 2675static void 2676ipw_set_channel(struct ieee80211com *ic) 2677{ 2678 struct ifnet *ifp = ic->ic_ifp; 2679 struct ipw_softc *sc = ifp->if_softc; --- 34 unchanged lines hidden --- |