summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-05-20 06:35:22 +0000
committeradrian <adrian@FreeBSD.org>2012-05-20 06:35:22 +0000
commite1654c32a71d2e40d8b2a80bee3314a8b2896d0b (patch)
tree339b51c65dfa576455c9388251dfd77c318b6a0b
parentb8d578077a6ca2ae9225c87dc8ffa19aa26b462a (diff)
downloadFreeBSD-src-e1654c32a71d2e40d8b2a80bee3314a8b2896d0b.zip
FreeBSD-src-e1654c32a71d2e40d8b2a80bee3314a8b2896d0b.tar.gz
Migrate the per-frame code out from ath_rx_proc() to ath_rx_pkt().
This will (eventually) be used by the EDMA RX path used by the AR93xx and later NICs.
-rw-r--r--sys/dev/ath/if_ath_rx.c636
1 files changed, 328 insertions, 308 deletions
diff --git a/sys/dev/ath/if_ath_rx.c b/sys/dev/ath/if_ath_rx.c
index e8d6f4d..27b5eba 100644
--- a/sys/dev/ath/if_ath_rx.c
+++ b/sys/dev/ath/if_ath_rx.c
@@ -437,6 +437,327 @@ ath_rx_tasklet(void *arg, int npending)
ath_rx_proc(sc, 1);
}
+static int
+ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status,
+ uint64_t tsf, int nf, struct ath_buf *bf)
+{
+ struct ath_hal *ah = sc->sc_ah;
+ struct mbuf *m = bf->bf_m;
+ uint64_t rstamp;
+ int len, type;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211_node *ni;
+ int is_good = 0;
+
+ /*
+ * Calculate the correct 64 bit TSF given
+ * the TSF64 register value and rs_tstamp.
+ */
+ rstamp = ath_extend_tsf(sc, rs->rs_tstamp, tsf);
+
+ /* These aren't specifically errors */
+#ifdef AH_SUPPORT_AR5416
+ if (rs->rs_flags & HAL_RX_GI)
+ sc->sc_stats.ast_rx_halfgi++;
+ if (rs->rs_flags & HAL_RX_2040)
+ sc->sc_stats.ast_rx_2040++;
+ if (rs->rs_flags & HAL_RX_DELIM_CRC_PRE)
+ sc->sc_stats.ast_rx_pre_crc_err++;
+ if (rs->rs_flags & HAL_RX_DELIM_CRC_POST)
+ sc->sc_stats.ast_rx_post_crc_err++;
+ if (rs->rs_flags & HAL_RX_DECRYPT_BUSY)
+ sc->sc_stats.ast_rx_decrypt_busy_err++;
+ if (rs->rs_flags & HAL_RX_HI_RX_CHAIN)
+ sc->sc_stats.ast_rx_hi_rx_chain++;
+#endif /* AH_SUPPORT_AR5416 */
+
+ if (rs->rs_status != 0) {
+ if (rs->rs_status & HAL_RXERR_CRC)
+ sc->sc_stats.ast_rx_crcerr++;
+ if (rs->rs_status & HAL_RXERR_FIFO)
+ sc->sc_stats.ast_rx_fifoerr++;
+ if (rs->rs_status & HAL_RXERR_PHY) {
+ sc->sc_stats.ast_rx_phyerr++;
+ /* Process DFS radar events */
+ if ((rs->rs_phyerr == HAL_PHYERR_RADAR) ||
+ (rs->rs_phyerr == HAL_PHYERR_FALSE_RADAR_EXT)) {
+ /* Since we're touching the frame data, sync it */
+ bus_dmamap_sync(sc->sc_dmat,
+ bf->bf_dmamap,
+ BUS_DMASYNC_POSTREAD);
+ /* Now pass it to the radar processing code */
+ ath_dfs_process_phy_err(sc, mtod(m, char *), rstamp, rs);
+ }
+
+ /* Be suitably paranoid about receiving phy errors out of the stats array bounds */
+ if (rs->rs_phyerr < 64)
+ sc->sc_stats.ast_rx_phy[rs->rs_phyerr]++;
+ goto rx_error; /* NB: don't count in ierrors */
+ }
+ if (rs->rs_status & HAL_RXERR_DECRYPT) {
+ /*
+ * Decrypt error. If the error occurred
+ * because there was no hardware key, then
+ * let the frame through so the upper layers
+ * can process it. This is necessary for 5210
+ * parts which have no way to setup a ``clear''
+ * key cache entry.
+ *
+ * XXX do key cache faulting
+ */
+ if (rs->rs_keyix == HAL_RXKEYIX_INVALID)
+ goto rx_accept;
+ sc->sc_stats.ast_rx_badcrypt++;
+ }
+ if (rs->rs_status & HAL_RXERR_MIC) {
+ sc->sc_stats.ast_rx_badmic++;
+ /*
+ * Do minimal work required to hand off
+ * the 802.11 header for notification.
+ */
+ /* XXX frag's and qos frames */
+ len = rs->rs_datalen;
+ if (len >= sizeof (struct ieee80211_frame)) {
+ bus_dmamap_sync(sc->sc_dmat,
+ bf->bf_dmamap,
+ BUS_DMASYNC_POSTREAD);
+ ath_handle_micerror(ic,
+ mtod(m, struct ieee80211_frame *),
+ sc->sc_splitmic ?
+ rs->rs_keyix-32 : rs->rs_keyix);
+ }
+ }
+ ifp->if_ierrors++;
+rx_error:
+ /*
+ * Cleanup any pending partial frame.
+ */
+ if (sc->sc_rxpending != NULL) {
+ m_freem(sc->sc_rxpending);
+ sc->sc_rxpending = NULL;
+ }
+ /*
+ * When a tap is present pass error frames
+ * that have been requested. By default we
+ * pass decrypt+mic errors but others may be
+ * interesting (e.g. crc).
+ */
+ if (ieee80211_radiotap_active(ic) &&
+ (rs->rs_status & sc->sc_monpass)) {
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
+ BUS_DMASYNC_POSTREAD);
+ /* NB: bpf needs the mbuf length setup */
+ len = rs->rs_datalen;
+ m->m_pkthdr.len = m->m_len = len;
+ bf->bf_m = NULL;
+ ath_rx_tap(ifp, m, rs, rstamp, nf);
+ ieee80211_radiotap_rx_all(ic, m);
+ m_freem(m);
+ }
+ /* XXX pass MIC errors up for s/w reclaculation */
+ goto rx_next;
+ }
+rx_accept:
+ /*
+ * Sync and unmap the frame. At this point we're
+ * committed to passing the mbuf somewhere so clear
+ * bf_m; this means a new mbuf must be allocated
+ * when the rx descriptor is setup again to receive
+ * another frame.
+ */
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
+ bf->bf_m = NULL;
+
+ len = rs->rs_datalen;
+ m->m_len = len;
+
+ if (rs->rs_more) {
+ /*
+ * Frame spans multiple descriptors; save
+ * it for the next completed descriptor, it
+ * will be used to construct a jumbogram.
+ */
+ if (sc->sc_rxpending != NULL) {
+ /* NB: max frame size is currently 2 clusters */
+ sc->sc_stats.ast_rx_toobig++;
+ m_freem(sc->sc_rxpending);
+ }
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = len;
+ sc->sc_rxpending = m;
+ goto rx_next;
+ } else if (sc->sc_rxpending != NULL) {
+ /*
+ * This is the second part of a jumbogram,
+ * chain it to the first mbuf, adjust the
+ * frame length, and clear the rxpending state.
+ */
+ sc->sc_rxpending->m_next = m;
+ sc->sc_rxpending->m_pkthdr.len += len;
+ m = sc->sc_rxpending;
+ sc->sc_rxpending = NULL;
+ } else {
+ /*
+ * Normal single-descriptor receive; setup
+ * the rcvif and packet length.
+ */
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = len;
+ }
+
+ /*
+ * Validate rs->rs_antenna.
+ *
+ * Some users w/ AR9285 NICs have reported crashes
+ * here because rs_antenna field is bogusly large.
+ * Let's enforce the maximum antenna limit of 8
+ * (and it shouldn't be hard coded, but that's a
+ * separate problem) and if there's an issue, print
+ * out an error and adjust rs_antenna to something
+ * sensible.
+ *
+ * This code should be removed once the actual
+ * root cause of the issue has been identified.
+ * For example, it may be that the rs_antenna
+ * field is only valid for the lsat frame of
+ * an aggregate and it just happens that it is
+ * "mostly" right. (This is a general statement -
+ * the majority of the statistics are only valid
+ * for the last frame in an aggregate.
+ */
+ if (rs->rs_antenna > 7) {
+ device_printf(sc->sc_dev, "%s: rs_antenna > 7 (%d)\n",
+ __func__, rs->rs_antenna);
+#ifdef ATH_DEBUG
+ ath_printrxbuf(sc, bf, 0, status == HAL_OK);
+#endif /* ATH_DEBUG */
+ rs->rs_antenna = 0; /* XXX better than nothing */
+ }
+
+ ifp->if_ipackets++;
+ sc->sc_stats.ast_ant_rx[rs->rs_antenna]++;
+
+ /*
+ * Populate the rx status block. When there are bpf
+ * listeners we do the additional work to provide
+ * complete status. Otherwise we fill in only the
+ * material required by ieee80211_input. Note that
+ * noise setting is filled in above.
+ */
+ if (ieee80211_radiotap_active(ic))
+ ath_rx_tap(ifp, m, rs, rstamp, nf);
+
+ /*
+ * From this point on we assume the frame is at least
+ * as large as ieee80211_frame_min; verify that.
+ */
+ if (len < IEEE80211_MIN_LEN) {
+ if (!ieee80211_radiotap_active(ic)) {
+ DPRINTF(sc, ATH_DEBUG_RECV,
+ "%s: short packet %d\n", __func__, len);
+ sc->sc_stats.ast_rx_tooshort++;
+ } else {
+ /* NB: in particular this captures ack's */
+ ieee80211_radiotap_rx_all(ic, m);
+ }
+ m_freem(m);
+ goto rx_next;
+ }
+
+ if (IFF_DUMPPKTS(sc, ATH_DEBUG_RECV)) {
+ const HAL_RATE_TABLE *rt = sc->sc_currates;
+ uint8_t rix = rt->rateCodeToIndex[rs->rs_rate];
+
+ ieee80211_dump_pkt(ic, mtod(m, caddr_t), len,
+ sc->sc_hwmap[rix].ieeerate, rs->rs_rssi);
+ }
+
+ m_adj(m, -IEEE80211_CRC_LEN);
+
+ /*
+ * Locate the node for sender, track state, and then
+ * pass the (referenced) node up to the 802.11 layer
+ * for its use.
+ */
+ ni = ieee80211_find_rxnode_withkey(ic,
+ mtod(m, const struct ieee80211_frame_min *),
+ rs->rs_keyix == HAL_RXKEYIX_INVALID ?
+ IEEE80211_KEYIX_NONE : rs->rs_keyix);
+ sc->sc_lastrs = rs;
+
+#ifdef AH_SUPPORT_AR5416
+ if (rs->rs_isaggr)
+ sc->sc_stats.ast_rx_agg++;
+#endif /* AH_SUPPORT_AR5416 */
+
+ if (ni != NULL) {
+ /*
+ * Only punt packets for ampdu reorder processing for
+ * 11n nodes; net80211 enforces that M_AMPDU is only
+ * set for 11n nodes.
+ */
+ if (ni->ni_flags & IEEE80211_NODE_HT)
+ m->m_flags |= M_AMPDU;
+
+ /*
+ * Sending station is known, dispatch directly.
+ */
+ type = ieee80211_input(ni, m, rs->rs_rssi, nf);
+ ieee80211_free_node(ni);
+ /*
+ * Arrange to update the last rx timestamp only for
+ * frames from our ap when operating in station mode.
+ * This assumes the rx key is always setup when
+ * associated.
+ */
+ if (ic->ic_opmode == IEEE80211_M_STA &&
+ rs->rs_keyix != HAL_RXKEYIX_INVALID)
+ is_good = 1;
+ } else {
+ type = ieee80211_input_all(ic, m, rs->rs_rssi, nf);
+ }
+ /*
+ * Track rx rssi and do any rx antenna management.
+ */
+ ATH_RSSI_LPF(sc->sc_halstats.ns_avgrssi, rs->rs_rssi);
+ if (sc->sc_diversity) {
+ /*
+ * When using fast diversity, change the default rx
+ * antenna if diversity chooses the other antenna 3
+ * times in a row.
+ */
+ if (sc->sc_defant != rs->rs_antenna) {
+ if (++sc->sc_rxotherant >= 3)
+ ath_setdefantenna(sc, rs->rs_antenna);
+ } else
+ sc->sc_rxotherant = 0;
+ }
+
+ /* Newer school diversity - kite specific for now */
+ /* XXX perhaps migrate the normal diversity code to this? */
+ if ((ah)->ah_rxAntCombDiversity)
+ (*(ah)->ah_rxAntCombDiversity)(ah, rs, ticks, hz);
+
+ if (sc->sc_softled) {
+ /*
+ * Blink for any data frame. Otherwise do a
+ * heartbeat-style blink when idle. The latter
+ * is mainly for station mode where we depend on
+ * periodic beacon frames to trigger the poll event.
+ */
+ if (type == IEEE80211_FC0_TYPE_DATA) {
+ const HAL_RATE_TABLE *rt = sc->sc_currates;
+ ath_led_event(sc,
+ rt->rateCodeToIndex[rs->rs_rate]);
+ } else if (ticks - sc->sc_ledevent >= sc->sc_ledidle)
+ ath_led_event(sc, 0);
+ }
+rx_next:
+ return (is_good);
+}
+
void
ath_rx_proc(struct ath_softc *sc, int resched)
{
@@ -450,11 +771,10 @@ ath_rx_proc(struct ath_softc *sc, int resched)
struct ath_desc *ds;
struct ath_rx_status *rs;
struct mbuf *m;
- struct ieee80211_node *ni;
- int len, type, ngood;
+ int ngood;
HAL_STATUS status;
int16_t nf;
- u_int64_t tsf, rstamp;
+ u_int64_t tsf;
int npkts = 0;
/* XXX we must not hold the ATH_LOCK here */
@@ -492,7 +812,7 @@ ath_rx_proc(struct ath_softc *sc, int resched)
/* XXX make debug msg */
if_printf(ifp, "%s: no mbuf!\n", __func__);
TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list);
- goto rx_next;
+ goto rx_proc_next;
}
ds = bf->bf_desc;
if (ds->ds_link == bf->bf_daddr) {
@@ -526,311 +846,11 @@ ath_rx_proc(struct ath_softc *sc, int resched)
npkts++;
/*
- * Calculate the correct 64 bit TSF given
- * the TSF64 register value and rs_tstamp.
- */
- rstamp = ath_extend_tsf(sc, rs->rs_tstamp, tsf);
-
- /* These aren't specifically errors */
-#ifdef AH_SUPPORT_AR5416
- if (rs->rs_flags & HAL_RX_GI)
- sc->sc_stats.ast_rx_halfgi++;
- if (rs->rs_flags & HAL_RX_2040)
- sc->sc_stats.ast_rx_2040++;
- if (rs->rs_flags & HAL_RX_DELIM_CRC_PRE)
- sc->sc_stats.ast_rx_pre_crc_err++;
- if (rs->rs_flags & HAL_RX_DELIM_CRC_POST)
- sc->sc_stats.ast_rx_post_crc_err++;
- if (rs->rs_flags & HAL_RX_DECRYPT_BUSY)
- sc->sc_stats.ast_rx_decrypt_busy_err++;
- if (rs->rs_flags & HAL_RX_HI_RX_CHAIN)
- sc->sc_stats.ast_rx_hi_rx_chain++;
-#endif /* AH_SUPPORT_AR5416 */
-
- if (rs->rs_status != 0) {
- if (rs->rs_status & HAL_RXERR_CRC)
- sc->sc_stats.ast_rx_crcerr++;
- if (rs->rs_status & HAL_RXERR_FIFO)
- sc->sc_stats.ast_rx_fifoerr++;
- if (rs->rs_status & HAL_RXERR_PHY) {
- sc->sc_stats.ast_rx_phyerr++;
- /* Process DFS radar events */
- if ((rs->rs_phyerr == HAL_PHYERR_RADAR) ||
- (rs->rs_phyerr == HAL_PHYERR_FALSE_RADAR_EXT)) {
- /* Since we're touching the frame data, sync it */
- bus_dmamap_sync(sc->sc_dmat,
- bf->bf_dmamap,
- BUS_DMASYNC_POSTREAD);
- /* Now pass it to the radar processing code */
- ath_dfs_process_phy_err(sc, mtod(m, char *), rstamp, rs);
- }
-
- /* Be suitably paranoid about receiving phy errors out of the stats array bounds */
- if (rs->rs_phyerr < 64)
- sc->sc_stats.ast_rx_phy[rs->rs_phyerr]++;
- goto rx_error; /* NB: don't count in ierrors */
- }
- if (rs->rs_status & HAL_RXERR_DECRYPT) {
- /*
- * Decrypt error. If the error occurred
- * because there was no hardware key, then
- * let the frame through so the upper layers
- * can process it. This is necessary for 5210
- * parts which have no way to setup a ``clear''
- * key cache entry.
- *
- * XXX do key cache faulting
- */
- if (rs->rs_keyix == HAL_RXKEYIX_INVALID)
- goto rx_accept;
- sc->sc_stats.ast_rx_badcrypt++;
- }
- if (rs->rs_status & HAL_RXERR_MIC) {
- sc->sc_stats.ast_rx_badmic++;
- /*
- * Do minimal work required to hand off
- * the 802.11 header for notification.
- */
- /* XXX frag's and qos frames */
- len = rs->rs_datalen;
- if (len >= sizeof (struct ieee80211_frame)) {
- bus_dmamap_sync(sc->sc_dmat,
- bf->bf_dmamap,
- BUS_DMASYNC_POSTREAD);
- ath_handle_micerror(ic,
- mtod(m, struct ieee80211_frame *),
- sc->sc_splitmic ?
- rs->rs_keyix-32 : rs->rs_keyix);
- }
- }
- ifp->if_ierrors++;
-rx_error:
- /*
- * Cleanup any pending partial frame.
- */
- if (sc->sc_rxpending != NULL) {
- m_freem(sc->sc_rxpending);
- sc->sc_rxpending = NULL;
- }
- /*
- * When a tap is present pass error frames
- * that have been requested. By default we
- * pass decrypt+mic errors but others may be
- * interesting (e.g. crc).
- */
- if (ieee80211_radiotap_active(ic) &&
- (rs->rs_status & sc->sc_monpass)) {
- bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
- BUS_DMASYNC_POSTREAD);
- /* NB: bpf needs the mbuf length setup */
- len = rs->rs_datalen;
- m->m_pkthdr.len = m->m_len = len;
- bf->bf_m = NULL;
- ath_rx_tap(ifp, m, rs, rstamp, nf);
- ieee80211_radiotap_rx_all(ic, m);
- m_freem(m);
- }
- /* XXX pass MIC errors up for s/w reclaculation */
- goto rx_next;
- }
-rx_accept:
- /*
- * Sync and unmap the frame. At this point we're
- * committed to passing the mbuf somewhere so clear
- * bf_m; this means a new mbuf must be allocated
- * when the rx descriptor is setup again to receive
- * another frame.
- */
- bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
- BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
- bf->bf_m = NULL;
-
- len = rs->rs_datalen;
- m->m_len = len;
-
- if (rs->rs_more) {
- /*
- * Frame spans multiple descriptors; save
- * it for the next completed descriptor, it
- * will be used to construct a jumbogram.
- */
- if (sc->sc_rxpending != NULL) {
- /* NB: max frame size is currently 2 clusters */
- sc->sc_stats.ast_rx_toobig++;
- m_freem(sc->sc_rxpending);
- }
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = len;
- sc->sc_rxpending = m;
- goto rx_next;
- } else if (sc->sc_rxpending != NULL) {
- /*
- * This is the second part of a jumbogram,
- * chain it to the first mbuf, adjust the
- * frame length, and clear the rxpending state.
- */
- sc->sc_rxpending->m_next = m;
- sc->sc_rxpending->m_pkthdr.len += len;
- m = sc->sc_rxpending;
- sc->sc_rxpending = NULL;
- } else {
- /*
- * Normal single-descriptor receive; setup
- * the rcvif and packet length.
- */
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = len;
- }
-
- /*
- * Validate rs->rs_antenna.
- *
- * Some users w/ AR9285 NICs have reported crashes
- * here because rs_antenna field is bogusly large.
- * Let's enforce the maximum antenna limit of 8
- * (and it shouldn't be hard coded, but that's a
- * separate problem) and if there's an issue, print
- * out an error and adjust rs_antenna to something
- * sensible.
- *
- * This code should be removed once the actual
- * root cause of the issue has been identified.
- * For example, it may be that the rs_antenna
- * field is only valid for the lsat frame of
- * an aggregate and it just happens that it is
- * "mostly" right. (This is a general statement -
- * the majority of the statistics are only valid
- * for the last frame in an aggregate.
+ * Process a single frame.
*/
- if (rs->rs_antenna > 7) {
- device_printf(sc->sc_dev, "%s: rs_antenna > 7 (%d)\n",
- __func__, rs->rs_antenna);
-#ifdef ATH_DEBUG
- ath_printrxbuf(sc, bf, 0, status == HAL_OK);
-#endif /* ATH_DEBUG */
- rs->rs_antenna = 0; /* XXX better than nothing */
- }
-
- ifp->if_ipackets++;
- sc->sc_stats.ast_ant_rx[rs->rs_antenna]++;
-
- /*
- * Populate the rx status block. When there are bpf
- * listeners we do the additional work to provide
- * complete status. Otherwise we fill in only the
- * material required by ieee80211_input. Note that
- * noise setting is filled in above.
- */
- if (ieee80211_radiotap_active(ic))
- ath_rx_tap(ifp, m, rs, rstamp, nf);
-
- /*
- * From this point on we assume the frame is at least
- * as large as ieee80211_frame_min; verify that.
- */
- if (len < IEEE80211_MIN_LEN) {
- if (!ieee80211_radiotap_active(ic)) {
- DPRINTF(sc, ATH_DEBUG_RECV,
- "%s: short packet %d\n", __func__, len);
- sc->sc_stats.ast_rx_tooshort++;
- } else {
- /* NB: in particular this captures ack's */
- ieee80211_radiotap_rx_all(ic, m);
- }
- m_freem(m);
- goto rx_next;
- }
-
- if (IFF_DUMPPKTS(sc, ATH_DEBUG_RECV)) {
- const HAL_RATE_TABLE *rt = sc->sc_currates;
- uint8_t rix = rt->rateCodeToIndex[rs->rs_rate];
-
- ieee80211_dump_pkt(ic, mtod(m, caddr_t), len,
- sc->sc_hwmap[rix].ieeerate, rs->rs_rssi);
- }
-
- m_adj(m, -IEEE80211_CRC_LEN);
-
- /*
- * Locate the node for sender, track state, and then
- * pass the (referenced) node up to the 802.11 layer
- * for its use.
- */
- ni = ieee80211_find_rxnode_withkey(ic,
- mtod(m, const struct ieee80211_frame_min *),
- rs->rs_keyix == HAL_RXKEYIX_INVALID ?
- IEEE80211_KEYIX_NONE : rs->rs_keyix);
- sc->sc_lastrs = rs;
-
-#ifdef AH_SUPPORT_AR5416
- if (rs->rs_isaggr)
- sc->sc_stats.ast_rx_agg++;
-#endif /* AH_SUPPORT_AR5416 */
-
- if (ni != NULL) {
- /*
- * Only punt packets for ampdu reorder processing for
- * 11n nodes; net80211 enforces that M_AMPDU is only
- * set for 11n nodes.
- */
- if (ni->ni_flags & IEEE80211_NODE_HT)
- m->m_flags |= M_AMPDU;
-
- /*
- * Sending station is known, dispatch directly.
- */
- type = ieee80211_input(ni, m, rs->rs_rssi, nf);
- ieee80211_free_node(ni);
- /*
- * Arrange to update the last rx timestamp only for
- * frames from our ap when operating in station mode.
- * This assumes the rx key is always setup when
- * associated.
- */
- if (ic->ic_opmode == IEEE80211_M_STA &&
- rs->rs_keyix != HAL_RXKEYIX_INVALID)
- ngood++;
- } else {
- type = ieee80211_input_all(ic, m, rs->rs_rssi, nf);
- }
- /*
- * Track rx rssi and do any rx antenna management.
- */
- ATH_RSSI_LPF(sc->sc_halstats.ns_avgrssi, rs->rs_rssi);
- if (sc->sc_diversity) {
- /*
- * When using fast diversity, change the default rx
- * antenna if diversity chooses the other antenna 3
- * times in a row.
- */
- if (sc->sc_defant != rs->rs_antenna) {
- if (++sc->sc_rxotherant >= 3)
- ath_setdefantenna(sc, rs->rs_antenna);
- } else
- sc->sc_rxotherant = 0;
- }
-
- /* Newer school diversity - kite specific for now */
- /* XXX perhaps migrate the normal diversity code to this? */
- if ((ah)->ah_rxAntCombDiversity)
- (*(ah)->ah_rxAntCombDiversity)(ah, rs, ticks, hz);
-
- if (sc->sc_softled) {
- /*
- * Blink for any data frame. Otherwise do a
- * heartbeat-style blink when idle. The latter
- * is mainly for station mode where we depend on
- * periodic beacon frames to trigger the poll event.
- */
- if (type == IEEE80211_FC0_TYPE_DATA) {
- const HAL_RATE_TABLE *rt = sc->sc_currates;
- ath_led_event(sc,
- rt->rateCodeToIndex[rs->rs_rate]);
- } else if (ticks - sc->sc_ledevent >= sc->sc_ledidle)
- ath_led_event(sc, 0);
- }
-rx_next:
+ if (ath_rx_pkt(sc, rs, status, tsf, nf, bf))
+ ngood++;
+rx_proc_next:
TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
} while (ath_rxbuf_init(sc, bf) == 0);
OpenPOWER on IntegriCloud