iwlwifi: pcie: update sw error interrupt for BZ family
authorMike Golant <michael.golant@intel.com>
Sun, 24 Oct 2021 13:55:03 +0000 (16:55 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Thu, 28 Oct 2021 09:04:09 +0000 (12:04 +0300)
The cause for sw error in BZ device family was changed

Signed-off-by: Mike Golant <michael.golant@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20211024165252.f674cd409b8e.I519f554d0a22d4711077785ec2bd7c564997241f@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-csr.h
drivers/net/wireless/intel/iwlwifi/pcie/rx.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c

index 2c4d70fb32fa8279a9427cd8fc56950d8b7217e2..ff79a2ecb242240ac73fca98d495b47286c780f6 100644 (file)
@@ -605,6 +605,7 @@ enum msix_hw_int_causes {
        MSIX_HW_INT_CAUSES_REG_WAKEUP           = BIT(1),
        MSIX_HW_INT_CAUSES_REG_IML              = BIT(1),
        MSIX_HW_INT_CAUSES_REG_RESET_DONE       = BIT(2),
+       MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ        = BIT(5),
        MSIX_HW_INT_CAUSES_REG_CT_KILL          = BIT(6),
        MSIX_HW_INT_CAUSES_REG_RF_KILL          = BIT(7),
        MSIX_HW_INT_CAUSES_REG_PERIODIC         = BIT(8),
index 8e45eb38304b244989853969071a334231c30110..14602d6d6699f6db44778539c30e137dded28522 100644 (file)
@@ -2149,6 +2149,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
        u32 inta_fh_msk = ~MSIX_FH_INT_CAUSES_DATA_QUEUE;
        u32 inta_fh, inta_hw;
        bool polling = false;
+       bool sw_err;
 
        if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_NON_RX)
                inta_fh_msk |= MSIX_FH_INT_CAUSES_Q0;
@@ -2221,9 +2222,13 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
                wake_up(&trans_pcie->ucode_write_waitq);
        }
 
+       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
+               sw_err = inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ;
+       else
+               sw_err = inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR;
+
        /* Error detected by uCode */
-       if ((inta_fh & MSIX_FH_INT_CAUSES_FH_ERR) ||
-           (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR)) {
+       if ((inta_fh & MSIX_FH_INT_CAUSES_FH_ERR) || sw_err) {
                IWL_ERR(trans,
                        "Microcode SW error detected. Restarting 0x%X.\n",
                        inta_fh);
index 262795368bfe35a0ac10f07a113273614b0a5f56..1efb53f78a62f39b4410d9c34c078617505fc12d 100644 (file)
@@ -1062,7 +1062,7 @@ struct iwl_causes_list {
        u8 addr;
 };
 
-static struct iwl_causes_list causes_list[] = {
+static const struct iwl_causes_list causes_list_common[] = {
        {MSIX_FH_INT_CAUSES_D2S_CH0_NUM,        CSR_MSIX_FH_INT_MASK_AD, 0},
        {MSIX_FH_INT_CAUSES_D2S_CH1_NUM,        CSR_MSIX_FH_INT_MASK_AD, 0x1},
        {MSIX_FH_INT_CAUSES_S2D,                CSR_MSIX_FH_INT_MASK_AD, 0x3},
@@ -1073,30 +1073,50 @@ static struct iwl_causes_list causes_list[] = {
        {MSIX_HW_INT_CAUSES_REG_CT_KILL,        CSR_MSIX_HW_INT_MASK_AD, 0x16},
        {MSIX_HW_INT_CAUSES_REG_RF_KILL,        CSR_MSIX_HW_INT_MASK_AD, 0x17},
        {MSIX_HW_INT_CAUSES_REG_PERIODIC,       CSR_MSIX_HW_INT_MASK_AD, 0x18},
-       {MSIX_HW_INT_CAUSES_REG_SW_ERR,         CSR_MSIX_HW_INT_MASK_AD, 0x29},
        {MSIX_HW_INT_CAUSES_REG_SCD,            CSR_MSIX_HW_INT_MASK_AD, 0x2A},
        {MSIX_HW_INT_CAUSES_REG_FH_TX,          CSR_MSIX_HW_INT_MASK_AD, 0x2B},
        {MSIX_HW_INT_CAUSES_REG_HW_ERR,         CSR_MSIX_HW_INT_MASK_AD, 0x2D},
        {MSIX_HW_INT_CAUSES_REG_HAP,            CSR_MSIX_HW_INT_MASK_AD, 0x2E},
 };
 
+static const struct iwl_causes_list causes_list_pre_bz[] = {
+       {MSIX_HW_INT_CAUSES_REG_SW_ERR,         CSR_MSIX_HW_INT_MASK_AD, 0x29},
+};
+
+static const struct iwl_causes_list causes_list_bz[] = {
+       {MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ,      CSR_MSIX_HW_INT_MASK_AD, 0x29},
+};
+
+static void iwl_pcie_map_list(struct iwl_trans *trans,
+                             const struct iwl_causes_list *causes,
+                             int arr_size, int val)
+{
+       int i;
+
+       for (i = 0; i < arr_size; i++) {
+               iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val);
+               iwl_clear_bit(trans, causes[i].mask_reg,
+                             causes[i].cause_num);
+       }
+}
+
 static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie =  IWL_TRANS_GET_PCIE_TRANS(trans);
        int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE;
-       int i, arr_size = ARRAY_SIZE(causes_list);
-       struct iwl_causes_list *causes = causes_list;
-
        /*
         * Access all non RX causes and map them to the default irq.
         * In case we are missing at least one interrupt vector,
         * the first interrupt vector will serve non-RX and FBQ causes.
         */
-       for (i = 0; i < arr_size; i++) {
-               iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val);
-               iwl_clear_bit(trans, causes[i].mask_reg,
-                             causes[i].cause_num);
-       }
+       iwl_pcie_map_list(trans, causes_list_common,
+                         ARRAY_SIZE(causes_list_common), val);
+       if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
+               iwl_pcie_map_list(trans, causes_list_bz,
+                                 ARRAY_SIZE(causes_list_bz), val);
+       else
+               iwl_pcie_map_list(trans, causes_list_pre_bz,
+                                 ARRAY_SIZE(causes_list_pre_bz), val);
 }
 
 static void iwl_pcie_map_rx_causes(struct iwl_trans *trans)
@@ -3384,7 +3404,10 @@ static void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
 
        if (trans_pcie->msix_enabled) {
                inta_addr = CSR_MSIX_HW_INT_CAUSES_AD;
-               sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR;
+               if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
+                       sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ;
+               else
+                       sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR;
        } else {
                inta_addr = CSR_INT;
                sw_err_bit = CSR_INT_BIT_SW_ERR;