Deleted Added
full compact
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 ---