iwlwifi: pcie: implement Bz device startup
authorJohannes Berg <johannes.berg@intel.com>
Mon, 2 Aug 2021 18:58:51 +0000 (21:58 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Thu, 26 Aug 2021 20:34:25 +0000 (23:34 +0300)
Device startup changed in Bz, some register bits moved around.
Change the code accordingly.

The new Bz hardware changes also the way we wake it (grab NIC
access) and the way we disable bus mastering, update the driver
code accordingly.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210802215208.00a137364a95.I059a2abac948965458862941ee7db6a2e1076fa6@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-csr.h
drivers/net/wireless/intel/iwlwifi/iwl-io.c
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c

index 004a1b0..704ff2a 100644 (file)
 #define CSR_GP_CNTRL_REG_FLAG_RFKILL_WAKE_L1A_EN     (0x04000000)
 #define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW          (0x08000000)
 
+/* From Bz we use these instead during init/reset flow */
+#define CSR_GP_CNTRL_REG_FLAG_MAC_INIT                 BIT(6)
+#define CSR_GP_CNTRL_REG_FLAG_ROM_START                        BIT(7)
+#define CSR_GP_CNTRL_REG_FLAG_MAC_STATUS               BIT(20)
+#define CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ                BIT(21)
+#define CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS        BIT(28)
+#define CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_REQ   BIT(29)
+#define CSR_GP_CNTRL_REG_FLAG_SW_RESET                 BIT(31)
 
 /* HW REV */
 #define CSR_HW_REV_DASH(_val)          (((_val) & 0x0000003) >> 0)
index 2a0be1f..dba54b3 100644 (file)
@@ -398,6 +398,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf)
 int iwl_finish_nic_init(struct iwl_trans *trans,
                        const struct iwl_cfg_trans_params *cfg_trans)
 {
+       u32 poll_ready;
        int err;
 
        if (cfg_trans->bisr_workaround) {
@@ -409,7 +410,16 @@ int iwl_finish_nic_init(struct iwl_trans *trans,
         * Set "initialization complete" bit to move adapter from
         * D0U* --> D0A* (powered-up active) state.
         */
-       iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+       if (cfg_trans->device_family >= IWL_DEVICE_FAMILY_BZ) {
+               iwl_set_bit(trans, CSR_GP_CNTRL,
+                           CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
+                           CSR_GP_CNTRL_REG_FLAG_MAC_INIT);
+               poll_ready = CSR_GP_CNTRL_REG_FLAG_MAC_STATUS;
+       } else {
+               iwl_set_bit(trans, CSR_GP_CNTRL,
+                           CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+               poll_ready = CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY;
+       }
 
        if (cfg_trans->device_family == IWL_DEVICE_FAMILY_8000)
                udelay(2);
@@ -419,10 +429,7 @@ int iwl_finish_nic_init(struct iwl_trans *trans,
         * device-internal resources is supported, e.g. iwl_write_prph()
         * and accesses to uCode SRAM.
         */
-       err = iwl_poll_bit(trans, CSR_GP_CNTRL,
-                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-                          25000);
+       err = iwl_poll_bit(trans, CSR_GP_CNTRL, poll_ready, poll_ready, 25000);
        if (err < 0)
                IWL_DEBUG_INFO(trans, "Failed to wake NIC\n");
 
index a266a35..fa416b4 100644 (file)
@@ -87,7 +87,12 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
         * Clear "initialization complete" bit to move adapter from
         * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
         */
-       iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
+               iwl_clear_bit(trans, CSR_GP_CNTRL,
+                             CSR_GP_CNTRL_REG_FLAG_MAC_INIT);
+       else
+               iwl_clear_bit(trans, CSR_GP_CNTRL,
+                             CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 }
 
 static void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans)
@@ -159,9 +164,17 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
                iwl_pcie_ctxt_info_free(trans);
 
        /* Make sure (redundant) we've released our request to stay awake */
-       iwl_clear_bit(trans, CSR_GP_CNTRL,
-                     CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
+               iwl_clear_bit(trans, CSR_GP_CNTRL,
+                             CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ);
+       else
+               iwl_clear_bit(trans, CSR_GP_CNTRL,
+                             CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 
+       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
+               iwl_set_bit(trans, CSR_GP_CNTRL,
+                           CSR_GP_CNTRL_REG_FLAG_SW_RESET);
+       }
        /* Stop the device, and put it in low power state */
        iwl_pcie_gen2_apm_stop(trans, false);
 
@@ -441,7 +454,10 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
 
        iwl_pcie_set_ltr(trans);
 
-       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
+       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
+               iwl_set_bit(trans, CSR_GP_CNTRL,
+                           CSR_GP_CNTRL_REG_FLAG_ROM_START);
+       else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
                iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
        else
                iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1);
index 65cc25c..86a9494 100644 (file)
@@ -449,11 +449,23 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans)
        int ret;
 
        /* stop device's busmaster DMA activity */
-       iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 
-       ret = iwl_poll_bit(trans, CSR_RESET,
-                          CSR_RESET_REG_FLAG_MASTER_DISABLED,
-                          CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
+       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
+               iwl_set_bit(trans, CSR_GP_CNTRL,
+                           CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_REQ);
+
+               ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
+                                  CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS,
+                                  CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS,
+                                  100);
+       } else {
+               iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+
+               ret = iwl_poll_bit(trans, CSR_RESET,
+                                  CSR_RESET_REG_FLAG_MASTER_DISABLED,
+                                  CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
+       }
+
        if (ret < 0)
                IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");
 
@@ -1995,15 +2007,24 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
 {
        int ret;
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       u32 write = CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ;
+       u32 mask = CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
+                  CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP;
+       u32 poll = CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN;
 
        spin_lock(&trans_pcie->reg_lock);
 
        if (trans_pcie->cmd_hold_nic_awake)
                goto out;
 
+       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
+               write = CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ;
+               mask = CSR_GP_CNTRL_REG_FLAG_MAC_STATUS;
+               poll = CSR_GP_CNTRL_REG_FLAG_MAC_STATUS;
+       }
+
        /* this bit wakes up the NIC */
-       __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
-                                CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, write);
        if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000)
                udelay(2);
 
@@ -2027,10 +2048,7 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
         * 5000 series and later (including 1000 series) have non-volatile SRAM,
         * and do not save/restore SRAM when power cycling.
         */
-       ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
-                          CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
-                          (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
-                           CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
+       ret = iwl_poll_bit(trans, CSR_GP_CNTRL, poll, mask, 15000);
        if (unlikely(ret < 0)) {
                u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL);