if_ath_rx_edma.c (265349) | if_ath_rx_edma.c (271887) |
---|---|
1/*- 2 * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org> 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> | 1/*- 2 * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org> 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_rx_edma.c 265349 2014-05-05 08:00:50Z adrian $"); | 31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_rx_edma.c 271887 2014-09-20 01:22:17Z 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 --- 115 unchanged lines hidden (view full) --- 155 HAL_RX_QUEUE qtype, int dosched); 156 157static void 158ath_edma_stoprecv(struct ath_softc *sc, int dodelay) 159{ 160 struct ath_hal *ah = sc->sc_ah; 161 162 ATH_RX_LOCK(sc); | 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 --- 115 unchanged lines hidden (view full) --- 155 HAL_RX_QUEUE qtype, int dosched); 156 157static void 158ath_edma_stoprecv(struct ath_softc *sc, int dodelay) 159{ 160 struct ath_hal *ah = sc->sc_ah; 161 162 ATH_RX_LOCK(sc); |
163 |
|
163 ath_hal_stoppcurecv(ah); 164 ath_hal_setrxfilter(ah, 0); | 164 ath_hal_stoppcurecv(ah); 165 ath_hal_setrxfilter(ah, 0); |
165 ath_hal_stopdmarecv(ah); | |
166 | 166 |
167 /* 168 * 169 */ 170 if (ath_hal_stopdmarecv(ah) == AH_TRUE) 171 sc->sc_rx_stopped = 1; 172 173 /* 174 * Give the various bus FIFOs (not EDMA descriptor FIFO) 175 * time to finish flushing out data. 176 */ |
|
167 DELAY(3000); 168 169 /* Flush RX pending for each queue */ 170 /* XXX should generic-ify this */ 171 if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending) { 172 m_freem(sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending); 173 sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL; 174 } --- 38 unchanged lines hidden (view full) --- 213 __func__, 214 i, 215 re->m_fifo_tail); 216 } 217} 218 219/* 220 * Start receive. | 177 DELAY(3000); 178 179 /* Flush RX pending for each queue */ 180 /* XXX should generic-ify this */ 181 if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending) { 182 m_freem(sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending); 183 sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL; 184 } --- 38 unchanged lines hidden (view full) --- 223 __func__, 224 i, 225 re->m_fifo_tail); 226 } 227} 228 229/* 230 * Start receive. |
221 * 222 * XXX TODO: this needs to reallocate the FIFO entries when a reset 223 * occurs, in case the FIFO is filled up and no new descriptors get 224 * thrown into the FIFO. | |
225 */ 226static int 227ath_edma_startrecv(struct ath_softc *sc) 228{ 229 struct ath_hal *ah = sc->sc_ah; 230 231 ATH_RX_LOCK(sc); 232 | 231 */ 232static int 233ath_edma_startrecv(struct ath_softc *sc) 234{ 235 struct ath_hal *ah = sc->sc_ah; 236 237 ATH_RX_LOCK(sc); 238 |
239 /* 240 * Sanity check - are we being called whilst RX 241 * isn't stopped? If so, we may end up pushing 242 * too many entries into the RX FIFO and 243 * badness occurs. 244 */ 245 |
|
233 /* Enable RX FIFO */ 234 ath_hal_rxena(ah); 235 236 /* | 246 /* Enable RX FIFO */ 247 ath_hal_rxena(ah); 248 249 /* |
237 * Entries should only be written out if the 238 * FIFO is empty. 239 * 240 * XXX This isn't correct. I should be looking 241 * at the value of AR_RXDP_SIZE (0x0070) to determine 242 * how many entries are in here. 243 * 244 * A warm reset will clear the registers but not the FIFO. 245 * 246 * And I believe this is actually the address of the last 247 * handled buffer rather than the current FIFO pointer. 248 * So if no frames have been (yet) seen, we'll reinit the 249 * FIFO. 250 * 251 * I'll chase that up at some point. | 250 * In theory the hardware has been initialised, right? |
252 */ | 251 */ |
253 if (ath_hal_getrxbuf(sc->sc_ah, HAL_RX_QUEUE_HP) == 0) { | 252 if (sc->sc_rx_resetted == 1) { |
254 DPRINTF(sc, ATH_DEBUG_EDMA_RX, 255 "%s: Re-initing HP FIFO\n", __func__); 256 ath_edma_reinit_fifo(sc, HAL_RX_QUEUE_HP); | 253 DPRINTF(sc, ATH_DEBUG_EDMA_RX, 254 "%s: Re-initing HP FIFO\n", __func__); 255 ath_edma_reinit_fifo(sc, HAL_RX_QUEUE_HP); |
257 } 258 if (ath_hal_getrxbuf(sc->sc_ah, HAL_RX_QUEUE_LP) == 0) { | |
259 DPRINTF(sc, ATH_DEBUG_EDMA_RX, 260 "%s: Re-initing LP FIFO\n", __func__); 261 ath_edma_reinit_fifo(sc, HAL_RX_QUEUE_LP); | 256 DPRINTF(sc, ATH_DEBUG_EDMA_RX, 257 "%s: Re-initing LP FIFO\n", __func__); 258 ath_edma_reinit_fifo(sc, HAL_RX_QUEUE_LP); |
259 sc->sc_rx_resetted = 0; 260 } else { 261 device_printf(sc->sc_dev, 262 "%s: called without resetting chip?\n", 263 __func__); |
|
262 } 263 264 /* Add up to m_fifolen entries in each queue */ 265 /* 266 * These must occur after the above write so the FIFO buffers 267 * are pushed/tracked in the same order as the hardware will 268 * process them. | 264 } 265 266 /* Add up to m_fifolen entries in each queue */ 267 /* 268 * These must occur after the above write so the FIFO buffers 269 * are pushed/tracked in the same order as the hardware will 270 * process them. |
271 * 272 * XXX TODO: is this really necessary? We should've stopped 273 * the hardware already and reinitialised it, so it's a no-op. |
|
269 */ 270 ath_edma_rxfifo_alloc(sc, HAL_RX_QUEUE_HP, 271 sc->sc_rxedma[HAL_RX_QUEUE_HP].m_fifolen); 272 273 ath_edma_rxfifo_alloc(sc, HAL_RX_QUEUE_LP, 274 sc->sc_rxedma[HAL_RX_QUEUE_LP].m_fifolen); 275 276 ath_mode_init(sc); 277 ath_hal_startpcurecv(ah); 278 | 274 */ 275 ath_edma_rxfifo_alloc(sc, HAL_RX_QUEUE_HP, 276 sc->sc_rxedma[HAL_RX_QUEUE_HP].m_fifolen); 277 278 ath_edma_rxfifo_alloc(sc, HAL_RX_QUEUE_LP, 279 sc->sc_rxedma[HAL_RX_QUEUE_LP].m_fifolen); 280 281 ath_mode_init(sc); 282 ath_hal_startpcurecv(ah); 283 |
284 /* 285 * We're now doing RX DMA! 286 */ 287 sc->sc_rx_stopped = 0; 288 |
|
279 ATH_RX_UNLOCK(sc); 280 281 return (0); 282} 283 284static void 285ath_edma_recv_sched_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, 286 int dosched) --- 88 unchanged lines hidden (view full) --- 375 int npkts = 0; 376 377 tsf = ath_hal_gettsf64(ah); 378 nf = ath_hal_getchannoise(ah, sc->sc_curchan); 379 sc->sc_stats.ast_rx_noise = nf; 380 381 ATH_RX_LOCK(sc); 382 | 289 ATH_RX_UNLOCK(sc); 290 291 return (0); 292} 293 294static void 295ath_edma_recv_sched_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, 296 int dosched) --- 88 unchanged lines hidden (view full) --- 385 int npkts = 0; 386 387 tsf = ath_hal_gettsf64(ah); 388 nf = ath_hal_getchannoise(ah, sc->sc_curchan); 389 sc->sc_stats.ast_rx_noise = nf; 390 391 ATH_RX_LOCK(sc); 392 |
393#if 1 394 if (sc->sc_rx_resetted == 1) { 395 /* 396 * XXX We shouldn't ever be scheduled if 397 * receive has been stopped - so complain 398 * loudly! 399 */ 400 device_printf(sc->sc_dev, 401 "%s: sc_rx_resetted=1! Bad!\n", 402 __func__); 403 ATH_RX_UNLOCK(sc); 404 return; 405 } 406#endif 407 |
|
383 do { 384 bf = re->m_fifo[re->m_fifo_head]; 385 /* This shouldn't occur! */ 386 if (bf == NULL) { 387 device_printf(sc->sc_dev, "%s: Q%d: NULL bf?\n", 388 __func__, 389 qtype); 390 break; --- 55 unchanged lines hidden (view full) --- 446 447 /* rx signal state monitoring */ 448 ath_hal_rxmonitor(ah, &sc->sc_halstats, sc->sc_curchan); 449 450 ATH_KTR(sc, ATH_KTR_INTERRUPTS, 1, 451 "ath edma rx proc: npkts=%d\n", 452 npkts); 453 | 408 do { 409 bf = re->m_fifo[re->m_fifo_head]; 410 /* This shouldn't occur! */ 411 if (bf == NULL) { 412 device_printf(sc->sc_dev, "%s: Q%d: NULL bf?\n", 413 __func__, 414 qtype); 415 break; --- 55 unchanged lines hidden (view full) --- 471 472 /* rx signal state monitoring */ 473 ath_hal_rxmonitor(ah, &sc->sc_halstats, sc->sc_curchan); 474 475 ATH_KTR(sc, ATH_KTR_INTERRUPTS, 1, 476 "ath edma rx proc: npkts=%d\n", 477 npkts); 478 |
454 /* Handle resched and kickpcu appropriately */ 455 ATH_PCU_LOCK(sc); 456 if (dosched && sc->sc_kickpcu) { 457 ATH_KTR(sc, ATH_KTR_ERROR, 0, 458 "ath_edma_recv_proc_queue(): kickpcu"); 459 if (npkts > 0) 460 device_printf(sc->sc_dev, 461 "%s: handled npkts %d\n", 462 __func__, npkts); 463 464 /* 465 * XXX TODO: what should occur here? Just re-poke and 466 * re-enable the RX FIFO? 467 */ 468 sc->sc_kickpcu = 0; 469 } 470 ATH_PCU_UNLOCK(sc); 471 | |
472 return; 473} 474 475/* 476 * Flush the deferred queue. 477 * 478 * This destructively flushes the deferred queue - it doesn't 479 * call the wireless stack on each mbuf. --- 527 unchanged lines hidden --- | 479 return; 480} 481 482/* 483 * Flush the deferred queue. 484 * 485 * This destructively flushes the deferred queue - it doesn't 486 * call the wireless stack on each mbuf. --- 527 unchanged lines hidden --- |