net/qede/base: interchangeably use SB between PF and VF
Status Block reallocation - allow a PF and its child VF to change SB between them using new base driver APIs. The changes that are inside base driver flows are: New APIs ecore_int_igu_reset_cam() and ecore_int_igu_reset_cam_default() added to reset IGU CAM. a. During hw_prepare(), driver would re-initialize the IGU CAM. b. During hw_stop(), driver would initialize the IGU CAM to default. Use igu_sb_id instead of sb_idx [protocol index] to allow setting of the timer-resolution in CAU[coalescing algorithm unit] for all SBs, sb_idx could limit SBs 0-11 only to be able change their timer-resolution. Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
This commit is contained in:
parent
a90c566f43
commit
6e4fcea92f
@ -279,7 +279,6 @@ struct ecore_qm_iids {
|
||||
* is received from MFW.
|
||||
*/
|
||||
enum ecore_resources {
|
||||
ECORE_SB,
|
||||
ECORE_L2_QUEUE,
|
||||
ECORE_VPORT,
|
||||
ECORE_RSS_ENG,
|
||||
@ -293,7 +292,13 @@ enum ecore_resources {
|
||||
ECORE_CMDQS_CQS,
|
||||
ECORE_RDMA_STATS_QUEUE,
|
||||
ECORE_BDQ,
|
||||
ECORE_MAX_RESC, /* must be last */
|
||||
|
||||
/* This is needed only internally for matching against the IGU.
|
||||
* In case of legacy MFW, would be set to `0'.
|
||||
*/
|
||||
ECORE_SB,
|
||||
|
||||
ECORE_MAX_RESC,
|
||||
};
|
||||
|
||||
/* Features that require resources, given as input to the resource management
|
||||
@ -556,10 +561,6 @@ struct ecore_hwfn {
|
||||
bool b_rdma_enabled_in_prs;
|
||||
u32 rdma_prs_search_reg;
|
||||
|
||||
/* Array of sb_info of all status blocks */
|
||||
struct ecore_sb_info *sbs_info[MAX_SB_PER_PF_MIMD];
|
||||
u16 num_sbs;
|
||||
|
||||
struct ecore_cxt_mngr *p_cxt_mngr;
|
||||
|
||||
/* Flag indicating whether interrupts are enabled or not*/
|
||||
|
@ -1232,7 +1232,7 @@ static enum _ecore_status_t ecore_hw_init_chip(struct ecore_hwfn *p_hwfn,
|
||||
static void ecore_init_cau_rt_data(struct ecore_dev *p_dev)
|
||||
{
|
||||
u32 offset = CAU_REG_SB_VAR_MEMORY_RT_OFFSET;
|
||||
int i, sb_id;
|
||||
int i, igu_sb_id;
|
||||
|
||||
for_each_hwfn(p_dev, i) {
|
||||
struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
|
||||
@ -1242,16 +1242,18 @@ static void ecore_init_cau_rt_data(struct ecore_dev *p_dev)
|
||||
|
||||
p_igu_info = p_hwfn->hw_info.p_igu_info;
|
||||
|
||||
for (sb_id = 0; sb_id < ECORE_MAPPING_MEMORY_SIZE(p_dev);
|
||||
sb_id++) {
|
||||
p_block = &p_igu_info->igu_map.igu_blocks[sb_id];
|
||||
for (igu_sb_id = 0;
|
||||
igu_sb_id < ECORE_MAPPING_MEMORY_SIZE(p_dev);
|
||||
igu_sb_id++) {
|
||||
p_block = &p_igu_info->entry[igu_sb_id];
|
||||
|
||||
if (!p_block->is_pf)
|
||||
continue;
|
||||
|
||||
ecore_init_cau_sb_entry(p_hwfn, &sb_entry,
|
||||
p_block->function_id, 0, 0);
|
||||
STORE_RT_REG_AGG(p_hwfn, offset + sb_id * 2, sb_entry);
|
||||
STORE_RT_REG_AGG(p_hwfn, offset + igu_sb_id * 2,
|
||||
sb_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2255,6 +2257,13 @@ enum _ecore_status_t ecore_hw_stop(struct ecore_dev *p_dev)
|
||||
ecore_wr(p_hwfn, p_ptt, IGU_REG_LEADING_EDGE_LATCH, 0);
|
||||
ecore_wr(p_hwfn, p_ptt, IGU_REG_TRAILING_EDGE_LATCH, 0);
|
||||
ecore_int_igu_init_pure_rt(p_hwfn, p_ptt, false, true);
|
||||
rc = ecore_int_igu_reset_cam_default(p_hwfn, p_ptt);
|
||||
if (rc != ECORE_SUCCESS) {
|
||||
DP_NOTICE(p_hwfn, true,
|
||||
"Failed to return IGU CAM to default\n");
|
||||
rc2 = ECORE_UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
/* Need to wait 1ms to guarantee SBs are cleared */
|
||||
OSAL_MSLEEP(1);
|
||||
|
||||
@ -2423,31 +2432,32 @@ static void get_function_id(struct ecore_hwfn *p_hwfn)
|
||||
static void ecore_hw_set_feat(struct ecore_hwfn *p_hwfn)
|
||||
{
|
||||
u32 *feat_num = p_hwfn->hw_info.feat_num;
|
||||
struct ecore_sb_cnt_info sb_cnt;
|
||||
u32 non_l2_sbs = 0;
|
||||
|
||||
OSAL_MEM_ZERO(&sb_cnt, sizeof(sb_cnt));
|
||||
ecore_int_get_num_sbs(p_hwfn, &sb_cnt);
|
||||
|
||||
/* L2 Queues require each: 1 status block. 1 L2 queue */
|
||||
if (ECORE_IS_L2_PERSONALITY(p_hwfn)) {
|
||||
struct ecore_sb_cnt_info sb_cnt_info;
|
||||
|
||||
OSAL_MEM_ZERO(&sb_cnt_info, sizeof(sb_cnt_info));
|
||||
ecore_int_get_num_sbs(p_hwfn, &sb_cnt_info);
|
||||
|
||||
/* Start by allocating VF queues, then PF's */
|
||||
feat_num[ECORE_VF_L2_QUE] =
|
||||
OSAL_MIN_T(u32,
|
||||
RESC_NUM(p_hwfn, ECORE_L2_QUEUE),
|
||||
sb_cnt_info.sb_iov_cnt);
|
||||
sb_cnt.iov_cnt);
|
||||
feat_num[ECORE_PF_L2_QUE] =
|
||||
OSAL_MIN_T(u32,
|
||||
RESC_NUM(p_hwfn, ECORE_SB) - non_l2_sbs,
|
||||
sb_cnt.cnt - non_l2_sbs,
|
||||
RESC_NUM(p_hwfn, ECORE_L2_QUEUE) -
|
||||
FEAT_NUM(p_hwfn, ECORE_VF_L2_QUE));
|
||||
}
|
||||
|
||||
feat_num[ECORE_FCOE_CQ] = OSAL_MIN_T(u32, RESC_NUM(p_hwfn, ECORE_SB),
|
||||
RESC_NUM(p_hwfn, ECORE_CMDQS_CQS));
|
||||
feat_num[ECORE_ISCSI_CQ] = OSAL_MIN_T(u32, RESC_NUM(p_hwfn, ECORE_SB),
|
||||
RESC_NUM(p_hwfn, ECORE_CMDQS_CQS));
|
||||
feat_num[ECORE_FCOE_CQ] = OSAL_MIN_T(u32, sb_cnt.cnt,
|
||||
RESC_NUM(p_hwfn,
|
||||
ECORE_CMDQS_CQS));
|
||||
feat_num[ECORE_ISCSI_CQ] = OSAL_MIN_T(u32, sb_cnt.cnt,
|
||||
RESC_NUM(p_hwfn,
|
||||
ECORE_CMDQS_CQS));
|
||||
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_PROBE,
|
||||
"#PF_L2_QUEUE=%d VF_L2_QUEUES=%d #ROCE_CNQ=%d #FCOE_CQ=%d #ISCSI_CQ=%d #SB=%d\n",
|
||||
@ -2456,14 +2466,12 @@ static void ecore_hw_set_feat(struct ecore_hwfn *p_hwfn)
|
||||
(int)FEAT_NUM(p_hwfn, ECORE_RDMA_CNQ),
|
||||
(int)FEAT_NUM(p_hwfn, ECORE_FCOE_CQ),
|
||||
(int)FEAT_NUM(p_hwfn, ECORE_ISCSI_CQ),
|
||||
RESC_NUM(p_hwfn, ECORE_SB));
|
||||
(int)sb_cnt.cnt);
|
||||
}
|
||||
|
||||
const char *ecore_hw_get_resc_name(enum ecore_resources res_id)
|
||||
{
|
||||
switch (res_id) {
|
||||
case ECORE_SB:
|
||||
return "SB";
|
||||
case ECORE_L2_QUEUE:
|
||||
return "L2_QUEUE";
|
||||
case ECORE_VPORT:
|
||||
@ -2490,6 +2498,8 @@ const char *ecore_hw_get_resc_name(enum ecore_resources res_id)
|
||||
return "RDMA_STATS_QUEUE";
|
||||
case ECORE_BDQ:
|
||||
return "BDQ";
|
||||
case ECORE_SB:
|
||||
return "SB";
|
||||
default:
|
||||
return "UNKNOWN_RESOURCE";
|
||||
}
|
||||
@ -2565,14 +2575,8 @@ enum _ecore_status_t ecore_hw_get_dflt_resc(struct ecore_hwfn *p_hwfn,
|
||||
{
|
||||
u8 num_funcs = p_hwfn->num_funcs_on_engine;
|
||||
bool b_ah = ECORE_IS_AH(p_hwfn->p_dev);
|
||||
struct ecore_sb_cnt_info sb_cnt_info;
|
||||
|
||||
switch (res_id) {
|
||||
case ECORE_SB:
|
||||
OSAL_MEM_ZERO(&sb_cnt_info, sizeof(sb_cnt_info));
|
||||
ecore_int_get_num_sbs(p_hwfn, &sb_cnt_info);
|
||||
*p_resc_num = sb_cnt_info.sb_cnt;
|
||||
break;
|
||||
case ECORE_L2_QUEUE:
|
||||
*p_resc_num = (b_ah ? MAX_NUM_L2_QUEUES_K2 :
|
||||
MAX_NUM_L2_QUEUES_BB) / num_funcs;
|
||||
@ -2629,6 +2633,12 @@ enum _ecore_status_t ecore_hw_get_dflt_resc(struct ecore_hwfn *p_hwfn,
|
||||
if (!*p_resc_num)
|
||||
*p_resc_start = 0;
|
||||
break;
|
||||
case ECORE_SB:
|
||||
/* Since we want its value to reflect whether MFW supports
|
||||
* the new scheme, have a default of 0.
|
||||
*/
|
||||
*p_resc_num = 0;
|
||||
break;
|
||||
default:
|
||||
*p_resc_start = *p_resc_num * p_hwfn->enabled_func_idx;
|
||||
break;
|
||||
@ -2693,14 +2703,9 @@ __ecore_hw_set_resc_info(struct ecore_hwfn *p_hwfn, enum ecore_resources res_id,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* TBD - remove this when revising the handling of the SB resource */
|
||||
if (res_id == ECORE_SB) {
|
||||
/* Excluding the slowpath SB */
|
||||
*p_resc_num -= 1;
|
||||
*p_resc_start -= p_hwfn->enabled_func_idx;
|
||||
}
|
||||
|
||||
if (*p_resc_num != dflt_resc_num || *p_resc_start != dflt_resc_start) {
|
||||
if ((*p_resc_num != dflt_resc_num ||
|
||||
*p_resc_start != dflt_resc_start) &&
|
||||
res_id != ECORE_SB) {
|
||||
DP_INFO(p_hwfn,
|
||||
"MFW allocation for resource %d [%s] differs from default values [%d,%d vs. %d,%d]%s\n",
|
||||
res_id, ecore_hw_get_resc_name(res_id), *p_resc_num,
|
||||
@ -2850,6 +2855,10 @@ static enum _ecore_status_t ecore_hw_get_resc(struct ecore_hwfn *p_hwfn,
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
|
||||
/* This will also learn the number of SBs from MFW */
|
||||
if (ecore_int_igu_reset_cam(p_hwfn, p_hwfn->p_main_ptt))
|
||||
return ECORE_INVAL;
|
||||
|
||||
ecore_hw_set_feat(p_hwfn);
|
||||
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_PROBE,
|
||||
@ -4540,7 +4549,7 @@ enum _ecore_status_t ecore_set_rxq_coalesce(struct ecore_hwfn *p_hwfn,
|
||||
timeset = (u8)(coalesce >> timer_res);
|
||||
|
||||
rc = ecore_int_set_timer_res(p_hwfn, p_ptt, timer_res,
|
||||
p_cid->abs.sb_idx, false);
|
||||
p_cid->sb_igu_id, false);
|
||||
if (rc != ECORE_SUCCESS)
|
||||
goto out;
|
||||
|
||||
@ -4581,7 +4590,7 @@ enum _ecore_status_t ecore_set_txq_coalesce(struct ecore_hwfn *p_hwfn,
|
||||
timeset = (u8)(coalesce >> timer_res);
|
||||
|
||||
rc = ecore_int_set_timer_res(p_hwfn, p_ptt, timer_res,
|
||||
p_cid->abs.sb_idx, true);
|
||||
p_cid->sb_igu_id, true);
|
||||
if (rc != ECORE_SUCCESS)
|
||||
goto out;
|
||||
|
||||
|
@ -1369,6 +1369,49 @@ void ecore_init_cau_sb_entry(struct ecore_hwfn *p_hwfn,
|
||||
SET_FIELD(p_sb_entry->data, CAU_SB_ENTRY_STATE1, cau_state);
|
||||
}
|
||||
|
||||
static void _ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
u16 igu_sb_id, u32 pi_index,
|
||||
enum ecore_coalescing_fsm coalescing_fsm,
|
||||
u8 timeset)
|
||||
{
|
||||
struct cau_pi_entry pi_entry;
|
||||
u32 sb_offset, pi_offset;
|
||||
|
||||
if (IS_VF(p_hwfn->p_dev))
|
||||
return;/* @@@TBD MichalK- VF CAU... */
|
||||
|
||||
sb_offset = igu_sb_id * PIS_PER_SB;
|
||||
OSAL_MEMSET(&pi_entry, 0, sizeof(struct cau_pi_entry));
|
||||
|
||||
SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_PI_TIMESET, timeset);
|
||||
if (coalescing_fsm == ECORE_COAL_RX_STATE_MACHINE)
|
||||
SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 0);
|
||||
else
|
||||
SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 1);
|
||||
|
||||
pi_offset = sb_offset + pi_index;
|
||||
if (p_hwfn->hw_init_done) {
|
||||
ecore_wr(p_hwfn, p_ptt,
|
||||
CAU_REG_PI_MEMORY + pi_offset * sizeof(u32),
|
||||
*((u32 *)&(pi_entry)));
|
||||
} else {
|
||||
STORE_RT_REG(p_hwfn,
|
||||
CAU_REG_PI_MEMORY_RT_OFFSET + pi_offset,
|
||||
*((u32 *)&(pi_entry)));
|
||||
}
|
||||
}
|
||||
|
||||
void ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
struct ecore_sb_info *p_sb, u32 pi_index,
|
||||
enum ecore_coalescing_fsm coalescing_fsm,
|
||||
u8 timeset)
|
||||
{
|
||||
_ecore_int_cau_conf_pi(p_hwfn, p_ptt, p_sb->igu_sb_id,
|
||||
pi_index, coalescing_fsm, timeset);
|
||||
}
|
||||
|
||||
void ecore_int_cau_conf_sb(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
dma_addr_t sb_phys, u16 igu_sb_id,
|
||||
@ -1420,8 +1463,9 @@ void ecore_int_cau_conf_sb(struct ecore_hwfn *p_hwfn,
|
||||
else
|
||||
timer_res = 2;
|
||||
timeset = (u8)(p_hwfn->p_dev->rx_coalesce_usecs >> timer_res);
|
||||
ecore_int_cau_conf_pi(p_hwfn, p_ptt, igu_sb_id, RX_PI,
|
||||
ECORE_COAL_RX_STATE_MACHINE, timeset);
|
||||
_ecore_int_cau_conf_pi(p_hwfn, p_ptt, igu_sb_id, RX_PI,
|
||||
ECORE_COAL_RX_STATE_MACHINE,
|
||||
timeset);
|
||||
|
||||
if (p_hwfn->p_dev->tx_coalesce_usecs <= 0x7F)
|
||||
timer_res = 0;
|
||||
@ -1431,46 +1475,14 @@ void ecore_int_cau_conf_sb(struct ecore_hwfn *p_hwfn,
|
||||
timer_res = 2;
|
||||
timeset = (u8)(p_hwfn->p_dev->tx_coalesce_usecs >> timer_res);
|
||||
for (i = 0; i < num_tc; i++) {
|
||||
ecore_int_cau_conf_pi(p_hwfn, p_ptt,
|
||||
igu_sb_id, TX_PI(i),
|
||||
ECORE_COAL_TX_STATE_MACHINE,
|
||||
timeset);
|
||||
_ecore_int_cau_conf_pi(p_hwfn, p_ptt,
|
||||
igu_sb_id, TX_PI(i),
|
||||
ECORE_COAL_TX_STATE_MACHINE,
|
||||
timeset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
u16 igu_sb_id, u32 pi_index,
|
||||
enum ecore_coalescing_fsm coalescing_fsm, u8 timeset)
|
||||
{
|
||||
struct cau_pi_entry pi_entry;
|
||||
u32 sb_offset, pi_offset;
|
||||
|
||||
if (IS_VF(p_hwfn->p_dev))
|
||||
return; /* @@@TBD MichalK- VF CAU... */
|
||||
|
||||
sb_offset = igu_sb_id * PIS_PER_SB;
|
||||
OSAL_MEMSET(&pi_entry, 0, sizeof(struct cau_pi_entry));
|
||||
|
||||
SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_PI_TIMESET, timeset);
|
||||
if (coalescing_fsm == ECORE_COAL_RX_STATE_MACHINE)
|
||||
SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 0);
|
||||
else
|
||||
SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 1);
|
||||
|
||||
pi_offset = sb_offset + pi_index;
|
||||
if (p_hwfn->hw_init_done) {
|
||||
ecore_wr(p_hwfn, p_ptt,
|
||||
CAU_REG_PI_MEMORY + pi_offset * sizeof(u32),
|
||||
*((u32 *)&(pi_entry)));
|
||||
} else {
|
||||
STORE_RT_REG(p_hwfn,
|
||||
CAU_REG_PI_MEMORY_RT_OFFSET + pi_offset,
|
||||
*((u32 *)&(pi_entry)));
|
||||
}
|
||||
}
|
||||
|
||||
void ecore_int_sb_setup(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt, struct ecore_sb_info *sb_info)
|
||||
{
|
||||
@ -1483,16 +1495,50 @@ void ecore_int_sb_setup(struct ecore_hwfn *p_hwfn,
|
||||
sb_info->igu_sb_id, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ecore_get_igu_sb_id - given a sw sb_id return the
|
||||
* igu_sb_id
|
||||
*
|
||||
* @param p_hwfn
|
||||
* @param sb_id
|
||||
*
|
||||
* @return u16
|
||||
*/
|
||||
static u16 ecore_get_igu_sb_id(struct ecore_hwfn *p_hwfn, u16 sb_id)
|
||||
struct ecore_igu_block *
|
||||
ecore_get_igu_free_sb(struct ecore_hwfn *p_hwfn, bool b_is_pf)
|
||||
{
|
||||
struct ecore_igu_block *p_block;
|
||||
u16 igu_id;
|
||||
|
||||
for (igu_id = 0; igu_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
|
||||
igu_id++) {
|
||||
p_block = &p_hwfn->hw_info.p_igu_info->entry[igu_id];
|
||||
|
||||
if (!(p_block->status & ECORE_IGU_STATUS_VALID) ||
|
||||
!(p_block->status & ECORE_IGU_STATUS_FREE))
|
||||
continue;
|
||||
|
||||
if (!!(p_block->status & ECORE_IGU_STATUS_PF) ==
|
||||
b_is_pf)
|
||||
return p_block;
|
||||
}
|
||||
|
||||
return OSAL_NULL;
|
||||
}
|
||||
|
||||
static u16 ecore_get_pf_igu_sb_id(struct ecore_hwfn *p_hwfn,
|
||||
u16 vector_id)
|
||||
{
|
||||
struct ecore_igu_block *p_block;
|
||||
u16 igu_id;
|
||||
|
||||
for (igu_id = 0; igu_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
|
||||
igu_id++) {
|
||||
p_block = &p_hwfn->hw_info.p_igu_info->entry[igu_id];
|
||||
|
||||
if (!(p_block->status & ECORE_IGU_STATUS_VALID) ||
|
||||
!p_block->is_pf ||
|
||||
p_block->vector_number != vector_id)
|
||||
continue;
|
||||
|
||||
return igu_id;
|
||||
}
|
||||
|
||||
return ECORE_SB_INVALID_IDX;
|
||||
}
|
||||
|
||||
u16 ecore_get_igu_sb_id(struct ecore_hwfn *p_hwfn, u16 sb_id)
|
||||
{
|
||||
u16 igu_sb_id;
|
||||
|
||||
@ -1500,11 +1546,15 @@ static u16 ecore_get_igu_sb_id(struct ecore_hwfn *p_hwfn, u16 sb_id)
|
||||
if (sb_id == ECORE_SP_SB_ID)
|
||||
igu_sb_id = p_hwfn->hw_info.p_igu_info->igu_dsb_id;
|
||||
else if (IS_PF(p_hwfn->p_dev))
|
||||
igu_sb_id = sb_id + p_hwfn->hw_info.p_igu_info->igu_base_sb;
|
||||
igu_sb_id = ecore_get_pf_igu_sb_id(p_hwfn, sb_id + 1);
|
||||
else
|
||||
igu_sb_id = ecore_vf_get_igu_sb_id(p_hwfn, sb_id);
|
||||
|
||||
if (sb_id == ECORE_SP_SB_ID)
|
||||
if (igu_sb_id == ECORE_SB_INVALID_IDX)
|
||||
DP_NOTICE(p_hwfn, true,
|
||||
"Slowpath SB vector %04x doesn't exist\n",
|
||||
sb_id);
|
||||
else if (sb_id == ECORE_SP_SB_ID)
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"Slowpath SB index in IGU is 0x%04x\n", igu_sb_id);
|
||||
else
|
||||
@ -1525,9 +1575,24 @@ enum _ecore_status_t ecore_int_sb_init(struct ecore_hwfn *p_hwfn,
|
||||
|
||||
sb_info->igu_sb_id = ecore_get_igu_sb_id(p_hwfn, sb_id);
|
||||
|
||||
if (sb_info->igu_sb_id == ECORE_SB_INVALID_IDX)
|
||||
return ECORE_INVAL;
|
||||
|
||||
/* Let the igu info reference the client's SB info */
|
||||
if (sb_id != ECORE_SP_SB_ID) {
|
||||
p_hwfn->sbs_info[sb_id] = sb_info;
|
||||
p_hwfn->num_sbs++;
|
||||
if (IS_PF(p_hwfn->p_dev)) {
|
||||
struct ecore_igu_info *p_info;
|
||||
struct ecore_igu_block *p_block;
|
||||
|
||||
p_info = p_hwfn->hw_info.p_igu_info;
|
||||
p_block = &p_info->entry[sb_info->igu_sb_id];
|
||||
|
||||
p_block->sb_info = sb_info;
|
||||
p_block->status &= ~ECORE_IGU_STATUS_FREE;
|
||||
p_info->usage.free_cnt--;
|
||||
} else {
|
||||
ecore_vf_set_sb_info(p_hwfn, sb_id, sb_info);
|
||||
}
|
||||
}
|
||||
#ifdef ECORE_CONFIG_DIRECT_HWFN
|
||||
sb_info->p_hwfn = p_hwfn;
|
||||
@ -1559,20 +1624,35 @@ enum _ecore_status_t ecore_int_sb_release(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_sb_info *sb_info,
|
||||
u16 sb_id)
|
||||
{
|
||||
if (sb_id == ECORE_SP_SB_ID) {
|
||||
DP_ERR(p_hwfn, "Do Not free sp sb using this function");
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
struct ecore_igu_info *p_info;
|
||||
struct ecore_igu_block *p_block;
|
||||
|
||||
if (sb_info == OSAL_NULL)
|
||||
return ECORE_SUCCESS;
|
||||
|
||||
/* zero status block and ack counter */
|
||||
sb_info->sb_ack = 0;
|
||||
OSAL_MEMSET(sb_info->sb_virt, 0, sizeof(*sb_info->sb_virt));
|
||||
|
||||
if (p_hwfn->sbs_info[sb_id] != OSAL_NULL) {
|
||||
p_hwfn->sbs_info[sb_id] = OSAL_NULL;
|
||||
p_hwfn->num_sbs--;
|
||||
if (IS_VF(p_hwfn->p_dev)) {
|
||||
ecore_vf_set_sb_info(p_hwfn, sb_id, OSAL_NULL);
|
||||
return ECORE_SUCCESS;
|
||||
}
|
||||
|
||||
p_info = p_hwfn->hw_info.p_igu_info;
|
||||
p_block = &p_info->entry[sb_info->igu_sb_id];
|
||||
|
||||
/* Vector 0 is reserved to Default SB */
|
||||
if (p_block->vector_number == 0) {
|
||||
DP_ERR(p_hwfn, "Do Not free sp sb using this function");
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
|
||||
/* Lose reference to client's SB info, and fix counters */
|
||||
p_block->sb_info = OSAL_NULL;
|
||||
p_block->status |= ECORE_IGU_STATUS_FREE;
|
||||
p_info->usage.free_cnt++;
|
||||
|
||||
return ECORE_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1778,11 +1858,13 @@ void ecore_int_igu_disable_int(struct ecore_hwfn *p_hwfn,
|
||||
|
||||
#define IGU_CLEANUP_SLEEP_LENGTH (1000)
|
||||
static void ecore_int_igu_cleanup_sb(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
u32 sb_id, bool cleanup_set, u16 opaque_fid)
|
||||
struct ecore_ptt *p_ptt,
|
||||
u32 igu_sb_id,
|
||||
bool cleanup_set,
|
||||
u16 opaque_fid)
|
||||
{
|
||||
u32 cmd_ctrl = 0, val = 0, sb_bit = 0, sb_bit_addr = 0, data = 0;
|
||||
u32 pxp_addr = IGU_CMD_INT_ACK_BASE + sb_id;
|
||||
u32 pxp_addr = IGU_CMD_INT_ACK_BASE + igu_sb_id;
|
||||
u32 sleep_cnt = IGU_CLEANUP_SLEEP_LENGTH;
|
||||
u8 type = 0; /* FIXME MichalS type??? */
|
||||
|
||||
@ -1813,8 +1895,8 @@ static void ecore_int_igu_cleanup_sb(struct ecore_hwfn *p_hwfn,
|
||||
OSAL_MMIOWB(p_hwfn->p_dev);
|
||||
|
||||
/* calculate where to read the status bit from */
|
||||
sb_bit = 1 << (sb_id % 32);
|
||||
sb_bit_addr = sb_id / 32 * sizeof(u32);
|
||||
sb_bit = 1 << (igu_sb_id % 32);
|
||||
sb_bit_addr = igu_sb_id / 32 * sizeof(u32);
|
||||
|
||||
sb_bit_addr += IGU_REG_CLEANUP_STATUS_0 + (0x80 * type);
|
||||
|
||||
@ -1829,21 +1911,28 @@ static void ecore_int_igu_cleanup_sb(struct ecore_hwfn *p_hwfn,
|
||||
if (!sleep_cnt)
|
||||
DP_NOTICE(p_hwfn, true,
|
||||
"Timeout waiting for clear status 0x%08x [for sb %d]\n",
|
||||
val, sb_id);
|
||||
val, igu_sb_id);
|
||||
}
|
||||
|
||||
void ecore_int_igu_init_pure_rt_single(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
u32 sb_id, u16 opaque, bool b_set)
|
||||
u16 igu_sb_id, u16 opaque, bool b_set)
|
||||
{
|
||||
struct ecore_igu_block *p_block;
|
||||
int pi, i;
|
||||
|
||||
p_block = &p_hwfn->hw_info.p_igu_info->entry[igu_sb_id];
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"Cleaning SB [%04x]: func_id= %d is_pf = %d vector_num = 0x%0x\n",
|
||||
igu_sb_id, p_block->function_id, p_block->is_pf,
|
||||
p_block->vector_number);
|
||||
|
||||
/* Set */
|
||||
if (b_set)
|
||||
ecore_int_igu_cleanup_sb(p_hwfn, p_ptt, sb_id, 1, opaque);
|
||||
ecore_int_igu_cleanup_sb(p_hwfn, p_ptt, igu_sb_id, 1, opaque);
|
||||
|
||||
/* Clear */
|
||||
ecore_int_igu_cleanup_sb(p_hwfn, p_ptt, sb_id, 0, opaque);
|
||||
ecore_int_igu_cleanup_sb(p_hwfn, p_ptt, igu_sb_id, 0, opaque);
|
||||
|
||||
/* Wait for the IGU SB to cleanup */
|
||||
for (i = 0; i < IGU_CLEANUP_SLEEP_LENGTH; i++) {
|
||||
@ -1851,8 +1940,8 @@ void ecore_int_igu_init_pure_rt_single(struct ecore_hwfn *p_hwfn,
|
||||
|
||||
val = ecore_rd(p_hwfn, p_ptt,
|
||||
IGU_REG_WRITE_DONE_PENDING +
|
||||
((sb_id / 32) * 4));
|
||||
if (val & (1 << (sb_id % 32)))
|
||||
((igu_sb_id / 32) * 4));
|
||||
if (val & (1 << (igu_sb_id % 32)))
|
||||
OSAL_UDELAY(10);
|
||||
else
|
||||
break;
|
||||
@ -1860,21 +1949,22 @@ void ecore_int_igu_init_pure_rt_single(struct ecore_hwfn *p_hwfn,
|
||||
if (i == IGU_CLEANUP_SLEEP_LENGTH)
|
||||
DP_NOTICE(p_hwfn, true,
|
||||
"Failed SB[0x%08x] still appearing in WRITE_DONE_PENDING\n",
|
||||
sb_id);
|
||||
igu_sb_id);
|
||||
|
||||
/* Clear the CAU for the SB */
|
||||
for (pi = 0; pi < 12; pi++)
|
||||
ecore_wr(p_hwfn, p_ptt,
|
||||
CAU_REG_PI_MEMORY + (sb_id * 12 + pi) * 4, 0);
|
||||
CAU_REG_PI_MEMORY + (igu_sb_id * 12 + pi) * 4, 0);
|
||||
}
|
||||
|
||||
void ecore_int_igu_init_pure_rt(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
bool b_set, bool b_slowpath)
|
||||
{
|
||||
u32 igu_base_sb = p_hwfn->hw_info.p_igu_info->igu_base_sb;
|
||||
u32 igu_sb_cnt = p_hwfn->hw_info.p_igu_info->igu_sb_cnt;
|
||||
u32 sb_id = 0, val = 0;
|
||||
struct ecore_igu_info *p_info = p_hwfn->hw_info.p_igu_info;
|
||||
struct ecore_igu_block *p_block;
|
||||
u16 igu_sb_id = 0;
|
||||
u32 val = 0;
|
||||
|
||||
/* @@@TBD MichalK temporary... should be moved to init-tool... */
|
||||
val = ecore_rd(p_hwfn, p_ptt, IGU_REG_BLOCK_CONFIGURATION);
|
||||
@ -1883,53 +1973,204 @@ void ecore_int_igu_init_pure_rt(struct ecore_hwfn *p_hwfn,
|
||||
ecore_wr(p_hwfn, p_ptt, IGU_REG_BLOCK_CONFIGURATION, val);
|
||||
/* end temporary */
|
||||
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"IGU cleaning SBs [%d,...,%d]\n",
|
||||
igu_base_sb, igu_base_sb + igu_sb_cnt - 1);
|
||||
for (igu_sb_id = 0;
|
||||
igu_sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
|
||||
igu_sb_id++) {
|
||||
p_block = &p_info->entry[igu_sb_id];
|
||||
|
||||
for (sb_id = igu_base_sb; sb_id < igu_base_sb + igu_sb_cnt; sb_id++)
|
||||
ecore_int_igu_init_pure_rt_single(p_hwfn, p_ptt, sb_id,
|
||||
if (!(p_block->status & ECORE_IGU_STATUS_VALID) ||
|
||||
!p_block->is_pf ||
|
||||
(p_block->status & ECORE_IGU_STATUS_DSB))
|
||||
continue;
|
||||
|
||||
ecore_int_igu_init_pure_rt_single(p_hwfn, p_ptt, igu_sb_id,
|
||||
p_hwfn->hw_info.opaque_fid,
|
||||
b_set);
|
||||
}
|
||||
|
||||
if (!b_slowpath)
|
||||
return;
|
||||
|
||||
sb_id = p_hwfn->hw_info.p_igu_info->igu_dsb_id;
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"IGU cleaning slowpath SB [%d]\n", sb_id);
|
||||
ecore_int_igu_init_pure_rt_single(p_hwfn, p_ptt, sb_id,
|
||||
p_hwfn->hw_info.opaque_fid, b_set);
|
||||
if (b_slowpath)
|
||||
ecore_int_igu_init_pure_rt_single(p_hwfn, p_ptt,
|
||||
p_info->igu_dsb_id,
|
||||
p_hwfn->hw_info.opaque_fid,
|
||||
b_set);
|
||||
}
|
||||
|
||||
static u32 ecore_int_igu_read_cam_block(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt, u16 sb_id)
|
||||
int ecore_int_igu_reset_cam(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt)
|
||||
{
|
||||
struct ecore_igu_info *p_info = p_hwfn->hw_info.p_igu_info;
|
||||
struct ecore_igu_block *p_block;
|
||||
int pf_sbs, vf_sbs;
|
||||
u16 igu_sb_id;
|
||||
u32 val, rval;
|
||||
|
||||
if (!RESC_NUM(p_hwfn, ECORE_SB)) {
|
||||
/* We're using an old MFW - have to prevent any switching
|
||||
* of SBs between PF and VFs as later driver wouldn't be
|
||||
* able to tell which belongs to which.
|
||||
*/
|
||||
p_info->b_allow_pf_vf_change = false;
|
||||
} else {
|
||||
/* Use the numbers the MFW have provided -
|
||||
* don't forget MFW accounts for the default SB as well.
|
||||
*/
|
||||
p_info->b_allow_pf_vf_change = true;
|
||||
|
||||
if (p_info->usage.cnt != RESC_NUM(p_hwfn, ECORE_SB) - 1) {
|
||||
DP_INFO(p_hwfn,
|
||||
"MFW notifies of 0x%04x PF SBs; IGU indicates of only 0x%04x\n",
|
||||
RESC_NUM(p_hwfn, ECORE_SB) - 1,
|
||||
p_info->usage.cnt);
|
||||
p_info->usage.cnt = RESC_NUM(p_hwfn, ECORE_SB) - 1;
|
||||
}
|
||||
|
||||
/* TODO - how do we learn about VF SBs from MFW? */
|
||||
if (IS_PF_SRIOV(p_hwfn)) {
|
||||
u16 vfs = p_hwfn->p_dev->p_iov_info->total_vfs;
|
||||
|
||||
if (vfs != p_info->usage.iov_cnt)
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"0x%04x VF SBs in IGU CAM != PCI configuration 0x%04x\n",
|
||||
p_info->usage.iov_cnt, vfs);
|
||||
|
||||
/* At this point we know how many SBs we have totally
|
||||
* in IGU + number of PF SBs. So we can validate that
|
||||
* we'd have sufficient for VF.
|
||||
*/
|
||||
if (vfs > p_info->usage.free_cnt +
|
||||
p_info->usage.free_cnt_iov -
|
||||
p_info->usage.cnt) {
|
||||
DP_NOTICE(p_hwfn, true,
|
||||
"Not enough SBs for VFs - 0x%04x SBs, from which %04x PFs and %04x are required\n",
|
||||
p_info->usage.free_cnt +
|
||||
p_info->usage.free_cnt_iov,
|
||||
p_info->usage.cnt, vfs);
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Cap the number of VFs SBs by the number of VFs */
|
||||
if (IS_PF_SRIOV(p_hwfn))
|
||||
p_info->usage.iov_cnt = p_hwfn->p_dev->p_iov_info->total_vfs;
|
||||
|
||||
/* Mark all SBs as free, now in the right PF/VFs division */
|
||||
p_info->usage.free_cnt = p_info->usage.cnt;
|
||||
p_info->usage.free_cnt_iov = p_info->usage.iov_cnt;
|
||||
p_info->usage.orig = p_info->usage.cnt;
|
||||
p_info->usage.iov_orig = p_info->usage.iov_cnt;
|
||||
|
||||
/* We now proceed to re-configure the IGU cam to reflect the initial
|
||||
* configuration. We can start with the Default SB.
|
||||
*/
|
||||
pf_sbs = p_info->usage.cnt;
|
||||
vf_sbs = p_info->usage.iov_cnt;
|
||||
|
||||
for (igu_sb_id = p_info->igu_dsb_id;
|
||||
igu_sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
|
||||
igu_sb_id++) {
|
||||
p_block = &p_info->entry[igu_sb_id];
|
||||
val = 0;
|
||||
|
||||
if (!(p_block->status & ECORE_IGU_STATUS_VALID))
|
||||
continue;
|
||||
|
||||
if (p_block->status & ECORE_IGU_STATUS_DSB) {
|
||||
p_block->function_id = p_hwfn->rel_pf_id;
|
||||
p_block->is_pf = 1;
|
||||
p_block->vector_number = 0;
|
||||
p_block->status = ECORE_IGU_STATUS_VALID |
|
||||
ECORE_IGU_STATUS_PF |
|
||||
ECORE_IGU_STATUS_DSB;
|
||||
} else if (pf_sbs) {
|
||||
pf_sbs--;
|
||||
p_block->function_id = p_hwfn->rel_pf_id;
|
||||
p_block->is_pf = 1;
|
||||
p_block->vector_number = p_info->usage.cnt - pf_sbs;
|
||||
p_block->status = ECORE_IGU_STATUS_VALID |
|
||||
ECORE_IGU_STATUS_PF |
|
||||
ECORE_IGU_STATUS_FREE;
|
||||
} else if (vf_sbs) {
|
||||
p_block->function_id =
|
||||
p_hwfn->p_dev->p_iov_info->first_vf_in_pf +
|
||||
p_info->usage.iov_cnt - vf_sbs;
|
||||
p_block->is_pf = 0;
|
||||
p_block->vector_number = 0;
|
||||
p_block->status = ECORE_IGU_STATUS_VALID |
|
||||
ECORE_IGU_STATUS_FREE;
|
||||
vf_sbs--;
|
||||
} else {
|
||||
p_block->function_id = 0;
|
||||
p_block->is_pf = 0;
|
||||
p_block->vector_number = 0;
|
||||
}
|
||||
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_FUNCTION_NUMBER,
|
||||
p_block->function_id);
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_PF_VALID, p_block->is_pf);
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER,
|
||||
p_block->vector_number);
|
||||
|
||||
/* VF entries would be enabled when VF is initializaed */
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_VALID, p_block->is_pf);
|
||||
|
||||
rval = ecore_rd(p_hwfn, p_ptt,
|
||||
IGU_REG_MAPPING_MEMORY +
|
||||
sizeof(u32) * igu_sb_id);
|
||||
|
||||
if (rval != val) {
|
||||
ecore_wr(p_hwfn, p_ptt,
|
||||
IGU_REG_MAPPING_MEMORY +
|
||||
sizeof(u32) * igu_sb_id,
|
||||
val);
|
||||
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"IGU reset: [SB 0x%04x] func_id = %d is_pf = %d vector_num = 0x%x [%08x -> %08x]\n",
|
||||
igu_sb_id, p_block->function_id,
|
||||
p_block->is_pf, p_block->vector_number,
|
||||
rval, val);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ecore_int_igu_reset_cam_default(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt)
|
||||
{
|
||||
struct ecore_sb_cnt_info *p_cnt = &p_hwfn->hw_info.p_igu_info->usage;
|
||||
|
||||
/* Return all the usage indications to default prior to the reset;
|
||||
* The reset expects the !orig to reflect the initial status of the
|
||||
* SBs, and would re-calculate the originals based on those.
|
||||
*/
|
||||
p_cnt->cnt = p_cnt->orig;
|
||||
p_cnt->free_cnt = p_cnt->orig;
|
||||
p_cnt->iov_cnt = p_cnt->iov_orig;
|
||||
p_cnt->free_cnt_iov = p_cnt->iov_orig;
|
||||
p_cnt->orig = 0;
|
||||
p_cnt->iov_orig = 0;
|
||||
|
||||
/* TODO - we probably need to re-configure the CAU as well... */
|
||||
return ecore_int_igu_reset_cam(p_hwfn, p_ptt);
|
||||
}
|
||||
|
||||
static void ecore_int_igu_read_cam_block(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
u16 igu_sb_id)
|
||||
{
|
||||
u32 val = ecore_rd(p_hwfn, p_ptt,
|
||||
IGU_REG_MAPPING_MEMORY + sizeof(u32) * sb_id);
|
||||
IGU_REG_MAPPING_MEMORY + sizeof(u32) * igu_sb_id);
|
||||
struct ecore_igu_block *p_block;
|
||||
|
||||
p_block = &p_hwfn->hw_info.p_igu_info->igu_map.igu_blocks[sb_id];
|
||||
|
||||
/* stop scanning when hit first invalid PF entry */
|
||||
if (!GET_FIELD(val, IGU_MAPPING_LINE_VALID) &&
|
||||
GET_FIELD(val, IGU_MAPPING_LINE_PF_VALID))
|
||||
goto out;
|
||||
p_block = &p_hwfn->hw_info.p_igu_info->entry[igu_sb_id];
|
||||
|
||||
/* Fill the block information */
|
||||
p_block->status = ECORE_IGU_STATUS_VALID;
|
||||
p_block->function_id = GET_FIELD(val, IGU_MAPPING_LINE_FUNCTION_NUMBER);
|
||||
p_block->is_pf = GET_FIELD(val, IGU_MAPPING_LINE_PF_VALID);
|
||||
p_block->vector_number = GET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER);
|
||||
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"IGU_BLOCK: [SB 0x%04x, Value in CAM 0x%08x] func_id = %d"
|
||||
" is_pf = %d vector_num = 0x%x\n",
|
||||
sb_id, val, p_block->function_id, p_block->is_pf,
|
||||
p_block->vector_number);
|
||||
|
||||
out:
|
||||
return val;
|
||||
p_block->igu_sb_id = igu_sb_id;
|
||||
}
|
||||
|
||||
enum _ecore_status_t ecore_int_igu_read_cam(struct ecore_hwfn *p_hwfn,
|
||||
@ -1937,140 +2178,217 @@ enum _ecore_status_t ecore_int_igu_read_cam(struct ecore_hwfn *p_hwfn,
|
||||
{
|
||||
struct ecore_igu_info *p_igu_info;
|
||||
struct ecore_igu_block *p_block;
|
||||
u32 min_vf = 0, max_vf = 0, val;
|
||||
u16 sb_id, last_iov_sb_id = 0;
|
||||
u16 prev_sb_id = 0xFF;
|
||||
u32 min_vf = 0, max_vf = 0;
|
||||
u16 igu_sb_id;
|
||||
|
||||
p_hwfn->hw_info.p_igu_info = OSAL_ALLOC(p_hwfn->p_dev,
|
||||
GFP_KERNEL,
|
||||
sizeof(*p_igu_info));
|
||||
p_hwfn->hw_info.p_igu_info = OSAL_ZALLOC(p_hwfn->p_dev,
|
||||
GFP_KERNEL,
|
||||
sizeof(*p_igu_info));
|
||||
if (!p_hwfn->hw_info.p_igu_info)
|
||||
return ECORE_NOMEM;
|
||||
|
||||
OSAL_MEMSET(p_hwfn->hw_info.p_igu_info, 0, sizeof(*p_igu_info));
|
||||
|
||||
p_igu_info = p_hwfn->hw_info.p_igu_info;
|
||||
|
||||
/* Initialize base sb / sb cnt for PFs and VFs */
|
||||
p_igu_info->igu_base_sb = 0xffff;
|
||||
p_igu_info->igu_sb_cnt = 0;
|
||||
p_igu_info->igu_dsb_id = 0xffff;
|
||||
p_igu_info->igu_base_sb_iov = 0xffff;
|
||||
/* Distinguish between existent and onn-existent default SB */
|
||||
p_igu_info->igu_dsb_id = ECORE_SB_INVALID_IDX;
|
||||
|
||||
/* Find the range of VF ids whose SB belong to this PF */
|
||||
if (p_hwfn->p_dev->p_iov_info) {
|
||||
struct ecore_hw_sriov_info *p_iov = p_hwfn->p_dev->p_iov_info;
|
||||
|
||||
min_vf = p_iov->first_vf_in_pf;
|
||||
max_vf = p_iov->first_vf_in_pf + p_iov->total_vfs;
|
||||
}
|
||||
for (sb_id = 0;
|
||||
sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
|
||||
sb_id++) {
|
||||
p_block = &p_igu_info->igu_map.igu_blocks[sb_id];
|
||||
val = ecore_int_igu_read_cam_block(p_hwfn, p_ptt, sb_id);
|
||||
if (!GET_FIELD(val, IGU_MAPPING_LINE_VALID) &&
|
||||
GET_FIELD(val, IGU_MAPPING_LINE_PF_VALID))
|
||||
break;
|
||||
|
||||
if (p_block->is_pf) {
|
||||
if (p_block->function_id == p_hwfn->rel_pf_id) {
|
||||
p_block->status |= ECORE_IGU_STATUS_PF;
|
||||
for (igu_sb_id = 0;
|
||||
igu_sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
|
||||
igu_sb_id++) {
|
||||
/* Read current entry; Notice it might not belong to this PF */
|
||||
ecore_int_igu_read_cam_block(p_hwfn, p_ptt, igu_sb_id);
|
||||
p_block = &p_igu_info->entry[igu_sb_id];
|
||||
|
||||
if (p_block->vector_number == 0) {
|
||||
if (p_igu_info->igu_dsb_id == 0xffff)
|
||||
p_igu_info->igu_dsb_id = sb_id;
|
||||
} else {
|
||||
if (p_igu_info->igu_base_sb == 0xffff) {
|
||||
p_igu_info->igu_base_sb = sb_id;
|
||||
} else if (prev_sb_id != sb_id - 1) {
|
||||
DP_NOTICE(p_hwfn->p_dev, false,
|
||||
"consecutive igu"
|
||||
" vectors for HWFN"
|
||||
" %x broken",
|
||||
p_hwfn->rel_pf_id);
|
||||
break;
|
||||
}
|
||||
prev_sb_id = sb_id;
|
||||
/* we don't count the default */
|
||||
(p_igu_info->igu_sb_cnt)++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((p_block->function_id >= min_vf) &&
|
||||
(p_block->function_id < max_vf)) {
|
||||
/* Available for VFs of this PF */
|
||||
if (p_igu_info->igu_base_sb_iov == 0xffff) {
|
||||
p_igu_info->igu_base_sb_iov = sb_id;
|
||||
} else if (last_iov_sb_id != sb_id - 1) {
|
||||
if (!val)
|
||||
DP_VERBOSE(p_hwfn->p_dev,
|
||||
ECORE_MSG_INTR,
|
||||
"First uninited IGU"
|
||||
" CAM entry at"
|
||||
" index 0x%04x\n",
|
||||
sb_id);
|
||||
else
|
||||
DP_NOTICE(p_hwfn->p_dev, false,
|
||||
"Consecutive igu"
|
||||
" vectors for HWFN"
|
||||
" %x vfs is broken"
|
||||
" [jumps from %04x"
|
||||
" to %04x]\n",
|
||||
p_hwfn->rel_pf_id,
|
||||
last_iov_sb_id,
|
||||
sb_id);
|
||||
break;
|
||||
}
|
||||
p_block->status |= ECORE_IGU_STATUS_FREE;
|
||||
p_hwfn->hw_info.p_igu_info->free_blks++;
|
||||
last_iov_sb_id = sb_id;
|
||||
}
|
||||
if ((p_block->is_pf) &&
|
||||
(p_block->function_id == p_hwfn->rel_pf_id)) {
|
||||
p_block->status = ECORE_IGU_STATUS_PF |
|
||||
ECORE_IGU_STATUS_VALID |
|
||||
ECORE_IGU_STATUS_FREE;
|
||||
|
||||
if (p_igu_info->igu_dsb_id != ECORE_SB_INVALID_IDX)
|
||||
p_igu_info->usage.cnt++;
|
||||
} else if (!(p_block->is_pf) &&
|
||||
(p_block->function_id >= min_vf) &&
|
||||
(p_block->function_id < max_vf)) {
|
||||
/* Available for VFs of this PF */
|
||||
p_block->status = ECORE_IGU_STATUS_VALID |
|
||||
ECORE_IGU_STATUS_FREE;
|
||||
|
||||
if (p_igu_info->igu_dsb_id != ECORE_SB_INVALID_IDX)
|
||||
p_igu_info->usage.iov_cnt++;
|
||||
}
|
||||
|
||||
/* Mark the First entry belonging to the PF or its VFs
|
||||
* as the default SB [we'll reset IGU prior to first usage].
|
||||
*/
|
||||
if ((p_block->status & ECORE_IGU_STATUS_VALID) &&
|
||||
(p_igu_info->igu_dsb_id == ECORE_SB_INVALID_IDX)) {
|
||||
p_igu_info->igu_dsb_id = igu_sb_id;
|
||||
p_block->status |= ECORE_IGU_STATUS_DSB;
|
||||
}
|
||||
|
||||
/* While this isn't suitable for all clients, limit number
|
||||
* of prints by having each PF print only its entries with the
|
||||
* exception of PF0 which would print everything.
|
||||
*/
|
||||
if ((p_block->status & ECORE_IGU_STATUS_VALID) ||
|
||||
(p_hwfn->abs_pf_id == 0))
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"IGU_BLOCK: [SB 0x%04x] func_id = %d is_pf = %d vector_num = 0x%x\n",
|
||||
igu_sb_id, p_block->function_id,
|
||||
p_block->is_pf, p_block->vector_number);
|
||||
}
|
||||
|
||||
/* There's a possibility the igu_sb_cnt_iov doesn't properly reflect
|
||||
* the number of VF SBs [especially for first VF on engine, as we can't
|
||||
* diffrentiate between empty entries and its entries].
|
||||
* Since we don't really support more SBs than VFs today, prevent any
|
||||
* such configuration by sanitizing the number of SBs to equal the
|
||||
* number of VFs.
|
||||
*/
|
||||
if (IS_PF_SRIOV(p_hwfn)) {
|
||||
u16 total_vfs = p_hwfn->p_dev->p_iov_info->total_vfs;
|
||||
|
||||
if (total_vfs < p_igu_info->free_blks) {
|
||||
DP_VERBOSE(p_hwfn, (ECORE_MSG_INTR | ECORE_MSG_IOV),
|
||||
"Limiting number of SBs for IOV - %04x --> %04x\n",
|
||||
p_igu_info->free_blks,
|
||||
p_hwfn->p_dev->p_iov_info->total_vfs);
|
||||
p_igu_info->free_blks = total_vfs;
|
||||
} else if (total_vfs > p_igu_info->free_blks) {
|
||||
DP_NOTICE(p_hwfn, true,
|
||||
"IGU has only %04x SBs for VFs while the device has %04x VFs\n",
|
||||
p_igu_info->free_blks, total_vfs);
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
}
|
||||
|
||||
p_igu_info->igu_sb_cnt_iov = p_igu_info->free_blks;
|
||||
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"IGU igu_base_sb=0x%x [IOV 0x%x] igu_sb_cnt=%d [IOV 0x%x] "
|
||||
"igu_dsb_id=0x%x\n",
|
||||
p_igu_info->igu_base_sb, p_igu_info->igu_base_sb_iov,
|
||||
p_igu_info->igu_sb_cnt, p_igu_info->igu_sb_cnt_iov,
|
||||
p_igu_info->igu_dsb_id);
|
||||
|
||||
if (p_igu_info->igu_base_sb == 0xffff ||
|
||||
p_igu_info->igu_dsb_id == 0xffff || p_igu_info->igu_sb_cnt == 0) {
|
||||
if (p_igu_info->igu_dsb_id == ECORE_SB_INVALID_IDX) {
|
||||
DP_NOTICE(p_hwfn, true,
|
||||
"IGU CAM returned invalid values igu_base_sb=0x%x "
|
||||
"igu_sb_cnt=%d igu_dsb_id=0x%x\n",
|
||||
p_igu_info->igu_base_sb, p_igu_info->igu_sb_cnt,
|
||||
"IGU CAM returned invalid values igu_dsb_id=0x%x\n",
|
||||
p_igu_info->igu_dsb_id);
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
|
||||
/* All non default SB are considered free at this point */
|
||||
p_igu_info->usage.free_cnt = p_igu_info->usage.cnt;
|
||||
p_igu_info->usage.free_cnt_iov = p_igu_info->usage.iov_cnt;
|
||||
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"igu_dsb_id=0x%x, num Free SBs - PF: %04x VF: %04x [might change after resource allocation]\n",
|
||||
p_igu_info->igu_dsb_id, p_igu_info->usage.cnt,
|
||||
p_igu_info->usage.iov_cnt);
|
||||
|
||||
return ECORE_SUCCESS;
|
||||
}
|
||||
|
||||
enum _ecore_status_t
|
||||
ecore_int_igu_relocate_sb(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
|
||||
u16 sb_id, bool b_to_vf)
|
||||
{
|
||||
struct ecore_igu_info *p_info = p_hwfn->hw_info.p_igu_info;
|
||||
struct ecore_igu_block *p_block = OSAL_NULL;
|
||||
u16 igu_sb_id = 0, vf_num = 0;
|
||||
u32 val = 0;
|
||||
|
||||
if (IS_VF(p_hwfn->p_dev) || !IS_PF_SRIOV(p_hwfn))
|
||||
return ECORE_INVAL;
|
||||
|
||||
if (sb_id == ECORE_SP_SB_ID)
|
||||
return ECORE_INVAL;
|
||||
|
||||
if (!p_info->b_allow_pf_vf_change) {
|
||||
DP_INFO(p_hwfn, "Can't relocate SBs as MFW is too old.\n");
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
|
||||
/* If we're moving a SB from PF to VF, the client had to specify
|
||||
* which vector it wants to move.
|
||||
*/
|
||||
if (b_to_vf) {
|
||||
igu_sb_id = ecore_get_pf_igu_sb_id(p_hwfn, sb_id + 1);
|
||||
if (igu_sb_id == ECORE_SB_INVALID_IDX)
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
|
||||
/* If we're moving a SB from VF to PF, need to validate there isn't
|
||||
* already a line configured for that vector.
|
||||
*/
|
||||
if (!b_to_vf) {
|
||||
if (ecore_get_pf_igu_sb_id(p_hwfn, sb_id + 1) !=
|
||||
ECORE_SB_INVALID_IDX)
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
|
||||
/* We need to validate that the SB can actually be relocated.
|
||||
* This would also handle the previous case where we've explicitly
|
||||
* stated which IGU SB needs to move.
|
||||
*/
|
||||
for (; igu_sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
|
||||
igu_sb_id++) {
|
||||
p_block = &p_info->entry[igu_sb_id];
|
||||
|
||||
if (!(p_block->status & ECORE_IGU_STATUS_VALID) ||
|
||||
!(p_block->status & ECORE_IGU_STATUS_FREE) ||
|
||||
(!!(p_block->status & ECORE_IGU_STATUS_PF) != b_to_vf)) {
|
||||
if (b_to_vf)
|
||||
return ECORE_INVAL;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (igu_sb_id == ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev)) {
|
||||
DP_VERBOSE(p_hwfn, (ECORE_MSG_INTR | ECORE_MSG_IOV),
|
||||
"Failed to find a free SB to move\n");
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
|
||||
/* At this point, p_block points to the SB we want to relocate */
|
||||
if (b_to_vf) {
|
||||
p_block->status &= ~ECORE_IGU_STATUS_PF;
|
||||
|
||||
/* It doesn't matter which VF number we choose, since we're
|
||||
* going to disable the line; But let's keep it in range.
|
||||
*/
|
||||
vf_num = (u16)p_hwfn->p_dev->p_iov_info->first_vf_in_pf;
|
||||
|
||||
p_block->function_id = (u8)vf_num;
|
||||
p_block->is_pf = 0;
|
||||
p_block->vector_number = 0;
|
||||
|
||||
p_info->usage.cnt--;
|
||||
p_info->usage.free_cnt--;
|
||||
p_info->usage.iov_cnt++;
|
||||
p_info->usage.free_cnt_iov++;
|
||||
|
||||
/* TODO - if SBs aren't really the limiting factor,
|
||||
* then it might not be accurate [in the since that
|
||||
* we might not need decrement the feature].
|
||||
*/
|
||||
p_hwfn->hw_info.feat_num[ECORE_PF_L2_QUE]--;
|
||||
p_hwfn->hw_info.feat_num[ECORE_VF_L2_QUE]++;
|
||||
} else {
|
||||
p_block->status |= ECORE_IGU_STATUS_PF;
|
||||
p_block->function_id = p_hwfn->rel_pf_id;
|
||||
p_block->is_pf = 1;
|
||||
p_block->vector_number = sb_id + 1;
|
||||
|
||||
p_info->usage.cnt++;
|
||||
p_info->usage.free_cnt++;
|
||||
p_info->usage.iov_cnt--;
|
||||
p_info->usage.free_cnt_iov--;
|
||||
|
||||
p_hwfn->hw_info.feat_num[ECORE_PF_L2_QUE]++;
|
||||
p_hwfn->hw_info.feat_num[ECORE_VF_L2_QUE]--;
|
||||
}
|
||||
|
||||
/* Update the IGU and CAU with the new configuration */
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_FUNCTION_NUMBER,
|
||||
p_block->function_id);
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_PF_VALID, p_block->is_pf);
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_VALID, p_block->is_pf);
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER,
|
||||
p_block->vector_number);
|
||||
|
||||
ecore_wr(p_hwfn, p_ptt,
|
||||
IGU_REG_MAPPING_MEMORY + sizeof(u32) * igu_sb_id,
|
||||
val);
|
||||
|
||||
ecore_int_cau_conf_sb(p_hwfn, p_ptt, 0,
|
||||
igu_sb_id, vf_num,
|
||||
p_block->is_pf ? 0 : 1);
|
||||
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
|
||||
"Relocation: [SB 0x%04x] func_id = %d is_pf = %d vector_num = 0x%x\n",
|
||||
igu_sb_id, p_block->function_id,
|
||||
p_block->is_pf, p_block->vector_number);
|
||||
|
||||
return ECORE_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2170,14 +2488,13 @@ void ecore_int_setup(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
|
||||
void ecore_int_get_num_sbs(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_sb_cnt_info *p_sb_cnt_info)
|
||||
{
|
||||
struct ecore_igu_info *info = p_hwfn->hw_info.p_igu_info;
|
||||
struct ecore_igu_info *p_igu_info = p_hwfn->hw_info.p_igu_info;
|
||||
|
||||
if (!info || !p_sb_cnt_info)
|
||||
if (!p_igu_info || !p_sb_cnt_info)
|
||||
return;
|
||||
|
||||
p_sb_cnt_info->sb_cnt = info->igu_sb_cnt;
|
||||
p_sb_cnt_info->sb_iov_cnt = info->igu_sb_cnt_iov;
|
||||
p_sb_cnt_info->sb_free_blk = info->free_blks;
|
||||
OSAL_MEMCPY(p_sb_cnt_info, &p_igu_info->usage,
|
||||
sizeof(*p_sb_cnt_info));
|
||||
}
|
||||
|
||||
void ecore_int_disable_post_isr_release(struct ecore_dev *p_dev)
|
||||
|
@ -21,31 +21,76 @@
|
||||
#define SB_ALIGNED_SIZE(p_hwfn) \
|
||||
ALIGNED_TYPE_SIZE(struct status_block, p_hwfn)
|
||||
|
||||
#define ECORE_SB_INVALID_IDX 0xffff
|
||||
|
||||
struct ecore_igu_block {
|
||||
u8 status;
|
||||
#define ECORE_IGU_STATUS_FREE 0x01
|
||||
#define ECORE_IGU_STATUS_VALID 0x02
|
||||
#define ECORE_IGU_STATUS_PF 0x04
|
||||
#define ECORE_IGU_STATUS_DSB 0x08
|
||||
|
||||
u8 vector_number;
|
||||
u8 function_id;
|
||||
u8 is_pf;
|
||||
};
|
||||
|
||||
struct ecore_igu_map {
|
||||
struct ecore_igu_block igu_blocks[MAX_TOT_SB_PER_PATH];
|
||||
/* Index inside IGU [meant for back reference] */
|
||||
u16 igu_sb_id;
|
||||
|
||||
struct ecore_sb_info *sb_info;
|
||||
};
|
||||
|
||||
struct ecore_igu_info {
|
||||
struct ecore_igu_map igu_map;
|
||||
struct ecore_igu_block entry[MAX_TOT_SB_PER_PATH];
|
||||
u16 igu_dsb_id;
|
||||
u16 igu_base_sb;
|
||||
u16 igu_base_sb_iov;
|
||||
u16 igu_sb_cnt;
|
||||
u16 igu_sb_cnt_iov;
|
||||
u16 free_blks;
|
||||
|
||||
/* The numbers can shift when using APIs to switch SBs between PF and
|
||||
* VF.
|
||||
*/
|
||||
struct ecore_sb_cnt_info usage;
|
||||
|
||||
/* Determine whether we can shift SBs between VFs and PFs */
|
||||
bool b_allow_pf_vf_change;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief - Make sure the IGU CAM reflects the resources provided by MFW
|
||||
*
|
||||
* @param p_hwfn
|
||||
* @param p_ptt
|
||||
*/
|
||||
int ecore_int_igu_reset_cam(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt);
|
||||
|
||||
/**
|
||||
* @brief - Make sure IGU CAM reflects the default resources once again,
|
||||
* starting with a 'dirty' SW database.
|
||||
* @param p_hwfn
|
||||
* @param p_ptt
|
||||
*/
|
||||
int ecore_int_igu_reset_cam_default(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt);
|
||||
|
||||
/**
|
||||
* @brief Translate the weakly-defined client sb-id into an IGU sb-id
|
||||
*
|
||||
* @param p_hwfn
|
||||
* @param sb_id - user provided sb_id
|
||||
*
|
||||
* @return an index inside IGU CAM where the SB resides
|
||||
*/
|
||||
u16 ecore_get_igu_sb_id(struct ecore_hwfn *p_hwfn, u16 sb_id);
|
||||
|
||||
/**
|
||||
* @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, OSAL_NULL if none is available
|
||||
*/
|
||||
struct ecore_igu_block *
|
||||
ecore_get_igu_free_sb(struct ecore_hwfn *p_hwfn, bool b_is_pf);
|
||||
/* TODO Names of function may change... */
|
||||
void ecore_int_igu_init_pure_rt(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
@ -125,9 +170,11 @@ u16 ecore_int_get_sp_sb_id(struct ecore_hwfn *p_hwfn);
|
||||
* @param opaque - opaque fid of the sb owner.
|
||||
* @param cleanup_set - set(1) / clear(0)
|
||||
*/
|
||||
void ecore_int_igu_init_pure_rt_single(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
u32 sb_id, u16 opaque, bool b_set);
|
||||
void ecore_int_igu_init_pure_rt_single(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
u16 sb_id,
|
||||
u16 opaque,
|
||||
bool b_set);
|
||||
|
||||
/**
|
||||
* @brief ecore_int_cau_conf - configure cau for a given status
|
||||
|
@ -48,9 +48,15 @@ struct ecore_sb_info_dbg {
|
||||
};
|
||||
|
||||
struct ecore_sb_cnt_info {
|
||||
int sb_cnt;
|
||||
int sb_iov_cnt;
|
||||
int sb_free_blk;
|
||||
/* Original, current, and free SBs for PF */
|
||||
int orig;
|
||||
int cnt;
|
||||
int free_cnt;
|
||||
|
||||
/* Original, current and free SBS for child VFs */
|
||||
int iov_orig;
|
||||
int iov_cnt;
|
||||
int free_cnt_iov;
|
||||
};
|
||||
|
||||
static OSAL_INLINE u16 ecore_sb_update_sb_idx(struct ecore_sb_info *sb_info)
|
||||
@ -173,17 +179,17 @@ enum ecore_coalescing_fsm {
|
||||
*
|
||||
* @param p_hwfn
|
||||
* @param p_ptt
|
||||
* @param igu_sb_id
|
||||
* @param p_sb
|
||||
* @param pi_index
|
||||
* @param state
|
||||
* @param timeset
|
||||
*/
|
||||
void ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
u16 igu_sb_id,
|
||||
u32 pi_index,
|
||||
enum ecore_coalescing_fsm coalescing_fsm,
|
||||
u8 timeset);
|
||||
void ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt,
|
||||
struct ecore_sb_info *p_sb,
|
||||
u32 pi_index,
|
||||
enum ecore_coalescing_fsm coalescing_fsm,
|
||||
u8 timeset);
|
||||
|
||||
/**
|
||||
*
|
||||
@ -219,6 +225,7 @@ void ecore_int_igu_disable_int(struct ecore_hwfn *p_hwfn,
|
||||
u64 ecore_int_igu_read_sisr_reg(struct ecore_hwfn *p_hwfn);
|
||||
|
||||
#define ECORE_SP_SB_ID 0xffff
|
||||
|
||||
/**
|
||||
* @brief ecore_int_sb_init - Initializes the sb_info structure.
|
||||
*
|
||||
@ -324,4 +331,18 @@ enum _ecore_status_t ecore_int_get_sb_dbg(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_sb_info *p_sb,
|
||||
struct ecore_sb_info_dbg *p_info);
|
||||
|
||||
/**
|
||||
* @brief - Move a free Status block between PF and child VF
|
||||
*
|
||||
* @param p_hwfn
|
||||
* @param p_ptt
|
||||
* @param sb_id - The PF fastpath vector to be moved [re-assigned if claiming
|
||||
* from VF, given-up if moving to VF]
|
||||
* @param b_to_vf - PF->VF == true, VF->PF == false
|
||||
*
|
||||
* @return ECORE_SUCCESS if SB successfully moved.
|
||||
*/
|
||||
enum _ecore_status_t
|
||||
ecore_int_igu_relocate_sb(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
|
||||
u16 sb_id, bool b_to_vf);
|
||||
#endif
|
||||
|
@ -207,9 +207,15 @@ _ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn,
|
||||
|
||||
p_cid->opaque_fid = opaque_fid;
|
||||
p_cid->cid = cid;
|
||||
p_cid->rel = *p_params;
|
||||
p_cid->p_owner = p_hwfn;
|
||||
|
||||
/* Fill in parameters */
|
||||
p_cid->rel.vport_id = p_params->vport_id;
|
||||
p_cid->rel.queue_id = p_params->queue_id;
|
||||
p_cid->rel.stats_id = p_params->stats_id;
|
||||
p_cid->sb_igu_id = p_params->p_sb->igu_sb_id;
|
||||
p_cid->sb_idx = p_params->sb_idx;
|
||||
|
||||
/* Fill-in bits related to VFs' queues if information was provided */
|
||||
if (p_vf_params != OSAL_NULL) {
|
||||
p_cid->vfid = p_vf_params->vfid;
|
||||
@ -251,10 +257,6 @@ _ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn,
|
||||
p_cid->abs.stats_id = p_cid->rel.stats_id;
|
||||
}
|
||||
|
||||
/* SBs relevant information was already provided as absolute */
|
||||
p_cid->abs.sb = p_cid->rel.sb;
|
||||
p_cid->abs.sb_idx = p_cid->rel.sb_idx;
|
||||
|
||||
out:
|
||||
/* VF-images have provided the qid_usage_idx on their own.
|
||||
* Otherwise, we need to allocate a unique one.
|
||||
@ -273,7 +275,7 @@ _ecore_eth_queue_to_cid(struct ecore_hwfn *p_hwfn,
|
||||
p_cid->rel.queue_id, p_cid->qid_usage_idx,
|
||||
p_cid->abs.queue_id,
|
||||
p_cid->rel.stats_id, p_cid->abs.stats_id,
|
||||
p_cid->abs.sb, p_cid->abs.sb_idx);
|
||||
p_cid->sb_igu_id, p_cid->sb_idx);
|
||||
|
||||
return p_cid;
|
||||
|
||||
@ -901,7 +903,7 @@ ecore_eth_rxq_start_ramrod(struct ecore_hwfn *p_hwfn,
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
|
||||
"opaque_fid=0x%x, cid=0x%x, rx_qzone=0x%x, vport_id=0x%x, sb_id=0x%x\n",
|
||||
p_cid->opaque_fid, p_cid->cid, p_cid->abs.queue_id,
|
||||
p_cid->abs.vport_id, p_cid->abs.sb);
|
||||
p_cid->abs.vport_id, p_cid->sb_igu_id);
|
||||
|
||||
/* Get SPQ entry */
|
||||
OSAL_MEMSET(&init_data, 0, sizeof(init_data));
|
||||
@ -917,8 +919,8 @@ ecore_eth_rxq_start_ramrod(struct ecore_hwfn *p_hwfn,
|
||||
|
||||
p_ramrod = &p_ent->ramrod.rx_queue_start;
|
||||
|
||||
p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_cid->abs.sb);
|
||||
p_ramrod->sb_index = p_cid->abs.sb_idx;
|
||||
p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_cid->sb_igu_id);
|
||||
p_ramrod->sb_index = p_cid->sb_idx;
|
||||
p_ramrod->vport_id = p_cid->abs.vport_id;
|
||||
p_ramrod->stats_counter_id = p_cid->abs.stats_id;
|
||||
p_ramrod->rx_queue_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
|
||||
@ -1153,8 +1155,8 @@ ecore_eth_txq_start_ramrod(struct ecore_hwfn *p_hwfn,
|
||||
p_ramrod = &p_ent->ramrod.tx_queue_start;
|
||||
p_ramrod->vport_id = p_cid->abs.vport_id;
|
||||
|
||||
p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_cid->abs.sb);
|
||||
p_ramrod->sb_index = p_cid->abs.sb_idx;
|
||||
p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_cid->sb_igu_id);
|
||||
p_ramrod->sb_index = p_cid->sb_idx;
|
||||
p_ramrod->stats_counter_id = p_cid->abs.stats_id;
|
||||
|
||||
p_ramrod->queue_zone_id = OSAL_CPU_TO_LE16(p_cid->abs.queue_id);
|
||||
|
@ -18,7 +18,16 @@
|
||||
#define MAX_QUEUES_PER_QZONE (sizeof(unsigned long) * 8)
|
||||
#define ECORE_QUEUE_CID_PF (0xff)
|
||||
|
||||
/* Additional parameters required for initialization of the queue_cid
|
||||
/* Almost identical to the ecore_queue_start_common_params,
|
||||
* but here we maintain the SB index in IGU CAM.
|
||||
*/
|
||||
struct ecore_queue_cid_params {
|
||||
u8 vport_id;
|
||||
u16 queue_id;
|
||||
u8 stats_id;
|
||||
};
|
||||
|
||||
/* Additional parameters required for initialization of the queue_cid
|
||||
* and are relevant only for a PF initializing one for its VFs.
|
||||
*/
|
||||
struct ecore_queue_cid_vf_params {
|
||||
@ -44,13 +53,14 @@ struct ecore_queue_cid_vf_params {
|
||||
};
|
||||
|
||||
struct ecore_queue_cid {
|
||||
/* 'Relative' is a relative term ;-). Usually the indices [not counting
|
||||
* SBs] would be PF-relative, but there are some cases where that isn't
|
||||
* the case - specifically for a PF configuring its VF indices it's
|
||||
* possible some fields [E.g., stats-id] in 'rel' would already be abs.
|
||||
*/
|
||||
struct ecore_queue_start_common_params rel;
|
||||
struct ecore_queue_start_common_params abs;
|
||||
/* For stats-id, the `rel' is actually absolute as well */
|
||||
struct ecore_queue_cid_params rel;
|
||||
struct ecore_queue_cid_params abs;
|
||||
|
||||
/* These have no 'relative' meaning */
|
||||
u16 sb_igu_id;
|
||||
u8 sb_idx;
|
||||
|
||||
u32 cid;
|
||||
u16 opaque_fid;
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "ecore_status.h"
|
||||
#include "ecore_sp_api.h"
|
||||
#include "ecore_int_api.h"
|
||||
|
||||
#ifndef __EXTRACT__LINUX__
|
||||
enum ecore_rss_caps {
|
||||
@ -35,8 +36,7 @@ struct ecore_queue_start_common_params {
|
||||
/* Relative, but relevant only for PFs */
|
||||
u8 stats_id;
|
||||
|
||||
/* These are always absolute */
|
||||
u16 sb;
|
||||
struct ecore_sb_info *p_sb;
|
||||
u8 sb_idx;
|
||||
};
|
||||
|
||||
|
@ -446,33 +446,6 @@ static enum _ecore_status_t ecore_iov_pci_cfg_info(struct ecore_dev *p_dev)
|
||||
return ECORE_SUCCESS;
|
||||
}
|
||||
|
||||
static void ecore_iov_clear_vf_igu_blocks(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_ptt *p_ptt)
|
||||
{
|
||||
struct ecore_igu_block *p_sb;
|
||||
u16 sb_id;
|
||||
u32 val;
|
||||
|
||||
if (!p_hwfn->hw_info.p_igu_info) {
|
||||
DP_ERR(p_hwfn,
|
||||
"ecore_iov_clear_vf_igu_blocks IGU Info not inited\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (sb_id = 0;
|
||||
sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev); sb_id++) {
|
||||
p_sb = &p_hwfn->hw_info.p_igu_info->igu_map.igu_blocks[sb_id];
|
||||
if ((p_sb->status & ECORE_IGU_STATUS_FREE) &&
|
||||
!(p_sb->status & ECORE_IGU_STATUS_PF)) {
|
||||
val = ecore_rd(p_hwfn, p_ptt,
|
||||
IGU_REG_MAPPING_MEMORY + sb_id * 4);
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_VALID, 0);
|
||||
ecore_wr(p_hwfn, p_ptt,
|
||||
IGU_REG_MAPPING_MEMORY + 4 * sb_id, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ecore_iov_setup_vfdb(struct ecore_hwfn *p_hwfn)
|
||||
{
|
||||
struct ecore_hw_sriov_info *p_iov = p_hwfn->p_dev->p_iov_info;
|
||||
@ -634,7 +607,6 @@ void ecore_iov_setup(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
|
||||
return;
|
||||
|
||||
ecore_iov_setup_vfdb(p_hwfn);
|
||||
ecore_iov_clear_vf_igu_blocks(p_hwfn, p_ptt);
|
||||
}
|
||||
|
||||
void ecore_iov_free(struct ecore_hwfn *p_hwfn)
|
||||
@ -938,46 +910,38 @@ static u8 ecore_iov_alloc_vf_igu_sbs(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_vf_info *vf,
|
||||
u16 num_rx_queues)
|
||||
{
|
||||
struct ecore_igu_block *igu_blocks;
|
||||
int qid = 0, igu_id = 0;
|
||||
struct ecore_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->igu_map.igu_blocks;
|
||||
|
||||
if (num_rx_queues > p_hwfn->hw_info.p_igu_info->free_blks)
|
||||
num_rx_queues = p_hwfn->hw_info.p_igu_info->free_blks;
|
||||
|
||||
p_hwfn->hw_info.p_igu_info->free_blks -= num_rx_queues;
|
||||
if (num_rx_queues > p_hwfn->hw_info.p_igu_info->usage.free_cnt_iov)
|
||||
num_rx_queues =
|
||||
(u16)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;
|
||||
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_FUNCTION_NUMBER, vf->abs_vf_id);
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_VALID, 1);
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_PF_VALID, 0);
|
||||
|
||||
while ((qid < num_rx_queues) &&
|
||||
(igu_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev))) {
|
||||
if (igu_blocks[igu_id].status & ECORE_IGU_STATUS_FREE) {
|
||||
struct cau_sb_entry sb_entry;
|
||||
for (qid = 0; qid < num_rx_queues; qid++) {
|
||||
p_block = ecore_get_igu_free_sb(p_hwfn, false);
|
||||
vf->igu_sbs[qid] = p_block->igu_sb_id;
|
||||
p_block->status &= ~ECORE_IGU_STATUS_FREE;
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER, qid);
|
||||
|
||||
vf->igu_sbs[qid] = (u16)igu_id;
|
||||
igu_blocks[igu_id].status &= ~ECORE_IGU_STATUS_FREE;
|
||||
ecore_wr(p_hwfn, p_ptt,
|
||||
IGU_REG_MAPPING_MEMORY +
|
||||
sizeof(u32) * p_block->igu_sb_id, val);
|
||||
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER, qid);
|
||||
|
||||
ecore_wr(p_hwfn, p_ptt,
|
||||
IGU_REG_MAPPING_MEMORY + sizeof(u32) * igu_id,
|
||||
val);
|
||||
|
||||
/* Configure igu sb in CAU which were marked valid */
|
||||
ecore_init_cau_sb_entry(p_hwfn, &sb_entry,
|
||||
p_hwfn->rel_pf_id,
|
||||
vf->abs_vf_id, 1);
|
||||
ecore_dmae_host2grc(p_hwfn, p_ptt,
|
||||
(u64)(osal_uintptr_t)&sb_entry,
|
||||
CAU_REG_SB_VAR_MEMORY +
|
||||
igu_id * sizeof(u64), 2, 0);
|
||||
qid++;
|
||||
}
|
||||
igu_id++;
|
||||
/* Configure igu sb in CAU which were marked valid */
|
||||
ecore_init_cau_sb_entry(p_hwfn, &sb_entry,
|
||||
p_hwfn->rel_pf_id,
|
||||
vf->abs_vf_id, 1);
|
||||
ecore_dmae_host2grc(p_hwfn, p_ptt,
|
||||
(u64)(osal_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;
|
||||
@ -1013,10 +977,8 @@ static void ecore_iov_free_vf_igu_sbs(struct ecore_hwfn *p_hwfn,
|
||||
SET_FIELD(val, IGU_MAPPING_LINE_VALID, 0);
|
||||
ecore_wr(p_hwfn, p_ptt, addr, val);
|
||||
|
||||
p_info->igu_map.igu_blocks[igu_id].status |=
|
||||
ECORE_IGU_STATUS_FREE;
|
||||
|
||||
p_hwfn->hw_info.p_igu_info->free_blks++;
|
||||
p_info->entry[igu_id].status |= ECORE_IGU_STATUS_FREE;
|
||||
p_hwfn->hw_info.p_igu_info->usage.free_cnt_iov++;
|
||||
}
|
||||
|
||||
vf->num_sbs = 0;
|
||||
@ -1114,34 +1076,28 @@ ecore_iov_init_hw_for_vf(struct ecore_hwfn *p_hwfn,
|
||||
vf->vport_id = p_params->vport_id;
|
||||
vf->rss_eng_id = p_params->rss_eng_id;
|
||||
|
||||
/* Perform sanity checking on the requested queue_id */
|
||||
/* Since it's possible to relocate SBs, it's a bit difficult to check
|
||||
* things here. Simply check whether the index falls in the range
|
||||
* belonging to the PF.
|
||||
*/
|
||||
for (i = 0; i < p_params->num_queues; i++) {
|
||||
u16 min_vf_qzone = (u16)FEAT_NUM(p_hwfn, ECORE_PF_L2_QUE);
|
||||
u16 max_vf_qzone = min_vf_qzone +
|
||||
FEAT_NUM(p_hwfn, ECORE_VF_L2_QUE) - 1;
|
||||
|
||||
qid = p_params->req_rx_queue[i];
|
||||
if (qid < min_vf_qzone || qid > max_vf_qzone) {
|
||||
if (qid > (u16)RESC_NUM(p_hwfn, ECORE_L2_QUEUE)) {
|
||||
DP_NOTICE(p_hwfn, true,
|
||||
"Can't enable Rx qid [%04x] for VF[%d]: qids [0x%04x,...,0x%04x] available\n",
|
||||
"Can't enable Rx qid [%04x] for VF[%d]: qids [0,,...,0x%04x] available\n",
|
||||
qid, p_params->rel_vf_id,
|
||||
min_vf_qzone, max_vf_qzone);
|
||||
(u16)RESC_NUM(p_hwfn, ECORE_L2_QUEUE));
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
|
||||
qid = p_params->req_tx_queue[i];
|
||||
if (qid > max_vf_qzone) {
|
||||
if (qid > (u16)RESC_NUM(p_hwfn, ECORE_L2_QUEUE)) {
|
||||
DP_NOTICE(p_hwfn, true,
|
||||
"Can't enable Tx qid [%04x] for VF[%d]: max qid 0x%04x\n",
|
||||
qid, p_params->rel_vf_id, max_vf_qzone);
|
||||
"Can't enable Tx qid [%04x] for VF[%d]: qids [0,,...,0x%04x] available\n",
|
||||
qid, p_params->rel_vf_id,
|
||||
(u16)RESC_NUM(p_hwfn, ECORE_L2_QUEUE));
|
||||
return ECORE_INVAL;
|
||||
}
|
||||
|
||||
/* If client *really* wants, Tx qid can be shared with PF */
|
||||
if (qid < min_vf_qzone)
|
||||
DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
|
||||
"VF[%d] is using PF qid [0x%04x] for Txq[0x%02x]\n",
|
||||
p_params->rel_vf_id, qid, i);
|
||||
}
|
||||
|
||||
/* Limit number of queues according to number of CIDs */
|
||||
@ -2233,6 +2189,7 @@ static void ecore_iov_vf_mbx_start_rxq(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_vf_queue *p_queue;
|
||||
struct vfpf_start_rxq_tlv *req;
|
||||
struct ecore_queue_cid *p_cid;
|
||||
struct ecore_sb_info sb_dummy;
|
||||
enum _ecore_status_t rc;
|
||||
|
||||
req = &mbx->req_virt->start_rxq;
|
||||
@ -2257,7 +2214,11 @@ static void ecore_iov_vf_mbx_start_rxq(struct ecore_hwfn *p_hwfn,
|
||||
params.queue_id = (u8)p_queue->fw_rx_qid;
|
||||
params.vport_id = vf->vport_id;
|
||||
params.stats_id = vf->abs_vf_id + 0x10;
|
||||
params.sb = req->hw_sb;
|
||||
|
||||
/* Since IGU index is passed via sb_info, construct a dummy one */
|
||||
OSAL_MEM_ZERO(&sb_dummy, sizeof(sb_dummy));
|
||||
sb_dummy.igu_sb_id = req->hw_sb;
|
||||
params.p_sb = &sb_dummy;
|
||||
params.sb_idx = req->sb_index;
|
||||
|
||||
OSAL_MEM_ZERO(&vf_params, sizeof(vf_params));
|
||||
@ -2500,6 +2461,7 @@ static void ecore_iov_vf_mbx_start_txq(struct ecore_hwfn *p_hwfn,
|
||||
struct ecore_vf_queue *p_queue;
|
||||
struct vfpf_start_txq_tlv *req;
|
||||
struct ecore_queue_cid *p_cid;
|
||||
struct ecore_sb_info sb_dummy;
|
||||
u8 qid_usage_idx, vf_legacy;
|
||||
u32 cid = 0;
|
||||
enum _ecore_status_t rc;
|
||||
@ -2527,7 +2489,11 @@ static void ecore_iov_vf_mbx_start_txq(struct ecore_hwfn *p_hwfn,
|
||||
params.queue_id = p_queue->fw_tx_qid;
|
||||
params.vport_id = vf->vport_id;
|
||||
params.stats_id = vf->abs_vf_id + 0x10;
|
||||
params.sb = req->hw_sb;
|
||||
|
||||
/* Since IGU index is passed via sb_info, construct a dummy one */
|
||||
OSAL_MEM_ZERO(&sb_dummy, sizeof(sb_dummy));
|
||||
sb_dummy.igu_sb_id = req->hw_sb;
|
||||
params.p_sb = &sb_dummy;
|
||||
params.sb_idx = req->sb_index;
|
||||
|
||||
OSAL_MEM_ZERO(&vf_params, sizeof(vf_params));
|
||||
|
@ -652,8 +652,8 @@ ecore_vf_pf_rxq_start(struct ecore_hwfn *p_hwfn,
|
||||
req->cqe_pbl_addr = cqe_pbl_addr;
|
||||
req->cqe_pbl_size = cqe_pbl_size;
|
||||
req->rxq_addr = bd_chain_phys_addr;
|
||||
req->hw_sb = p_cid->rel.sb;
|
||||
req->sb_index = p_cid->rel.sb_idx;
|
||||
req->hw_sb = p_cid->sb_igu_id;
|
||||
req->sb_index = p_cid->sb_idx;
|
||||
req->bd_max_bytes = bd_max_bytes;
|
||||
req->stat_id = -1; /* Keep initialized, for future compatibility */
|
||||
|
||||
@ -774,8 +774,8 @@ ecore_vf_pf_txq_start(struct ecore_hwfn *p_hwfn,
|
||||
/* Tx */
|
||||
req->pbl_addr = pbl_addr;
|
||||
req->pbl_size = pbl_size;
|
||||
req->hw_sb = p_cid->rel.sb;
|
||||
req->sb_index = p_cid->rel.sb_idx;
|
||||
req->hw_sb = p_cid->sb_igu_id;
|
||||
req->sb_index = p_cid->sb_idx;
|
||||
|
||||
ecore_vf_pf_add_qid(p_hwfn, p_cid);
|
||||
|
||||
@ -930,9 +930,12 @@ ecore_vf_pf_vport_start(struct ecore_hwfn *p_hwfn, u8 vport_id,
|
||||
req->only_untagged = only_untagged;
|
||||
|
||||
/* status blocks */
|
||||
for (i = 0; i < p_hwfn->vf_iov_info->acquire_resp.resc.num_sbs; i++)
|
||||
if (p_hwfn->sbs_info[i])
|
||||
req->sb_addr[i] = p_hwfn->sbs_info[i]->sb_phys;
|
||||
for (i = 0; i < p_hwfn->vf_iov_info->acquire_resp.resc.num_sbs; i++) {
|
||||
struct ecore_sb_info *p_sb = p_hwfn->vf_iov_info->sbs_info[i];
|
||||
|
||||
if (p_sb)
|
||||
req->sb_addr[i] = p_sb->sb_phys;
|
||||
}
|
||||
|
||||
/* add list termination tlv */
|
||||
ecore_add_tlv(p_hwfn, &p_iov->offset,
|
||||
@ -1501,6 +1504,24 @@ u16 ecore_vf_get_igu_sb_id(struct ecore_hwfn *p_hwfn,
|
||||
return p_iov->acquire_resp.resc.hw_sbs[sb_id].hw_sb_id;
|
||||
}
|
||||
|
||||
void ecore_vf_set_sb_info(struct ecore_hwfn *p_hwfn,
|
||||
u16 sb_id, struct ecore_sb_info *p_sb)
|
||||
{
|
||||
struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
|
||||
|
||||
if (!p_iov) {
|
||||
DP_NOTICE(p_hwfn, true, "vf_sriov_info isn't initialized\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sb_id >= PFVF_MAX_SBS_PER_VF) {
|
||||
DP_NOTICE(p_hwfn, true, "Can't configure SB %04x\n", sb_id);
|
||||
return;
|
||||
}
|
||||
|
||||
p_iov->sbs_info[sb_id] = p_sb;
|
||||
}
|
||||
|
||||
enum _ecore_status_t ecore_vf_read_bulletin(struct ecore_hwfn *p_hwfn,
|
||||
u8 *p_change)
|
||||
{
|
||||
|
@ -41,6 +41,14 @@ struct ecore_vf_iov {
|
||||
* this has to be propagated as it affects the fastpath.
|
||||
*/
|
||||
bool b_pre_fp_hsi;
|
||||
|
||||
/* Current day VFs are passing the SBs physical address on vport
|
||||
* start, and as they lack an IGU mapping they need to store the
|
||||
* addresses of previously registered SBs.
|
||||
* Even if we were to change configuration flow, due to backward
|
||||
* compatibility [with older PFs] we'd still need to store these.
|
||||
*/
|
||||
struct ecore_sb_info *sbs_info[PFVF_MAX_SBS_PER_VF];
|
||||
};
|
||||
|
||||
|
||||
@ -205,6 +213,15 @@ enum _ecore_status_t ecore_vf_pf_release(struct ecore_hwfn *p_hwfn);
|
||||
u16 ecore_vf_get_igu_sb_id(struct ecore_hwfn *p_hwfn,
|
||||
u16 sb_id);
|
||||
|
||||
/**
|
||||
* @brief Stores [or removes] a configured sb_info.
|
||||
*
|
||||
* @param p_hwfn
|
||||
* @param sb_id - zero-based SB index [for fastpath]
|
||||
* @param sb_info - may be OSAL_NULL [during removal].
|
||||
*/
|
||||
void ecore_vf_set_sb_info(struct ecore_hwfn *p_hwfn,
|
||||
u16 sb_id, struct ecore_sb_info *p_sb);
|
||||
|
||||
/**
|
||||
* @brief ecore_vf_pf_vport_start - perform vport start for VF.
|
||||
|
@ -555,7 +555,7 @@ qede_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
|
||||
params.queue_id = rx_queue_id / edev->num_hwfns;
|
||||
params.vport_id = 0;
|
||||
params.stats_id = params.vport_id;
|
||||
params.sb = fp->sb_info->igu_sb_id;
|
||||
params.p_sb = fp->sb_info;
|
||||
DP_INFO(edev, "rxq %u igu_sb_id 0x%x\n",
|
||||
fp->rxq->queue_id, fp->sb_info->igu_sb_id);
|
||||
params.sb_idx = RX_PI;
|
||||
@ -614,7 +614,7 @@ qede_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
|
||||
params.queue_id = tx_queue_id / edev->num_hwfns;
|
||||
params.vport_id = 0;
|
||||
params.stats_id = params.vport_id;
|
||||
params.sb = fp->sb_info->igu_sb_id;
|
||||
params.p_sb = fp->sb_info;
|
||||
DP_INFO(edev, "txq %u igu_sb_id 0x%x\n",
|
||||
fp->txq->queue_id, fp->sb_info->igu_sb_id);
|
||||
params.sb_idx = TX_PI(0); /* tc = 0 */
|
||||
|
Loading…
Reference in New Issue
Block a user