Add firmware and driver own functions. These are needed to bring up the
authormartijn <martijn@openbsd.org>
Wed, 22 May 2024 08:38:57 +0000 (08:38 +0000)
committermartijn <martijn@openbsd.org>
Wed, 22 May 2024 08:38:57 +0000 (08:38 +0000)
MT7922.

OK claudio@

sys/dev/pci/if_mwx.c
sys/dev/pci/if_mwxreg.h

index 9b3466a..8f9ea2c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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.
@@ -375,6 +375,8 @@ int mwx_mcu_wait_resp_msg(struct mwx_softc *, uint32_t, int,
 
 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 *);
@@ -1207,6 +1209,10 @@ mwx_attach(struct device *parent, struct device *self, void *aux)
        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);
@@ -2590,6 +2596,46 @@ mt7921_dma_enable(struct mwx_softc *sc)
        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)
 {
index efa5e2d..0468a2f 100644 (file)
 #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)