From 572726fa3b8b9148beb292d5d1d4ab5057f1451f Mon Sep 17 00:00:00 2001 From: stsp Date: Thu, 29 Jul 2021 12:01:45 +0000 Subject: [PATCH] Implement support for the BAR_FRAME_RELEASE iwx(4) firmware notification. New firmware will generate this notification when a block ack request is received. Older firmware passed the block ack request frame to the driver. ok kevlo@ --- sys/dev/pci/if_iwx.c | 43 ++++++++++++++++++++++++++++++++++++++++- sys/dev/pci/if_iwxreg.h | 41 ++++++++++++++++++++++++++++++++++++++- 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 @@ -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); @@ -2866,6 +2868,41 @@ iwx_rx_ba_session_expired(void *arg) splx(s); } +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) { @@ -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 ) -- 2.20.1