Commit 813f8e29 authored by David S. Miller's avatar David S. Miller

Merge branch 'cxgb4-next'

Hariprasad Shenai says:

====================
cxgb4: Fix for PCI passthrough and some Misc. fixes

This patch series fixes probe failure in VM when PF is exposed through PCI
Passthrough. Adds support to use firmware interface to get BAR0 value.
Replace the backdoor mechanism to access the HW memory with PCIe Window method
which fixes memory I/O. Also adds device ID of few more adapters for cxgb4 and
cxgb4vf driver.

The patches series is created against 'net-next' tree.
And includes patches on cxgb4, cxgb4vf and iw_cxgb4 driver.

Since this patch-series contains mainly cxgb4 related changes, we would like to
request this patch series to get merged via David Miller's 'net-next' tree.

We have included all the maintainers of respective drivers. Kindly review the
change and let us know in case of any review comments.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2eb27a16 dde3aadf
......@@ -465,7 +465,8 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)
16)) | FW_WR_FLOWID(ep->hwtid));
flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN;
flowc->mnemval[0].val = cpu_to_be32(PCI_FUNC(ep->com.dev->rdev.lldi.pdev->devfn) << 8);
flowc->mnemval[0].val = cpu_to_be32(FW_PFVF_CMD_PFN
(ep->com.dev->rdev.lldi.pf));
flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH;
flowc->mnemval[1].val = cpu_to_be32(ep->tx_chan);
flowc->mnemval[2].mnemonic = FW_FLOWC_MNEM_PORT;
......
......@@ -85,7 +85,8 @@ enum {
MEMWIN1_BASE_T5 = 0x52000,
MEMWIN2_APERTURE = 65536,
MEMWIN2_BASE = 0x30000,
MEMWIN2_BASE_T5 = 0x54000,
MEMWIN2_APERTURE_T5 = 131072,
MEMWIN2_BASE_T5 = 0x60000,
};
enum dev_master {
......@@ -608,6 +609,7 @@ struct l2t_data;
struct adapter {
void __iomem *regs;
void __iomem *bar2;
u32 t4_bar0;
struct pci_dev *pdev;
struct device *pdev_dev;
unsigned int mbox;
......@@ -652,6 +654,7 @@ struct adapter {
struct dentry *debugfs_root;
spinlock_t stats_lock;
spinlock_t win0_lock ____cacheline_aligned_in_smp;
};
/* Defined bit width of user definable filter tuples
......@@ -946,6 +949,7 @@ void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
unsigned int data_reg, u32 *vals, unsigned int nregs,
unsigned int start_idx);
void t4_hw_pci_read_cfg4(struct adapter *adapter, int reg, u32 *val);
struct fw_filter_wr;
......@@ -957,8 +961,17 @@ int t4_wait_dev_ready(struct adapter *adap);
int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
struct link_config *lc);
int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port);
int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len,
__be32 *buf);
#define T4_MEMORY_WRITE 0
#define T4_MEMORY_READ 1
int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr, u32 len,
__be32 *buf, int dir);
static inline int t4_memory_write(struct adapter *adap, int mtype, u32 addr,
u32 len, __be32 *buf)
{
return t4_memory_rw(adap, 0, mtype, addr, len, buf, 0);
}
int t4_seeprom_wp(struct adapter *adapter, bool enable);
int get_vpd_params(struct adapter *adapter, struct vpd_params *p);
int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
......@@ -1056,7 +1069,6 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
void t4_db_full(struct adapter *adapter);
void t4_db_dropped(struct adapter *adapter);
int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len);
int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
u32 addr, u32 val);
void t4_sge_decode_idma_state(struct adapter *adapter, int state);
......
......@@ -224,6 +224,17 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
CH_DEVICE(0x4008, -1),
CH_DEVICE(0x4009, -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(0x4402, 4),
CH_DEVICE(0x4403, 4),
......@@ -236,6 +247,15 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
CH_DEVICE(0x440a, 4),
CH_DEVICE(0x440d, 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(0x5002, 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;
unsigned int mem = (uintptr_t)file->private_data & 3;
struct adapter *adap = file->private_data - mem;
__be32 *data;
int ret;
if (pos < 0)
return -EINVAL;
......@@ -3074,29 +3096,24 @@ static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
if (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;
}
......@@ -3757,7 +3774,11 @@ static int read_eq_indices(struct adapter *adap, u16 qid, u16 *pidx, u16 *cidx)
__be64 indices;
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) {
*cidx = (be64_to_cpu(indices) >> 25) & 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;
lli.pdev = adap->pdev;
lli.pf = adap->fn;
lli.l2t = adap->l2t;
lli.tids = &adap->tids;
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");
}
/* 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)
{
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)) {
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_win1_base = bar0 + MEMWIN1_BASE;
mem_win2_base = bar0 + MEMWIN2_BASE;
mem_win2_aperture = MEMWIN2_APERTURE;
} else {
/* For T5, only relative offset inside the PCIe BAR is passed */
mem_win0_base = MEMWIN0_BASE;
mem_win1_base = MEMWIN1_BASE_T5;
mem_win1_base = MEMWIN1_BASE;
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),
mem_win0_base | BIR(0) |
......@@ -4795,16 +4872,19 @@ static void setup_memwin(struct adapter *adap)
WINDOW(ilog2(MEMWIN1_APERTURE) - 10));
t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2),
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)
{
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;
t4_write_reg(adap,
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);
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
* bytes. So, if the Configuration File isn't
* 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]);
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) {
union {
__be32 word;
......@@ -5045,10 +5126,12 @@ static int adap_init0_config(struct adapter *adapter, int reset)
last.word = data[size >> 2];
for (i = resid; i < 4; i++)
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;
}
/* 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);
if (err) {
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;
}
/* 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_dev = &pdev->dev;
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))
attach_ulds(adapter);
sriov:
#ifdef CONFIG_PCI_IOV
if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
if (pci_enable_sriov(pdev, num_vf[func]) == 0)
......
......@@ -253,6 +253,7 @@ struct cxgb4_lld_info {
int dbfifo_int_thresh; /* doorbell fifo int threshold */
unsigned int sge_pktshift; /* Padding between CPL and */
/* packet data */
unsigned int pf; /* Physical Function we're using */
bool enable_fw_ofld_conn; /* Enable connection through fw */
/* WR */
bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */
......
This diff is collapsed.
......@@ -387,6 +387,8 @@
#define MSTGRPPERR 0x00000001U
#define PCIE_NONFAT_ERR 0x3010
#define PCIE_CFG_SPACE_REQ 0x3060
#define PCIE_CFG_SPACE_DATA 0x3064
#define PCIE_MEM_ACCESS_BASE_WIN 0x3068
#define S_PCIEOFST 10
#define M_PCIEOFST 0x3fffffU
......@@ -398,7 +400,11 @@
#define WINDOW_MASK 0x000000ffU
#define WINDOW_SHIFT 0
#define WINDOW(x) ((x) << WINDOW_SHIFT)
#define GET_WINDOW(x) (((x) >> WINDOW_SHIFT) & WINDOW_MASK)
#define PCIE_MEM_ACCESS_OFFSET 0x306c
#define ENABLE (1U << 30)
#define FUNCTION(x) ((x) << 12)
#define F_LOCALCFG (1U << 28)
#define S_PFNUM 0
#define V_PFNUM(x) ((x) << S_PFNUM)
......
......@@ -2924,6 +2924,15 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4vf_pci_tbl) = {
CH_DEVICE(0x480a, 0), /* T404-bt */
CH_DEVICE(0x480d, 0), /* T480-cr */
CH_DEVICE(0x480e, 0), /* T440-lp-cr */
CH_DEVICE(0x4880, 0),
CH_DEVICE(0x4880, 1),
CH_DEVICE(0x4880, 2),
CH_DEVICE(0x4880, 3),
CH_DEVICE(0x4880, 4),
CH_DEVICE(0x4880, 5),
CH_DEVICE(0x4880, 6),
CH_DEVICE(0x4880, 7),
CH_DEVICE(0x4880, 8),
CH_DEVICE(0x5800, 0), /* T580-dbg */
CH_DEVICE(0x5801, 0), /* T520-cr */
CH_DEVICE(0x5802, 0), /* T522-cr */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment