-/* $OpenBSD: qwx.c,v 1.17 2024/02/04 17:51:59 kettenis Exp $ */
+/* $OpenBSD: qwx.c,v 1.18 2024/02/06 14:18:15 stsp Exp $ */
/*
* Copyright 2023 Stefan Sperling <stsp@openbsd.org>
* Driver for Qualcomm Technologies 802.11ax chipset.
*/
+#include "bpfilter.h"
+
#include <sys/types.h>
#include <sys/param.h>
#include <sys/device.h>
#include <dev/ofw/openfirm.h>
#endif
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
#include <net/if.h>
#include <net/if_media.h>
wh = mtod(m, struct ieee80211_frame *);
frame_type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+#if NBPFILTER > 0
+ if (sc->sc_drvbpf != NULL) {
+ struct qwx_tx_radiotap_header *tap = &sc->sc_txtap;
+
+ bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_txtap_len,
+ m, BPF_DIRECTION_OUT);
+ }
+#endif
+
if (frame_type == IEEE80211_FC0_TYPE_MGT)
return qwx_mac_mgmt_tx_wmi(sc, arvif, pdev_id, m);
DNPRINTF(QWX_D_MGMT, "%s: event mgmt rx freq %d chan %d snr %d\n",
__func__, rx_ev.chan_freq, rx_ev.channel, rx_ev.snr);
+#if NBPFILTER > 0
+ if (sc->sc_drvbpf != NULL) {
+ struct qwx_rx_radiotap_header *tap = &sc->sc_rxtap;
+
+ bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_rxtap_len,
+ m, BPF_DIRECTION_IN);
+ }
+#endif
ieee80211_input(ifp, m, ni, &rxi);
exit:
#ifdef notyet
wh = mtod(msdu->m, struct ieee80211_frame *);
ni = ieee80211_find_rxnode(ic, wh);
- /* TODO: bpf */
+#if NBPFILTER > 0
+ if (sc->sc_drvbpf != NULL) {
+ struct qwx_rx_radiotap_header *tap = &sc->sc_rxtap;
+ bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_rxtap_len,
+ msdu->m, BPF_DIRECTION_IN);
+ }
+#endif
ieee80211_input(ifp, msdu->m, ni, &msdu->rxi);
ieee80211_release_node(ic, ni);
}
return ENOTSUP;
}
+#if NBPFILTER > 0
+void
+qwx_radiotap_attach(struct qwx_softc *sc)
+{
+ bpfattach(&sc->sc_drvbpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO,
+ sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
+
+ sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
+ sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
+ sc->sc_rxtap.wr_ihdr.it_present = htole32(IWX_RX_RADIOTAP_PRESENT);
+
+ sc->sc_txtap_len = sizeof(sc->sc_txtapu);
+ sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
+ sc->sc_txtap.wt_ihdr.it_present = htole32(IWX_TX_RADIOTAP_PRESENT);
+}
+#endif
+
int
qwx_attach(struct qwx_softc *sc)
{
task_set(&sc->init_task, qwx_init_task, sc);
task_set(&sc->newstate_task, qwx_newstate_task, sc);
timeout_set_proc(&sc->scan.timeout, qwx_scan_timeout, sc);
-
+#if NBPFILTER > 0
+ qwx_radiotap_attach(sc);
+#endif
for (i = 0; i < nitems(sc->pdevs); i++)
sc->pdevs[i].sc = sc;
-/* $OpenBSD: qwxvar.h,v 1.11 2024/02/03 20:07:19 kettenis Exp $ */
+/* $OpenBSD: qwxvar.h,v 1.12 2024/02/06 14:18:15 stsp Exp $ */
/*
* Copyright (c) 2018-2019 The Linux Foundation.
#endif
};
+struct qwx_rx_radiotap_header {
+ struct ieee80211_radiotap_header wr_ihdr;
+} __packed;
+
+#define IWX_RX_RADIOTAP_PRESENT 0 /* TODO add more information */
+
+struct qwx_tx_radiotap_header {
+ struct ieee80211_radiotap_header wt_ihdr;
+} __packed;
+
+#define IWX_TX_RADIOTAP_PRESENT 0 /* TODO add more information */
+
struct qwx_softc {
struct device sc_dev;
struct ieee80211com sc_ic;
uint32_t msi_ce_irqmask;
struct qmi_wlanfw_request_mem_ind_msg_v01 *sc_req_mem_ind;
+
+#if NBPFILTER > 0
+ caddr_t sc_drvbpf;
+
+ union {
+ struct qwx_rx_radiotap_header th;
+ uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
+ } sc_rxtapu;
+#define sc_rxtap sc_rxtapu.th
+ int sc_rxtap_len;
+
+ union {
+ struct qwx_tx_radiotap_header th;
+ uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
+ } sc_txtapu;
+#define sc_txtap sc_txtapu.th
+ int sc_txtap_len;
+#endif
};
int qwx_ce_intr(void *);