-/* $OpenBSD: if_mwx.c,v 1.3 2024/05/20 21:22:43 martijn Exp $ */
+/* $OpenBSD: if_mwx.c,v 1.4 2024/05/22 08:38:57 martijn Exp $ */
/*
* Copyright (c) 2022 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2021 MediaTek Inc.
int mt7921_dma_disable(struct mwx_softc *sc, int force);
void mt7921_dma_enable(struct mwx_softc *sc);
+int mt7921_e_mcu_fw_pmctrl(struct mwx_softc *);
+int mt7921_e_mcu_drv_pmctrl(struct mwx_softc *);
int mt7921_wfsys_reset(struct mwx_softc *sc);
uint32_t mt7921_reg_addr(struct mwx_softc *, uint32_t);
int mt7921_init_hardware(struct mwx_softc *);
sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET,
mwx_intr, sc, DEVNAME(sc));
+ if (mt7921_e_mcu_fw_pmctrl(sc) != 0 ||
+ mt7921_e_mcu_drv_pmctrl(sc) != 0)
+ goto fail;
+
if ((error = mwx_txwi_alloc(sc, MWX_TXWI_MAX)) != 0) {
printf("%s: failed to allocate DMA resources %d\n",
DEVNAME(sc), error);
mwx_write(sc, MT_PCIE_MAC_INT_ENABLE, 0xff);
}
+int
+mt7921_e_mcu_fw_pmctrl(struct mwx_softc *sc)
+{
+ int i;
+
+ for (i = 0; i < MT7921_MCU_INIT_RETRY_COUNT; i++) {
+ mwx_write(sc, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_SET_OWN);
+ if (mwx_poll(sc, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_OWN_SYNC,
+ 4, 50) == 0)
+ break;
+ }
+
+ if (i == MT7921_MCU_INIT_RETRY_COUNT) {
+ printf("%s: firmware own failed\n", DEVNAME(sc));
+ return EIO;
+ }
+
+ return 0;
+}
+
+int
+mt7921_e_mcu_drv_pmctrl(struct mwx_softc *sc)
+{
+ int i;
+
+ for (i = 0; i < MT7921_MCU_INIT_RETRY_COUNT; i++) {
+ mwx_write(sc, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_CLR_OWN);
+ if (mwx_poll(sc, MT_CONN_ON_LPCTL, 0,
+ PCIE_LPCR_HOST_OWN_SYNC, 50) == 0)
+ break;
+ }
+
+ if (i == MT7921_MCU_INIT_RETRY_COUNT) {
+ printf("%s: driver own failed\n", DEVNAME(sc));
+ return EIO;
+ }
+
+ return 0;
+}
+
int
mt7921_wfsys_reset(struct mwx_softc *sc)
{
#define MT_CONN_ON_MISC 0x7c0600f0
#define MT_TOP_MISC2_FW_N9_RDY 0x3
+#define MT_CONN_ON_LPCTL 0x7c060010
+#define PCIE_LPCR_HOST_SET_OWN (1U << 0)
+#define PCIE_LPCR_HOST_CLR_OWN (1U << 1)
+#define PCIE_LPCR_HOST_OWN_SYNC (1U << 2)
+
#define MT_WFSYS_SW_RST_B 0x18000140
#define WFSYS_SW_RST_B (1U << 0)
#define WFSYS_SW_INIT_DONE (1U << 4)