|
@@ -224,6 +224,17 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
|
|
CH_DEVICE(0x4008, -1),
|
|
CH_DEVICE(0x4008, -1),
|
|
CH_DEVICE(0x4009, -1),
|
|
CH_DEVICE(0x4009, -1),
|
|
CH_DEVICE(0x400a, -1),
|
|
CH_DEVICE(0x400a, -1),
|
|
|
|
+ CH_DEVICE(0x400d, -1),
|
|
|
|
+ CH_DEVICE(0x400e, -1),
|
|
|
|
+ CH_DEVICE(0x4080, -1),
|
|
|
|
+ CH_DEVICE(0x4081, -1),
|
|
|
|
+ CH_DEVICE(0x4082, -1),
|
|
|
|
+ CH_DEVICE(0x4083, -1),
|
|
|
|
+ CH_DEVICE(0x4084, -1),
|
|
|
|
+ CH_DEVICE(0x4085, -1),
|
|
|
|
+ CH_DEVICE(0x4086, -1),
|
|
|
|
+ CH_DEVICE(0x4087, -1),
|
|
|
|
+ CH_DEVICE(0x4088, -1),
|
|
CH_DEVICE(0x4401, 4),
|
|
CH_DEVICE(0x4401, 4),
|
|
CH_DEVICE(0x4402, 4),
|
|
CH_DEVICE(0x4402, 4),
|
|
CH_DEVICE(0x4403, 4),
|
|
CH_DEVICE(0x4403, 4),
|
|
@@ -236,6 +247,15 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
|
|
CH_DEVICE(0x440a, 4),
|
|
CH_DEVICE(0x440a, 4),
|
|
CH_DEVICE(0x440d, 4),
|
|
CH_DEVICE(0x440d, 4),
|
|
CH_DEVICE(0x440e, 4),
|
|
CH_DEVICE(0x440e, 4),
|
|
|
|
+ CH_DEVICE(0x4480, 4),
|
|
|
|
+ CH_DEVICE(0x4481, 4),
|
|
|
|
+ CH_DEVICE(0x4482, 4),
|
|
|
|
+ CH_DEVICE(0x4483, 4),
|
|
|
|
+ CH_DEVICE(0x4484, 4),
|
|
|
|
+ CH_DEVICE(0x4485, 4),
|
|
|
|
+ CH_DEVICE(0x4486, 4),
|
|
|
|
+ CH_DEVICE(0x4487, 4),
|
|
|
|
+ CH_DEVICE(0x4488, 4),
|
|
CH_DEVICE(0x5001, 4),
|
|
CH_DEVICE(0x5001, 4),
|
|
CH_DEVICE(0x5002, 4),
|
|
CH_DEVICE(0x5002, 4),
|
|
CH_DEVICE(0x5003, 4),
|
|
CH_DEVICE(0x5003, 4),
|
|
@@ -3066,6 +3086,8 @@ static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
|
|
loff_t avail = file_inode(file)->i_size;
|
|
loff_t avail = file_inode(file)->i_size;
|
|
unsigned int mem = (uintptr_t)file->private_data & 3;
|
|
unsigned int mem = (uintptr_t)file->private_data & 3;
|
|
struct adapter *adap = file->private_data - mem;
|
|
struct adapter *adap = file->private_data - mem;
|
|
|
|
+ __be32 *data;
|
|
|
|
+ int ret;
|
|
|
|
|
|
if (pos < 0)
|
|
if (pos < 0)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
@@ -3074,29 +3096,24 @@ static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
|
|
if (count > avail - pos)
|
|
if (count > avail - pos)
|
|
count = avail - pos;
|
|
count = avail - pos;
|
|
|
|
|
|
- while (count) {
|
|
|
|
- size_t len;
|
|
|
|
- int ret, ofst;
|
|
|
|
- __be32 data[16];
|
|
|
|
|
|
+ data = t4_alloc_mem(count);
|
|
|
|
+ if (!data)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
- if ((mem == MEM_MC) || (mem == MEM_MC1))
|
|
|
|
- ret = t4_mc_read(adap, mem % MEM_MC, pos, data, NULL);
|
|
|
|
- else
|
|
|
|
- ret = t4_edc_read(adap, mem, pos, data, NULL);
|
|
|
|
- if (ret)
|
|
|
|
- return ret;
|
|
|
|
|
|
+ spin_lock(&adap->win0_lock);
|
|
|
|
+ ret = t4_memory_rw(adap, 0, mem, pos, count, data, T4_MEMORY_READ);
|
|
|
|
+ spin_unlock(&adap->win0_lock);
|
|
|
|
+ if (ret) {
|
|
|
|
+ t4_free_mem(data);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ ret = copy_to_user(buf, data, count);
|
|
|
|
|
|
- ofst = pos % sizeof(data);
|
|
|
|
- len = min(count, sizeof(data) - ofst);
|
|
|
|
- if (copy_to_user(buf, (u8 *)data + ofst, len))
|
|
|
|
- return -EFAULT;
|
|
|
|
|
|
+ t4_free_mem(data);
|
|
|
|
+ if (ret)
|
|
|
|
+ return -EFAULT;
|
|
|
|
|
|
- buf += len;
|
|
|
|
- pos += len;
|
|
|
|
- count -= len;
|
|
|
|
- }
|
|
|
|
- count = pos - *ppos;
|
|
|
|
- *ppos = pos;
|
|
|
|
|
|
+ *ppos = pos + count;
|
|
return count;
|
|
return count;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3757,7 +3774,11 @@ static int read_eq_indices(struct adapter *adap, u16 qid, u16 *pidx, u16 *cidx)
|
|
__be64 indices;
|
|
__be64 indices;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- ret = t4_mem_win_read_len(adap, addr, (__be32 *)&indices, 8);
|
|
|
|
|
|
+ spin_lock(&adap->win0_lock);
|
|
|
|
+ ret = t4_memory_rw(adap, 0, MEM_EDC0, addr,
|
|
|
|
+ sizeof(indices), (__be32 *)&indices,
|
|
|
|
+ T4_MEMORY_READ);
|
|
|
|
+ spin_unlock(&adap->win0_lock);
|
|
if (!ret) {
|
|
if (!ret) {
|
|
*cidx = (be64_to_cpu(indices) >> 25) & 0xffff;
|
|
*cidx = (be64_to_cpu(indices) >> 25) & 0xffff;
|
|
*pidx = (be64_to_cpu(indices) >> 9) & 0xffff;
|
|
*pidx = (be64_to_cpu(indices) >> 9) & 0xffff;
|
|
@@ -4053,6 +4074,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
|
|
unsigned short i;
|
|
unsigned short i;
|
|
|
|
|
|
lli.pdev = adap->pdev;
|
|
lli.pdev = adap->pdev;
|
|
|
|
+ lli.pf = adap->fn;
|
|
lli.l2t = adap->l2t;
|
|
lli.l2t = adap->l2t;
|
|
lli.tids = &adap->tids;
|
|
lli.tids = &adap->tids;
|
|
lli.ports = adap->port;
|
|
lli.ports = adap->port;
|
|
@@ -4772,20 +4794,75 @@ void t4_fatal_err(struct adapter *adap)
|
|
dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n");
|
|
dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Return the specified PCI-E Configuration Space register from our Physical
|
|
|
|
+ * Function. We try first via a Firmware LDST Command since we prefer to let
|
|
|
|
+ * the firmware own all of these registers, but if that fails we go for it
|
|
|
|
+ * directly ourselves.
|
|
|
|
+ */
|
|
|
|
+static u32 t4_read_pcie_cfg4(struct adapter *adap, int reg)
|
|
|
|
+{
|
|
|
|
+ struct fw_ldst_cmd ldst_cmd;
|
|
|
|
+ u32 val;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ /* Construct and send the Firmware LDST Command to retrieve the
|
|
|
|
+ * specified PCI-E Configuration Space register.
|
|
|
|
+ */
|
|
|
|
+ memset(&ldst_cmd, 0, sizeof(ldst_cmd));
|
|
|
|
+ ldst_cmd.op_to_addrspace =
|
|
|
|
+ htonl(FW_CMD_OP(FW_LDST_CMD) |
|
|
|
|
+ FW_CMD_REQUEST |
|
|
|
|
+ FW_CMD_READ |
|
|
|
|
+ FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_PCIE));
|
|
|
|
+ ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd));
|
|
|
|
+ ldst_cmd.u.pcie.select_naccess = FW_LDST_CMD_NACCESS(1);
|
|
|
|
+ ldst_cmd.u.pcie.ctrl_to_fn =
|
|
|
|
+ (FW_LDST_CMD_LC | FW_LDST_CMD_FN(adap->fn));
|
|
|
|
+ ldst_cmd.u.pcie.r = reg;
|
|
|
|
+ ret = t4_wr_mbox(adap, adap->mbox, &ldst_cmd, sizeof(ldst_cmd),
|
|
|
|
+ &ldst_cmd);
|
|
|
|
+
|
|
|
|
+ /* If the LDST Command suucceeded, exctract the returned register
|
|
|
|
+ * value. Otherwise read it directly ourself.
|
|
|
|
+ */
|
|
|
|
+ if (ret == 0)
|
|
|
|
+ val = ntohl(ldst_cmd.u.pcie.data[0]);
|
|
|
|
+ else
|
|
|
|
+ t4_hw_pci_read_cfg4(adap, reg, &val);
|
|
|
|
+
|
|
|
|
+ return val;
|
|
|
|
+}
|
|
|
|
+
|
|
static void setup_memwin(struct adapter *adap)
|
|
static void setup_memwin(struct adapter *adap)
|
|
{
|
|
{
|
|
- u32 bar0, mem_win0_base, mem_win1_base, mem_win2_base;
|
|
|
|
|
|
+ u32 mem_win0_base, mem_win1_base, mem_win2_base, mem_win2_aperture;
|
|
|
|
|
|
- bar0 = pci_resource_start(adap->pdev, 0); /* truncation intentional */
|
|
|
|
if (is_t4(adap->params.chip)) {
|
|
if (is_t4(adap->params.chip)) {
|
|
|
|
+ u32 bar0;
|
|
|
|
+
|
|
|
|
+ /* Truncation intentional: we only read the bottom 32-bits of
|
|
|
|
+ * the 64-bit BAR0/BAR1 ... We use the hardware backdoor
|
|
|
|
+ * mechanism to read BAR0 instead of using
|
|
|
|
+ * pci_resource_start() because we could be operating from
|
|
|
|
+ * within a Virtual Machine which is trapping our accesses to
|
|
|
|
+ * our Configuration Space and we need to set up the PCI-E
|
|
|
|
+ * Memory Window decoders with the actual addresses which will
|
|
|
|
+ * be coming across the PCI-E link.
|
|
|
|
+ */
|
|
|
|
+ bar0 = t4_read_pcie_cfg4(adap, PCI_BASE_ADDRESS_0);
|
|
|
|
+ bar0 &= PCI_BASE_ADDRESS_MEM_MASK;
|
|
|
|
+ adap->t4_bar0 = bar0;
|
|
|
|
+
|
|
mem_win0_base = bar0 + MEMWIN0_BASE;
|
|
mem_win0_base = bar0 + MEMWIN0_BASE;
|
|
mem_win1_base = bar0 + MEMWIN1_BASE;
|
|
mem_win1_base = bar0 + MEMWIN1_BASE;
|
|
mem_win2_base = bar0 + MEMWIN2_BASE;
|
|
mem_win2_base = bar0 + MEMWIN2_BASE;
|
|
|
|
+ mem_win2_aperture = MEMWIN2_APERTURE;
|
|
} else {
|
|
} else {
|
|
/* For T5, only relative offset inside the PCIe BAR is passed */
|
|
/* For T5, only relative offset inside the PCIe BAR is passed */
|
|
mem_win0_base = MEMWIN0_BASE;
|
|
mem_win0_base = MEMWIN0_BASE;
|
|
- mem_win1_base = MEMWIN1_BASE_T5;
|
|
|
|
|
|
+ mem_win1_base = MEMWIN1_BASE;
|
|
mem_win2_base = MEMWIN2_BASE_T5;
|
|
mem_win2_base = MEMWIN2_BASE_T5;
|
|
|
|
+ mem_win2_aperture = MEMWIN2_APERTURE_T5;
|
|
}
|
|
}
|
|
t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0),
|
|
t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0),
|
|
mem_win0_base | BIR(0) |
|
|
mem_win0_base | BIR(0) |
|
|
@@ -4795,16 +4872,19 @@ static void setup_memwin(struct adapter *adap)
|
|
WINDOW(ilog2(MEMWIN1_APERTURE) - 10));
|
|
WINDOW(ilog2(MEMWIN1_APERTURE) - 10));
|
|
t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2),
|
|
t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2),
|
|
mem_win2_base | BIR(0) |
|
|
mem_win2_base | BIR(0) |
|
|
- WINDOW(ilog2(MEMWIN2_APERTURE) - 10));
|
|
|
|
|
|
+ WINDOW(ilog2(mem_win2_aperture) - 10));
|
|
|
|
+ t4_read_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2));
|
|
}
|
|
}
|
|
|
|
|
|
static void setup_memwin_rdma(struct adapter *adap)
|
|
static void setup_memwin_rdma(struct adapter *adap)
|
|
{
|
|
{
|
|
if (adap->vres.ocq.size) {
|
|
if (adap->vres.ocq.size) {
|
|
- unsigned int start, sz_kb;
|
|
|
|
|
|
+ u32 start;
|
|
|
|
+ unsigned int sz_kb;
|
|
|
|
|
|
- start = pci_resource_start(adap->pdev, 2) +
|
|
|
|
- OCQ_WIN_OFFSET(adap->pdev, &adap->vres);
|
|
|
|
|
|
+ start = t4_read_pcie_cfg4(adap, PCI_BASE_ADDRESS_2);
|
|
|
|
+ start &= PCI_BASE_ADDRESS_MEM_MASK;
|
|
|
|
+ start += OCQ_WIN_OFFSET(adap->pdev, &adap->vres);
|
|
sz_kb = roundup_pow_of_two(adap->vres.ocq.size) >> 10;
|
|
sz_kb = roundup_pow_of_two(adap->vres.ocq.size) >> 10;
|
|
t4_write_reg(adap,
|
|
t4_write_reg(adap,
|
|
PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 3),
|
|
PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 3),
|
|
@@ -5017,7 +5097,7 @@ static int adap_init0_config(struct adapter *adapter, int reset)
|
|
adapter->fn, 0, 1, params, val);
|
|
adapter->fn, 0, 1, params, val);
|
|
if (ret == 0) {
|
|
if (ret == 0) {
|
|
/*
|
|
/*
|
|
- * For t4_memory_write() below addresses and
|
|
|
|
|
|
+ * For t4_memory_rw() below addresses and
|
|
* sizes have to be in terms of multiples of 4
|
|
* sizes have to be in terms of multiples of 4
|
|
* bytes. So, if the Configuration File isn't
|
|
* bytes. So, if the Configuration File isn't
|
|
* a multiple of 4 bytes in length we'll have
|
|
* a multiple of 4 bytes in length we'll have
|
|
@@ -5033,8 +5113,9 @@ static int adap_init0_config(struct adapter *adapter, int reset)
|
|
mtype = FW_PARAMS_PARAM_Y_GET(val[0]);
|
|
mtype = FW_PARAMS_PARAM_Y_GET(val[0]);
|
|
maddr = FW_PARAMS_PARAM_Z_GET(val[0]) << 16;
|
|
maddr = FW_PARAMS_PARAM_Z_GET(val[0]) << 16;
|
|
|
|
|
|
- ret = t4_memory_write(adapter, mtype, maddr,
|
|
|
|
- size, data);
|
|
|
|
|
|
+ spin_lock(&adapter->win0_lock);
|
|
|
|
+ ret = t4_memory_rw(adapter, 0, mtype, maddr,
|
|
|
|
+ size, data, T4_MEMORY_WRITE);
|
|
if (ret == 0 && resid != 0) {
|
|
if (ret == 0 && resid != 0) {
|
|
union {
|
|
union {
|
|
__be32 word;
|
|
__be32 word;
|
|
@@ -5045,10 +5126,12 @@ static int adap_init0_config(struct adapter *adapter, int reset)
|
|
last.word = data[size >> 2];
|
|
last.word = data[size >> 2];
|
|
for (i = resid; i < 4; i++)
|
|
for (i = resid; i < 4; i++)
|
|
last.buf[i] = 0;
|
|
last.buf[i] = 0;
|
|
- ret = t4_memory_write(adapter, mtype,
|
|
|
|
- maddr + size,
|
|
|
|
- 4, &last.word);
|
|
|
|
|
|
+ ret = t4_memory_rw(adapter, 0, mtype,
|
|
|
|
+ maddr + size,
|
|
|
|
+ 4, &last.word,
|
|
|
|
+ T4_MEMORY_WRITE);
|
|
}
|
|
}
|
|
|
|
+ spin_unlock(&adapter->win0_lock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -6294,13 +6377,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
- /* We control everything through one PF */
|
|
|
|
- func = PCI_FUNC(pdev->devfn);
|
|
|
|
- if (func != ent->driver_data) {
|
|
|
|
- pci_save_state(pdev); /* to restore SR-IOV later */
|
|
|
|
- goto sriov;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
err = pci_enable_device(pdev);
|
|
err = pci_enable_device(pdev);
|
|
if (err) {
|
|
if (err) {
|
|
dev_err(&pdev->dev, "cannot enable PCI device\n");
|
|
dev_err(&pdev->dev, "cannot enable PCI device\n");
|
|
@@ -6344,6 +6420,15 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
goto out_free_adapter;
|
|
goto out_free_adapter;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* We control everything through one PF */
|
|
|
|
+ func = SOURCEPF_GET(readl(adapter->regs + PL_WHOAMI));
|
|
|
|
+ if ((pdev->device == 0xa000 && func != 0) ||
|
|
|
|
+ func != ent->driver_data) {
|
|
|
|
+ pci_save_state(pdev); /* to restore SR-IOV later */
|
|
|
|
+ err = 0;
|
|
|
|
+ goto out_unmap_bar0;
|
|
|
|
+ }
|
|
|
|
+
|
|
adapter->pdev = pdev;
|
|
adapter->pdev = pdev;
|
|
adapter->pdev_dev = &pdev->dev;
|
|
adapter->pdev_dev = &pdev->dev;
|
|
adapter->mbox = func;
|
|
adapter->mbox = func;
|
|
@@ -6507,7 +6592,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
if (is_offload(adapter))
|
|
if (is_offload(adapter))
|
|
attach_ulds(adapter);
|
|
attach_ulds(adapter);
|
|
|
|
|
|
-sriov:
|
|
|
|
#ifdef CONFIG_PCI_IOV
|
|
#ifdef CONFIG_PCI_IOV
|
|
if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
|
|
if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
|
|
if (pci_enable_sriov(pdev, num_vf[func]) == 0)
|
|
if (pci_enable_sriov(pdev, num_vf[func]) == 0)
|