Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09b6b147 authored by Mintz, Yuval's avatar Mintz, Yuval Committed by David S. Miller
Browse files

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: default avatarYuval Mintz <Yuval.Mintz@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1ac72433
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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;
+11 −0
Original line number Diff line number Diff line
@@ -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,
+20 −29
Original line number Diff line number Diff line
@@ -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;

	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) * igu_id,
			       val);
		       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);
				      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++;
				  p_block->igu_sb_id * sizeof(u64), 2, 0);
	}

	vf->num_sbs = (u8) num_rx_queues;