From 8674c33ca92661799386a724b4b6173a7f36ccf7 Mon Sep 17 00:00:00 2001 From: kettenis Date: Tue, 8 Nov 2022 18:28:10 +0000 Subject: [PATCH] Implement alternative mailbox handling mechanism required by newer firmware. ok patrick@ --- sys/dev/pci/if_bwfm_pci.c | 69 +++++++++++++++++++++++++++++++++++++-- sys/dev/pci/if_bwfm_pci.h | 27 ++++++++++++++- 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/sys/dev/pci/if_bwfm_pci.c b/sys/dev/pci/if_bwfm_pci.c index c966db119f5..a2ff1de73d6 100644 --- a/sys/dev/pci/if_bwfm_pci.c +++ b/sys/dev/pci/if_bwfm_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bwfm_pci.c,v 1.72 2022/10/23 13:45:32 kettenis Exp $ */ +/* $OpenBSD: if_bwfm_pci.c,v 1.73 2022/11/08 18:28:10 kettenis Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2017 Patrick Wildt @@ -187,6 +187,7 @@ struct bwfm_pci_softc { uint8_t sc_mbdata_done; uint8_t sc_pcireg64; + uint8_t sc_mb_via_ctl; }; struct bwfm_pci_dmamem { @@ -305,6 +306,8 @@ int bwfm_pci_msgbuf_set_dcmd(struct bwfm_softc *, int, int, char *, size_t); void bwfm_pci_msgbuf_rxioctl(struct bwfm_pci_softc *, struct msgbuf_ioctl_resp_hdr *); +int bwfm_pci_msgbuf_h2d_mb_write(struct bwfm_pci_softc *, + uint32_t); struct bwfm_buscore_ops bwfm_pci_buscore_ops = { .bc_read = bwfm_pci_buscore_read, @@ -533,6 +536,25 @@ bwfm_pci_preinit(struct bwfm_softc *bwfm) return 1; } + if (sc->sc_shared_version >= 6) { + uint32_t host_cap; + + if ((sc->sc_shared_flags & BWFM_SHARED_INFO_USE_MAILBOX) == 0) + sc->sc_mb_via_ctl = 1; + + host_cap = sc->sc_shared_version; + if (sc->sc_shared_flags & BWFM_SHARED_INFO_HOSTRDY_DB1) + host_cap |= BWFM_SHARED_HOST_CAP_H2D_ENABLE_HOSTRDY; + if (sc->sc_shared_flags & BWFM_SHARED_INFO_SHARED_DAR) + host_cap |= BWFM_SHARED_HOST_CAP_H2D_DAR; + host_cap |= BWFM_SHARED_HOST_CAP_DS_NO_OOB_DW; + + bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh, + sc->sc_shared_address + BWFM_SHARED_HOST_CAP, host_cap); + bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh, + sc->sc_shared_address + BWFM_SHARED_HOST_CAP2, 0); + } + sc->sc_dma_idx_sz = 0; if (sc->sc_shared_flags & BWFM_SHARED_INFO_DMA_INDEX) { if (sc->sc_shared_flags & BWFM_SHARED_INFO_DMA_2B_IDX) @@ -1408,7 +1430,7 @@ void bwfm_pci_ring_bell(struct bwfm_pci_softc *sc, struct bwfm_pci_msgring *ring) { - if (sc->sc_pcireg64) + if (sc->sc_shared_flags & BWFM_SHARED_INFO_SHARED_DAR) bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh, BWFM_PCI_64_PCIE2REG_H2D_MAILBOX_0, 1); else @@ -1641,6 +1663,7 @@ bwfm_pci_msg_rx(struct bwfm_pci_softc *sc, void *buf, struct mbuf_list *ml) struct msgbuf_tx_status *tx; struct msgbuf_rx_complete *rx; struct msgbuf_rx_event *event; + struct msgbuf_d2h_mailbox_data *d2h; struct msgbuf_common_hdr *msg; struct msgbuf_flowring_create_resp *fcr; struct msgbuf_flowring_delete_resp *fdr; @@ -1755,6 +1778,13 @@ bwfm_pci_msg_rx(struct bwfm_pci_softc *sc, void *buf, struct mbuf_list *ml) if_rxr_put(&sc->sc_rxbuf_ring, 1); bwfm_pci_fill_rx_rings(sc); break; + case MSGBUF_TYPE_D2H_MAILBOX_DATA: + d2h = (struct msgbuf_d2h_mailbox_data *)buf; + if (d2h->data & BWFM_PCI_D2H_DEV_D3_ACK) { + sc->sc_mbdata_done = 1; + wakeup(&sc->sc_mbdata_done); + } + break; default: printf("%s: msgtype 0x%08x\n", __func__, msg->msgtype); break; @@ -2099,6 +2129,10 @@ bwfm_pci_flowring_delete(struct bwfm_pci_softc *sc, int flowid) bwfm_pci_ring_write_commit(sc, &sc->sc_ctrl_submit); splx(s); + + tsleep_nsec(ring, PCATCH, DEVNAME(sc), SEC_TO_NSEC(2)); + if (ring->status != RING_CLOSED) + printf("%s: flowring not closing\n", DEVNAME(sc)); } void @@ -2111,6 +2145,7 @@ bwfm_pci_flowring_delete_cb(struct bwfm_softc *bwfm, void *arg) ring = &sc->sc_flowrings[cmd->flowid]; bwfm_pci_dmamem_free(sc, ring->ring); ring->status = RING_CLOSED; + wakeup(ring); } void @@ -2225,6 +2260,9 @@ bwfm_pci_send_mb_data(struct bwfm_pci_softc *sc, uint32_t htod_mb_data) uint32_t reg; int i; + if (sc->sc_mb_via_ctl) + return bwfm_pci_msgbuf_h2d_mb_write(sc, htod_mb_data); + for (i = 0; i < 100; i++) { reg = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh, sc->sc_htod_mb_data_addr); @@ -2405,7 +2443,7 @@ bwfm_pci_hostready(struct bwfm_pci_softc *sc) if ((sc->sc_shared_flags & BWFM_SHARED_INFO_HOSTRDY_DB1) == 0) return; - if (sc->sc_pcireg64) + if (sc->sc_shared_flags & BWFM_SHARED_INFO_SHARED_DAR) bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh, BWFM_PCI_64_PCIE2REG_H2D_MAILBOX_1, 1); else @@ -2524,3 +2562,28 @@ bwfm_pci_msgbuf_rxioctl(struct bwfm_pci_softc *sc, m_freem(m); } + +int +bwfm_pci_msgbuf_h2d_mb_write(struct bwfm_pci_softc *sc, uint32_t data) +{ + struct msgbuf_h2d_mailbox_data *req; + int s; + + s = splnet(); + req = bwfm_pci_ring_write_reserve(sc, &sc->sc_ctrl_submit); + if (req == NULL) { + splx(s); + return ENOBUFS; + } + + req->msg.msgtype = MSGBUF_TYPE_H2D_MAILBOX_DATA; + req->msg.ifidx = -1; + req->msg.flags = 0; + req->msg.request_id = 0; + req->data = data; + + bwfm_pci_ring_write_commit(sc, &sc->sc_ctrl_submit); + splx(s); + + return 0; +} diff --git a/sys/dev/pci/if_bwfm_pci.h b/sys/dev/pci/if_bwfm_pci.h index b9edacf2bed..3522833a0ca 100644 --- a/sys/dev/pci/if_bwfm_pci.h +++ b/sys/dev/pci/if_bwfm_pci.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bwfm_pci.h,v 1.8 2021/12/31 09:24:18 patrick Exp $ */ +/* $OpenBSD: if_bwfm_pci.h,v 1.9 2022/11/08 18:28:10 kettenis Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2017 Patrick Wildt @@ -114,7 +114,12 @@ #define BWFM_SHARED_INFO_VERSION_MASK 0x00FF #define BWFM_SHARED_INFO_DMA_INDEX 0x10000 #define BWFM_SHARED_INFO_DMA_2B_IDX 0x100000 +#define BWFM_SHARED_INFO_USE_MAILBOX 0x2000000 +#define BWFM_SHARED_INFO_TIMESTAMP_DB0 0x8000000 #define BWFM_SHARED_INFO_HOSTRDY_DB1 0x10000000 +#define BWFM_SHARED_INFO_NO_OOB_DW 0x20000000 +#define BWFM_SHARED_INFO_INBAND_DS 0x40000000 +#define BWFM_SHARED_INFO_SHARED_DAR 0x80000000 #define BWFM_SHARED_CONSOLE_ADDR 0x14 #define BWFM_SHARED_MAX_RXBUFPOST 0x22 #define BWFM_SHARED_MAX_RXBUFPOST_DEFAULT 255 @@ -136,6 +141,11 @@ #define BWFM_SHARED_DMA_RINGUPD_LEN 0x40 #define BWFM_SHARED_DMA_RINGUPD_ADDR_LOW 0x44 #define BWFM_SHARED_DMA_RINGUPD_ADDR_HIGH 0x48 +#define BWFM_SHARED_HOST_CAP 0x54 +#define BWFM_SHARED_HOST_CAP_H2D_ENABLE_HOSTRDY 0x00000400 +#define BWFM_SHARED_HOST_CAP_DS_NO_OOB_DW 0x00001000 +#define BWFM_SHARED_HOST_CAP_H2D_DAR 0x00010000 +#define BWFM_SHARED_HOST_CAP2 0x70 #define BWFM_RING_MAX_ITEM 0x04 #define BWFM_RING_LEN_ITEMS 0x06 @@ -200,6 +210,8 @@ struct bwfm_pci_ringinfo { #define MSGBUF_TYPE_RX_CMPLT 0x12 #define MSGBUF_TYPE_LPBK_DMAXFER 0x13 #define MSGBUF_TYPE_LPBK_DMAXFER_CMPLT 0x14 +#define MSGBUF_TYPE_H2D_MAILBOX_DATA 0x23 +#define MSGBUF_TYPE_D2H_MAILBOX_DATA 0x24 struct msgbuf_common_hdr { uint8_t msgtype; @@ -336,3 +348,16 @@ struct msgbuf_flowring_flush_resp { struct msgbuf_completion_hdr compl_hdr; uint32_t rsvd0[3]; }; + +struct msgbuf_h2d_mailbox_data { + struct msgbuf_common_hdr msg; + uint32_t data; + uint32_t rsvd0[7]; +}; + +struct msgbuf_d2h_mailbox_data { + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint32_t data; + uint32_t rsvd0[2]; +}; -- 2.20.1