if_mwl.c (197441) | if_mwl.c (199559) |
---|---|
1/*- 2 * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting 3 * Copyright (c) 2007-2008 Marvell Semiconductor, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 15 unchanged lines hidden (view full) --- 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 26 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGES. 29 */ 30 31#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting 3 * Copyright (c) 2007-2008 Marvell Semiconductor, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 15 unchanged lines hidden (view full) --- 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 26 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGES. 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sys/dev/mwl/if_mwl.c 197441 2009-09-23 17:48:16Z rpaulo $"); | 32__FBSDID("$FreeBSD: head/sys/dev/mwl/if_mwl.c 199559 2009-11-19 22:06:40Z jhb $"); |
33 34/* 35 * Driver for the Marvell 88W8363 Wireless LAN controller. 36 */ 37 38#include "opt_inet.h" 39#include "opt_mwl.h" 40 --- 52 unchanged lines hidden (view full) --- 93static void mwl_init(void *); 94static void mwl_stop_locked(struct ifnet *, int); 95static int mwl_reset(struct ieee80211vap *, u_long); 96static void mwl_stop(struct ifnet *, int); 97static void mwl_start(struct ifnet *); 98static int mwl_raw_xmit(struct ieee80211_node *, struct mbuf *, 99 const struct ieee80211_bpf_params *); 100static int mwl_media_change(struct ifnet *); | 33 34/* 35 * Driver for the Marvell 88W8363 Wireless LAN controller. 36 */ 37 38#include "opt_inet.h" 39#include "opt_mwl.h" 40 --- 52 unchanged lines hidden (view full) --- 93static void mwl_init(void *); 94static void mwl_stop_locked(struct ifnet *, int); 95static int mwl_reset(struct ieee80211vap *, u_long); 96static void mwl_stop(struct ifnet *, int); 97static void mwl_start(struct ifnet *); 98static int mwl_raw_xmit(struct ieee80211_node *, struct mbuf *, 99 const struct ieee80211_bpf_params *); 100static int mwl_media_change(struct ifnet *); |
101static void mwl_watchdog(struct ifnet *); | 101static void mwl_watchdog(void *); |
102static int mwl_ioctl(struct ifnet *, u_long, caddr_t); 103static void mwl_radar_proc(void *, int); 104static void mwl_chanswitch_proc(void *, int); 105static void mwl_bawatchdog_proc(void *, int); 106static int mwl_key_alloc(struct ieee80211vap *, 107 struct ieee80211_key *, 108 ieee80211_keyix *, ieee80211_keyix *); 109static int mwl_key_delete(struct ieee80211vap *, --- 245 unchanged lines hidden (view full) --- 355 if_printf(ifp, "failed to setup descriptors: %d\n", error); 356 goto bad1; 357 } 358 error = mwl_setupdma(sc); /* push to firmware */ 359 if (error != 0) /* NB: mwl_setupdma prints msg */ 360 goto bad1; 361 362 callout_init(&sc->sc_timer, CALLOUT_MPSAFE); | 102static int mwl_ioctl(struct ifnet *, u_long, caddr_t); 103static void mwl_radar_proc(void *, int); 104static void mwl_chanswitch_proc(void *, int); 105static void mwl_bawatchdog_proc(void *, int); 106static int mwl_key_alloc(struct ieee80211vap *, 107 struct ieee80211_key *, 108 ieee80211_keyix *, ieee80211_keyix *); 109static int mwl_key_delete(struct ieee80211vap *, --- 245 unchanged lines hidden (view full) --- 355 if_printf(ifp, "failed to setup descriptors: %d\n", error); 356 goto bad1; 357 } 358 error = mwl_setupdma(sc); /* push to firmware */ 359 if (error != 0) /* NB: mwl_setupdma prints msg */ 360 goto bad1; 361 362 callout_init(&sc->sc_timer, CALLOUT_MPSAFE); |
363 callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); |
|
363 364 sc->sc_tq = taskqueue_create("mwl_taskq", M_NOWAIT, 365 taskqueue_thread_enqueue, &sc->sc_tq); 366 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 367 "%s taskq", ifp->if_xname); 368 369 TASK_INIT(&sc->sc_rxtask, 0, mwl_rx_proc, sc); 370 TASK_INIT(&sc->sc_radartask, 0, mwl_radar_proc, sc); --- 25 unchanged lines hidden (view full) --- 396 sc->sc_ac2q[WME_AC_VI] = sc->sc_ac2q[WME_AC_BK]; 397 sc->sc_ac2q[WME_AC_VO] = sc->sc_ac2q[WME_AC_BK]; 398 } 399 TASK_INIT(&sc->sc_txtask, 0, mwl_tx_proc, sc); 400 401 ifp->if_softc = sc; 402 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 403 ifp->if_start = mwl_start; | 364 365 sc->sc_tq = taskqueue_create("mwl_taskq", M_NOWAIT, 366 taskqueue_thread_enqueue, &sc->sc_tq); 367 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 368 "%s taskq", ifp->if_xname); 369 370 TASK_INIT(&sc->sc_rxtask, 0, mwl_rx_proc, sc); 371 TASK_INIT(&sc->sc_radartask, 0, mwl_radar_proc, sc); --- 25 unchanged lines hidden (view full) --- 397 sc->sc_ac2q[WME_AC_VI] = sc->sc_ac2q[WME_AC_BK]; 398 sc->sc_ac2q[WME_AC_VO] = sc->sc_ac2q[WME_AC_BK]; 399 } 400 TASK_INIT(&sc->sc_txtask, 0, mwl_tx_proc, sc); 401 402 ifp->if_softc = sc; 403 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 404 ifp->if_start = mwl_start; |
404 ifp->if_watchdog = mwl_watchdog; | |
405 ifp->if_ioctl = mwl_ioctl; 406 ifp->if_init = mwl_init; 407 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 408 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 409 IFQ_SET_READY(&ifp->if_snd); 410 411 ic->ic_ifp = ifp; 412 /* XXX not right but it's not used anywhere important */ --- 140 unchanged lines hidden (view full) --- 553 * o reclaim the tx queue data structures after calling 554 * the 802.11 layer as we'll get called back to reclaim 555 * node state and potentially want to use them 556 * o to cleanup the tx queues the hal is called, so detach 557 * it last 558 * Other than that, it's straightforward... 559 */ 560 ieee80211_ifdetach(ic); | 405 ifp->if_ioctl = mwl_ioctl; 406 ifp->if_init = mwl_init; 407 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 408 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 409 IFQ_SET_READY(&ifp->if_snd); 410 411 ic->ic_ifp = ifp; 412 /* XXX not right but it's not used anywhere important */ --- 140 unchanged lines hidden (view full) --- 553 * o reclaim the tx queue data structures after calling 554 * the 802.11 layer as we'll get called back to reclaim 555 * node state and potentially want to use them 556 * o to cleanup the tx queues the hal is called, so detach 557 * it last 558 * Other than that, it's straightforward... 559 */ 560 ieee80211_ifdetach(ic); |
561 callout_drain(&sc->sc_watchdog); |
|
561 mwl_dma_cleanup(sc); 562 mwl_tx_cleanup(sc); 563 mwl_hal_detach(sc->sc_mh); 564 if_free(ifp); 565 566 return 0; 567} 568 --- 640 unchanged lines hidden (view full) --- 1209 | MACREG_A2HRIC_BIT_QUEUE_EMPTY 1210#endif 1211 | MACREG_A2HRIC_BIT_BA_WATCHDOG 1212 | MACREQ_A2HRIC_BIT_TX_ACK 1213 ; 1214 1215 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1216 mwl_hal_intrset(mh, sc->sc_imask); | 562 mwl_dma_cleanup(sc); 563 mwl_tx_cleanup(sc); 564 mwl_hal_detach(sc->sc_mh); 565 if_free(ifp); 566 567 return 0; 568} 569 --- 640 unchanged lines hidden (view full) --- 1210 | MACREG_A2HRIC_BIT_QUEUE_EMPTY 1211#endif 1212 | MACREG_A2HRIC_BIT_BA_WATCHDOG 1213 | MACREQ_A2HRIC_BIT_TX_ACK 1214 ; 1215 1216 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1217 mwl_hal_intrset(mh, sc->sc_imask); |
1218 callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc); |
|
1217 1218 return 0; 1219} 1220 1221static void 1222mwl_init(void *arg) 1223{ 1224 struct mwl_softc *sc = arg; --- 21 unchanged lines hidden (view full) --- 1246 __func__, sc->sc_invalid, ifp->if_flags); 1247 1248 MWL_LOCK_ASSERT(sc); 1249 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1250 /* 1251 * Shutdown the hardware and driver. 1252 */ 1253 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; | 1219 1220 return 0; 1221} 1222 1223static void 1224mwl_init(void *arg) 1225{ 1226 struct mwl_softc *sc = arg; --- 21 unchanged lines hidden (view full) --- 1248 __func__, sc->sc_invalid, ifp->if_flags); 1249 1250 MWL_LOCK_ASSERT(sc); 1251 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1252 /* 1253 * Shutdown the hardware and driver. 1254 */ 1255 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; |
1254 ifp->if_timer = 0; | 1256 callout_stop(&sc->sc_watchdog); 1257 sc->sc_tx_timer = 0; |
1255 mwl_draintxq(sc); 1256 } 1257} 1258 1259static void 1260mwl_stop(struct ifnet *ifp, int disable) 1261{ 1262 struct mwl_softc *sc = ifp->if_softc; --- 2143 unchanged lines hidden (view full) --- 3406 m0->m_len - sizeof(uint16_t), ds->DataRate, -1); 3407 3408 MWL_TXQ_LOCK(txq); 3409 ds->Status = htole32(EAGLE_TXD_STATUS_FW_OWNED); 3410 STAILQ_INSERT_TAIL(&txq->active, bf, bf_list); 3411 MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3412 3413 ifp->if_opackets++; | 1258 mwl_draintxq(sc); 1259 } 1260} 1261 1262static void 1263mwl_stop(struct ifnet *ifp, int disable) 1264{ 1265 struct mwl_softc *sc = ifp->if_softc; --- 2143 unchanged lines hidden (view full) --- 3409 m0->m_len - sizeof(uint16_t), ds->DataRate, -1); 3410 3411 MWL_TXQ_LOCK(txq); 3412 ds->Status = htole32(EAGLE_TXD_STATUS_FW_OWNED); 3413 STAILQ_INSERT_TAIL(&txq->active, bf, bf_list); 3414 MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3415 3416 ifp->if_opackets++; |
3414 ifp->if_timer = 5; | 3417 sc->sc_tx_timer = 5; |
3415 MWL_TXQ_UNLOCK(txq); 3416 3417 return 0; 3418#undef IEEE80211_DIR_DSTODS 3419} 3420 3421static __inline int 3422mwl_cvtlegacyrix(int rix) --- 130 unchanged lines hidden (view full) --- 3553 nreaped += mwl_tx_processq(sc, &sc->sc_txq[1]); 3554 if (!STAILQ_EMPTY(&sc->sc_txq[2].active)) 3555 nreaped += mwl_tx_processq(sc, &sc->sc_txq[2]); 3556 if (!STAILQ_EMPTY(&sc->sc_txq[3].active)) 3557 nreaped += mwl_tx_processq(sc, &sc->sc_txq[3]); 3558 3559 if (nreaped != 0) { 3560 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | 3418 MWL_TXQ_UNLOCK(txq); 3419 3420 return 0; 3421#undef IEEE80211_DIR_DSTODS 3422} 3423 3424static __inline int 3425mwl_cvtlegacyrix(int rix) --- 130 unchanged lines hidden (view full) --- 3556 nreaped += mwl_tx_processq(sc, &sc->sc_txq[1]); 3557 if (!STAILQ_EMPTY(&sc->sc_txq[2].active)) 3558 nreaped += mwl_tx_processq(sc, &sc->sc_txq[2]); 3559 if (!STAILQ_EMPTY(&sc->sc_txq[3].active)) 3560 nreaped += mwl_tx_processq(sc, &sc->sc_txq[3]); 3561 3562 if (nreaped != 0) { 3563 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; |
3561 ifp->if_timer = 0; | 3564 sc->sc_tx_timer = 0; |
3562 if (!IFQ_IS_EMPTY(&ifp->if_snd)) { 3563 /* NB: kick fw; the tx thread may have been preempted */ 3564 mwl_hal_txstart(sc->sc_mh, 0); 3565 mwl_start(ifp); 3566 } 3567 } 3568} 3569 --- 49 unchanged lines hidden (view full) --- 3619mwl_draintxq(struct mwl_softc *sc) 3620{ 3621 struct ifnet *ifp = sc->sc_ifp; 3622 int i; 3623 3624 for (i = 0; i < MWL_NUM_TX_QUEUES; i++) 3625 mwl_tx_draintxq(sc, &sc->sc_txq[i]); 3626 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | 3565 if (!IFQ_IS_EMPTY(&ifp->if_snd)) { 3566 /* NB: kick fw; the tx thread may have been preempted */ 3567 mwl_hal_txstart(sc->sc_mh, 0); 3568 mwl_start(ifp); 3569 } 3570 } 3571} 3572 --- 49 unchanged lines hidden (view full) --- 3622mwl_draintxq(struct mwl_softc *sc) 3623{ 3624 struct ifnet *ifp = sc->sc_ifp; 3625 int i; 3626 3627 for (i = 0; i < MWL_NUM_TX_QUEUES; i++) 3628 mwl_tx_draintxq(sc, &sc->sc_txq[i]); 3629 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; |
3627 ifp->if_timer = 0; | 3630 sc->sc_tx_timer = 0; |
3628} 3629 3630#ifdef MWL_DIAGAPI 3631/* 3632 * Reset the transmit queues to a pristine state after a fw download. 3633 */ 3634static void 3635mwl_resettxq(struct mwl_softc *sc) --- 1129 unchanged lines hidden (view full) --- 4765#endif 4766 i++; 4767 } 4768 MWL_TXQ_UNLOCK(txq); 4769} 4770#endif 4771 4772static void | 3631} 3632 3633#ifdef MWL_DIAGAPI 3634/* 3635 * Reset the transmit queues to a pristine state after a fw download. 3636 */ 3637static void 3638mwl_resettxq(struct mwl_softc *sc) --- 1129 unchanged lines hidden (view full) --- 4768#endif 4769 i++; 4770 } 4771 MWL_TXQ_UNLOCK(txq); 4772} 4773#endif 4774 4775static void |
4773mwl_watchdog(struct ifnet *ifp) | 4776mwl_watchdog(void *arg) |
4774{ | 4777{ |
4775 struct mwl_softc *sc = ifp->if_softc; | 4778 struct mwl_softc *sc; 4779 struct ifnet *ifp; |
4776 | 4780 |
4781 sc = arg; 4782 callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc); 4783 if (sc->sc_tx_timer == 0 || --sc->sc_tx_timer > 0) 4784 return; 4785 4786 ifp = sc->sc_ifp; |
|
4777 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->sc_invalid) { 4778 if (mwl_hal_setkeepalive(sc->sc_mh)) 4779 if_printf(ifp, "transmit timeout (firmware hung?)\n"); 4780 else 4781 if_printf(ifp, "transmit timeout\n"); 4782#if 0 4783 mwl_reset(ifp); 4784mwl_txq_dump(&sc->sc_txq[0]);/*XXX*/ --- 248 unchanged lines hidden --- | 4787 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->sc_invalid) { 4788 if (mwl_hal_setkeepalive(sc->sc_mh)) 4789 if_printf(ifp, "transmit timeout (firmware hung?)\n"); 4790 else 4791 if_printf(ifp, "transmit timeout\n"); 4792#if 0 4793 mwl_reset(ifp); 4794mwl_txq_dump(&sc->sc_txq[0]);/*XXX*/ --- 248 unchanged lines hidden --- |