Skip to content

Commit

Permalink
Merge branch 'nfp-add-NFP5000-support'
Browse files Browse the repository at this point in the history
Jakub Kicinski says:

====================
nfp: add NFP5000 support

This series broadly speaking adds support for NFP5000 and
related products.

First we add support for loading FW from flash.  We need to allow
for the management processor to provide extended log messages when
FW is loaded.  This is needed when FW selection policy is to compare
the FW on the disk and in the flash, and load the newer.  User should
be told what FW was selected.

We use this opportunity to add extended errors for normal FW loading
as well.

Next we add support for requesting HW information from the management
processor.  Up until now the driver read the HWinfo as it appears in
card memory, but there can be cases when management processor has
additional information or generates the entries dynamically so
occasionally we will have to consult it.  We use this to look up MAC
addresses for PCIe netdevs.

Next the actual patch with NFP5000 support and a small dose of
refactoring of PCIe init.

The remaining patches add support for reading RTsymbol types we
didn't need before.  Ones explicitly placed in external memory unit's
cache and absolute ones.

This part begins with a patch moving the logic which figures out
the correct bit offsets to device probe, to avoid redoing the
calculation for each access.  Second patch adds error messages
for easier troubleshooting.  Next patch adds helpers which will
take care of address conversions to reach into EMU cache.
Subsequently users are migrated from the raw CPP API to the new RTsym
helpers.  Finally we add support for reading absolute symbols.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 28, 2018
2 parents 09990ad + 4152e58 commit 817e60a
Show file tree
Hide file tree
Showing 15 changed files with 682 additions and 236 deletions.
32 changes: 11 additions & 21 deletions drivers/net/ethernet/netronome/nfp/abm/ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,21 @@
#define NFP_QMSTAT_DROP 16
#define NFP_QMSTAT_ECN 24

static unsigned long long
nfp_abm_q_lvl_thrs(struct nfp_abm_link *alink, unsigned int queue)
{
return alink->abm->q_lvls->addr +
(alink->queue_base + queue) * NFP_QLVL_STRIDE + NFP_QLVL_THRS;
}

