summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2019-11-26 16:14:46 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2019-11-26 16:14:46 +0000
commit61e60a55d14d69a5b303112906718d76aaafde88 (patch)
tree7e94fec5e9f000965c733495931fd3e9fe418e62 /sys/dev
parent60dd022c509ce3205fef0c585e342722ca7cc706 (diff)
Eliminate some code duplication in iwm(4) 7k/8k vs. 9k Rx code paths.
Tested by mlarkin@ on 9560 and myself on 8265. ok mlarkin@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_iwm.c203
1 files changed, 83 insertions, 120 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index 3ecceec48e6..8d5ed7c03bb 100644
--- a/sys/dev/pci/if_iwm.c
+++ b/sys/dev/pci/if_iwm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwm.c,v 1.286 2019/11/26 07:37:50 patrick Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.287 2019/11/26 16:14:45 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -3880,62 +3880,16 @@ iwm_get_noise(const struct iwm_statistics_rx_non_phy *stats)
}
void
-iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
- struct iwm_rx_data *data, struct mbuf_list *ml)
+iwm_rx_frame(struct iwm_softc *sc, struct mbuf *m, int chanidx,
+ int is_shortpre, int rate_n_flags, uint32_t device_timestamp,
+ struct ieee80211_rxinfo *rxi, struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
- struct ieee80211_rxinfo rxi;
struct ieee80211_channel *bss_chan;
- struct mbuf *m;
- struct iwm_rx_phy_info *phy_info;
- struct iwm_rx_mpdu_res_start *rx_res;
- int device_timestamp;
- uint32_t len;
- uint32_t rx_pkt_status;
- int rssi, chanidx;
uint8_t saved_bssid[IEEE80211_ADDR_LEN] = { 0 };
- bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
- BUS_DMASYNC_POSTREAD);
-
- phy_info = &sc->sc_last_phy_info;
- rx_res = (struct iwm_rx_mpdu_res_start *)pkt->data;
- wh = (struct ieee80211_frame *)(pkt->data + sizeof(*rx_res));
- len = le16toh(rx_res->byte_count);
- if (len < IEEE80211_MIN_LEN) {
- ic->ic_stats.is_rx_tooshort++;
- IC2IFP(ic)->if_ierrors++;
- return;
- }
- if (len > IWM_RBUF_SIZE - sizeof(*rx_res)) {
- IC2IFP(ic)->if_ierrors++;
- return;
- }
- rx_pkt_status = le32toh(*(uint32_t *)(pkt->data +
- sizeof(*rx_res) + len));
-
- if (__predict_false(phy_info->cfg_phy_cnt > 20))
- return;
-
- if (!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_CRC_OK) ||
- !(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_OVERRUN_OK))
- return; /* drop */
-
- m = data->m;
- if (iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0)
- return;
- m->m_data = pkt->data + sizeof(*rx_res);
- m->m_pkthdr.len = m->m_len = len;
-
- device_timestamp = le32toh(phy_info->system_timestamp);
-
- rssi = iwm_get_signal_strength(sc, phy_info);
- rssi = (0 - IWM_MIN_DBM) + rssi; /* normalize */
- rssi = MIN(rssi, ic->ic_max_rssi); /* clip to max. 100% */
-
- chanidx = letoh32(phy_info->channel);
if (chanidx < 0 || chanidx >= nitems(ic->ic_channels))
chanidx = ieee80211_chan2ieee(ic, ic->ic_ibss_chan);
@@ -3950,17 +3904,13 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
}
ni->ni_chan = &ic->ic_channels[chanidx];
- memset(&rxi, 0, sizeof(rxi));
- rxi.rxi_rssi = rssi;
- rxi.rxi_tstamp = device_timestamp;
-
#if NBPFILTER > 0
if (sc->sc_drvbpf != NULL) {
struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap;
uint16_t chan_flags;
tap->wr_flags = 0;
- if (phy_info->phy_flags & htole16(IWM_PHY_INFO_FLAG_SHPREAMBLE))
+ if (is_shortpre)
tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
tap->wr_chan_freq =
htole16(ic->ic_channels[chanidx].ic_freq);
@@ -3968,18 +3918,17 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
if (ic->ic_curmode != IEEE80211_MODE_11N)
chan_flags &= ~IEEE80211_CHAN_HT;
tap->wr_chan_flags = htole16(chan_flags);
- tap->wr_dbm_antsignal = (int8_t)rssi;
+ tap->wr_dbm_antsignal = (int8_t)rxi->rxi_rssi;
tap->wr_dbm_antnoise = (int8_t)sc->sc_noise;
- tap->wr_tsft = phy_info->system_timestamp;
- if (phy_info->phy_flags &
- htole16(IWM_RX_RES_PHY_FLAGS_OFDM_HT)) {
- uint8_t mcs = (phy_info->rate_n_flags &
- htole32(IWM_RATE_HT_MCS_RATE_CODE_MSK |
- IWM_RATE_HT_MCS_NSS_MSK));
+ tap->wr_tsft = device_timestamp;
+ if (rate_n_flags & IWM_RATE_HT_MCS_RATE_CODE_MSK) {
+ uint8_t mcs = (rate_n_flags &
+ (IWM_RATE_HT_MCS_RATE_CODE_MSK |
+ IWM_RATE_HT_MCS_NSS_MSK));
tap->wr_rate = (0x80 | mcs);
} else {
- uint8_t rate = (phy_info->rate_n_flags &
- htole32(IWM_RATE_LEGACY_RATE_MSK));
+ uint8_t rate = (rate_n_flags &
+ IWM_RATE_LEGACY_RATE_MSK);
switch (rate) {
/* CCK rates. */
case 10: tap->wr_rate = 2; break;
@@ -4004,7 +3953,7 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
m, BPF_DIRECTION_IN);
}
#endif
- ieee80211_inputm(IC2IFP(ic), m, ni, &rxi, ml);
+ ieee80211_inputm(IC2IFP(ic), m, ni, rxi, ml);
/*
* ieee80211_inputm() might have changed our BSS.
* Restore ic_bss's channel if we are still in the same BSS.
@@ -4015,6 +3964,71 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
}
void
+iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
+ struct iwm_rx_data *data, struct mbuf_list *ml)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_frame *wh;
+ struct ieee80211_rxinfo rxi;
+ struct mbuf *m;
+ struct iwm_rx_phy_info *phy_info;
+ struct iwm_rx_mpdu_res_start *rx_res;
+ int device_timestamp;
+ uint16_t phy_flags;
+ uint32_t len;
+ uint32_t rx_pkt_status;
+ int rssi, chanidx, rate_n_flags;
+
+ bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
+ BUS_DMASYNC_POSTREAD);
+
+ phy_info = &sc->sc_last_phy_info;
+ rx_res = (struct iwm_rx_mpdu_res_start *)pkt->data;
+ wh = (struct ieee80211_frame *)(pkt->data + sizeof(*rx_res));
+ len = le16toh(rx_res->byte_count);
+ if (len < IEEE80211_MIN_LEN) {
+ ic->ic_stats.is_rx_tooshort++;
+ IC2IFP(ic)->if_ierrors++;
+ return;
+ }
+ if (len > IWM_RBUF_SIZE - sizeof(*rx_res)) {
+ IC2IFP(ic)->if_ierrors++;
+ return;
+ }
+ rx_pkt_status = le32toh(*(uint32_t *)(pkt->data +
+ sizeof(*rx_res) + len));
+
+ if (__predict_false(phy_info->cfg_phy_cnt > 20))
+ return;
+
+ if (!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_CRC_OK) ||
+ !(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_OVERRUN_OK))
+ return; /* drop */
+
+ m = data->m;
+ if (iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0)
+ return;
+ m->m_data = pkt->data + sizeof(*rx_res);
+ m->m_pkthdr.len = m->m_len = len;
+
+ chanidx = letoh32(phy_info->channel);
+ device_timestamp = le32toh(phy_info->system_timestamp);
+ phy_flags = letoh16(phy_info->phy_flags);
+ rate_n_flags = le32toh(phy_info->rate_n_flags);
+
+ rssi = iwm_get_signal_strength(sc, phy_info);
+ rssi = (0 - IWM_MIN_DBM) + rssi; /* normalize */
+ rssi = MIN(rssi, ic->ic_max_rssi); /* clip to max. 100% */
+
+ memset(&rxi, 0, sizeof(rxi));
+ rxi.rxi_rssi = rssi;
+ rxi.rxi_tstamp = device_timestamp;
+
+ iwm_rx_frame(sc, m, chanidx, (phy_flags & IWM_PHY_INFO_FLAG_SHPREAMBLE),
+ rate_n_flags, device_timestamp, &rxi, ml);
+}
+
+void
iwm_rx_mpdu_mq(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
struct iwm_rx_data *data, struct mbuf_list *ml)
{
@@ -4025,7 +4039,7 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
struct ieee80211_channel *bss_chan;
struct mbuf *m;
struct iwm_rx_mpdu_desc *desc;
- uint32_t len, hdrlen, rate_n_flags;
+ uint32_t len, hdrlen, rate_n_flags, device_timestamp;
int rssi;
uint8_t chanidx;
uint16_t phy_info;
@@ -4103,61 +4117,10 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = le64toh(desc->v1.tsf_on_air_rise);
-#if NBPFILTER > 0
- if (sc->sc_drvbpf != NULL) {
- struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap;
- uint16_t chan_flags;
-
- tap->wr_flags = 0;
- if (phy_info & IWM_RX_MPDU_PHY_SHORT_PREAMBLE)
- tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
- tap->wr_chan_freq =
- htole16(ic->ic_channels[chanidx].ic_freq);
- chan_flags = ic->ic_channels[chanidx].ic_flags;
- if (ic->ic_curmode != IEEE80211_MODE_11N)
- chan_flags &= ~IEEE80211_CHAN_HT;
- tap->wr_chan_flags = htole16(chan_flags);
- tap->wr_dbm_antsignal = (int8_t)rssi;
- tap->wr_dbm_antnoise = (int8_t)sc->sc_noise;
- tap->wr_tsft = desc->v1.gp2_on_air_rise;
- if (rate_n_flags & IWM_RATE_HT_MCS_RATE_CODE_MSK) {
- uint8_t mcs = (rate_n_flags &
- (IWM_RATE_HT_MCS_RATE_CODE_MSK |
- IWM_RATE_HT_MCS_NSS_MSK));
- tap->wr_rate = (0x80 | mcs);
- } else {
- switch ((rate_n_flags & IWM_RATE_LEGACY_RATE_MSK)) {
- /* CCK rates. */
- case 10: tap->wr_rate = 2; break;
- case 20: tap->wr_rate = 4; break;
- case 55: tap->wr_rate = 11; break;
- case 110: tap->wr_rate = 22; break;
- /* OFDM rates. */
- case 0xd: tap->wr_rate = 12; break;
- case 0xf: tap->wr_rate = 18; break;
- case 0x5: tap->wr_rate = 24; break;
- case 0x7: tap->wr_rate = 36; break;
- case 0x9: tap->wr_rate = 48; break;
- case 0xb: tap->wr_rate = 72; break;
- case 0x1: tap->wr_rate = 96; break;
- case 0x3: tap->wr_rate = 108; break;
- /* Unknown rate: should not happen. */
- default: tap->wr_rate = 0;
- }
- }
+ device_timestamp = desc->v1.gp2_on_air_rise;
- bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_rxtap_len,
- m, BPF_DIRECTION_IN);
- }
-#endif
- ieee80211_inputm(IC2IFP(ic), m, ni, &rxi, ml);
- /*
- * ieee80211_inputm() might have changed our BSS.
- * Restore ic_bss's channel if we are still in the same BSS.
- */
- if (ni == ic->ic_bss && IEEE80211_ADDR_EQ(saved_bssid, ni->ni_macaddr))
- ni->ni_chan = bss_chan;
- ieee80211_release_node(ic, ni);
+ iwm_rx_frame(sc, m, chanidx, (phy_info & IWM_RX_MPDU_PHY_SHORT_PREAMBLE),
+ rate_n_flags, device_timestamp, &rxi, ml);
}
void