1/*- 2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3 * 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 --- 14 unchanged lines hidden (view full) --- 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 227346 2011-11-08 18:10:04Z adrian $"); |
32 33/* 34 * Driver for the Atheros Wireless LAN controller. 35 * 36 * This software is derived from work of Atsushi Onoe; his contribution 37 * is greatly appreciated. 38 */ 39 --- 1259 unchanged lines hidden (view full) --- 1299 */ 1300void 1301ath_intr(void *arg) 1302{ 1303 struct ath_softc *sc = arg; 1304 struct ifnet *ifp = sc->sc_ifp; 1305 struct ath_hal *ah = sc->sc_ah; 1306 HAL_INT status = 0; |
1307 uint32_t txqs; |
1308 1309 if (sc->sc_invalid) { 1310 /* 1311 * The hardware is not ready/present, don't touch anything. 1312 * Note this can happen early on if the IRQ is shared. 1313 */ 1314 DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid; ignored\n", __func__); 1315 return; --- 57 unchanged lines hidden (view full) --- 1373 * traffic so any frames held on the staging 1374 * queue are aged and potentially flushed. 1375 */ 1376 taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask); 1377#endif 1378 } 1379 } 1380 if (status & HAL_INT_RXEOL) { |
1381 int imask; |
1382 /* 1383 * NB: the hardware should re-read the link when 1384 * RXE bit is written, but it doesn't work at 1385 * least on older hardware revs. 1386 */ 1387 sc->sc_stats.ast_rxeol++; 1388 /* 1389 * Disable RXEOL/RXORN - prevent an interrupt 1390 * storm until the PCU logic can be reset. 1391 * In case the interface is reset some other 1392 * way before "sc_kickpcu" is called, don't 1393 * modify sc_imask - that way if it is reset 1394 * by a call to ath_reset() somehow, the 1395 * interrupt mask will be correctly reprogrammed. 1396 */ |
1397 ATH_LOCK(sc); 1398 imask = sc->sc_imask; |
1399 imask &= ~(HAL_INT_RXEOL | HAL_INT_RXORN); 1400 ath_hal_intrset(ah, imask); 1401 /* |
1402 * Only blank sc_rxlink if we've not yet kicked 1403 * the PCU. 1404 * 1405 * This isn't entirely correct - the correct solution 1406 * would be to have a PCU lock and engage that for 1407 * the duration of the PCU fiddling; which would include 1408 * running the RX process. Otherwise we could end up 1409 * messing up the RX descriptor chain and making the 1410 * RX desc list much shorter. 1411 */ 1412 if (! sc->sc_kickpcu) 1413 sc->sc_rxlink = NULL; 1414 sc->sc_kickpcu = 1; 1415 ATH_UNLOCK(sc); 1416 /* |
1417 * Enqueue an RX proc, to handled whatever 1418 * is in the RX queue. 1419 * This will then kick the PCU. 1420 */ 1421 taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask); |
1422 } 1423 if (status & HAL_INT_TXURN) { 1424 sc->sc_stats.ast_txurn++; 1425 /* bump tx trigger level */ 1426 ath_hal_updatetxtriglevel(ah, AH_TRUE); 1427 } |
1428 if (status & HAL_INT_RX) { 1429 sc->sc_stats.ast_rx_intr++; |
1430 taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask); |
1431 } 1432 if (status & HAL_INT_TX) { 1433 sc->sc_stats.ast_tx_intr++; 1434 /* 1435 * Grab all the currently set bits in the HAL txq bitmap 1436 * and blank them. This is the only place we should be 1437 * doing this. 1438 */ 1439 ATH_LOCK(sc); 1440 txqs = 0xffffffff; 1441 ath_hal_gettxintrtxqs(sc->sc_ah, &txqs); 1442 sc->sc_txq_active |= txqs; 1443 ATH_UNLOCK(sc); |
1444 taskqueue_enqueue(sc->sc_tq, &sc->sc_txtask); |
1445 } |
1446 if (status & HAL_INT_BMISS) { 1447 sc->sc_stats.ast_bmiss++; 1448 taskqueue_enqueue(sc->sc_tq, &sc->sc_bmisstask); 1449 } 1450 if (status & HAL_INT_GTT) 1451 sc->sc_stats.ast_tx_timeout++; 1452 if (status & HAL_INT_CST) 1453 sc->sc_stats.ast_tx_cst++; --- 4 unchanged lines hidden (view full) --- 1458 * interrupt; otherwise it will continue to fire. 1459 */ 1460 ath_hal_intrset(ah, 0); 1461 /* 1462 * Let the hal handle the event. We assume it will 1463 * clear whatever condition caused the interrupt. 1464 */ 1465 ath_hal_mibevent(ah, &sc->sc_halstats); |
1466 /* 1467 * Don't reset the interrupt if we've just 1468 * kicked the PCU, or we may get a nested 1469 * RXEOL before the rxproc has had a chance 1470 * to run. 1471 */ 1472 ATH_LOCK(sc); 1473 if (sc->sc_kickpcu == 0) 1474 ath_hal_intrset(ah, sc->sc_imask); 1475 ATH_UNLOCK(sc); |
1476 } 1477 if (status & HAL_INT_RXORN) { 1478 /* NB: hal marks HAL_INT_FATAL when RXORN is fatal */ 1479 sc->sc_stats.ast_rxorn++; 1480 } 1481 } 1482} 1483 --- 159 unchanged lines hidden (view full) --- 1643 /* 1644 * Beacon timers were cleared here; give ath_newstate() 1645 * a hint that the beacon timers should be poked when 1646 * things transition to the RUN state. 1647 */ 1648 sc->sc_beacons = 0; 1649 1650 /* |
1651 * Initial aggregation settings. 1652 */ 1653 sc->sc_hwq_limit = ATH_AGGR_MIN_QDEPTH; 1654 sc->sc_tid_hwq_lo = ATH_AGGR_SCHED_LOW; 1655 sc->sc_tid_hwq_hi = ATH_AGGR_SCHED_HIGH; 1656 1657 /* |
1658 * Setup the hardware after reset: the key cache 1659 * is filled as needed and the receive engine is 1660 * set going. Frame transmit is handled entirely 1661 * in the frame output path; there's nothing to do 1662 * here except setup the interrupt mask. 1663 */ 1664 if (ath_startrecv(sc) != 0) { 1665 if_printf(ifp, "unable to start recv logic\n"); --- 1853 unchanged lines hidden (view full) --- 3519 struct ath_desc *ds; 3520 struct ath_rx_status *rs; 3521 struct mbuf *m; 3522 struct ieee80211_node *ni; 3523 int len, type, ngood; 3524 HAL_STATUS status; 3525 int16_t nf; 3526 u_int64_t tsf; |
3527 int npkts = 0; |
3528 3529 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); 3530 ngood = 0; 3531 nf = ath_hal_getchannoise(ah, sc->sc_curchan); 3532 sc->sc_stats.ast_rx_noise = nf; 3533 tsf = ath_hal_gettsf64(ah); 3534 do { 3535 bf = TAILQ_FIRST(&sc->sc_rxbuf); --- 43 unchanged lines hidden (view full) --- 3579#ifdef ATH_DEBUG 3580 if (sc->sc_debug & ATH_DEBUG_RECV_DESC) 3581 ath_printrxbuf(sc, bf, 0, status == HAL_OK); 3582#endif 3583 if (status == HAL_EINPROGRESS) 3584 break; 3585 3586 TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list); |
3587 npkts++; |
3588 3589 /* These aren't specifically errors */ 3590 if (rs->rs_flags & HAL_RX_GI) 3591 sc->sc_stats.ast_rx_halfgi++; 3592 if (rs->rs_flags & HAL_RX_2040) 3593 sc->sc_stats.ast_rx_2040++; 3594 if (rs->rs_flags & HAL_RX_DELIM_CRC_PRE) 3595 sc->sc_stats.ast_rx_pre_crc_err++; --- 270 unchanged lines hidden (view full) --- 3866 taskqueue_enqueue(sc->sc_tq, &sc->sc_dfstask); 3867 3868 /* 3869 * Now that all the RX frames were handled that 3870 * need to be handled, kick the PCU if there's 3871 * been an RXEOL condition. 3872 */ 3873 if (sc->sc_kickpcu) { |
3874 device_printf(sc->sc_dev, "%s: kickpcu; handled %d packets\n", 3875 __func__, npkts); 3876 3877 /* XXX rxslink? */ 3878 bf = TAILQ_FIRST(&sc->sc_rxbuf); 3879 ath_hal_putrxbuf(ah, bf->bf_daddr); 3880 ath_hal_rxena(ah); /* enable recv descriptors */ 3881 ath_mode_init(sc); /* set filters, etc. */ 3882 ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */ 3883 3884 ATH_LOCK(sc); |
3885 ath_hal_intrset(ah, sc->sc_imask); |
3886 sc->sc_kickpcu = 0; 3887 ATH_UNLOCK(sc); |
3888 } 3889 3890 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { 3891#ifdef IEEE80211_SUPPORT_SUPERG 3892 ieee80211_ff_age_all(ic, 100); 3893#endif 3894 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 3895 ath_start(ifp); --- 368 unchanged lines hidden (view full) --- 4264 * Flush fast-frame staging queue when traffic slows. 4265 */ 4266 if (txq->axq_depth <= 1) 4267 ieee80211_ff_flush(ic, txq->axq_ac); 4268#endif 4269 return nacked; 4270} 4271 |
4272#define TXQACTIVE(t, q) ( (t) & (1 << (q))) |
4273 4274/* 4275 * Deferred processing of transmit interrupt; special-cased 4276 * for a single hardware transmit queue (e.g. 5210 and 5211). 4277 */ 4278static void 4279ath_tx_proc_q0(void *arg, int npending) 4280{ 4281 struct ath_softc *sc = arg; 4282 struct ifnet *ifp = sc->sc_ifp; |
4283 uint32_t txqs; |
4284 |
4285 ATH_LOCK(sc); 4286 txqs = sc->sc_txq_active; 4287 sc->sc_txq_active &= ~txqs; 4288 ATH_UNLOCK(sc); 4289 4290 if (TXQACTIVE(txqs, 0) && ath_tx_processq(sc, &sc->sc_txq[0])) 4291 /* XXX why is lastrx updated in tx code? */ |
4292 sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); |
4293 if (TXQACTIVE(txqs, sc->sc_cabq->axq_qnum)) |
4294 ath_tx_processq(sc, sc->sc_cabq); 4295 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 4296 sc->sc_wd_timer = 0; 4297 4298 if (sc->sc_softled) 4299 ath_led_event(sc, sc->sc_txrix); 4300 4301 ath_start(ifp); --- 4 unchanged lines hidden (view full) --- 4306 * for four hardware queues, 0-3 (e.g. 5212 w/ WME support). 4307 */ 4308static void 4309ath_tx_proc_q0123(void *arg, int npending) 4310{ 4311 struct ath_softc *sc = arg; 4312 struct ifnet *ifp = sc->sc_ifp; 4313 int nacked; |
4314 uint32_t txqs; |
4315 |
4316 ATH_LOCK(sc); 4317 txqs = sc->sc_txq_active; 4318 sc->sc_txq_active &= ~txqs; 4319 ATH_UNLOCK(sc); 4320 |
4321 /* 4322 * Process each active queue. 4323 */ 4324 nacked = 0; |
4325 if (TXQACTIVE(txqs, 0)) |
4326 nacked += ath_tx_processq(sc, &sc->sc_txq[0]); |
4327 if (TXQACTIVE(txqs, 1)) |
4328 nacked += ath_tx_processq(sc, &sc->sc_txq[1]); |
4329 if (TXQACTIVE(txqs, 2)) |
4330 nacked += ath_tx_processq(sc, &sc->sc_txq[2]); |
4331 if (TXQACTIVE(txqs, 3)) |
4332 nacked += ath_tx_processq(sc, &sc->sc_txq[3]); |
4333 if (TXQACTIVE(txqs, sc->sc_cabq->axq_qnum)) |
4334 ath_tx_processq(sc, sc->sc_cabq); 4335 if (nacked) 4336 sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); 4337 4338 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 4339 sc->sc_wd_timer = 0; 4340 4341 if (sc->sc_softled) --- 6 unchanged lines hidden (view full) --- 4348 * Deferred processing of transmit interrupt. 4349 */ 4350static void 4351ath_tx_proc(void *arg, int npending) 4352{ 4353 struct ath_softc *sc = arg; 4354 struct ifnet *ifp = sc->sc_ifp; 4355 int i, nacked; |
4356 uint32_t txqs; |
4357 |
4358 ATH_LOCK(sc); 4359 txqs = sc->sc_txq_active; 4360 sc->sc_txq_active &= ~txqs; 4361 ATH_UNLOCK(sc); 4362 |
4363 /* 4364 * Process each active queue. 4365 */ 4366 nacked = 0; 4367 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) |
4368 if (ATH_TXQ_SETUP(sc, i) && TXQACTIVE(txqs, i)) |
4369 nacked += ath_tx_processq(sc, &sc->sc_txq[i]); 4370 if (nacked) 4371 sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); 4372 4373 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 4374 sc->sc_wd_timer = 0; 4375 4376 if (sc->sc_softled) --- 1548 unchanged lines hidden --- |