diff options
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/ar5008.c | 109 | ||||
-rw-r--r-- | sys/dev/ic/ar9003.c | 122 | ||||
-rw-r--r-- | sys/dev/ic/athn.c | 85 | ||||
-rw-r--r-- | sys/dev/ic/athnreg.h | 4 | ||||
-rw-r--r-- | sys/dev/ic/athnvar.h | 3 |
5 files changed, 285 insertions, 38 deletions
diff --git a/sys/dev/ic/ar5008.c b/sys/dev/ic/ar5008.c index 51efacdf524..00eebe4541b 100644 --- a/sys/dev/ic/ar5008.c +++ b/sys/dev/ic/ar5008.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5008.c,v 1.4 2010/05/16 08:55:39 damien Exp $ */ +/* $OpenBSD: ar5008.c,v 1.5 2010/05/16 09:19:48 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -86,6 +86,7 @@ void ar5008_rx_radiotap(struct athn_softc *, struct mbuf *, void ar5008_rx_intr(struct athn_softc *); int ar5008_tx_process(struct athn_softc *, int); void ar5008_tx_intr(struct athn_softc *); +int ar5008_swba_intr(struct athn_softc *); int ar5008_intr(struct athn_softc *); int ar5008_tx(struct athn_softc *, struct mbuf *, struct ieee80211_node *); void ar5008_set_rf_mode(struct athn_softc *, struct ieee80211_channel *); @@ -134,6 +135,8 @@ void athn_stop(struct ifnet *, int); int athn_interpolate(int, int, int, int, int); int athn_txtime(struct athn_softc *, int, int, u_int); void athn_inc_tx_trigger_level(struct athn_softc *); +int athn_tx_pending(struct athn_softc *, int); +void athn_stop_tx_dma(struct athn_softc *, int); void athn_get_delta_slope(uint32_t, uint32_t *, uint32_t *); void athn_config_pcie(struct athn_softc *); void athn_config_nonpcie(struct athn_softc *); @@ -1007,6 +1010,100 @@ ar5008_tx_intr(struct athn_softc *sc) } } +#ifndef IEEE80211_STA_ONLY +/* + * Process Software Beacon Alert interrupts. + */ +int +ar5008_swba_intr(struct athn_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct athn_tx_buf *bf = sc->bcnbuf; + struct ieee80211_frame *wh; + struct ar_tx_desc *ds; + struct mbuf *m; + uint8_t ridx, hwrate; + int error, totlen; + + if (ic->ic_dtim_count == 0) + ic->ic_dtim_count = ic->ic_dtim_period - 1; + else + ic->ic_dtim_count--; + + /* Make sure previous beacon has been sent. */ + if (athn_tx_pending(sc, ATHN_QID_BEACON)) { + DPRINTF(("beacon stuck\n")); + return (EBUSY); + } + /* Get new beacon. */ + m = ieee80211_beacon_alloc(ic, ic->ic_bss); + if (__predict_false(m == NULL)) + return (ENOBUFS); + /* Assign sequence number. */ + wh = mtod(m, struct ieee80211_frame *); + *(uint16_t *)&wh->i_seq[0] = + htole16(ic->ic_bss->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT); + ic->ic_bss->ni_txseq++; + + /* Unmap and free old beacon if any. */ + if (__predict_true(bf->bf_m != NULL)) { + bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, + bf->bf_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, bf->bf_map); + m_freem(bf->bf_m); + bf->bf_m = NULL; + } + /* DMA map new beacon. */ + error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m, + BUS_DMA_NOWAIT | BUS_DMA_WRITE); + if (__predict_false(error != 0)) { + m_freem(m); + return (error); + } + bf->bf_m = m; + + /* Setup Tx descriptor (simplified ar5008_tx()). */ + ds = bf->bf_descs; + memset(ds, 0, sizeof(*ds)); + + totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; + ds->ds_ctl0 = SM(AR_TXC0_FRAME_LEN, totlen); + ds->ds_ctl0 |= SM(AR_TXC0_XMIT_POWER, AR_MAX_RATE_POWER); + ds->ds_ctl1 = SM(AR_TXC1_FRAME_TYPE, AR_FRAME_TYPE_BEACON); + ds->ds_ctl1 |= AR_TXC1_NO_ACK; + ds->ds_ctl6 = SM(AR_TXC6_ENCR_TYPE, AR_ENCR_TYPE_CLEAR); + + /* Write number of tries. */ + ds->ds_ctl2 = SM(AR_TXC2_XMIT_DATA_TRIES0, 1); + + /* Write Tx rate. */ + ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ? + ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK1; + hwrate = athn_rates[ridx].hwrate; + ds->ds_ctl3 = SM(AR_TXC3_XMIT_RATE0, hwrate); + + /* Write Tx chains. */ + ds->ds_ctl7 = SM(AR_TXC7_CHAIN_SEL0, sc->txchainmask); + + ds->ds_data = bf->bf_map->dm_segs[0].ds_addr; + /* Segment length must be a multiple of 4. */ + ds->ds_ctl1 |= SM(AR_TXC1_BUF_LEN, + (bf->bf_map->dm_segs[0].ds_len + 3) & ~3); + + bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize, + BUS_DMASYNC_PREWRITE); + + /* Stop Tx DMA before putting the new beacon on the queue. */ + athn_stop_tx_dma(sc, ATHN_QID_BEACON); + + AR_WRITE(sc, AR_QTXDP(ATHN_QID_BEACON), bf->bf_daddr); + + /* Kick Tx. */ + AR_WRITE(sc, AR_Q_TXE, 1 << ATHN_QID_BEACON); + return (0); +} +#endif + int ar5008_intr(struct athn_softc *sc) { @@ -1041,6 +1138,10 @@ ar5008_intr(struct athn_softc *sc) if (intr == AR_INTR_SPURIOUS) return (1); +#ifndef IEEE80211_STA_ONLY + if (intr & AR_ISR_SWBA) + ar5008_swba_intr(sc); +#endif if (intr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) ar5008_rx_intr(sc); if (intr & (AR_ISR_RXOK | AR_ISR_RXERR | AR_ISR_RXORN)) @@ -1116,10 +1217,8 @@ ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) wh = mtod(m, struct ieee80211_frame *); if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) { + /* NB: Beacons do not use ar5008_tx(). */ if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == - IEEE80211_FC0_SUBTYPE_BEACON) - type = AR_FRAME_TYPE_BEACON; - else if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) type = AR_FRAME_TYPE_PROBE_RESP; else if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == @@ -1148,8 +1247,6 @@ ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) qos = ieee80211_get_qos(wh); tid = qos & IEEE80211_QOS_TID; qid = athn_ac2qid[ieee80211_up_to_ac(ic, tid)]; - } else if (type == AR_FRAME_TYPE_BEACON) { - qid = ATHN_QID_BEACON; } else if (type == AR_FRAME_TYPE_PSPOLL) { qid = ATHN_QID_PSPOLL; } else diff --git a/sys/dev/ic/ar9003.c b/sys/dev/ic/ar9003.c index de38a9ba3af..1038ac987ad 100644 --- a/sys/dev/ic/ar9003.c +++ b/sys/dev/ic/ar9003.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar9003.c,v 1.7 2010/05/16 09:01:05 damien Exp $ */ +/* $OpenBSD: ar9003.c,v 1.8 2010/05/16 09:19:48 damien Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> @@ -90,6 +90,7 @@ int ar9003_rx_process(struct athn_softc *, int); void ar9003_rx_intr(struct athn_softc *, int); int ar9003_tx_process(struct athn_softc *); void ar9003_tx_intr(struct athn_softc *); +int ar9003_swba_intr(struct athn_softc *); int ar9003_intr(struct athn_softc *); int ar9003_tx(struct athn_softc *, struct mbuf *, struct ieee80211_node *); void ar9003_set_rf_mode(struct athn_softc *, struct ieee80211_channel *); @@ -139,6 +140,8 @@ void athn_stop(struct ifnet *, int); int athn_interpolate(int, int, int, int, int); int athn_txtime(struct athn_softc *, int, int, u_int); void athn_inc_tx_trigger_level(struct athn_softc *); +int athn_tx_pending(struct athn_softc *, int); +void athn_stop_tx_dma(struct athn_softc *, int); void athn_get_delta_slope(uint32_t, uint32_t *, uint32_t *); void athn_config_pcie(struct athn_softc *); void athn_config_nonpcie(struct athn_softc *); @@ -1024,6 +1027,113 @@ ar9003_tx_intr(struct athn_softc *sc) while (ar9003_tx_process(sc) == 0); } +#ifndef IEEE80211_STA_ONLY +/* + * Process Software Beacon Alert interrupts. + */ +int +ar9003_swba_intr(struct athn_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct athn_tx_buf *bf = sc->bcnbuf; + struct ieee80211_frame *wh; + struct ar_tx_desc *ds; + struct mbuf *m; + uint32_t sum; + uint8_t ridx, hwrate; + int error, totlen; + + if (ic->ic_dtim_count == 0) + ic->ic_dtim_count = ic->ic_dtim_period - 1; + else + ic->ic_dtim_count--; + + /* Make sure previous beacon has been sent. */ + if (athn_tx_pending(sc, ATHN_QID_BEACON)) { + DPRINTF(("beacon stuck problem\n")); + return (EBUSY); + } + /* Get new beacon. */ + m = ieee80211_beacon_alloc(ic, ic->ic_bss); + if (__predict_false(m == NULL)) + return (ENOBUFS); + /* Assign sequence number. */ + wh = mtod(m, struct ieee80211_frame *); + *(uint16_t *)&wh->i_seq[0] = + htole16(ic->ic_bss->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT); + ic->ic_bss->ni_txseq++; + + /* Unmap and free old beacon if any. */ + if (__predict_true(bf->bf_m != NULL)) { + bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, + bf->bf_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, bf->bf_map); + m_freem(bf->bf_m); + bf->bf_m = NULL; + } + /* DMA map new beacon. */ + error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m, + BUS_DMA_NOWAIT | BUS_DMA_WRITE); + if (__predict_false(error != 0)) { + m_freem(m); + return (error); + } + bf->bf_m = m; + + /* Setup Tx descriptor (simplified ar9003_tx()). */ + ds = bf->bf_descs; + memset(ds, 0, sizeof(*ds)); + + ds->ds_info = + SM(AR_TXI_DESC_ID, AR_VENDOR_ATHEROS) | + SM(AR_TXI_DESC_NDWORDS, 23) | + SM(AR_TXI_QCU_NUM, ATHN_QID_BEACON) | + AR_TXI_DESC_TX | AR_TXI_CTRL_STAT; + + totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; + ds->ds_ctl11 = SM(AR_TXC11_FRAME_LEN, totlen); + ds->ds_ctl11 |= SM(AR_TXC11_XMIT_POWER, AR_MAX_RATE_POWER); + ds->ds_ctl12 = SM(AR_TXC12_FRAME_TYPE, AR_FRAME_TYPE_BEACON); + ds->ds_ctl12 |= AR_TXC12_NO_ACK; + ds->ds_ctl17 = SM(AR_TXC17_ENCR_TYPE, AR_ENCR_TYPE_CLEAR); + + /* Write number of tries. */ + ds->ds_ctl13 = SM(AR_TXC13_XMIT_DATA_TRIES0, 1); + + /* Write Tx rate. */ + ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ? + ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK1; + hwrate = athn_rates[ridx].hwrate; + ds->ds_ctl14 = SM(AR_TXC14_XMIT_RATE0, hwrate); + + /* Write Tx chains. */ + ds->ds_ctl18 = SM(AR_TXC18_CHAIN_SEL0, sc->txchainmask); + + ds->ds_segs[0].ds_data = bf->bf_map->dm_segs[0].ds_addr; + /* Segment length must be a multiple of 4. */ + ds->ds_segs[0].ds_ctl |= SM(AR_TXC_BUF_LEN, + (bf->bf_map->dm_segs[0].ds_len + 3) & ~3); + /* Compute Tx descriptor checksum. */ + sum = ds->ds_info; + sum += ds->ds_segs[0].ds_data; + sum += ds->ds_segs[0].ds_ctl; + sum = (sum >> 16) + (sum & 0xffff); + ds->ds_ctl10 = SM(AR_TXC10_PTR_CHK_SUM, sum); + + bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize, + BUS_DMASYNC_PREWRITE); + + /* Stop Tx DMA before putting the new beacon on the queue. */ + athn_stop_tx_dma(sc, ATHN_QID_BEACON); + + AR_WRITE(sc, AR_QTXDP(ATHN_QID_BEACON), bf->bf_daddr); + + /* Kick Tx. */ + AR_WRITE(sc, AR_Q_TXE, 1 << ATHN_QID_BEACON); + return (0); +} +#endif + int ar9003_intr(struct athn_softc *sc) { @@ -1058,6 +1168,10 @@ ar9003_intr(struct athn_softc *sc) if (intr == AR_INTR_SPURIOUS) return (1); +#ifndef IEEE80211_STA_ONLY + if (intr & AR_ISR_SWBA) + ar9003_swba_intr(sc); +#endif if (intr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) ar9003_rx_intr(sc, ATHN_QID_LP); if (intr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) @@ -1127,10 +1241,8 @@ ar9003_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) wh = mtod(m, struct ieee80211_frame *); if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) { + /* NB: Beacons do not use ar9003_tx(). */ if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == - IEEE80211_FC0_SUBTYPE_BEACON) - type = AR_FRAME_TYPE_BEACON; - else if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) type = AR_FRAME_TYPE_PROBE_RESP; else if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == @@ -1159,8 +1271,6 @@ ar9003_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) qos = ieee80211_get_qos(wh); tid = qos & IEEE80211_QOS_TID; qid = athn_ac2qid[ieee80211_up_to_ac(ic, tid)]; - } else if (type == AR_FRAME_TYPE_BEACON) { - qid = ATHN_QID_BEACON; } else if (type == AR_FRAME_TYPE_PSPOLL) { qid = ATHN_QID_PSPOLL; } else diff --git a/sys/dev/ic/athn.c b/sys/dev/ic/athn.c index 2bbe3409f24..719e5558a78 100644 --- a/sys/dev/ic/athn.c +++ b/sys/dev/ic/athn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: athn.c,v 1.41 2010/05/16 09:02:13 damien Exp $ */ +/* $OpenBSD: athn.c,v 1.42 2010/05/16 09:19:48 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -112,7 +112,8 @@ void athn_tx_reclaim(struct athn_softc *, int); int athn_tx_pending(struct athn_softc *, int); void athn_stop_tx_dma(struct athn_softc *, int); int athn_txtime(struct athn_softc *, int, int, u_int); -void athn_set_beacon_timers(struct athn_softc *); +void athn_set_sta_timers(struct athn_softc *); +void athn_set_hostap_timers(struct athn_softc *); void athn_set_opmode(struct athn_softc *); void athn_set_bss(struct athn_softc *, struct ieee80211_node *); void athn_enable_interrupts(struct athn_softc *); @@ -194,6 +195,7 @@ athn_attach(struct athn_softc *sc) printf(": could not attach chip\n"); return (error); } + printf(", address %s\n", ether_sprintf(ic->ic_myaddr)); /* We can put the chip in sleep state now. */ athn_set_power_sleep(sc); @@ -204,8 +206,9 @@ athn_attach(struct athn_softc *sc) sc->sc_dev.dv_xname); return (error); } - - printf(", address %s\n", ether_sprintf(ic->ic_myaddr)); + /* Steal one Tx buffer for beacons. */ + sc->bcnbuf = SIMPLEQ_FIRST(&sc->txbufs); + SIMPLEQ_REMOVE_HEAD(&sc->txbufs, bf_list); if (sc->flags & ATHN_FLAG_RFSILENT) { DPRINTF(("found RF switch connected to GPIO pin %d\n", @@ -258,12 +261,15 @@ athn_attach(struct athn_softc *sc) /* Set device capabilities. */ ic->ic_caps = - IEEE80211_C_WEP | /* WEP */ - IEEE80211_C_RSN | /* WPA/RSN */ - IEEE80211_C_MONITOR | /* monitor mode supported */ - IEEE80211_C_SHSLOT | /* short slot time supported */ - IEEE80211_C_SHPREAMBLE | /* short preamble supported */ - IEEE80211_C_PMGT; /* power saving supported */ + IEEE80211_C_WEP | /* WEP. */ + IEEE80211_C_RSN | /* WPA/RSN. */ +#ifndef IEEE80211_STA_ONLY + IEEE80211_C_HOSTAP | /* Host Ap mode supported. */ +#endif + IEEE80211_C_MONITOR | /* Monitor mode supported. */ + IEEE80211_C_SHSLOT | /* Short slot time supported. */ + IEEE80211_C_SHPREAMBLE | /* Short preamble supported. */ + IEEE80211_C_PMGT; /* Power saving supported. */ #ifndef IEEE80211_NO_HT if (sc->flags & ATHN_FLAG_11N) { @@ -1688,7 +1694,6 @@ athn_txtime(struct athn_softc *sc, int len, int ridx, u_int flags) void athn_init_tx_queues(struct athn_softc *sc) { - uint32_t reg; int qid; for (qid = 0; qid < ATHN_QID_COUNT; qid++) { @@ -1715,13 +1720,10 @@ athn_init_tx_queues(struct athn_softc *sc) AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL) | AR_D_MISC_BEACON_USE | AR_D_MISC_POST_FR_BKOFF_DIS); - if (AR_SREV_9380_10_OR_LATER(sc)) { - /* CWmin and CWmax should be 0 for beacon queue. */ - reg = AR_READ(sc, AR_DLCL_IFS(ATHN_QID_BEACON)); - reg = RW(reg, AR_D_LCL_IFS_CWMIN, 0); - reg = RW(reg, AR_D_LCL_IFS_CWMAX, 0); - AR_WRITE(sc, AR_DLCL_IFS(ATHN_QID_BEACON), reg); - } + AR_WRITE(sc, AR_DLCL_IFS(ATHN_QID_BEACON), + SM(AR_D_LCL_IFS_CWMIN, 0) | + SM(AR_D_LCL_IFS_CWMAX, 0) | + SM(AR_D_LCL_IFS_AIFS, 1)); /* Init CAB (Content After Beacon) queue. */ AR_SETBITS(sc, AR_QMISC(ATHN_QID_CAB), @@ -1750,10 +1752,9 @@ athn_init_tx_queues(struct athn_softc *sc) } void -athn_set_beacon_timers(struct athn_softc *sc) +athn_set_sta_timers(struct athn_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; uint32_t tsfhi, tsflo, tsftu, reg; uint32_t intval, next_tbtt, next_dtim; int dtim_period, dtim_count, rem_dtim_count; @@ -1763,7 +1764,7 @@ athn_set_beacon_timers(struct athn_softc *sc) tsftu = AR_TSF_TO_TU(tsfhi, tsflo) + AR_FUDGE; /* Beacon interval in TU. */ - intval = ni->ni_intval; + intval = ic->ic_bss->ni_intval; next_tbtt = roundup(tsftu, intval); #ifdef notyet @@ -1816,6 +1817,33 @@ athn_set_beacon_timers(struct athn_softc *sc) AR_WRITE(sc, AR_TSFOOR_THRESHOLD, 0x4240); } +#ifndef IEEE80211_STA_ONLY +void +athn_set_hostap_timers(struct athn_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + uint32_t intval, next_tbtt; + + /* Beacon interval in TU. */ + intval = ic->ic_bss->ni_intval; + next_tbtt = intval; + + AR_WRITE(sc, AR_NEXT_TBTT_TIMER, next_tbtt * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_NEXT_DMA_BEACON_ALERT, + (next_tbtt - AR_BEACON_DMA_DELAY) * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_NEXT_CFP, + (next_tbtt - AR_SWBA_DELAY) * IEEE80211_DUR_TU); + + AR_WRITE(sc, AR_BEACON_PERIOD, intval * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_DMA_BEACON_PERIOD, intval * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_SWBA_PERIOD, intval * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_NDP_PERIOD, intval * IEEE80211_DUR_TU); + + AR_WRITE(sc, AR_TIMER_MODE, + AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN); +} +#endif + void athn_set_opmode(struct athn_softc *sc) { @@ -2256,9 +2284,18 @@ athn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) athn_set_bss(sc, ic->ic_bss); athn_disable_interrupts(sc); - athn_set_beacon_timers(sc); - /* Enable beacon miss interrupts. */ - sc->imask |= AR_IMR_BMISS; +#ifndef IEEE80211_STA_ONLY + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + athn_set_hostap_timers(sc); + /* Enable sotfware beacon alert interrupts. */ + sc->imask |= AR_IMR_SWBA; + } else +#endif + { + athn_set_sta_timers(sc); + /* Enable beacon miss interrupts. */ + sc->imask |= AR_IMR_BMISS; + } athn_enable_interrupts(sc); /* XXX Start ANI. */ diff --git a/sys/dev/ic/athnreg.h b/sys/dev/ic/athnreg.h index 2e2008c3042..4fcc16ca510 100644 --- a/sys/dev/ic/athnreg.h +++ b/sys/dev/ic/athnreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: athnreg.h,v 1.10 2010/05/16 08:50:58 damien Exp $ */ +/* $OpenBSD: athnreg.h,v 1.11 2010/05/16 09:19:48 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -1280,6 +1280,8 @@ #define AR_MIN_BEACON_TIMEOUT_VAL 1 #define AR_FUDGE 2 +#define AR_BEACON_DMA_DELAY 2 +#define AR_SWBA_DELAY 10 /* Divides by 1024 (usecs to TU) without doing 64-bit arithmetic. */ #define AR_TSF_TO_TU(hi, lo) ((hi) << 22 | (lo) >> 10) diff --git a/sys/dev/ic/athnvar.h b/sys/dev/ic/athnvar.h index 66a4c4d377a..db931042038 100644 --- a/sys/dev/ic/athnvar.h +++ b/sys/dev/ic/athnvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: athnvar.h,v 1.11 2010/05/11 19:34:20 damien Exp $ */ +/* $OpenBSD: athnvar.h,v 1.12 2010/05/16 09:19:48 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -474,6 +474,7 @@ struct athn_softc { bus_dmamap_t map; bus_dma_segment_t seg; SIMPLEQ_HEAD(, athn_tx_buf) txbufs; + struct athn_tx_buf *bcnbuf; struct athn_tx_buf txpool[ATHN_NTXBUFS]; bus_dmamap_t txsmap; |