summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_iwx.c43
-rw-r--r--sys/dev/pci/if_iwxreg.h41
2 files changed, 82 insertions, 2 deletions
diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c
index 892577d6736..af46177a2e0 100644
--- a/sys/dev/pci/if_iwx.c
+++ b/sys/dev/pci/if_iwx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwx.c,v 1.84 2021/07/29 12:01:04 stsp Exp $ */
+/* $OpenBSD: if_iwx.c,v 1.85 2021/07/29 12:01:45 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -318,6 +318,8 @@ int iwx_ampdu_rx_start(struct ieee80211com *, struct ieee80211_node *,
void iwx_ampdu_rx_stop(struct ieee80211com *, struct ieee80211_node *,
uint8_t);
void iwx_rx_ba_session_expired(void *);
+void iwx_rx_bar_frame_release(struct iwx_softc *, struct iwx_rx_packet *,
+ struct iwx_rx_data *, struct mbuf_list *);
void iwx_reorder_timer_expired(void *);
void iwx_sta_rx_agg(struct iwx_softc *, struct ieee80211_node *, uint8_t,
uint16_t, uint16_t, int, int);
@@ -2867,6 +2869,41 @@ iwx_rx_ba_session_expired(void *arg)
}
void
+iwx_rx_bar_frame_release(struct iwx_softc *sc, struct iwx_rx_packet *pkt,
+ struct iwx_rx_data *data, struct mbuf_list *ml)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_node *ni = ic->ic_bss;
+ struct iwx_bar_frame_release *release = (void *)data;
+ struct iwx_reorder_buffer *buf;
+ struct iwx_rxba_data *rxba;
+ unsigned int baid, nssn, sta_id, tid;
+
+ if (iwx_rx_packet_payload_len(pkt) < sizeof(*release))
+ return;
+
+ baid = (le32toh(release->ba_info) & IWX_BAR_FRAME_RELEASE_BAID_MASK) >>
+ IWX_BAR_FRAME_RELEASE_BAID_SHIFT;
+ if (baid == IWX_RX_REORDER_DATA_INVALID_BAID ||
+ baid >= nitems(sc->sc_rxba_data))
+ return;
+
+ rxba = &sc->sc_rxba_data[baid];
+ if (rxba == NULL || rxba->baid == IWX_RX_REORDER_DATA_INVALID_BAID)
+ return;
+
+ tid = le32toh(release->sta_tid) & IWX_BAR_FRAME_RELEASE_TID_MASK;
+ sta_id = (le32toh(release->sta_tid) &
+ IWX_BAR_FRAME_RELEASE_STA_MASK) >> IWX_BAR_FRAME_RELEASE_STA_SHIFT;
+ if (tid != rxba->tid || rxba->sta_id != IWX_STATION_ID)
+ return;
+
+ nssn = le32toh(release->ba_info) & IWX_BAR_FRAME_RELEASE_NSSN_MASK;
+ buf = &rxba->reorder_buf;
+ iwx_release_frames(sc, ni, rxba, buf, nssn, ml);
+}
+
+void
iwx_reorder_timer_expired(void *arg)
{
struct mbuf_list ml = MBUF_LIST_INITIALIZER();
@@ -8524,6 +8561,10 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf_list *ml)
break;
}
+ case IWX_BAR_FRAME_RELEASE:
+ iwx_rx_bar_frame_release(sc, pkt, data, ml);
+ break;
+
case IWX_TX_CMD:
iwx_rx_tx_cmd(sc, pkt, data);
break;
diff --git a/sys/dev/pci/if_iwxreg.h b/sys/dev/pci/if_iwxreg.h
index ba0f5a49d45..bd6a662accb 100644
--- a/sys/dev/pci/if_iwxreg.h
+++ b/sys/dev/pci/if_iwxreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwxreg.h,v 1.28 2021/07/29 12:00:30 stsp Exp $ */
+/* $OpenBSD: if_iwxreg.h,v 1.29 2021/07/29 12:01:45 stsp Exp $ */
/*-
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
@@ -1580,6 +1580,8 @@ struct iwx_tx_queue_cfg_rsp {
#define IWX_REPLY_RX_PHY_CMD 0xc0
#define IWX_REPLY_RX_MPDU_CMD 0xc1
+#define IWX_BAR_FRAME_RELEASE 0xc2
+#define IWX_FRAME_RELEASE 0xc3
#define IWX_BA_NOTIF 0xc5
/* Location Aware Regulatory */
@@ -3317,6 +3319,43 @@ struct iwx_rx_mpdu_desc {
struct iwx_rx_mpdu_desc_v1 v1;
} __packed;
+struct iwx_frame_release {
+ uint8_t baid;
+ uint8_t reserved;
+ uint16_t nssn;
+};
+
+/**
+ * enum iwx_bar_frame_release_sta_tid - STA/TID information for BAR release
+ * @IWX_BAR_FRAME_RELEASE_TID_MASK: TID mask
+ * @IWX_BAR_FRAME_RELEASE_STA_MASK: STA mask
+ */
+#define IWX_BAR_FRAME_RELEASE_TID_MASK 0x0000000f
+#define IWX_BAR_FRAME_RELEASE_STA_MASK 0x000001f0
+#define IWX_BAR_FRAME_RELEASE_STA_SHIFT 4
+
+/**
+ * enum iwx_bar_frame_release_ba_info - BA information for BAR release
+ * @IWL_BAR_FRAME_RELEASE_NSSN_MASK: NSSN mask
+ * @IWL_BAR_FRAME_RELEASE_SN_MASK: SN mask (ignored by driver)
+ * @IWL_BAR_FRAME_RELEASE_BAID_MASK: BAID mask
+ */
+#define IWX_BAR_FRAME_RELEASE_NSSN_MASK 0x00000fff
+#define IWX_BAR_FRAME_RELEASE_SN_MASK 0x00fff000
+#define IWX_BAR_FRAME_RELEASE_SN_SHIFT 12
+#define IWX_BAR_FRAME_RELEASE_BAID_MASK 0x3f000000
+#define IWX_BAR_FRAME_RELEASE_BAID_SHIFT 24
+
+/**
+ * struct iwx_bar_frame_release - frame release from BAR info
+ * @sta_tid: STA & TID information, see &enum iwx_bar_frame_release_sta_tid.
+ * @ba_info: BA information, see &enum iwx_bar_frame_release_ba_info.
+ */
+struct iwx_bar_frame_release {
+ uint32_t sta_tid;
+ uint32_t ba_info;
+} __packed; /* RX_BAR_TO_FRAME_RELEASE_API_S_VER_1 */
+
/**
* struct iwx_radio_version_notif - information on the radio version
* ( IWX_RADIO_VERSION_NOTIFICATION = 0x68 )