sync with OpenBSD -current

This commit is contained in:
purplerain 2024-02-04 06:16:28 +00:00
parent 7d66fd8cb0
commit 3f3212838f
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
122 changed files with 1363 additions and 8580 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bcm2711_pcie.c,v 1.11 2022/04/06 18:59:28 naddy Exp $ */
/* $OpenBSD: bcm2711_pcie.c,v 1.12 2024/02/03 10:37:26 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
*
@ -299,6 +299,7 @@ bcmpcie_attach(struct device *parent, struct device *self, void *aux)
sc->sc_pc.pc_intr_v = sc;
sc->sc_pc.pc_intr_map = bcmpcie_intr_map;
sc->sc_pc.pc_intr_map_msi = _pci_intr_map_msi;
sc->sc_pc.pc_intr_map_msivec = _pci_intr_map_msivec;
sc->sc_pc.pc_intr_map_msix = _pci_intr_map_msix;
sc->sc_pc.pc_intr_string = bcmpcie_intr_string;
sc->sc_pc.pc_intr_establish = bcmpcie_intr_establish;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: dwpcie.c,v 1.50 2023/09/21 19:39:41 patrick Exp $ */
/* $OpenBSD: dwpcie.c,v 1.51 2024/02/03 10:37:26 kettenis Exp $ */
/*
* Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
*
@ -711,6 +711,7 @@ dwpcie_attach_deferred(struct device *self)
sc->sc_pc.pc_intr_v = sc;
sc->sc_pc.pc_intr_map = dwpcie_intr_map;
sc->sc_pc.pc_intr_map_msi = _pci_intr_map_msi;
sc->sc_pc.pc_intr_map_msivec = _pci_intr_map_msivec;
sc->sc_pc.pc_intr_map_msix = _pci_intr_map_msix;
sc->sc_pc.pc_intr_string = dwpcie_intr_string;
sc->sc_pc.pc_intr_establish = dwpcie_intr_establish;
@ -729,6 +730,8 @@ dwpcie_attach_deferred(struct device *self)
OF_getproplen(sc->sc_node, "msi-map") > 0 ||
sc->sc_msi_addr)
pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
if (OF_getproplen(sc->sc_node, "msi-map") > 0)
pba.pba_flags |= PCI_FLAGS_MSIVEC_ENABLED;
/* XXX No working MSI on RK3588 yet. */
if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-pcie"))
@ -1835,6 +1838,8 @@ dwpcie_intr_establish(void *v, pci_intr_handle_t ih, int level,
uint64_t addr, data;
if (sc->sc_msi_addr) {
if (ih.ih_type == PCI_MSI && ih.ih_intrpin > 0)
return NULL;
dm = dwpcie_msi_establish(sc, level, func, arg, name);
if (dm == NULL)
return NULL;
@ -1845,6 +1850,7 @@ dwpcie_intr_establish(void *v, pci_intr_handle_t ih, int level,
* Assume hardware passes Requester ID as
* sideband data.
*/
addr = ih.ih_intrpin;
data = pci_requester_id(ih.ih_pc, ih.ih_tag);
cookie = fdt_intr_establish_msi_cpu(sc->sc_node, &addr,
&data, level, ci, func, arg, (void *)name);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: mvkpcie.c,v 1.13 2022/04/06 18:59:28 naddy Exp $ */
/* $OpenBSD: mvkpcie.c,v 1.14 2024/02/03 10:37:26 kettenis Exp $ */
/*
* Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
* Copyright (c) 2020 Patrick Wildt <patrick@blueri.se>
@ -528,6 +528,7 @@ mvkpcie_attach(struct device *parent, struct device *self, void *aux)
sc->sc_pc.pc_intr_v = sc;
sc->sc_pc.pc_intr_map = mvkpcie_intr_map;
sc->sc_pc.pc_intr_map_msi = _pci_intr_map_msi;
sc->sc_pc.pc_intr_map_msivec = _pci_intr_map_msivec;
sc->sc_pc.pc_intr_map_msix = _pci_intr_map_msix;
sc->sc_pc.pc_intr_string = mvkpcie_intr_string;
sc->sc_pc.pc_intr_establish = mvkpcie_intr_establish;
@ -783,7 +784,7 @@ mvkpcie_intr_establish(void *v, pci_intr_handle_t ih, int level,
KASSERT(ih.ih_type != PCI_NONE);
if (ih.ih_type != PCI_INTX) {
uint64_t addr, data;
uint64_t addr = 0, data;
/* Assume hardware passes Requester ID as sideband data. */
data = pci_requester_id(ih.ih_pc, ih.ih_tag);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: pciecam.c,v 1.4 2022/04/06 18:59:28 naddy Exp $ */
/* $OpenBSD: pciecam.c,v 1.5 2024/02/03 10:37:26 kettenis Exp $ */
/*
* Copyright (c) 2013,2017 Patrick Wildt <patrick@blueri.se>
*
@ -245,6 +245,7 @@ pciecam_attach(struct device *parent, struct device *self, void *aux)
sc->sc_pc.pc_intr_v = sc;
sc->sc_pc.pc_intr_map = pciecam_intr_map;
sc->sc_pc.pc_intr_map_msi = _pci_intr_map_msi;
sc->sc_pc.pc_intr_map_msivec = _pci_intr_map_msivec;
sc->sc_pc.pc_intr_map_msix = _pci_intr_map_msix;
sc->sc_pc.pc_intr_string = pciecam_intr_string;
sc->sc_pc.pc_intr_establish = pciecam_intr_establish;
@ -391,7 +392,7 @@ pciecam_intr_establish(void *self, pci_intr_handle_t ih, int level,
KASSERT(ih.ih_type != PCI_NONE);
if (ih.ih_type != PCI_INTX) {
uint64_t addr, data;
uint64_t addr = 0, data;
/* Assume hardware passes Requester ID as sideband data. */
data = pci_requester_id(ih.ih_pc, ih.ih_tag);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: rkpcie.c,v 1.17 2023/04/11 00:45:08 jsg Exp $ */
/* $OpenBSD: rkpcie.c,v 1.18 2024/02/03 10:37:26 kettenis Exp $ */
/*
* Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
*
@ -372,6 +372,7 @@ rkpcie_attach(struct device *parent, struct device *self, void *aux)
sc->sc_pc.pc_intr_v = sc;
sc->sc_pc.pc_intr_map = rkpcie_intr_map;
sc->sc_pc.pc_intr_map_msi = _pci_intr_map_msi;
sc->sc_pc.pc_intr_map_msivec = _pci_intr_map_msivec;
sc->sc_pc.pc_intr_map_msix = _pci_intr_map_msix;
sc->sc_pc.pc_intr_string = rkpcie_intr_string;
sc->sc_pc.pc_intr_establish = rkpcie_intr_establish;
@ -605,7 +606,7 @@ rkpcie_intr_establish(void *v, pci_intr_handle_t ih, int level,
KASSERT(ih.ih_type != PCI_NONE);
if (ih.ih_type != PCI_INTX) {
uint64_t addr, data;
uint64_t addr = 0, data;
/* Assume hardware passes Requester ID as sideband data. */
data = pci_requester_id(ih.ih_pc, ih.ih_tag);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: qwx.c,v 1.14 2024/02/02 15:44:19 stsp Exp $ */
/* $OpenBSD: qwx.c,v 1.16 2024/02/03 20:07:19 kettenis Exp $ */
/*
* Copyright 2023 Stefan Sperling <stsp@openbsd.org>
@ -68,6 +68,10 @@
#include <machine/bus.h>
#include <machine/intr.h>
#ifdef __HAVE_FDT
#include <dev/ofw/openfirm.h>
#endif
#include <net/if.h>
#include <net/if_media.h>
@ -136,6 +140,8 @@ int qwx_mac_start(struct qwx_softc *);
void qwx_mac_scan_finish(struct qwx_softc *);
int qwx_mac_mgmt_tx_wmi(struct qwx_softc *, struct qwx_vif *, uint8_t,
struct mbuf *);
int qwx_dp_tx(struct qwx_softc *, struct qwx_vif *, uint8_t,
struct ieee80211_node *, struct mbuf *);
int qwx_dp_tx_send_reo_cmd(struct qwx_softc *, struct dp_rx_tid *,
enum hal_reo_cmd_type , struct ath11k_hal_reo_cmd *,
void (*func)(struct qwx_dp *, void *, enum hal_reo_cmd_status));
@ -358,9 +364,7 @@ qwx_tx(struct qwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
if (frame_type == IEEE80211_FC0_TYPE_MGT)
return qwx_mac_mgmt_tx_wmi(sc, arvif, pdev_id, m);
printf("%s: not implemented\n", __func__);
m_freem(m);
return ENOTSUP;
return qwx_dp_tx(sc, arvif, pdev_id, ni, m);
}
void
@ -1455,10 +1459,38 @@ qwx_hw_wcn6855_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
return desc->u.wcn6855.mpdu_start.addr2;
}
/* Map from pdev index to hw mac index */
uint8_t
qwx_hw_ipq8074_mac_from_pdev_id(int pdev_idx)
{
switch (pdev_idx) {
case 0:
return 0;
case 1:
return 2;
case 2:
return 1;
default:
return ATH11K_INVALID_HW_MAC_ID;
}
}
uint8_t qwx_hw_ipq6018_mac_from_pdev_id(int pdev_idx)
{
return pdev_idx;
}
static inline int
qwx_hw_get_mac_from_pdev_id(struct qwx_softc *sc, int pdev_idx)
{
if (sc->hw_params.hw_ops->get_hw_mac_from_pdev_id)
return sc->hw_params.hw_ops->get_hw_mac_from_pdev_id(pdev_idx);
return 0;
}
const struct ath11k_hw_ops ipq8074_ops = {
#if notyet
.get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id,
#endif
.get_hw_mac_from_pdev_id = qwx_hw_ipq8074_mac_from_pdev_id,
.wmi_init_config = qwx_init_wmi_config_ipq8074,
.mac_id_to_pdev_id = qwx_hw_mac_id_to_pdev_id_ipq8074,
.mac_id_to_srng_id = qwx_hw_mac_id_to_srng_id_ipq8074,
@ -1510,9 +1542,7 @@ const struct ath11k_hw_ops ipq8074_ops = {
};
const struct ath11k_hw_ops ipq6018_ops = {
#if notyet
.get_hw_mac_from_pdev_id = ath11k_hw_ipq6018_mac_from_pdev_id,
#endif
.get_hw_mac_from_pdev_id = qwx_hw_ipq6018_mac_from_pdev_id,
.wmi_init_config = qwx_init_wmi_config_ipq8074,
.mac_id_to_pdev_id = qwx_hw_mac_id_to_pdev_id_ipq8074,
.mac_id_to_srng_id = qwx_hw_mac_id_to_srng_id_ipq8074,
@ -1564,9 +1594,7 @@ const struct ath11k_hw_ops ipq6018_ops = {
};
const struct ath11k_hw_ops qca6390_ops = {
#if notyet
.get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id,
#endif
.get_hw_mac_from_pdev_id = qwx_hw_ipq8074_mac_from_pdev_id,
.wmi_init_config = qwx_init_wmi_config_qca6390,
.mac_id_to_pdev_id = qwx_hw_mac_id_to_pdev_id_qca6390,
.mac_id_to_srng_id = qwx_hw_mac_id_to_srng_id_qca6390,
@ -1618,13 +1646,11 @@ const struct ath11k_hw_ops qca6390_ops = {
};
const struct ath11k_hw_ops qcn9074_ops = {
#if notyet
.get_hw_mac_from_pdev_id = ath11k_hw_ipq6018_mac_from_pdev_id,
#endif
.get_hw_mac_from_pdev_id = qwx_hw_ipq6018_mac_from_pdev_id,
.wmi_init_config = qwx_init_wmi_config_ipq8074,
.mac_id_to_pdev_id = qwx_hw_mac_id_to_pdev_id_ipq8074,
.mac_id_to_srng_id = qwx_hw_mac_id_to_srng_id_ipq8074,
#ifdef notyet
#if notyet
.tx_mesh_enable = ath11k_hw_qcn9074_tx_mesh_enable,
.rx_desc_get_first_msdu = ath11k_hw_qcn9074_rx_desc_get_first_msdu,
.rx_desc_get_last_msdu = ath11k_hw_qcn9074_rx_desc_get_last_msdu,
@ -1672,13 +1698,11 @@ const struct ath11k_hw_ops qcn9074_ops = {
};
const struct ath11k_hw_ops wcn6855_ops = {
#if notyet
.get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id,
#endif
.get_hw_mac_from_pdev_id = qwx_hw_ipq8074_mac_from_pdev_id,
.wmi_init_config = qwx_init_wmi_config_qca6390,
.mac_id_to_pdev_id = qwx_hw_mac_id_to_pdev_id_qca6390,
.mac_id_to_srng_id = qwx_hw_mac_id_to_srng_id_qca6390,
#ifdef notyet
#if notyet
.tx_mesh_enable = ath11k_hw_wcn6855_tx_mesh_enable,
.rx_desc_get_first_msdu = ath11k_hw_wcn6855_rx_desc_get_first_msdu,
.rx_desc_get_last_msdu = ath11k_hw_wcn6855_rx_desc_get_last_msdu,
@ -1726,9 +1750,7 @@ const struct ath11k_hw_ops wcn6855_ops = {
};
const struct ath11k_hw_ops wcn6750_ops = {
#if notyet
.get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id,
#endif
.get_hw_mac_from_pdev_id = qwx_hw_ipq8074_mac_from_pdev_id,
.wmi_init_config = qwx_init_wmi_config_qca6390,
.mac_id_to_pdev_id = qwx_hw_mac_id_to_pdev_id_qca6390,
.mac_id_to_srng_id = qwx_hw_mac_id_to_srng_id_qca6390,
@ -3052,7 +3074,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.sram_dump = {},
.tcl_ring_retry = true,
#endif
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
#ifdef notyet
.smp2p_wow_exit = false,
#endif
},
@ -3139,7 +3163,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.sram_dump = {},
.tcl_ring_retry = true,
#endif
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
#ifdef notyet
.smp2p_wow_exit = false,
#endif
},
@ -3228,7 +3254,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
},
.tcl_ring_retry = true,
#endif
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
#ifdef notyet
.smp2p_wow_exit = false,
#endif
},
@ -3316,7 +3344,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.sram_dump = {},
.tcl_ring_retry = true,
#endif
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
#ifdef notyet
.smp2p_wow_exit = false,
#endif
},
@ -3405,7 +3435,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
},
.tcl_ring_retry = true,
#endif
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
#ifdef notyet
.smp2p_wow_exit = false,
#endif
},
@ -3493,7 +3525,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
},
.tcl_ring_retry = true,
#endif
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
#ifdef notyet
.smp2p_wow_exit = false,
#endif
},
@ -3578,7 +3612,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.sram_dump = {},
.tcl_ring_retry = false,
#endif
.tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750,
#ifdef notyet
.smp2p_wow_exit = true,
#endif
},
@ -7815,7 +7851,15 @@ qwx_core_check_smbios(struct qwx_softc *sc)
int
qwx_core_check_dt(struct qwx_softc *sc)
{
return 0; /* TODO */
#ifdef __HAVE_FDT
if (sc->sc_node == 0)
return 0;
OF_getprop(sc->sc_node, "qcom,ath11k-calibration-variant",
sc->qmi_target.bdf_ext, sizeof(sc->qmi_target.bdf_ext) - 1);
#endif
return 0;
}
int
@ -9953,6 +9997,51 @@ qwx_dp_link_desc_cleanup(struct qwx_softc *sc,
}
}
void
qwx_dp_tx_ring_free_tx_data(struct qwx_softc *sc, struct dp_tx_ring *tx_ring)
{
int i;
if (tx_ring->data == NULL)
return;
for (i = 0; i < sc->hw_params.tx_ring_size; i++) {
struct qwx_tx_data *tx_data = &tx_ring->data[i];
if (tx_data->map) {
bus_dmamap_unload(sc->sc_dmat, tx_data->map);
bus_dmamap_destroy(sc->sc_dmat, tx_data->map);
}
m_freem(tx_data->m);
}
free(tx_ring->data, M_DEVBUF,
sc->hw_params.tx_ring_size * sizeof(struct qwx_tx_data));
tx_ring->data = NULL;
}
int
qwx_dp_tx_ring_alloc_tx_data(struct qwx_softc *sc, struct dp_tx_ring *tx_ring)
{
int i, ret;
tx_ring->data = mallocarray(sc->hw_params.tx_ring_size,
sizeof(struct qwx_tx_data), M_DEVBUF, M_NOWAIT | M_ZERO);
if (tx_ring->data == NULL)
return ENOMEM;
for (i = 0; i < sc->hw_params.tx_ring_size; i++) {
struct qwx_tx_data *tx_data = &tx_ring->data[i];
ret = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
BUS_DMA_NOWAIT, &tx_data->map);
if (ret)
return ret;
}
return 0;
}
int
qwx_dp_alloc(struct qwx_softc *sc)
@ -10003,8 +10092,13 @@ qwx_dp_alloc(struct qwx_softc *sc)
idr_init(&dp->tx_ring[i].txbuf_idr);
spin_lock_init(&dp->tx_ring[i].tx_idr_lock);
#endif
dp->tx_ring[i].tcl_data_ring_id = i;
ret = qwx_dp_tx_ring_alloc_tx_data(sc, &dp->tx_ring[i]);
if (ret)
goto fail_cmn_srng_cleanup;
dp->tx_ring[i].cur = 0;
dp->tx_ring[i].queued = 0;
dp->tx_ring[i].tcl_data_ring_id = i;
dp->tx_ring[i].tx_status_head = 0;
dp->tx_ring[i].tx_status_tail = DP_TX_COMP_RING_SIZE - 1;
dp->tx_ring[i].tx_status = malloc(size, M_DEVBUF,
@ -10051,6 +10145,7 @@ qwx_dp_free(struct qwx_softc *sc)
idr_destroy(&dp->tx_ring[i].txbuf_idr);
spin_unlock_bh(&dp->tx_ring[i].tx_idr_lock);
#endif
qwx_dp_tx_ring_free_tx_data(sc, &dp->tx_ring[i]);
free(dp->tx_ring[i].tx_status, M_DEVBUF,
sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE);
dp->tx_ring[i].tx_status = NULL;
@ -14544,9 +14639,146 @@ qwx_dp_vdev_tx_attach(struct qwx_softc *sc, struct qwx_pdev *pdev,
qwx_dp_update_vdev_search(sc, arvif);
}
void
qwx_dp_tx_status_parse(struct qwx_softc *sc, struct hal_wbm_release_ring *desc,
struct hal_tx_status *ts)
{
ts->buf_rel_source = FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE,
desc->info0);
if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW &&
ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)
return;
if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)
return;
ts->status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON,
desc->info0);
ts->ppdu_id = FIELD_GET(HAL_WBM_RELEASE_INFO1_TQM_STATUS_NUMBER,
desc->info1);
ts->try_cnt = FIELD_GET(HAL_WBM_RELEASE_INFO1_TRANSMIT_COUNT,
desc->info1);
ts->ack_rssi = FIELD_GET(HAL_WBM_RELEASE_INFO2_ACK_FRAME_RSSI,
desc->info2);
if (desc->info2 & HAL_WBM_RELEASE_INFO2_FIRST_MSDU)
ts->flags |= HAL_TX_STATUS_FLAGS_FIRST_MSDU;
ts->peer_id = FIELD_GET(HAL_WBM_RELEASE_INFO3_PEER_ID, desc->info3);
ts->tid = FIELD_GET(HAL_WBM_RELEASE_INFO3_TID, desc->info3);
if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_VALID)
ts->rate_stats = desc->rate_stats.info0;
else
ts->rate_stats = 0;
}
void
qwx_dp_tx_process_htt_tx_complete(struct qwx_softc *sc, void *desc,
uint8_t mac_id, uint32_t msdu_id, struct dp_tx_ring *tx_ring)
{
printf("%s: not implemented\n", __func__);
}
void
qwx_dp_tx_complete_msdu(struct qwx_softc *sc, struct dp_tx_ring *tx_ring,
uint32_t msdu_id, struct hal_tx_status *ts)
{
struct qwx_tx_data *tx_data = &tx_ring->data[msdu_id];
if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM) {
/* Must not happen */
return;
}
bus_dmamap_unload(sc->sc_dmat, tx_data->map);
m_freem(tx_data->m);
tx_data->m = NULL;
/* TODO: Tx rate adjustment? */
if (tx_ring->queued > 0)
tx_ring->queued--;
}
#define QWX_TX_COMPL_NEXT(x) (((x) + 1) % DP_TX_COMP_RING_SIZE)
int
qwx_dp_tx_completion_handler(struct qwx_softc *sc, int ring_id)
{
struct qwx_dp *dp = &sc->dp;
int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id;
struct hal_srng *status_ring = &sc->hal.srng_list[hal_ring_id];
struct hal_tx_status ts = { 0 };
struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];
uint32_t *desc;
uint32_t msdu_id;
uint8_t mac_id;
#ifdef notyet
spin_lock_bh(&status_ring->lock);
#endif
qwx_hal_srng_access_begin(sc, status_ring);
while ((QWX_TX_COMPL_NEXT(tx_ring->tx_status_head) !=
tx_ring->tx_status_tail) &&
(desc = qwx_hal_srng_dst_get_next_entry(sc, status_ring))) {
memcpy(&tx_ring->tx_status[tx_ring->tx_status_head], desc,
sizeof(struct hal_wbm_release_ring));
tx_ring->tx_status_head =
QWX_TX_COMPL_NEXT(tx_ring->tx_status_head);
}
#if 0
if (unlikely((ath11k_hal_srng_dst_peek(ab, status_ring) != NULL) &&
(ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) ==
tx_ring->tx_status_tail))) {
/* TODO: Process pending tx_status messages when kfifo_is_full() */
ath11k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n");
}
#endif
qwx_hal_srng_access_end(sc, status_ring);
#ifdef notyet
spin_unlock_bh(&status_ring->lock);
#endif
while (QWX_TX_COMPL_NEXT(tx_ring->tx_status_tail) !=
tx_ring->tx_status_head) {
struct hal_wbm_release_ring *tx_status;
uint32_t desc_id;
tx_ring->tx_status_tail =
QWX_TX_COMPL_NEXT(tx_ring->tx_status_tail);
tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail];
qwx_dp_tx_status_parse(sc, tx_status, &ts);
desc_id = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
tx_status->buf_addr_info.info1);
mac_id = FIELD_GET(DP_TX_DESC_ID_MAC_ID, desc_id);
if (mac_id >= MAX_RADIOS)
continue;
msdu_id = FIELD_GET(DP_TX_DESC_ID_MSDU_ID, desc_id);
if (msdu_id >= sc->hw_params.tx_ring_size)
continue;
if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) {
qwx_dp_tx_process_htt_tx_complete(sc,
(void *)tx_status, mac_id, msdu_id, tx_ring);
continue;
}
#if 0
spin_lock(&tx_ring->tx_idr_lock);
msdu = idr_remove(&tx_ring->txbuf_idr, msdu_id);
if (unlikely(!msdu)) {
ath11k_warn(ab, "tx completion for unknown msdu_id %d\n",
msdu_id);
spin_unlock(&tx_ring->tx_idr_lock);
continue;
}
spin_unlock(&tx_ring->tx_idr_lock);
ar = ab->pdevs[mac_id].ar;
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
wake_up(&ar->dp.tx_empty_waitq);
#endif
qwx_dp_tx_complete_msdu(sc, tx_ring, msdu_id, &ts);
}
return 0;
}
@ -21050,6 +21282,7 @@ int
qwx_peer_create(struct qwx_softc *sc, struct qwx_vif *arvif, uint8_t pdev_id,
struct ieee80211_node *ni, struct peer_create_params *param)
{
struct ieee80211com *ic = &sc->sc_ic;
struct qwx_node *nq = (struct qwx_node *)ni;
struct ath11k_peer *peer;
int ret;
@ -21131,11 +21364,12 @@ qwx_peer_create(struct qwx_softc *sc, struct qwx_vif *arvif, uint8_t pdev_id,
peer->pdev_id = pdev_id;
#if 0
peer->sta = sta;
if (arvif->vif->type == NL80211_IFTYPE_STATION) {
#endif
if (ic->ic_opmode == IEEE80211_M_STA) {
arvif->ast_hash = peer->ast_hash;
arvif->ast_idx = peer->hw_peer_id;
}
#if 0
peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
@ -21715,6 +21949,249 @@ peer_clean:
return ret;
}
enum hal_tcl_encap_type
qwx_dp_tx_get_encap_type(struct qwx_softc *sc)
{
if (test_bit(ATH11K_FLAG_RAW_MODE, sc->sc_flags))
return HAL_TCL_ENCAP_TYPE_RAW;
#if 0
if (tx_info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
return HAL_TCL_ENCAP_TYPE_ETHERNET;
#endif
return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI;
}
uint8_t
qwx_dp_tx_get_tid(struct mbuf *m)
{
struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
uint16_t qos = ieee80211_get_qos(wh);
uint8_t tid = qos & IEEE80211_QOS_TID;
return tid;
}
void
qwx_hal_tx_cmd_desc_setup(struct qwx_softc *sc, void *cmd,
struct hal_tx_info *ti)
{
struct hal_tcl_data_cmd *tcl_cmd = (struct hal_tcl_data_cmd *)cmd;
tcl_cmd->buf_addr_info.info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR,
ti->paddr);
tcl_cmd->buf_addr_info.info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR,
((uint64_t)ti->paddr >> HAL_ADDR_MSB_REG_SHIFT));
tcl_cmd->buf_addr_info.info1 |= FIELD_PREP(
BUFFER_ADDR_INFO1_RET_BUF_MGR, ti->rbm_id) |
FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, ti->desc_id);
tcl_cmd->info0 =
FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_DESC_TYPE, ti->type) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ENCAP_TYPE, ti->encap_type) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ENCRYPT_TYPE, ti->encrypt_type) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_SEARCH_TYPE, ti->search_type) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ADDR_EN, ti->addr_search_flags) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_CMD_NUM, ti->meta_data_flags);
tcl_cmd->info1 = ti->flags0 |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_DATA_LEN, ti->data_len) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_PKT_OFFSET, ti->pkt_offset);
tcl_cmd->info2 = ti->flags1 |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID, ti->tid) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_LMAC_ID, ti->lmac_id);
tcl_cmd->info3 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_DSCP_TID_TABLE_IDX,
ti->dscp_tid_tbl_idx) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_SEARCH_INDEX, ti->bss_ast_idx) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_CACHE_SET_NUM, ti->bss_ast_hash);
tcl_cmd->info4 = 0;
#ifdef notyet
if (ti->enable_mesh)
ab->hw_params.hw_ops->tx_mesh_enable(ab, tcl_cmd);
#endif
}
int
qwx_dp_tx(struct qwx_softc *sc, struct qwx_vif *arvif, uint8_t pdev_id,
struct ieee80211_node *ni, struct mbuf *m)
{
struct ieee80211com *ic = &sc->sc_ic;
struct qwx_dp *dp = &sc->dp;
struct hal_tx_info ti = {0};
struct qwx_tx_data *tx_data;
struct hal_srng *tcl_ring;
struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
struct ieee80211_key *k = NULL;
struct dp_tx_ring *tx_ring;
void *hal_tcl_desc;
uint8_t pool_id;
uint8_t hal_ring_id;
int ret, msdu_id;
uint32_t ring_selector = 0;
uint8_t ring_map = 0;
if (test_bit(ATH11K_FLAG_CRASH_FLUSH, sc->sc_flags)) {
m_freem(m);
printf("%s: crash flush\n", __func__);
return ESHUTDOWN;
}
#if 0
if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
!ieee80211_is_data(hdr->frame_control)))
return -ENOTSUPP;
#endif
pool_id = 0;
ring_selector = 0;
ti.ring_id = ring_selector % sc->hw_params.max_tx_ring;
ti.rbm_id = sc->hw_params.hal_params->tcl2wbm_rbm_map[ti.ring_id].rbm_id;
ring_map |= (1 << ti.ring_id);
tx_ring = &dp->tx_ring[ti.ring_id];
if (tx_ring->queued >= sc->hw_params.tx_ring_size) {
m_freem(m);
return ENOSPC;
}
msdu_id = tx_ring->cur;
tx_data = &tx_ring->data[msdu_id];
if (tx_data->m != NULL) {
m_freem(m);
return ENOSPC;
}
ti.desc_id = FIELD_PREP(DP_TX_DESC_ID_MAC_ID, pdev_id) |
FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, msdu_id) |
FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id);
ti.encap_type = qwx_dp_tx_get_encap_type(sc);
ti.meta_data_flags = arvif->tcl_metadata;
if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) {
#if 0
if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) {
ti.encrypt_type =
ath11k_dp_tx_get_encrypt_type(skb_cb->cipher);
if (ieee80211_has_protected(hdr->frame_control))
skb_put(skb, IEEE80211_CCMP_MIC_LEN);
} else
#endif
ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
k = ieee80211_get_txkey(ic, wh, ni);
if ((m = ieee80211_encrypt(ic, m, k)) == NULL) {
printf("%s: encrypt failed\n", __func__);
return ENOBUFS;
}
/* 802.11 header may have moved. */
wh = mtod(m, struct ieee80211_frame *);
}
}
ti.addr_search_flags = arvif->hal_addr_search_flags;
ti.search_type = arvif->search_type;
ti.type = HAL_TCL_DESC_TYPE_BUFFER;
ti.pkt_offset = 0;
ti.lmac_id = qwx_hw_get_mac_from_pdev_id(sc, pdev_id);
ti.bss_ast_hash = arvif->ast_hash;
ti.bss_ast_idx = arvif->ast_idx;
ti.dscp_tid_tbl_idx = 0;
#if 0
if (likely(skb->ip_summed == CHECKSUM_PARTIAL &&
ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW)) {
ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_IP4_CKSUM_EN, 1) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP4_CKSUM_EN, 1) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP6_CKSUM_EN, 1) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TCP4_CKSUM_EN, 1) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TCP6_CKSUM_EN, 1);
}
if (ieee80211_vif_is_mesh(arvif->vif))
ti.enable_mesh = true;
#endif
ti.flags1 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE, 1);
ti.tid = qwx_dp_tx_get_tid(m);
#if 0
switch (ti.encap_type) {
case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI:
ath11k_dp_tx_encap_nwifi(skb);
break;
case HAL_TCL_ENCAP_TYPE_RAW:
if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
ret = -EINVAL;
goto fail_remove_idr;
}
break;
case HAL_TCL_ENCAP_TYPE_ETHERNET:
/* no need to encap */
break;
case HAL_TCL_ENCAP_TYPE_802_3:
default:
/* TODO: Take care of other encap modes as well */
ret = -EINVAL;
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
goto fail_remove_idr;
}
#endif
ret = bus_dmamap_load_mbuf(sc->sc_dmat, tx_data->map,
m, BUS_DMA_WRITE | BUS_DMA_NOWAIT);
if (ret) {
printf("%s: failed to map Tx buffer: %d\n",
sc->sc_dev.dv_xname, ret);
m_freem(m);
return ret;
}
ti.paddr = tx_data->map->dm_segs[0].ds_addr;
ti.data_len = m->m_pkthdr.len;
hal_ring_id = tx_ring->tcl_data_ring.ring_id;
tcl_ring = &sc->hal.srng_list[hal_ring_id];
#ifdef notyet
spin_lock_bh(&tcl_ring->lock);
#endif
qwx_hal_srng_access_begin(sc, tcl_ring);
hal_tcl_desc = (void *)qwx_hal_srng_src_get_next_entry(sc, tcl_ring);
if (!hal_tcl_desc) {
printf("%s: hal_tcl_desc == NULL\n", __func__);
/* NOTE: It is highly unlikely we'll be running out of tcl_ring
* desc because the desc is directly enqueued onto hw queue.
*/
qwx_hal_srng_access_end(sc, tcl_ring);
#if 0
ab->soc_stats.tx_err.desc_na[ti.ring_id]++;
#endif
#ifdef notyet
spin_unlock_bh(&tcl_ring->lock);
#endif
bus_dmamap_unload(sc->sc_dmat, tx_data->map);
m_freem(m);
return ENOMEM;
}
tx_data->m = m;
qwx_hal_tx_cmd_desc_setup(sc,
hal_tcl_desc + sizeof(struct hal_tlv_hdr), &ti);
qwx_hal_srng_access_end(sc, tcl_ring);
qwx_dp_shadow_start_timer(sc, tcl_ring, &dp->tx_ring_timer[ti.ring_id]);
#ifdef notyet
spin_unlock_bh(&tcl_ring->lock);
#endif
tx_ring->queued++;
tx_ring->cur = (tx_ring->cur + 1) % sc->hw_params.tx_ring_size;
return 0;
}
int
qwx_mac_station_add(struct qwx_softc *sc, struct qwx_vif *arvif,
uint8_t pdev_id, struct ieee80211_node *ni)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: qwxreg.h,v 1.5 2024/02/02 15:44:19 stsp Exp $ */
/* $OpenBSD: qwxreg.h,v 1.6 2024/02/03 10:03:18 stsp Exp $ */
/*
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
@ -38,6 +38,16 @@
* core.h
*/
#define ATH11K_TX_MGMT_NUM_PENDING_MAX 512
#define ATH11K_TX_MGMT_TARGET_MAX_SUPPORT_WMI 64
/* Pending management packets threshold for dropping probe responses */
#define ATH11K_PRB_RSP_DROP_THRESHOLD ((ATH11K_TX_MGMT_TARGET_MAX_SUPPORT_WMI * 3) / 4)
#define ATH11K_INVALID_HW_MAC_ID 0xFF
#define ATH11K_CONNECTION_LOSS_HZ (3 * HZ)
enum ath11k_hw_rev {
ATH11K_HW_IPQ8074,
ATH11K_HW_QCA6390_HW20,

View file

@ -1,4 +1,4 @@
/* $OpenBSD: qwxvar.h,v 1.9 2024/02/02 15:44:19 stsp Exp $ */
/* $OpenBSD: qwxvar.h,v 1.11 2024/02/03 20:07:19 kettenis Exp $ */
/*
* Copyright (c) 2018-2019 The Linux Foundation.
@ -113,6 +113,53 @@ struct ath11k_hw_hal_params {
const struct ath11k_hw_tcl2wbm_rbm_map *tcl2wbm_rbm_map;
};
struct hal_tx_info {
uint16_t meta_data_flags; /* %HAL_TCL_DATA_CMD_INFO0_META_ */
uint8_t ring_id;
uint32_t desc_id;
enum hal_tcl_desc_type type;
enum hal_tcl_encap_type encap_type;
uint64_t paddr;
uint32_t data_len;
uint32_t pkt_offset;
enum hal_encrypt_type encrypt_type;
uint32_t flags0; /* %HAL_TCL_DATA_CMD_INFO1_ */
uint32_t flags1; /* %HAL_TCL_DATA_CMD_INFO2_ */
uint16_t addr_search_flags; /* %HAL_TCL_DATA_CMD_INFO0_ADDR(X/Y)_ */
uint16_t bss_ast_hash;
uint16_t bss_ast_idx;
uint8_t tid;
uint8_t search_type; /* %HAL_TX_ADDR_SEARCH_ */
uint8_t lmac_id;
uint8_t dscp_tid_tbl_idx;
bool enable_mesh;
uint8_t rbm_id;
};
/* TODO: Check if the actual desc macros can be used instead */
#define HAL_TX_STATUS_FLAGS_FIRST_MSDU BIT(0)
#define HAL_TX_STATUS_FLAGS_LAST_MSDU BIT(1)
#define HAL_TX_STATUS_FLAGS_MSDU_IN_AMSDU BIT(2)
#define HAL_TX_STATUS_FLAGS_RATE_STATS_VALID BIT(3)
#define HAL_TX_STATUS_FLAGS_RATE_LDPC BIT(4)
#define HAL_TX_STATUS_FLAGS_RATE_STBC BIT(5)
#define HAL_TX_STATUS_FLAGS_OFDMA BIT(6)
#define HAL_TX_STATUS_DESC_LEN sizeof(struct hal_wbm_release_ring)
/* Tx status parsed from srng desc */
struct hal_tx_status {
enum hal_wbm_rel_src_module buf_rel_source;
enum hal_wbm_tqm_rel_reason status;
uint8_t ack_rssi;
uint32_t flags; /* %HAL_TX_STATUS_FLAGS_ */
uint32_t ppdu_id;
uint8_t try_cnt;
uint8_t tid;
uint16_t peer_id;
uint32_t rate_stats;
};
struct ath11k_hw_params {
const char *name;
uint16_t hw_rev;
@ -209,9 +256,7 @@ struct ath11k_hw_params {
};
struct ath11k_hw_ops {
#if notyet
uint8_t (*get_hw_mac_from_pdev_id)(int pdev_id);
#endif
void (*wmi_init_config)(struct qwx_softc *sc,
struct target_resource_config *config);
int (*mac_id_to_pdev_id)(struct ath11k_hw_params *hw, int mac_id);
@ -922,11 +967,9 @@ struct dp_tx_ring {
uint8_t tcl_data_ring_id;
struct dp_srng tcl_data_ring;
struct dp_srng tcl_comp_ring;
#if 0
struct idr txbuf_idr;
/* Protects txbuf_idr and num_pending */
spinlock_t tx_idr_lock;
#endif
int cur;
int queued;
struct qwx_tx_data *data;
struct hal_wbm_release_ring *tx_status;
int tx_status_head;
int tx_status_tail;
@ -1585,6 +1628,7 @@ struct qwx_softc {
struct device sc_dev;
struct ieee80211com sc_ic;
uint32_t sc_flags;
int sc_node;
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);

View file

@ -2120,8 +2120,10 @@ static struct edid *edid_filter_invalid_blocks(struct edid *edid,
kfree(edid);
#else
new = kmalloc(*alloc_size, GFP_KERNEL);
if (!new)
if (!new) {
kfree(edid);
return NULL;
}
memcpy(new, edid, EDID_LENGTH);
kfree(edid);
#endif

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_qwx_pci.c,v 1.4 2024/01/25 17:00:21 stsp Exp $ */
/* $OpenBSD: if_qwx_pci.c,v 1.5 2024/02/03 20:07:19 kettenis Exp $ */
/*
* Copyright 2023 Stefan Sperling <stsp@openbsd.org>
@ -770,6 +770,10 @@ qwx_pci_attach(struct device *parent, struct device *self, void *aux)
psc->sc_pc = pa->pa_pc;
psc->sc_tag = pa->pa_tag;
#ifdef __HAVE_FDT
sc->sc_node = PCITAG_NODE(pa->pa_tag);
#endif
rw_init(&sc->ioctl_rwl, "qwxioctl");
sreg = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_SUBSYS_ID_REG);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: pcivar.h,v 1.78 2023/04/13 15:07:43 miod Exp $ */
/* $OpenBSD: pcivar.h,v 1.79 2024/02/03 10:37:26 kettenis Exp $ */
/* $NetBSD: pcivar.h,v 1.23 1997/06/06 23:48:05 thorpej Exp $ */
/*
@ -161,13 +161,15 @@ struct pci_attach_args {
*
* OpenBSD doesn't actually use them yet -- csapuntz@cvs.openbsd.org
*/
#define PCI_FLAGS_IO_ENABLED 0x01 /* I/O space is enabled */
#define PCI_FLAGS_MEM_ENABLED 0x02 /* memory space is enabled */
#define PCI_FLAGS_MRL_OKAY 0x04 /* Memory Read Line okay */
#define PCI_FLAGS_MRM_OKAY 0x08 /* Memory Read Multiple okay */
#define PCI_FLAGS_MWI_OKAY 0x10 /* Memory Write and Invalidate
#define PCI_FLAGS_IO_ENABLED 0x01 /* I/O space is enabled */
#define PCI_FLAGS_MEM_ENABLED 0x02 /* memory space is enabled */
#define PCI_FLAGS_MRL_OKAY 0x04 /* Memory Read Line okay */
#define PCI_FLAGS_MRM_OKAY 0x08 /* Memory Read Multiple okay */
#define PCI_FLAGS_MWI_OKAY 0x10 /* Memory Write and Invalidate
okay */
#define PCI_FLAGS_MSI_ENABLED 0x20 /* Message Signaled Interrupt
#define PCI_FLAGS_MSI_ENABLED 0x20 /* Message Signaled Interrupt
enabled */
#define PCI_FLAGS_MSIVEC_ENABLED 0x40 /* Multiple Message Capability
enabled */
/*

View file

@ -1,4 +1,4 @@
/* $OpenBSD: softraid.c,v 1.429 2022/12/21 09:54:23 kn Exp $ */
/* $OpenBSD: softraid.c,v 1.430 2024/02/03 18:51:58 beck Exp $ */
/*
* Copyright (c) 2007, 2008, 2009 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
@ -445,7 +445,6 @@ sr_rw(struct sr_softc *sc, dev_t dev, char *buf, size_t size, daddr_t blkno,
splx(s);
}
LIST_INIT(&b.b_dep);
VOP_STRATEGY(vp, &b);
biowait(&b);
@ -2018,8 +2017,6 @@ sr_ccb_rw(struct sr_discipline *sd, int chunk, daddr_t blkno,
splx(s);
}
LIST_INIT(&ccb->ccb_buf.b_dep);
DNPRINTF(SR_D_DIS, "%s: %s %s ccb "
"b_bcount %ld b_blkno %lld b_flags 0x%0lx b_data %p\n",
DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, sd->sd_name,