net: qed: attention clearing properties
authorIgor Russkikh <irusskikh@marvell.com>
Thu, 14 May 2020 09:57:22 +0000 (12:57 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 14 May 2020 20:25:46 +0000 (13:25 -0700)
On different hardware events we have to respond differently,
on some of hardware indications hw attention (error condition)
should be cleared by the driver to continue normal functioning.

Here we introduce attention clear flags, and put them on some
important events (in aeu_descs).

Signed-off-by: Ariel Elior <ariel.elior@marvell.com>
Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qed/qed.h
drivers/net/ethernet/qlogic/qed/qed_int.c
drivers/net/ethernet/qlogic/qed/qed_int.h
drivers/net/ethernet/qlogic/qed/qed_main.c
drivers/net/ethernet/qlogic/qede/qede_main.c
include/linux/qed/qed_if.h

index 07f6ef930b522ad744064bb884db15bd600432c1..66ed39d6f357bc937effd7d0b13a995602209f0f 100644 (file)
@@ -838,6 +838,9 @@ struct qed_dev {
        /* Recovery */
        bool recov_in_prog;
 
+       /* Indicates whether should prevent attentions from being reasserted */
+       bool attn_clr_en;
+
        /* LLH info */
        u8 ppfid_bitmap;
        struct qed_llh_info *p_llh_info;
index 1b1447b2f059bc3a92f41b8f95f81ff7bb59f675..b7b974f0ef210e16e2661c8b2c834dd5c7aead32 100644 (file)
@@ -96,6 +96,7 @@ struct aeu_invert_reg_bit {
 #define ATTENTION_BB(value)             (value << ATTENTION_BB_SHIFT)
 #define ATTENTION_BB_DIFFERENT          BIT(23)
 
+#define ATTENTION_CLEAR_ENABLE          BIT(28)
        unsigned int flags;
 
        /* Callback to call if attention will be triggered */
@@ -371,6 +372,13 @@ static int qed_fw_assertion(struct qed_hwfn *p_hwfn)
        return -EINVAL;
 }
 
+static int qed_general_attention_35(struct qed_hwfn *p_hwfn)
+{
+       DP_INFO(p_hwfn, "General attention 35!\n");
+
+       return 0;
+}
+
 #define QED_DORQ_ATTENTION_REASON_MASK  (0xfffff)
 #define QED_DORQ_ATTENTION_OPAQUE_MASK  (0xffff)
 #define QED_DORQ_ATTENTION_OPAQUE_SHIFT (0x0)
@@ -613,14 +621,15 @@ static struct aeu_invert_reg aeu_descs[NUM_ATTN_REGS] = {
 
        {
                {       /* After Invert 4 */
-                       {"General Attention 32", ATTENTION_SINGLE,
-                        qed_fw_assertion,
+                       {"General Attention 32", ATTENTION_SINGLE |
+                        ATTENTION_CLEAR_ENABLE, qed_fw_assertion,
                         MAX_BLOCK_ID},
                        {"General Attention %d",
                         (2 << ATTENTION_LENGTH_SHIFT) |
                         (33 << ATTENTION_OFFSET_SHIFT), NULL, MAX_BLOCK_ID},
-                       {"General Attention 35", ATTENTION_SINGLE,
-                        NULL, MAX_BLOCK_ID},
+                       {"General Attention 35", ATTENTION_SINGLE |
+                        ATTENTION_CLEAR_ENABLE, qed_general_attention_35,
+                        MAX_BLOCK_ID},
                        {"NWS Parity",
                         ATTENTION_PAR | ATTENTION_BB_DIFFERENT |
                         ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_0),
@@ -2361,6 +2370,11 @@ void qed_int_disable_post_isr_release(struct qed_dev *cdev)
                cdev->hwfns[i].b_int_requested = false;
 }
 
+void qed_int_attn_clr_enable(struct qed_dev *cdev, bool clr_enable)
+{
+       cdev->attn_clr_en = clr_enable;
+}
+
 int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
                          u8 timer_res, u16 sb_id, bool tx)
 {
index 9ad568d93ae6501c8dd3780fe5c657956ca4f4ba..e09db33863670072e047b2d13304aa18a463afdc 100644 (file)
@@ -190,6 +190,17 @@ void qed_int_get_num_sbs(struct qed_hwfn   *p_hwfn,
  */
 void qed_int_disable_post_isr_release(struct qed_dev *cdev);
 
+/**
+ * @brief qed_int_attn_clr_enable - sets whether the general behavior is
+ *        preventing attentions from being reasserted, or following the
+ *        attributes of the specific attention.
+ *
+ * @param cdev
+ * @param clr_enable
+ *
+ */
+void qed_int_attn_clr_enable(struct qed_dev *cdev, bool clr_enable);
+
 /**
  * @brief - Doorbell Recovery handler.
  *          Run doorbell recovery in case of PF overflow (and flush DORQ if
index d7c9d94e4c59c8f95a2ddee30a3c727d2780d69a..83e798d4eebb1764aa30a94fe14bf52fdcdda361 100644 (file)
@@ -2491,10 +2491,14 @@ void qed_hw_error_occurred(struct qed_hwfn *p_hwfn,
 
        DP_NOTICE(p_hwfn, "HW error occurred [%s]\n", err_str);
 
-       /* Call the HW error handler of the protocol driver
+       /* Call the HW error handler of the protocol driver.
+        * If it is not available - perform a minimal handling of preventing
+        * HW attentions from being reasserted.
         */
        if (ops && ops->schedule_hw_err_handler)
                ops->schedule_hw_err_handler(cookie, err_type);
+       else
+               qed_int_attn_clr_enable(p_hwfn->cdev, true);
 }
 
 static int qed_set_coalesce(struct qed_dev *cdev, u16 rx_coal, u16 tx_coal,
@@ -2718,6 +2722,7 @@ const struct qed_common_ops qed_common_ops_pass = {
        .set_led = &qed_set_led,
        .recovery_process = &qed_recovery_process,
        .recovery_prolog = &qed_recovery_prolog,
+       .attn_clr_enable = &qed_int_attn_clr_enable,
        .update_drv_state = &qed_update_drv_state,
        .update_mac = &qed_update_mac,
        .update_mtu = &qed_update_mtu,
index e67d5da237927984b6a37311c4f6da6e1f82d335..ee7662da641379d9ebdc5578ff1f2a14d068b02b 100644 (file)
@@ -2516,6 +2516,8 @@ err:
 
 static void qede_atomic_hw_err_handler(struct qede_dev *edev)
 {
+       struct qed_dev *cdev = edev->cdev;
+
        DP_NOTICE(edev,
                  "Generic non-sleepable HW error handling started - err_flags 0x%lx\n",
                  edev->err_flags);
@@ -2523,6 +2525,10 @@ static void qede_atomic_hw_err_handler(struct qede_dev *edev)
        /* Get a call trace of the flow that led to the error */
        WARN_ON(test_bit(QEDE_ERR_WARN, &edev->err_flags));
 
+       /* Prevent HW attentions from being reasserted */
+       if (test_bit(QEDE_ERR_ATTN_CLR_EN, &edev->err_flags))
+               edev->ops->common->attn_clr_enable(cdev, true);
+
        DP_NOTICE(edev, "Generic non-sleepable HW error handling is done\n");
 }
 
index 1b7d9548ee433cfce7c2051e26aa632ece7141e9..978e91e9ab65273061acafdfcba541b4da35110a 100644 (file)
@@ -1046,6 +1046,15 @@ struct qed_common_ops {
  */
        int (*set_led)(struct qed_dev *cdev,
                       enum qed_led_mode mode);
+
+/**
+ * @brief attn_clr_enable - Prevent attentions from being reasserted
+ *
+ * @param cdev
+ * @param clr_enable
+ */
+       void (*attn_clr_enable)(struct qed_dev *cdev, bool clr_enable);
+
 /**
  * @brief db_recovery_add - add doorbell information to the doorbell
  * recovery mechanism.