mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-17 12:56:55 +07:00
cxgb4vf: Add and initialize some sge params for VF driver
Add sge_vf_eq_qpp and sge_vf_iq_qpp to (struct sge_params), initialize sge_queues_per_page and sge_vf_qpp in t4vf_get_sge_params(), add new t4vf_prep_adapter() which initializes basic adapter parameters. Grab both SGE_EGRESS_QUEUES_PER_PAGE_VF and SGE_INGRESS_QUEUES_PER_PAGE_VF for VF Drivers since we need both to calculate the User Doorbell area offsets for Egress and Ingress Queues. Based on original work by Casey Leedom <leedom@chelsio.com> Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
88b17b6a22
commit
e0a8b34a9c
@ -164,8 +164,13 @@
|
||||
#define HOSTPAGESIZEPF0(x) ((x) << HOSTPAGESIZEPF0_SHIFT)
|
||||
|
||||
#define SGE_EGRESS_QUEUES_PER_PAGE_PF 0x1010
|
||||
#define QUEUESPERPAGEPF0_MASK 0x0000000fU
|
||||
#define QUEUESPERPAGEPF0_GET(x) ((x) & QUEUESPERPAGEPF0_MASK)
|
||||
#define SGE_EGRESS_QUEUES_PER_PAGE_VF_A 0x1014
|
||||
|
||||
#define QUEUESPERPAGEPF1_S 4
|
||||
|
||||
#define QUEUESPERPAGEPF0_S 0
|
||||
#define QUEUESPERPAGEPF0_MASK 0x0000000fU
|
||||
#define QUEUESPERPAGEPF0_GET(x) ((x) & QUEUESPERPAGEPF0_MASK)
|
||||
|
||||
#define QUEUESPERPAGEPF0 0
|
||||
#define QUEUESPERPAGEPF1 4
|
||||
@ -323,6 +328,7 @@
|
||||
#define SGE_DEBUG_DATA_LOW_INDEX_3 0x12cc
|
||||
#define SGE_DEBUG_DATA_HIGH_INDEX_10 0x12a8
|
||||
#define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4
|
||||
#define SGE_INGRESS_QUEUES_PER_PAGE_VF_A 0x10f8
|
||||
|
||||
#define S_HP_INT_THRESH 28
|
||||
#define M_HP_INT_THRESH 0xfU
|
||||
|
@ -2594,6 +2594,27 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
|
||||
goto err_free_adapter;
|
||||
}
|
||||
|
||||
/* Wait for the device to become ready before proceeding ...
|
||||
*/
|
||||
err = t4vf_prep_adapter(adapter);
|
||||
if (err) {
|
||||
dev_err(adapter->pdev_dev, "device didn't become ready:"
|
||||
" err=%d\n", err);
|
||||
goto err_unmap_bar0;
|
||||
}
|
||||
|
||||
/* For T5 and later we want to use the new BAR-based User Doorbells,
|
||||
* so we need to map BAR2 here ...
|
||||
*/
|
||||
if (!is_t4(adapter->params.chip)) {
|
||||
adapter->bar2 = ioremap_wc(pci_resource_start(pdev, 2),
|
||||
pci_resource_len(pdev, 2));
|
||||
if (!adapter->bar2) {
|
||||
dev_err(adapter->pdev_dev, "cannot map BAR2 doorbells\n");
|
||||
err = -ENOMEM;
|
||||
goto err_unmap_bar0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Initialize adapter level features.
|
||||
*/
|
||||
@ -2786,6 +2807,10 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
err_unmap_bar:
|
||||
if (!is_t4(adapter->params.chip))
|
||||
iounmap(adapter->bar2);
|
||||
|
||||
err_unmap_bar0:
|
||||
iounmap(adapter->regs);
|
||||
|
||||
err_free_adapter:
|
||||
@ -2856,6 +2881,8 @@ static void cxgb4vf_pci_remove(struct pci_dev *pdev)
|
||||
free_netdev(netdev);
|
||||
}
|
||||
iounmap(adapter->regs);
|
||||
if (!is_t4(adapter->params.chip))
|
||||
iounmap(adapter->bar2);
|
||||
kfree(adapter);
|
||||
}
|
||||
|
||||
|
@ -135,9 +135,11 @@ struct dev_params {
|
||||
struct sge_params {
|
||||
u32 sge_control; /* padding, boundaries, lengths, etc. */
|
||||
u32 sge_control2; /* T5: more of the same */
|
||||
u32 sge_host_page_size; /* RDMA page sizes */
|
||||
u32 sge_queues_per_page; /* RDMA queues/page */
|
||||
u32 sge_user_mode_limits; /* limits for BAR2 user mode accesses */
|
||||
u32 sge_host_page_size; /* PF0-7 page sizes */
|
||||
u32 sge_egress_queues_per_page; /* PF0-7 egress queues/page */
|
||||
u32 sge_ingress_queues_per_page;/* PF0-7 ingress queues/page */
|
||||
u32 sge_vf_eq_qpp; /* egress queues/page for our VF */
|
||||
u32 sge_vf_iq_qpp; /* ingress queues/page for our VF */
|
||||
u32 sge_fl_buffer_size[16]; /* free list buffer sizes */
|
||||
u32 sge_ingress_rx_threshold; /* RX counter interrupt threshold[4] */
|
||||
u32 sge_congestion_control; /* congestion thresholds, etc. */
|
||||
@ -267,6 +269,8 @@ static inline int t4vf_wr_mbox_ns(struct adapter *adapter, const void *cmd,
|
||||
return t4vf_wr_mbox_core(adapter, cmd, size, rpl, false);
|
||||
}
|
||||
|
||||
#define CHELSIO_PCI_ID_VER(dev_id) ((dev_id) >> 12)
|
||||
|
||||
static inline int is_t4(enum chip_type chip)
|
||||
{
|
||||
return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T4;
|
||||
@ -309,5 +313,6 @@ int t4vf_iq_free(struct adapter *, unsigned int, unsigned int, unsigned int,
|
||||
int t4vf_eth_eq_free(struct adapter *, unsigned int);
|
||||
|
||||
int t4vf_handle_fw_rpl(struct adapter *, const __be64 *);
|
||||
int t4vf_prep_adapter(struct adapter *);
|
||||
|
||||
#endif /* __T4VF_COMMON_H__ */
|
||||
|
@ -501,6 +501,48 @@ int t4vf_get_sge_params(struct adapter *adapter)
|
||||
sge_params->sge_ingress_rx_threshold = vals[0];
|
||||
sge_params->sge_congestion_control = vals[1];
|
||||
|
||||
/* For T5 and later we want to use the new BAR2 Doorbells.
|
||||
* Unfortunately, older firmware didn't allow the this register to be
|
||||
* read.
|
||||
*/
|
||||
if (!is_t4(adapter->params.chip)) {
|
||||
u32 whoami;
|
||||
unsigned int pf, s_qpp;
|
||||
|
||||
params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
|
||||
FW_PARAMS_PARAM_XYZ_V(
|
||||
SGE_EGRESS_QUEUES_PER_PAGE_VF_A));
|
||||
params[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) |
|
||||
FW_PARAMS_PARAM_XYZ_V(
|
||||
SGE_INGRESS_QUEUES_PER_PAGE_VF_A));
|
||||
v = t4vf_query_params(adapter, 2, params, vals);
|
||||
if (v != FW_SUCCESS) {
|
||||
dev_warn(adapter->pdev_dev,
|
||||
"Unable to get VF SGE Queues/Page; "
|
||||
"probably old firmware.\n");
|
||||
return v;
|
||||
}
|
||||
sge_params->sge_egress_queues_per_page = vals[0];
|
||||
sge_params->sge_ingress_queues_per_page = vals[1];
|
||||
|
||||
/* We need the Queues/Page for our VF. This is based on the
|
||||
* PF from which we're instantiated and is indexed in the
|
||||
* register we just read. Do it once here so other code in
|
||||
* the driver can just use it.
|
||||
*/
|
||||
whoami = t4_read_reg(adapter,
|
||||
T4VF_PL_BASE_ADDR + A_PL_VF_WHOAMI);
|
||||
pf = SOURCEPF_GET(whoami);
|
||||
s_qpp = (QUEUESPERPAGEPF0_S +
|
||||
(QUEUESPERPAGEPF1_S - QUEUESPERPAGEPF0_S) * pf);
|
||||
sge_params->sge_vf_eq_qpp =
|
||||
((sge_params->sge_egress_queues_per_page >> s_qpp)
|
||||
& QUEUESPERPAGEPF0_MASK);
|
||||
sge_params->sge_vf_iq_qpp =
|
||||
((sge_params->sge_ingress_queues_per_page >> s_qpp)
|
||||
& QUEUESPERPAGEPF0_MASK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1420,3 +1462,38 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
int t4vf_prep_adapter(struct adapter *adapter)
|
||||
{
|
||||
int err;
|
||||
unsigned int chipid;
|
||||
|
||||
/* Wait for the device to become ready before proceeding ...
|
||||
*/
|
||||
err = t4vf_wait_dev_ready(adapter);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Default port and clock for debugging in case we can't reach
|
||||
* firmware.
|
||||
*/
|
||||
adapter->params.nports = 1;
|
||||
adapter->params.vfres.pmask = 1;
|
||||
adapter->params.vpd.cclk = 50000;
|
||||
|
||||
adapter->params.chip = 0;
|
||||
switch (CHELSIO_PCI_ID_VER(adapter->pdev->device)) {
|
||||
case CHELSIO_T4:
|
||||
adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T4, 0);
|
||||
break;
|
||||
|
||||
case CHELSIO_T5:
|
||||
chipid = G_REV(t4_read_reg(adapter, A_PL_VF_REV));
|
||||
adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, chipid);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user