qed: Provide auxiliary for getting free VF SB
authorMintz, Yuval <Yuval.Mintz@cavium.com>
Thu, 1 Jun 2017 12:29:08 +0000 (15:29 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 1 Jun 2017 16:17:19 +0000 (12:17 -0400)
IOV code is very intrusive in its manipulation of the status block
database.
Add a new auxiliary function to allow the PF to find an available unused
status block to configure for a specific VF's MSI-x vector.

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

index a49484a8726c25dcca3dc02a592baffa9150ebc8..96eee1ede8ab648fc7d4d202040e7b22ef0b0a42 100644 (file)
@@ -1412,6 +1412,26 @@ void qed_int_sb_setup(struct qed_hwfn *p_hwfn,
                                    sb_info->igu_sb_id, 0, 0);
 }
 
+struct qed_igu_block *qed_get_igu_free_sb(struct qed_hwfn *p_hwfn, bool b_is_pf)
+{
+       struct qed_igu_block *p_block;
+       u16 igu_id;
+
+       for (igu_id = 0; igu_id < QED_MAPPING_MEMORY_SIZE(p_hwfn->cdev);
+            igu_id++) {
+               p_block = &p_hwfn->hw_info.p_igu_info->entry[igu_id];
+
+               if (!(p_block->status & QED_IGU_STATUS_VALID) ||
+                   !(p_block->status & QED_IGU_STATUS_FREE))
+                       continue;
+
+               if (!!(p_block->status & QED_IGU_STATUS_PF) == b_is_pf)
+                       return p_block;
+       }
+
+       return NULL;
+}
+
 static u16 qed_get_pf_igu_sb_id(struct qed_hwfn *p_hwfn, u16 vector_id)
 {
        struct qed_igu_block *p_block;
index b55334ff76a24391649af408c4b8a08642db8999..273e73a1f850c1bea312bad9817563fbfc100076 100644 (file)
@@ -225,6 +225,17 @@ struct qed_igu_info {
 };
 
 /* TODO Names of function may change... */
+/**
+ * @brief return a pointer to an unused valid SB
+ *
+ * @param p_hwfn
+ * @param b_is_pf - true iff we want a SB belonging to a PF
+ *
+ * @return point to an igu_block, NULL if none is available
+ */
+struct qed_igu_block *qed_get_igu_free_sb(struct qed_hwfn *p_hwfn,
+                                         bool b_is_pf);
+
 void qed_int_igu_init_pure_rt(struct qed_hwfn *p_hwfn,
                              struct qed_ptt *p_ptt,
                              bool b_set,
index 62b207a80a03306b25189f2b050650ae6ab4b902..cb9123b8c8fc98ca05a454af9a637bdc949df105 100644 (file)
@@ -868,12 +868,11 @@ static u8 qed_iov_alloc_vf_igu_sbs(struct qed_hwfn *p_hwfn,
                                   struct qed_ptt *p_ptt,
                                   struct qed_vf_info *vf, u16 num_rx_queues)
 {
-       struct qed_igu_block *igu_blocks;
-       int qid = 0, igu_id = 0;
+       struct qed_igu_block *p_block;
+       struct cau_sb_entry sb_entry;
+       int qid = 0;
        u32 val = 0;
 
-       igu_blocks = p_hwfn->hw_info.p_igu_info->entry;
-
        if (num_rx_queues > p_hwfn->hw_info.p_igu_info->usage.free_cnt_iov)
                num_rx_queues = p_hwfn->hw_info.p_igu_info->usage.free_cnt_iov;
        p_hwfn->hw_info.p_igu_info->usage.free_cnt_iov -= num_rx_queues;
@@ -882,31 +881,23 @@ static u8 qed_iov_alloc_vf_igu_sbs(struct qed_hwfn *p_hwfn,
        SET_FIELD(val, IGU_MAPPING_LINE_VALID, 1);
        SET_FIELD(val, IGU_MAPPING_LINE_PF_VALID, 0);
 
-       while ((qid < num_rx_queues) &&
-              (igu_id < QED_MAPPING_MEMORY_SIZE(p_hwfn->cdev))) {
-               if (igu_blocks[igu_id].status & QED_IGU_STATUS_FREE) {
-                       struct cau_sb_entry sb_entry;
-
-                       vf->igu_sbs[qid] = (u16)igu_id;
-                       igu_blocks[igu_id].status &= ~QED_IGU_STATUS_FREE;
-
-                       SET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER, qid);
-
-                       qed_wr(p_hwfn, p_ptt,
-                              IGU_REG_MAPPING_MEMORY + sizeof(u32) * igu_id,
-                              val);
-
-                       /* Configure igu sb in CAU which were marked valid */
-                       qed_init_cau_sb_entry(p_hwfn, &sb_entry,
-                                             p_hwfn->rel_pf_id,
-                                             vf->abs_vf_id, 1);
-                       qed_dmae_host2grc(p_hwfn, p_ptt,
-                                         (u64)(uintptr_t)&sb_entry,
-                                         CAU_REG_SB_VAR_MEMORY +
-                                         igu_id * sizeof(u64), 2, 0);
-                       qid++;
-               }
-               igu_id++;
+       for (qid = 0; qid < num_rx_queues; qid++) {
+               p_block = qed_get_igu_free_sb(p_hwfn, false);
+               vf->igu_sbs[qid] = p_block->igu_sb_id;
+               p_block->status &= ~QED_IGU_STATUS_FREE;
+               SET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER, qid);
+
+               qed_wr(p_hwfn, p_ptt,
+                      IGU_REG_MAPPING_MEMORY +
+                      sizeof(u32) * p_block->igu_sb_id, val);
+
+               /* Configure igu sb in CAU which were marked valid */
+               qed_init_cau_sb_entry(p_hwfn, &sb_entry,
+                                     p_hwfn->rel_pf_id, vf->abs_vf_id, 1);
+               qed_dmae_host2grc(p_hwfn, p_ptt,
+                                 (u64)(uintptr_t)&sb_entry,
+                                 CAU_REG_SB_VAR_MEMORY +
+                                 p_block->igu_sb_id * sizeof(u64), 2, 0);
        }
 
        vf->num_sbs = (u8) num_rx_queues;