qed: Disable RoCE dpm when DCBx change occurs
authorMintz, Yuval <Yuval.Mintz@cavium.com>
Tue, 20 Jun 2017 13:00:02 +0000 (16:00 +0300)
committerDavid S. Miller <davem@davemloft.net>
Tue, 20 Jun 2017 16:34:07 +0000 (12:34 -0400)
If DCBx update occurs while QPs are open, stop sending edpms until all
QPs are closed.

Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qed/qed_dcbx.c
drivers/net/ethernet/qlogic/qed/qed_roce.c
drivers/net/ethernet/qlogic/qed/qed_roce.h

index 15b516a845821fec9413998c47f1176186925868..f888045e1ae9394b1bf92f0e14c2b46b8fa65dc1 100644 (file)
@@ -44,6 +44,7 @@
 #include "qed_hsi.h"
 #include "qed_sp.h"
 #include "qed_sriov.h"
+#include "qed_roce.h"
 #ifdef CONFIG_DCB
 #include <linux/qed/qed_eth_if.h>
 #endif
@@ -892,6 +893,13 @@ qed_dcbx_mib_update_event(struct qed_hwfn *p_hwfn,
 
                        /* update storm FW with negotiation results */
                        qed_sp_pf_update(p_hwfn);
+
+                       /* for roce PFs, we may want to enable/disable DPM
+                        * when DCBx change occurs
+                        */
+                       if (p_hwfn->hw_info.personality ==
+                           QED_PCI_ETH_ROCE)
+                               qed_roce_dpm_dcbx(p_hwfn, p_ptt);
                }
        }
 
index 4bc2f6c47f69b7826c92628378bb8e3bfa82221e..8419dcc111d830e8bbc7a8eb6aae5c2464aff15f 100644 (file)
@@ -162,6 +162,11 @@ static int qed_bmap_test_id(struct qed_hwfn *p_hwfn,
        return test_bit(id_num, bmap->bitmap);
 }
 
+static bool qed_bmap_is_empty(struct qed_bmap *bmap)
+{
+       return bmap->max_count == find_first_bit(bmap->bitmap, bmap->max_count);
+}
+
 static u32 qed_rdma_get_sb_id(void *p_hwfn, u32 rel_sb_id)
 {
        /* First sb id for RoCE is after all the l2 sb */
@@ -2638,6 +2643,23 @@ static void *qed_rdma_get_rdma_ctx(struct qed_dev *cdev)
        return QED_LEADING_HWFN(cdev);
 }
 
+static bool qed_rdma_allocated_qps(struct qed_hwfn *p_hwfn)
+{
+       bool result;
+
+       /* if rdma info has not been allocated, naturally there are no qps */
+       if (!p_hwfn->p_rdma_info)
+               return false;
+
+       spin_lock_bh(&p_hwfn->p_rdma_info->lock);
+       if (!p_hwfn->p_rdma_info->cid_map.bitmap)
+               result = false;
+       else
+               result = !qed_bmap_is_empty(&p_hwfn->p_rdma_info->cid_map);
+       spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
+       return result;
+}
+
 static void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
        u32 val;
@@ -2650,6 +2672,20 @@ static void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
                   val, p_hwfn->dcbx_no_edpm, p_hwfn->db_bar_no_edpm);
 }
 
+void qed_roce_dpm_dcbx(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
+{
+       u8 val;
+
+       /* if any QPs are already active, we want to disable DPM, since their
+        * context information contains information from before the latest DCBx
+        * update. Otherwise enable it.
+        */
+       val = qed_rdma_allocated_qps(p_hwfn) ? true : false;
+       p_hwfn->dcbx_no_edpm = (u8)val;
+
+       qed_rdma_dpm_conf(p_hwfn, p_ptt);
+}
+
 void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
        p_hwfn->db_bar_no_edpm = true;
index 94be3b5a39c481c821e86ce8210ac3a9fa23099c..ddd77618e6fa522274cadcfd918659a3f103ed55 100644 (file)
@@ -168,10 +168,15 @@ struct qed_rdma_qp {
 
 #if IS_ENABLED(CONFIG_QED_RDMA)
 void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
+void qed_roce_dpm_dcbx(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
 void qed_roce_async_event(struct qed_hwfn *p_hwfn,
                          u8 fw_event_code, union rdma_eqe_data *rdma_data);
 #else
 static inline void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) {}
+
+static inline void qed_roce_dpm_dcbx(struct qed_hwfn *p_hwfn,
+                                    struct qed_ptt *p_ptt) {}
+
 static inline void qed_roce_async_event(struct qed_hwfn *p_hwfn,
                                        u8 fw_event_code,
                                        union rdma_eqe_data *rdma_data) {}