qed: Provide auxiliary for getting free VF SB
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>
This commit is contained in:
committed by
David S. Miller
parent
1ac72433c5
commit
09b6b14749
@@ -1412,6 +1412,26 @@ void qed_int_sb_setup(struct qed_hwfn *p_hwfn,
|
|||||||
sb_info->igu_sb_id, 0, 0);
|
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)
|
static u16 qed_get_pf_igu_sb_id(struct qed_hwfn *p_hwfn, u16 vector_id)
|
||||||
{
|
{
|
||||||
struct qed_igu_block *p_block;
|
struct qed_igu_block *p_block;
|
||||||
|
|||||||
@@ -225,6 +225,17 @@ struct qed_igu_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* TODO Names of function may change... */
|
/* 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,
|
void qed_int_igu_init_pure_rt(struct qed_hwfn *p_hwfn,
|
||||||
struct qed_ptt *p_ptt,
|
struct qed_ptt *p_ptt,
|
||||||
bool b_set,
|
bool b_set,
|
||||||
|
|||||||
@@ -868,12 +868,11 @@ static u8 qed_iov_alloc_vf_igu_sbs(struct qed_hwfn *p_hwfn,
|
|||||||
struct qed_ptt *p_ptt,
|
struct qed_ptt *p_ptt,
|
||||||
struct qed_vf_info *vf, u16 num_rx_queues)
|
struct qed_vf_info *vf, u16 num_rx_queues)
|
||||||
{
|
{
|
||||||
struct qed_igu_block *igu_blocks;
|
struct qed_igu_block *p_block;
|
||||||
int qid = 0, igu_id = 0;
|
struct cau_sb_entry sb_entry;
|
||||||
|
int qid = 0;
|
||||||
u32 val = 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)
|
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;
|
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;
|
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_VALID, 1);
|
||||||
SET_FIELD(val, IGU_MAPPING_LINE_PF_VALID, 0);
|
SET_FIELD(val, IGU_MAPPING_LINE_PF_VALID, 0);
|
||||||
|
|
||||||
while ((qid < num_rx_queues) &&
|
for (qid = 0; qid < num_rx_queues; qid++) {
|
||||||
(igu_id < QED_MAPPING_MEMORY_SIZE(p_hwfn->cdev))) {
|
p_block = qed_get_igu_free_sb(p_hwfn, false);
|
||||||
if (igu_blocks[igu_id].status & QED_IGU_STATUS_FREE) {
|
vf->igu_sbs[qid] = p_block->igu_sb_id;
|
||||||
struct cau_sb_entry sb_entry;
|
p_block->status &= ~QED_IGU_STATUS_FREE;
|
||||||
|
|
||||||
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);
|
SET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER, qid);
|
||||||
|
|
||||||
qed_wr(p_hwfn, p_ptt,
|
qed_wr(p_hwfn, p_ptt,
|
||||||
IGU_REG_MAPPING_MEMORY + sizeof(u32) * igu_id,
|
IGU_REG_MAPPING_MEMORY +
|
||||||
val);
|
sizeof(u32) * p_block->igu_sb_id, val);
|
||||||
|
|
||||||
/* Configure igu sb in CAU which were marked valid */
|
/* Configure igu sb in CAU which were marked valid */
|
||||||
qed_init_cau_sb_entry(p_hwfn, &sb_entry,
|
qed_init_cau_sb_entry(p_hwfn, &sb_entry,
|
||||||
p_hwfn->rel_pf_id,
|
p_hwfn->rel_pf_id, vf->abs_vf_id, 1);
|
||||||
vf->abs_vf_id, 1);
|
|
||||||
qed_dmae_host2grc(p_hwfn, p_ptt,
|
qed_dmae_host2grc(p_hwfn, p_ptt,
|
||||||
(u64)(uintptr_t)&sb_entry,
|
(u64)(uintptr_t)&sb_entry,
|
||||||
CAU_REG_SB_VAR_MEMORY +
|
CAU_REG_SB_VAR_MEMORY +
|
||||||
igu_id * sizeof(u64), 2, 0);
|
p_block->igu_sb_id * sizeof(u64), 2, 0);
|
||||||
qid++;
|
|
||||||
}
|
|
||||||
igu_id++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vf->num_sbs = (u8) num_rx_queues;
|
vf->num_sbs = (u8) num_rx_queues;
|
||||||
|
|||||||
Reference in New Issue
Block a user