|
@@ -75,7 +75,8 @@ enum BAR_ID {
|
|
BAR_ID_1 /* Used for doorbells */
|
|
BAR_ID_1 /* Used for doorbells */
|
|
};
|
|
};
|
|
|
|
|
|
-static u32 qed_hw_bar_size(struct qed_hwfn *p_hwfn, enum BAR_ID bar_id)
|
|
|
|
|
|
+static u32 qed_hw_bar_size(struct qed_hwfn *p_hwfn,
|
|
|
|
+ struct qed_ptt *p_ptt, enum BAR_ID bar_id)
|
|
{
|
|
{
|
|
u32 bar_reg = (bar_id == BAR_ID_0 ?
|
|
u32 bar_reg = (bar_id == BAR_ID_0 ?
|
|
PGLUE_B_REG_PF_BAR0_SIZE : PGLUE_B_REG_PF_BAR1_SIZE);
|
|
PGLUE_B_REG_PF_BAR0_SIZE : PGLUE_B_REG_PF_BAR1_SIZE);
|
|
@@ -84,7 +85,7 @@ static u32 qed_hw_bar_size(struct qed_hwfn *p_hwfn, enum BAR_ID bar_id)
|
|
if (IS_VF(p_hwfn->cdev))
|
|
if (IS_VF(p_hwfn->cdev))
|
|
return 1 << 17;
|
|
return 1 << 17;
|
|
|
|
|
|
- val = qed_rd(p_hwfn, p_hwfn->p_main_ptt, bar_reg);
|
|
|
|
|
|
+ val = qed_rd(p_hwfn, p_ptt, bar_reg);
|
|
if (val)
|
|
if (val)
|
|
return 1 << (val + 15);
|
|
return 1 << (val + 15);
|
|
|
|
|
|
@@ -780,7 +781,7 @@ int qed_qm_reconf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
|
qed_init_clear_rt_data(p_hwfn);
|
|
qed_init_clear_rt_data(p_hwfn);
|
|
|
|
|
|
/* prepare QM portion of runtime array */
|
|
/* prepare QM portion of runtime array */
|
|
- qed_qm_init_pf(p_hwfn);
|
|
|
|
|
|
+ qed_qm_init_pf(p_hwfn, p_ptt);
|
|
|
|
|
|
/* activate init tool on runtime array */
|
|
/* activate init tool on runtime array */
|
|
rc = qed_init_run(p_hwfn, p_ptt, PHASE_QM_PF, p_hwfn->rel_pf_id,
|
|
rc = qed_init_run(p_hwfn, p_ptt, PHASE_QM_PF, p_hwfn->rel_pf_id,
|
|
@@ -1191,6 +1192,57 @@ static void qed_init_cau_rt_data(struct qed_dev *cdev)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void qed_init_cache_line_size(struct qed_hwfn *p_hwfn,
|
|
|
|
+ struct qed_ptt *p_ptt)
|
|
|
|
+{
|
|
|
|
+ u32 val, wr_mbs, cache_line_size;
|
|
|
|
+
|
|
|
|
+ val = qed_rd(p_hwfn, p_ptt, PSWRQ2_REG_WR_MBS0);
|
|
|
|
+ switch (val) {
|
|
|
|
+ case 0:
|
|
|
|
+ wr_mbs = 128;
|
|
|
|
+ break;
|
|
|
|
+ case 1:
|
|
|
|
+ wr_mbs = 256;
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ wr_mbs = 512;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ DP_INFO(p_hwfn,
|
|
|
|
+ "Unexpected value of PSWRQ2_REG_WR_MBS0 [0x%x]. Avoid configuring PGLUE_B_REG_CACHE_LINE_SIZE.\n",
|
|
|
|
+ val);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cache_line_size = min_t(u32, L1_CACHE_BYTES, wr_mbs);
|
|
|
|
+ switch (cache_line_size) {
|
|
|
|
+ case 32:
|
|
|
|
+ val = 0;
|
|
|
|
+ break;
|
|
|
|
+ case 64:
|
|
|
|
+ val = 1;
|
|
|
|
+ break;
|
|
|
|
+ case 128:
|
|
|
|
+ val = 2;
|
|
|
|
+ break;
|
|
|
|
+ case 256:
|
|
|
|
+ val = 3;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ DP_INFO(p_hwfn,
|
|
|
|
+ "Unexpected value of cache line size [0x%x]. Avoid configuring PGLUE_B_REG_CACHE_LINE_SIZE.\n",
|
|
|
|
+ cache_line_size);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (L1_CACHE_BYTES > wr_mbs)
|
|
|
|
+ DP_INFO(p_hwfn,
|
|
|
|
+ "The cache line size for padding is suboptimal for performance [OS cache line size 0x%x, wr mbs 0x%x]\n",
|
|
|
|
+ L1_CACHE_BYTES, wr_mbs);
|
|
|
|
+
|
|
|
|
+ STORE_RT_REG(p_hwfn, PGLUE_REG_B_CACHE_LINE_SIZE_RT_OFFSET, val);
|
|
|
|
+}
|
|
|
|
+
|
|
static int qed_hw_init_common(struct qed_hwfn *p_hwfn,
|
|
static int qed_hw_init_common(struct qed_hwfn *p_hwfn,
|
|
struct qed_ptt *p_ptt, int hw_mode)
|
|
struct qed_ptt *p_ptt, int hw_mode)
|
|
{
|
|
{
|
|
@@ -1227,17 +1279,7 @@ static int qed_hw_init_common(struct qed_hwfn *p_hwfn,
|
|
|
|
|
|
qed_cxt_hw_init_common(p_hwfn);
|
|
qed_cxt_hw_init_common(p_hwfn);
|
|
|
|
|
|
- /* Close gate from NIG to BRB/Storm; By default they are open, but
|
|
|
|
- * we close them to prevent NIG from passing data to reset blocks.
|
|
|
|
- * Should have been done in the ENGINE phase, but init-tool lacks
|
|
|
|
- * proper port-pretend capabilities.
|
|
|
|
- */
|
|
|
|
- qed_wr(p_hwfn, p_ptt, NIG_REG_RX_BRB_OUT_EN, 0);
|
|
|
|
- qed_wr(p_hwfn, p_ptt, NIG_REG_STORM_OUT_EN, 0);
|
|
|
|
- qed_port_pretend(p_hwfn, p_ptt, p_hwfn->port_id ^ 1);
|
|
|
|
- qed_wr(p_hwfn, p_ptt, NIG_REG_RX_BRB_OUT_EN, 0);
|
|
|
|
- qed_wr(p_hwfn, p_ptt, NIG_REG_STORM_OUT_EN, 0);
|
|
|
|
- qed_port_unpretend(p_hwfn, p_ptt);
|
|
|
|
|
|
+ qed_init_cache_line_size(p_hwfn, p_ptt);
|
|
|
|
|
|
rc = qed_init_run(p_hwfn, p_ptt, PHASE_ENGINE, ANY_PHASE_ID, hw_mode);
|
|
rc = qed_init_run(p_hwfn, p_ptt, PHASE_ENGINE, ANY_PHASE_ID, hw_mode);
|
|
if (rc)
|
|
if (rc)
|
|
@@ -1320,7 +1362,7 @@ qed_hw_init_pf_doorbell_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
|
int rc = 0;
|
|
int rc = 0;
|
|
u8 cond;
|
|
u8 cond;
|
|
|
|
|
|
- db_bar_size = qed_hw_bar_size(p_hwfn, BAR_ID_1);
|
|
|
|
|
|
+ db_bar_size = qed_hw_bar_size(p_hwfn, p_ptt, BAR_ID_1);
|
|
if (p_hwfn->cdev->num_hwfns > 1)
|
|
if (p_hwfn->cdev->num_hwfns > 1)
|
|
db_bar_size /= 2;
|
|
db_bar_size /= 2;
|
|
|
|
|
|
@@ -1431,7 +1473,7 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,
|
|
p_hwfn->qm_info.pf_rl = 100000;
|
|
p_hwfn->qm_info.pf_rl = 100000;
|
|
}
|
|
}
|
|
|
|
|
|
- qed_cxt_hw_init_pf(p_hwfn);
|
|
|
|
|
|
+ qed_cxt_hw_init_pf(p_hwfn, p_ptt);
|
|
|
|
|
|
qed_int_igu_init_rt(p_hwfn);
|
|
qed_int_igu_init_rt(p_hwfn);
|
|
|
|
|
|
@@ -1852,18 +1894,21 @@ int qed_hw_stop(struct qed_dev *cdev)
|
|
return rc2;
|
|
return rc2;
|
|
}
|
|
}
|
|
|
|
|
|
-void qed_hw_stop_fastpath(struct qed_dev *cdev)
|
|
|
|
|
|
+int qed_hw_stop_fastpath(struct qed_dev *cdev)
|
|
{
|
|
{
|
|
int j;
|
|
int j;
|
|
|
|
|
|
for_each_hwfn(cdev, j) {
|
|
for_each_hwfn(cdev, j) {
|
|
struct qed_hwfn *p_hwfn = &cdev->hwfns[j];
|
|
struct qed_hwfn *p_hwfn = &cdev->hwfns[j];
|
|
- struct qed_ptt *p_ptt = p_hwfn->p_main_ptt;
|
|
|
|
|
|
+ struct qed_ptt *p_ptt;
|
|
|
|
|
|
if (IS_VF(cdev)) {
|
|
if (IS_VF(cdev)) {
|
|
qed_vf_pf_int_cleanup(p_hwfn);
|
|
qed_vf_pf_int_cleanup(p_hwfn);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
+ p_ptt = qed_ptt_acquire(p_hwfn);
|
|
|
|
+ if (!p_ptt)
|
|
|
|
+ return -EAGAIN;
|
|
|
|
|
|
DP_VERBOSE(p_hwfn,
|
|
DP_VERBOSE(p_hwfn,
|
|
NETIF_MSG_IFDOWN, "Shutting down the fastpath\n");
|
|
NETIF_MSG_IFDOWN, "Shutting down the fastpath\n");
|
|
@@ -1881,17 +1926,28 @@ void qed_hw_stop_fastpath(struct qed_dev *cdev)
|
|
|
|
|
|
/* Need to wait 1ms to guarantee SBs are cleared */
|
|
/* Need to wait 1ms to guarantee SBs are cleared */
|
|
usleep_range(1000, 2000);
|
|
usleep_range(1000, 2000);
|
|
|
|
+ qed_ptt_release(p_hwfn, p_ptt);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-void qed_hw_start_fastpath(struct qed_hwfn *p_hwfn)
|
|
|
|
|
|
+int qed_hw_start_fastpath(struct qed_hwfn *p_hwfn)
|
|
{
|
|
{
|
|
|
|
+ struct qed_ptt *p_ptt;
|
|
|
|
+
|
|
if (IS_VF(p_hwfn->cdev))
|
|
if (IS_VF(p_hwfn->cdev))
|
|
- return;
|
|
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ p_ptt = qed_ptt_acquire(p_hwfn);
|
|
|
|
+ if (!p_ptt)
|
|
|
|
+ return -EAGAIN;
|
|
|
|
|
|
/* Re-open incoming traffic */
|
|
/* Re-open incoming traffic */
|
|
- qed_wr(p_hwfn, p_hwfn->p_main_ptt,
|
|
|
|
- NIG_REG_RX_LLH_BRB_GATE_DNTFWD_PERPF, 0x0);
|
|
|
|
|
|
+ qed_wr(p_hwfn, p_ptt, NIG_REG_RX_LLH_BRB_GATE_DNTFWD_PERPF, 0x0);
|
|
|
|
+ qed_ptt_release(p_hwfn, p_ptt);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* Free hwfn memory and resources acquired in hw_hwfn_prepare */
|
|
/* Free hwfn memory and resources acquired in hw_hwfn_prepare */
|
|
@@ -1989,12 +2045,17 @@ static void qed_hw_set_feat(struct qed_hwfn *p_hwfn)
|
|
QED_VF_L2_QUE));
|
|
QED_VF_L2_QUE));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (p_hwfn->hw_info.personality == QED_PCI_ISCSI)
|
|
|
|
+ feat_num[QED_ISCSI_CQ] = min_t(u32, RESC_NUM(p_hwfn, QED_SB),
|
|
|
|
+ RESC_NUM(p_hwfn,
|
|
|
|
+ QED_CMDQS_CQS));
|
|
DP_VERBOSE(p_hwfn,
|
|
DP_VERBOSE(p_hwfn,
|
|
NETIF_MSG_PROBE,
|
|
NETIF_MSG_PROBE,
|
|
- "#PF_L2_QUEUES=%d VF_L2_QUEUES=%d #ROCE_CNQ=%d #SBS=%d\n",
|
|
|
|
|
|
+ "#PF_L2_QUEUES=%d VF_L2_QUEUES=%d #ROCE_CNQ=%d ISCSI_CQ=%d #SBS=%d\n",
|
|
(int)FEAT_NUM(p_hwfn, QED_PF_L2_QUE),
|
|
(int)FEAT_NUM(p_hwfn, QED_PF_L2_QUE),
|
|
(int)FEAT_NUM(p_hwfn, QED_VF_L2_QUE),
|
|
(int)FEAT_NUM(p_hwfn, QED_VF_L2_QUE),
|
|
(int)FEAT_NUM(p_hwfn, QED_RDMA_CNQ),
|
|
(int)FEAT_NUM(p_hwfn, QED_RDMA_CNQ),
|
|
|
|
+ (int)FEAT_NUM(p_hwfn, QED_ISCSI_CQ),
|
|
RESC_NUM(p_hwfn, QED_SB));
|
|
RESC_NUM(p_hwfn, QED_SB));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2697,9 +2758,9 @@ qed_get_hw_info(struct qed_hwfn *p_hwfn,
|
|
return qed_hw_get_resc(p_hwfn, p_ptt);
|
|
return qed_hw_get_resc(p_hwfn, p_ptt);
|
|
}
|
|
}
|
|
|
|
|
|
-static int qed_get_dev_info(struct qed_dev *cdev)
|
|
|
|
|
|
+static int qed_get_dev_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
|
{
|
|
{
|
|
- struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
|
|
|
|
|
|
+ struct qed_dev *cdev = p_hwfn->cdev;
|
|
u16 device_id_mask;
|
|
u16 device_id_mask;
|
|
u32 tmp;
|
|
u32 tmp;
|
|
|
|
|
|
@@ -2721,15 +2782,13 @@ static int qed_get_dev_info(struct qed_dev *cdev)
|
|
return -EBUSY;
|
|
return -EBUSY;
|
|
}
|
|
}
|
|
|
|
|
|
- cdev->chip_num = (u16)qed_rd(p_hwfn, p_hwfn->p_main_ptt,
|
|
|
|
- MISCS_REG_CHIP_NUM);
|
|
|
|
- cdev->chip_rev = (u16)qed_rd(p_hwfn, p_hwfn->p_main_ptt,
|
|
|
|
- MISCS_REG_CHIP_REV);
|
|
|
|
|
|
+ cdev->chip_num = (u16)qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_NUM);
|
|
|
|
+ cdev->chip_rev = (u16)qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_REV);
|
|
|
|
+
|
|
MASK_FIELD(CHIP_REV, cdev->chip_rev);
|
|
MASK_FIELD(CHIP_REV, cdev->chip_rev);
|
|
|
|
|
|
/* Learn number of HW-functions */
|
|
/* Learn number of HW-functions */
|
|
- tmp = qed_rd(p_hwfn, p_hwfn->p_main_ptt,
|
|
|
|
- MISCS_REG_CMT_ENABLED_FOR_PAIR);
|
|
|
|
|
|
+ tmp = qed_rd(p_hwfn, p_ptt, MISCS_REG_CMT_ENABLED_FOR_PAIR);
|
|
|
|
|
|
if (tmp & (1 << p_hwfn->rel_pf_id)) {
|
|
if (tmp & (1 << p_hwfn->rel_pf_id)) {
|
|
DP_NOTICE(cdev->hwfns, "device in CMT mode\n");
|
|
DP_NOTICE(cdev->hwfns, "device in CMT mode\n");
|
|
@@ -2738,11 +2797,10 @@ static int qed_get_dev_info(struct qed_dev *cdev)
|
|
cdev->num_hwfns = 1;
|
|
cdev->num_hwfns = 1;
|
|
}
|
|
}
|
|
|
|
|
|
- cdev->chip_bond_id = qed_rd(p_hwfn, p_hwfn->p_main_ptt,
|
|
|
|
|
|
+ cdev->chip_bond_id = qed_rd(p_hwfn, p_ptt,
|
|
MISCS_REG_CHIP_TEST_REG) >> 4;
|
|
MISCS_REG_CHIP_TEST_REG) >> 4;
|
|
MASK_FIELD(CHIP_BOND_ID, cdev->chip_bond_id);
|
|
MASK_FIELD(CHIP_BOND_ID, cdev->chip_bond_id);
|
|
- cdev->chip_metal = (u16)qed_rd(p_hwfn, p_hwfn->p_main_ptt,
|
|
|
|
- MISCS_REG_CHIP_METAL);
|
|
|
|
|
|
+ cdev->chip_metal = (u16)qed_rd(p_hwfn, p_ptt, MISCS_REG_CHIP_METAL);
|
|
MASK_FIELD(CHIP_METAL, cdev->chip_metal);
|
|
MASK_FIELD(CHIP_METAL, cdev->chip_metal);
|
|
|
|
|
|
DP_INFO(cdev->hwfns,
|
|
DP_INFO(cdev->hwfns,
|
|
@@ -2795,7 +2853,7 @@ static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn,
|
|
|
|
|
|
/* First hwfn learns basic information, e.g., number of hwfns */
|
|
/* First hwfn learns basic information, e.g., number of hwfns */
|
|
if (!p_hwfn->my_id) {
|
|
if (!p_hwfn->my_id) {
|
|
- rc = qed_get_dev_info(p_hwfn->cdev);
|
|
|
|
|
|
+ rc = qed_get_dev_info(p_hwfn, p_hwfn->p_main_ptt);
|
|
if (rc)
|
|
if (rc)
|
|
goto err1;
|
|
goto err1;
|
|
}
|
|
}
|
|
@@ -2866,11 +2924,14 @@ int qed_hw_prepare(struct qed_dev *cdev,
|
|
u8 __iomem *addr;
|
|
u8 __iomem *addr;
|
|
|
|
|
|
/* adjust bar offset for second engine */
|
|
/* adjust bar offset for second engine */
|
|
- addr = cdev->regview + qed_hw_bar_size(p_hwfn, BAR_ID_0) / 2;
|
|
|
|
|
|
+ addr = cdev->regview +
|
|
|
|
+ qed_hw_bar_size(p_hwfn, p_hwfn->p_main_ptt,
|
|
|
|
+ BAR_ID_0) / 2;
|
|
p_regview = addr;
|
|
p_regview = addr;
|
|
|
|
|
|
- /* adjust doorbell bar offset for second engine */
|
|
|
|
- addr = cdev->doorbells + qed_hw_bar_size(p_hwfn, BAR_ID_1) / 2;
|
|
|
|
|
|
+ addr = cdev->doorbells +
|
|
|
|
+ qed_hw_bar_size(p_hwfn, p_hwfn->p_main_ptt,
|
|
|
|
+ BAR_ID_1) / 2;
|
|
p_doorbell = addr;
|
|
p_doorbell = addr;
|
|
|
|
|
|
/* prepare second hw function */
|
|
/* prepare second hw function */
|