static int
nfp_abm_ctrl_stat(struct nfp_abm_link *alink, const struct nfp_rtsym *sym,
unsigned int stride, unsigned int offset, unsigned int i,
bool is_u64, u64 *res)
{
struct nfp_cpp *cpp = alink->abm->app->cpp;
u32 val32, mur;
u64 val, addr;
u64 val, sym_offset;
u32 val32;
int err;

mur = NFP_CPP_ATOMIC_RD(sym->target, sym->domain);

addr = sym->addr + (alink->queue_base + i) * stride + offset;
sym_offset = (alink->queue_base + i) * stride + offset;
if (is_u64)
err = nfp_cpp_readq(cpp, mur, addr, &val);
err = __nfp_rtsym_readq(cpp, sym, 3, 0, sym_offset, &val);
else
err = nfp_cpp_readl(cpp, mur, addr, &val32);
err = __nfp_rtsym_readl(cpp, sym, 3, 0, sym_offset, &val32);
if (err) {
nfp_err(cpp,
"RED offload reading stat failed on vNIC %d queue %d\n",
Expand Down Expand Up @@ -114,13 +105,12 @@ nfp_abm_ctrl_stat_all(struct nfp_abm_link *alink, const struct nfp_rtsym *sym,
int nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int i, u32 val)
{
struct nfp_cpp *cpp = alink->abm->app->cpp;
u32 muw;
u64 sym_offset;
int err;

muw = NFP_CPP_ATOMIC_WR(alink->abm->q_lvls->target,
alink->abm->q_lvls->domain);

err = nfp_cpp_writel(cpp, muw, nfp_abm_q_lvl_thrs(alink, i), val);
sym_offset = (alink->queue_base + i) * NFP_QLVL_STRIDE + NFP_QLVL_THRS;
err = __nfp_rtsym_writel(cpp, alink->abm->q_lvls, 4, 0,
sym_offset, val);
if (err) {
nfp_err(cpp, "RED offload setting level failed on vNIC %d queue %d\n",
alink->id, i);
Expand Down Expand Up @@ -290,10 +280,10 @@ nfp_abm_ctrl_find_rtsym(struct nfp_pf *pf, const char *name, unsigned int size)
nfp_err(pf->cpp, "Symbol '%s' not found\n", name);
return ERR_PTR(-ENOENT);
}
if (sym->size != size) {
if (nfp_rtsym_size(sym) != size) {
nfp_err(pf->cpp,
"Symbol '%s' wrong size: expected %u got %llu\n",
name, size, sym->size);
name, size, nfp_rtsym_size(sym));
return ERR_PTR(-EINVAL);
}

Expand Down
34 changes: 25 additions & 9 deletions drivers/net/ethernet/netronome/nfp/abm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,31 +540,47 @@ nfp_abm_vnic_set_mac(struct nfp_pf *pf, struct nfp_abm *abm, struct nfp_net *nn,
{
struct nfp_eth_table_port *eth_port = &pf->eth_tbl->ports[id];
u8 mac_addr[ETH_ALEN];
const char *mac_str;
char name[32];
struct nfp_nsp *nsp;
char hwinfo[32];
int err;

if (id > pf->eth_tbl->count) {
nfp_warn(pf->cpp, "No entry for persistent MAC address\n");
eth_hw_addr_random(nn->dp.netdev);
return;
}

snprintf(name, sizeof(name), "eth%u.mac.pf%u",
snprintf(hwinfo, sizeof(hwinfo), "eth%u.mac.pf%u",
eth_port->eth_index, abm->pf_id);

mac_str = nfp_hwinfo_lookup(pf->hwinfo, name);
if (!mac_str) {
nfp_warn(pf->cpp, "Can't lookup persistent MAC address (%s)\n",
name);
nsp = nfp_nsp_open(pf->cpp);
if (IS_ERR(nsp)) {
nfp_warn(pf->cpp, "Failed to access the NSP for persistent MAC address: %ld\n",
PTR_ERR(nsp));
eth_hw_addr_random(nn->dp.netdev);
return;
}

if (!nfp_nsp_has_hwinfo_lookup(nsp)) {
nfp_warn(pf->cpp, "NSP doesn't support PF MAC generation\n");
eth_hw_addr_random(nn->dp.netdev);
return;
}

err = nfp_nsp_hwinfo_lookup(nsp, hwinfo, sizeof(hwinfo));
nfp_nsp_close(nsp);
if (err) {
nfp_warn(pf->cpp, "Reading persistent MAC address failed: %d\n",
err);
eth_hw_addr_random(nn->dp.netdev);
return;
}

if (sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
if (sscanf(hwinfo, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
&mac_addr[0], &mac_addr[1], &mac_addr[2],
&mac_addr[3], &mac_addr[4], &mac_addr[5]) != 6) {
nfp_warn(pf->cpp, "Can't parse persistent MAC address (%s)\n",
mac_str);
hwinfo);
eth_hw_addr_random(nn->dp.netdev);
return;
}
Expand Down
44 changes: 22 additions & 22 deletions drivers/net/ethernet/netronome/nfp/nfp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ static const struct pci_device_id nfp_pci_device_ids[] = {
PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID,
PCI_ANY_ID, 0,
},
{ PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP5000,
PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID,
PCI_ANY_ID, 0,
},
{ PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP4000,
PCI_VENDOR_ID_NETRONOME, PCI_ANY_ID,
PCI_ANY_ID, 0,
Expand Down Expand Up @@ -112,54 +116,48 @@ nfp_pf_map_rtsym(struct nfp_pf *pf, const char *name, const char *sym_fmt,
int nfp_mbox_cmd(struct nfp_pf *pf, u32 cmd, void *in_data, u64 in_length,
void *out_data, u64 out_length)
{
unsigned long long addr;
unsigned long err_at;
u64 max_data_sz;
u32 val = 0;
u32 cpp_id;
int n, err;

if (!pf->mbox)
return -EOPNOTSUPP;

cpp_id = NFP_CPP_ISLAND_ID(pf->mbox->target, NFP_CPP_ACTION_RW, 0,
pf->mbox->domain);
addr = pf->mbox->addr;
max_data_sz = pf->mbox->size - NFP_MBOX_SYM_MIN_SIZE;
max_data_sz = nfp_rtsym_size(pf->mbox) - NFP_MBOX_SYM_MIN_SIZE;

/* Check if cmd field is clear */
err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_CMD, &val);
err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_CMD, &val);
if (err || val) {
nfp_warn(pf->cpp, "failed to issue command (%u): %u, err: %d\n",
cmd, val, err);
return err ?: -EBUSY;
}

in_length = min(in_length, max_data_sz);
n = nfp_cpp_write(pf->cpp, cpp_id, addr + NFP_MBOX_DATA,
in_data, in_length);
n = nfp_rtsym_write(pf->cpp, pf->mbox, NFP_MBOX_DATA, in_data,
in_length);
if (n != in_length)
return -EIO;
/* Write data_len and wipe reserved */
err = nfp_cpp_writeq(pf->cpp, cpp_id, addr + NFP_MBOX_DATA_LEN,
in_length);
err = nfp_rtsym_writeq(pf->cpp, pf->mbox, NFP_MBOX_DATA_LEN, in_length);
if (err)
return err;

/* Read back for ordering */
err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_DATA_LEN, &val);
err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_DATA_LEN, &val);
if (err)
return err;

/* Write cmd and wipe return value */
err = nfp_cpp_writeq(pf->cpp, cpp_id, addr + NFP_MBOX_CMD, cmd);
err = nfp_rtsym_writeq(pf->cpp, pf->mbox, NFP_MBOX_CMD, cmd);
if (err)
return err;

err_at = jiffies + 5 * HZ;
while (true) {
/* Wait for command to go to 0 (NFP_MBOX_NO_CMD) */
err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_CMD, &val);
err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_CMD, &val);
if (err)
return err;
if (!val)
Expand All @@ -172,18 +170,18 @@ int nfp_mbox_cmd(struct nfp_pf *pf, u32 cmd, void *in_data, u64 in_length,
}

/* Copy output if any (could be error info, do it before reading ret) */
err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_DATA_LEN, &val);
err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_DATA_LEN, &val);
if (err)
return err;

out_length = min_t(u32, val, min(out_length, max_data_sz));
n = nfp_cpp_read(pf->cpp, cpp_id, addr + NFP_MBOX_DATA,
out_data, out_length);
n = nfp_rtsym_read(pf->cpp, pf->mbox, NFP_MBOX_DATA,
out_data, out_length);
if (n != out_length)
return -EIO;

/* Check if there is an error */
err = nfp_cpp_readl(pf->cpp, cpp_id, addr + NFP_MBOX_RET, &val);
err = nfp_rtsym_readl(pf->cpp, pf->mbox, NFP_MBOX_RET, &val);
if (err)
return err;
if (val)
Expand Down Expand Up @@ -441,8 +439,11 @@ nfp_fw_load(struct pci_dev *pdev, struct nfp_pf *pf, struct nfp_nsp *nsp)
}

fw = nfp_net_fw_find(pdev, pf);
if (!fw)
if (!fw) {
if (nfp_nsp_has_stored_fw_load(nsp))
nfp_nsp_load_stored_fw(nsp);
return 0;
}

dev_info(&pdev->dev, "Soft-reset, loading FW image\n");
err = nfp_nsp_device_soft_reset(nsp);
Expand All @@ -453,7 +454,6 @@ nfp_fw_load(struct pci_dev *pdev, struct nfp_pf *pf, struct nfp_nsp *nsp)
}

err = nfp_nsp_load_fw(nsp, fw);

if (err < 0) {
dev_err(&pdev->dev, "FW loading failed: %d\n", err);
goto exit_release_fw;
Expand Down Expand Up @@ -566,9 +566,9 @@ static int nfp_pf_find_rtsyms(struct nfp_pf *pf)
/* Optional per-PCI PF mailbox */
snprintf(pf_symbol, sizeof(pf_symbol), NFP_MBOX_SYM_NAME, pf_id);
pf->mbox = nfp_rtsym_lookup(pf->rtbl, pf_symbol);
if (pf->mbox && pf->mbox->size < NFP_MBOX_SYM_MIN_SIZE) {
if (pf->mbox && nfp_rtsym_size(pf->mbox) < NFP_MBOX_SYM_MIN_SIZE) {
nfp_err(pf->cpp, "PF mailbox symbol too small: %llu < %d\n",
pf->mbox->size, NFP_MBOX_SYM_MIN_SIZE);
nfp_rtsym_size(pf->mbox), NFP_MBOX_SYM_MIN_SIZE);
return -EINVAL;
}

Expand Down
50 changes: 16 additions & 34 deletions drivers/net/ethernet/netronome/nfp/nfp_net_debugdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,25 +188,21 @@ nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct nfp_rtsym_table *rtbl)
const struct nfp_rtsym *specsym;
struct nfp_dumpspec *dumpspec;
int bytes_read;
u32 cpp_id;
u64 sym_size;

specsym = nfp_rtsym_lookup(rtbl, NFP_DUMP_SPEC_RTSYM);
if (!specsym)
return NULL;
sym_size = nfp_rtsym_size(specsym);

/* expected size of this buffer is in the order of tens of kilobytes */
dumpspec = vmalloc(sizeof(*dumpspec) + specsym->size);
dumpspec = vmalloc(sizeof(*dumpspec) + sym_size);
if (!dumpspec)
return NULL;
dumpspec->size = sym_size;

dumpspec->size = specsym->size;

cpp_id = NFP_CPP_ISLAND_ID(specsym->target, NFP_CPP_ACTION_RW, 0,
specsym->domain);

bytes_read = nfp_cpp_read(cpp, cpp_id, specsym->addr, dumpspec->data,
specsym->size);
if (bytes_read != specsym->size) {
bytes_read = nfp_rtsym_read(cpp, specsym, 0, dumpspec->data, sym_size);
if (bytes_read != sym_size) {
vfree(dumpspec);
nfp_warn(cpp, "Debug dump specification read failed.\n");
return NULL;
Expand Down Expand Up @@ -266,7 +262,6 @@ nfp_calc_rtsym_dump_sz(struct nfp_pf *pf, struct nfp_dump_tl *spec)
struct nfp_dumpspec_rtsym *spec_rtsym;
const struct nfp_rtsym *sym;
u32 tl_len, key_len;
u32 size;

spec_rtsym = (struct nfp_dumpspec_rtsym *)spec;
tl_len = be32_to_cpu(spec->length);
Expand All @@ -278,13 +273,8 @@ nfp_calc_rtsym_dump_sz(struct nfp_pf *pf, struct nfp_dump_tl *spec)
if (!sym)
return nfp_dump_error_tlv_size(spec);

if (sym->type == NFP_RTSYM_TYPE_ABS)
size = sizeof(sym->addr);
else
size = sym->size;

return ALIGN8(offsetof(struct nfp_dump_rtsym, rtsym) + key_len + 1) +
ALIGN8(size);
ALIGN8(nfp_rtsym_size(sym));
}

static int
Expand Down Expand Up @@ -644,7 +634,6 @@ nfp_dump_single_rtsym(struct nfp_pf *pf, struct nfp_dumpspec_rtsym *spec,
const struct nfp_rtsym *sym;
u32 tl_len, key_len;
int bytes_read;
u32 cpp_id;
void *dest;
int err;

Expand All @@ -657,11 +646,7 @@ nfp_dump_single_rtsym(struct nfp_pf *pf, struct nfp_dumpspec_rtsym *spec,
if (!sym)
return nfp_dump_error_tlv(&spec->tl, -ENOENT, dump);

if (sym->type == NFP_RTSYM_TYPE_ABS)
sym_size = sizeof(sym->addr);
else
sym_size = sym->size;

sym_size = nfp_rtsym_size(sym);
header_size =
ALIGN8(offsetof(struct nfp_dump_rtsym, rtsym) + key_len + 1);
total_size = header_size + ALIGN8(sym_size);
Expand All @@ -676,23 +661,20 @@ nfp_dump_single_rtsym(struct nfp_pf *pf, struct nfp_dumpspec_rtsym *spec,
memcpy(dump_header->rtsym, spec->rtsym, key_len + 1);
dump_header->cpp.dump_length = cpu_to_be32(sym_size);

if (sym->type == NFP_RTSYM_TYPE_ABS) {
*(u64 *)dest = sym->addr;
} else {
if (sym->type != NFP_RTSYM_TYPE_ABS) {
cpp_params.target = sym->target;
cpp_params.action = NFP_CPP_ACTION_RW;
cpp_params.token = 0;
cpp_params.island = sym->domain;
cpp_id = nfp_get_numeric_cpp_id(&cpp_params);
dump_header->cpp.cpp_id = cpp_params;
dump_header->cpp.offset = cpu_to_be32(sym->addr);
bytes_read = nfp_cpp_read(pf->cpp, cpp_id, sym->addr, dest,
sym_size);
if (bytes_read != sym_size) {
if (bytes_read >= 0)
bytes_read = -EIO;
dump_header->error = cpu_to_be32(bytes_read);
}
}

bytes_read = nfp_rtsym_read(pf->cpp, sym, 0, dest, sym_size);
if (bytes_read != sym_size) {
if (bytes_read >= 0)
bytes_read = -EIO;
dump_header->error = cpu_to_be32(bytes_read);
}

return 0;
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/ethernet/netronome/nfp/nfp_net_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,8 @@ static void nfp_net_pci_unmap_mem(struct nfp_pf *pf)

static int nfp_net_pci_map_mem(struct nfp_pf *pf)
{
u32 min_size, cpp_id;
u8 __iomem *mem;
u32 min_size;
int err;

min_size = pf->max_data_vnics * NFP_PF_CSR_SLICE_SIZE;
Expand Down Expand Up @@ -519,9 +519,9 @@ static int nfp_net_pci_map_mem(struct nfp_pf *pf)
pf->vfcfg_tbl2 = NULL;
}

mem = nfp_cpp_map_area(pf->cpp, "net.qc", 0, 0,
NFP_PCIE_QUEUE(0), NFP_QCP_QUEUE_AREA_SZ,
&pf->qc_area);
cpp_id = NFP_CPP_ISLAND_ID(0, NFP_CPP_ACTION_RW, 0, 0);
mem = nfp_cpp_map_area(pf->cpp, "net.qc", cpp_id, NFP_PCIE_QUEUE(0),
NFP_QCP_QUEUE_AREA_SZ, &pf->qc_area);
if (IS_ERR(mem)) {
nfp_err(pf->cpp, "Failed to map Queue Controller area.\n");
err = PTR_ERR(mem);
Expand Down
Loading

0 comments on commit 817e60a

Please sign in to comment.