summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/chelsio
diff options
context:
space:
mode:
authorVarun Prakash <varun@chelsio.com>2019-06-10 16:06:34 +0300
committerDavid S. Miller <davem@davemloft.net>2019-06-10 19:20:23 +0300
commita248384e6420ebda63f788d33fac1c0a081e57a8 (patch)
treea9c39190e749e184fcda98d85f54777bfee9a980 /drivers/net/ethernet/chelsio
parentba217a44f815ae06226461ab74a9df09b35e5a5f (diff)
downloadlinux-a248384e6420ebda63f788d33fac1c0a081e57a8.tar.xz
cxgb4/libcxgb/cxgb4i/cxgbit: enable eDRAM page pods for iSCSI
Page pods are used for direct data placement, this patch enables eDRAM page pods if firmware supports this feature. Signed-off-by: Varun Prakash <varun@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/chelsio')
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c57
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h3
-rw-r--r--drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c47
-rw-r--r--drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.h7
5 files changed, 104 insertions, 11 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index cd957a1eea45..54908002c786 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -782,6 +782,40 @@ static void free_msix_queue_irqs(struct adapter *adap)
}
}
+static int setup_ppod_edram(struct adapter *adap)
+{
+ unsigned int param, val;
+ int ret;
+
+ /* Driver sends FW_PARAMS_PARAM_DEV_PPOD_EDRAM read command to check
+ * if firmware supports ppod edram feature or not. If firmware
+ * returns 1, then driver can enable this feature by sending
+ * FW_PARAMS_PARAM_DEV_PPOD_EDRAM write command with value 1 to
+ * enable ppod edram feature.
+ */
+ param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
+ FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_PPOD_EDRAM));
+
+ ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, &param, &val);
+ if (ret < 0) {
+ dev_warn(adap->pdev_dev,
+ "querying PPOD_EDRAM support failed: %d\n",
+ ret);
+ return -1;
+ }
+
+ if (val != 1)
+ return -1;
+
+ ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1, &param, &val);
+ if (ret < 0) {
+ dev_err(adap->pdev_dev,
+ "setting PPOD_EDRAM failed: %d\n", ret);
+ return -1;
+ }
+ return 0;
+}
+
/**
* cxgb4_write_rss - write the RSS table for a given port
* @pi: the port
@@ -4166,6 +4200,13 @@ static int adap_init0_config(struct adapter *adapter, int reset)
dev_err(adapter->pdev_dev,
"HMA configuration failed with error %d\n", ret);
+ if (is_t6(adapter->params.chip)) {
+ ret = setup_ppod_edram(adapter);
+ if (!ret)
+ dev_info(adapter->pdev_dev, "Successfully enabled "
+ "ppod edram feature\n");
+ }
+
/*
* And finally tell the firmware to initialize itself using the
* parameters from the Configuration File.
@@ -4789,6 +4830,22 @@ static int adap_init0(struct adapter *adap)
goto bye;
adap->vres.iscsi.start = val[0];
adap->vres.iscsi.size = val[1] - val[0] + 1;
+ if (is_t6(adap->params.chip)) {
+ params[0] = FW_PARAM_PFVF(PPOD_EDRAM_START);
+ params[1] = FW_PARAM_PFVF(PPOD_EDRAM_END);
+ ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2,
+ params, val);
+ if (!ret) {
+ adap->vres.ppod_edram.start = val[0];
+ adap->vres.ppod_edram.size =
+ val[1] - val[0] + 1;
+
+ dev_info(adap->pdev_dev,
+ "ppod edram start 0x%x end 0x%x size 0x%x\n",
+ val[0], val[1],
+ adap->vres.ppod_edram.size);
+ }
+ }
/* LIO target and cxgb4i initiaitor */
adap->num_ofld_uld += 2;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 42ae28d651e7..cee582e36134 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -292,6 +292,7 @@ struct cxgb4_virt_res { /* virtualized HW resources */
struct cxgb4_range ocq;
struct cxgb4_range key;
unsigned int ncrypto_fc;
+ struct cxgb4_range ppod_edram;
};
struct chcr_stats_debug {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
index 0be4ce520352..65313f6b5704 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
@@ -1270,6 +1270,7 @@ enum fw_params_param_dev {
FW_PARAMS_PARAM_DEV_TPCHMAP = 0x1F,
FW_PARAMS_PARAM_DEV_HMA_SIZE = 0x20,
FW_PARAMS_PARAM_DEV_RDMA_WRITE_WITH_IMM = 0x21,
+ FW_PARAMS_PARAM_DEV_PPOD_EDRAM = 0x23,
FW_PARAMS_PARAM_DEV_RI_WRITE_CMPL_WR = 0x24,
FW_PARAMS_PARAM_DEV_OPAQUE_VIID_SMT_EXTN = 0x27,
FW_PARAMS_PARAM_DEV_HASHFILTER_WITH_OFLD = 0x28,
@@ -1332,6 +1333,8 @@ enum fw_params_param_pfvf {
FW_PARAMS_PARAM_PFVF_RAWF_END = 0x37,
FW_PARAMS_PARAM_PFVF_NCRYPTO_LOOKASIDE = 0x39,
FW_PARAMS_PARAM_PFVF_PORT_CAPS32 = 0x3A,
+ FW_PARAMS_PARAM_PFVF_PPOD_EDRAM_START = 0x3B,
+ FW_PARAMS_PARAM_PFVF_PPOD_EDRAM_END = 0x3C,
FW_PARAMS_PARAM_PFVF_LINK_STATE = 0x40,
};
diff --git a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c
index e2919005ead3..21034536c9c5 100644
--- a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c
+++ b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.c
@@ -123,6 +123,9 @@ static int ppm_get_cpu_entries(struct cxgbi_ppm *ppm, unsigned int count,
unsigned int cpu;
int i;
+ if (!ppm->pool)
+ return -EINVAL;
+
cpu = get_cpu();
pool = per_cpu_ptr(ppm->pool, cpu);
spin_lock_bh(&pool->lock);
@@ -169,7 +172,9 @@ static int ppm_get_entries(struct cxgbi_ppm *ppm, unsigned int count,
}
ppm->next = i + count;
- if (ppm->next >= ppm->bmap_index_max)
+ if (ppm->max_index_in_edram && (ppm->next >= ppm->max_index_in_edram))
+ ppm->next = 0;
+ else if (ppm->next >= ppm->bmap_index_max)
ppm->next = 0;
spin_unlock_bh(&ppm->map_lock);
@@ -382,18 +387,36 @@ static struct cxgbi_ppm_pool *ppm_alloc_cpu_pool(unsigned int *total,
int cxgbi_ppm_init(void **ppm_pp, struct net_device *ndev,
struct pci_dev *pdev, void *lldev,
- struct cxgbi_tag_format *tformat,
- unsigned int ppmax,
- unsigned int llimit,
- unsigned int start,
- unsigned int reserve_factor)
+ struct cxgbi_tag_format *tformat, unsigned int iscsi_size,
+ unsigned int llimit, unsigned int start,
+ unsigned int reserve_factor, unsigned int iscsi_edram_start,
+ unsigned int iscsi_edram_size)
{
struct cxgbi_ppm *ppm = (struct cxgbi_ppm *)(*ppm_pp);
struct cxgbi_ppm_pool *pool = NULL;
- unsigned int ppmax_pool = 0;
unsigned int pool_index_max = 0;
- unsigned int alloc_sz;
+ unsigned int ppmax_pool = 0;
unsigned int ppod_bmap_size;
+ unsigned int alloc_sz;
+ unsigned int ppmax;
+
+ if (!iscsi_edram_start)
+ iscsi_edram_size = 0;
+
+ if (iscsi_edram_size &&
+ ((iscsi_edram_start + iscsi_edram_size) != start)) {
+ pr_err("iscsi ppod region not contiguous: EDRAM start 0x%x "
+ "size 0x%x DDR start 0x%x\n",
+ iscsi_edram_start, iscsi_edram_size, start);
+ return -EINVAL;
+ }
+
+ if (iscsi_edram_size) {
+ reserve_factor = 0;
+ start = iscsi_edram_start;
+ }
+
+ ppmax = (iscsi_edram_size + iscsi_size) >> PPOD_SIZE_SHIFT;
if (ppm) {
pr_info("ippm: %s, ppm 0x%p,0x%p already initialized, %u/%u.\n",
@@ -434,6 +457,14 @@ int cxgbi_ppm_init(void **ppm_pp, struct net_device *ndev,
__func__, ppmax, ppmax_pool, ppod_bmap_size, start,
end);
}
+ if (iscsi_edram_size) {
+ unsigned int first_ddr_idx =
+ iscsi_edram_size >> PPOD_SIZE_SHIFT;
+
+ ppm->max_index_in_edram = first_ddr_idx - 1;
+ bitmap_set(ppm->ppod_bmap, first_ddr_idx, 1);
+ pr_debug("reserved %u ppod in bitmap\n", first_ddr_idx);
+ }
spin_lock_init(&ppm->map_lock);
kref_init(&ppm->refcnt);
diff --git a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.h b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.h
index a91ad766cef0..7b02c200dd1e 100644
--- a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.h
+++ b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_ppm.h
@@ -143,6 +143,7 @@ struct cxgbi_ppm {
spinlock_t map_lock; /* ppm map lock */
unsigned int bmap_index_max;
unsigned int next;
+ unsigned int max_index_in_edram;
unsigned long *ppod_bmap;
struct cxgbi_ppod_data ppod_data[0];
};
@@ -324,9 +325,9 @@ int cxgbi_ppm_ppods_reserve(struct cxgbi_ppm *, unsigned short nr_pages,
unsigned long caller_data);
int cxgbi_ppm_init(void **ppm_pp, struct net_device *, struct pci_dev *,
void *lldev, struct cxgbi_tag_format *,
- unsigned int ppmax, unsigned int llimit,
- unsigned int start,
- unsigned int reserve_factor);
+ unsigned int iscsi_size, unsigned int llimit,
+ unsigned int start, unsigned int reserve_factor,
+ unsigned int edram_start, unsigned int edram_size);
int cxgbi_ppm_release(struct cxgbi_ppm *ppm);
void cxgbi_tagmask_check(unsigned int tagmask, struct cxgbi_tag_format *);
unsigned int cxgbi_tagmask_set(unsigned int ppmax);