* [PATCH net 1/3] nfp: add whitelist of supported flow dissector
2017-09-13 15:51 [PATCH net 0/3] nfp: wait more carefully for card init Jakub Kicinski
@ 2017-09-13 15:51 ` Jakub Kicinski
2017-09-13 15:51 ` [PATCH net 2/3] nfp: wait for board state before talking to the NSP Jakub Kicinski
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Jakub Kicinski @ 2017-09-13 15:51 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Pieter Jansen van Vuuren
From: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Previously we did not check the flow dissector against a list of allowed
and supported flow key dissectors. This patch introduces such a list and
correctly rejects unsupported flow keys.
Fixes: 43f84b72c50d ("nfp: add metadata to each flow offload")
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
drivers/net/ethernet/netronome/nfp/flower/offload.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index d396183108f7..a18b4d2b1d3e 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -44,6 +44,16 @@
#include "../nfp_net.h"
#include "../nfp_port.h"
+#define NFP_FLOWER_WHITELIST_DISSECTOR \
+ (BIT(FLOW_DISSECTOR_KEY_CONTROL) | \
+ BIT(FLOW_DISSECTOR_KEY_BASIC) | \
+ BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) | \
+ BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | \
+ BIT(FLOW_DISSECTOR_KEY_PORTS) | \
+ BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | \
+ BIT(FLOW_DISSECTOR_KEY_VLAN) | \
+ BIT(FLOW_DISSECTOR_KEY_IP))
+
static int
nfp_flower_xmit_flow(struct net_device *netdev,
struct nfp_fl_payload *nfp_flow, u8 mtype)
@@ -112,6 +122,9 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls,
u8 key_layer;
int key_size;
+ if (flow->dissector->used_keys & ~NFP_FLOWER_WHITELIST_DISSECTOR)
+ return -EOPNOTSUPP;
+
if (dissector_uses_key(flow->dissector,
FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
struct flow_dissector_key_control *mask_enc_ctl =
--
2.14.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH net 2/3] nfp: wait for board state before talking to the NSP
2017-09-13 15:51 [PATCH net 0/3] nfp: wait more carefully for card init Jakub Kicinski
2017-09-13 15:51 ` [PATCH net 1/3] nfp: add whitelist of supported flow dissector Jakub Kicinski
@ 2017-09-13 15:51 ` Jakub Kicinski
2017-09-13 15:51 ` [PATCH net 3/3] nfp: wait for the NSP resource to appear on boot Jakub Kicinski
2017-09-13 16:39 ` [PATCH net 0/3] nfp: wait more carefully for card init David Miller
3 siblings, 0 replies; 6+ messages in thread
From: Jakub Kicinski @ 2017-09-13 15:51 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
Board state informs us which low-level initialization stages the card
has completed. We should wait for the card to be fully initialized
before trying to communicate with it, not only before we configure
passing traffic.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_main.c | 43 +++++++++++++++++++++++
drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 23 ------------
2 files changed, 43 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index f055b1774d65..424707d41fbd 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -74,6 +74,45 @@ static const struct pci_device_id nfp_pci_device_ids[] = {
};
MODULE_DEVICE_TABLE(pci, nfp_pci_device_ids);
+static bool nfp_board_ready(struct nfp_pf *pf)
+{
+ const char *cp;
+ long state;
+ int err;
+
+ cp = nfp_hwinfo_lookup(pf->hwinfo, "board.state");
+ if (!cp)
+ return false;
+
+ err = kstrtol(cp, 0, &state);
+ if (err < 0)
+ return false;
+
+ return state == 15;
+}
+
+static int nfp_pf_board_state_wait(struct nfp_pf *pf)
+{
+ const unsigned long wait_until = jiffies + 10 * HZ;
+
+ while (!nfp_board_ready(pf)) {
+ if (time_is_before_eq_jiffies(wait_until)) {
+ nfp_err(pf->cpp, "NFP board initialization timeout\n");
+ return -EINVAL;
+ }
+
+ nfp_info(pf->cpp, "waiting for board initialization\n");
+ if (msleep_interruptible(500))
+ return -ERESTARTSYS;
+
+ /* Refresh cached information */
+ kfree(pf->hwinfo);
+ pf->hwinfo = nfp_hwinfo_read(pf->cpp);
+ }
+
+ return 0;
+}
+
static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf)
{
int err;
@@ -425,6 +464,10 @@ static int nfp_pci_probe(struct pci_dev *pdev,
nfp_hwinfo_lookup(pf->hwinfo, "assembly.revision"),
nfp_hwinfo_lookup(pf->hwinfo, "cpld.version"));
+ err = nfp_pf_board_state_wait(pf);
+ if (err)
+ goto err_hwinfo_free;
+
err = devlink_register(devlink, &pdev->dev);
if (err)
goto err_hwinfo_free;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index 5abb9ba31e7d..ff373acd28f3 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -64,23 +64,6 @@
#define NFP_PF_CSR_SLICE_SIZE (32 * 1024)
-static int nfp_is_ready(struct nfp_pf *pf)
-{
- const char *cp;
- long state;
- int err;
-
- cp = nfp_hwinfo_lookup(pf->hwinfo, "board.state");
- if (!cp)
- return 0;
-
- err = kstrtol(cp, 0, &state);
- if (err < 0)
- return 0;
-
- return state == 15;
-}
-
/**
* nfp_net_get_mac_addr() - Get the MAC address.
* @pf: NFP PF handle
@@ -725,12 +708,6 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
INIT_WORK(&pf->port_refresh_work, nfp_net_refresh_vnics);
- /* Verify that the board has completed initialization */
- if (!nfp_is_ready(pf)) {
- nfp_err(pf->cpp, "NFP is not ready for NIC operation.\n");
- return -EINVAL;
- }
-
if (!pf->rtbl) {
nfp_err(pf->cpp, "No %s, giving up.\n",
pf->fw_loaded ? "symbol table" : "firmware found");
--
2.14.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH net 3/3] nfp: wait for the NSP resource to appear on boot
2017-09-13 15:51 [PATCH net 0/3] nfp: wait more carefully for card init Jakub Kicinski
2017-09-13 15:51 ` [PATCH net 1/3] nfp: add whitelist of supported flow dissector Jakub Kicinski
2017-09-13 15:51 ` [PATCH net 2/3] nfp: wait for board state before talking to the NSP Jakub Kicinski
@ 2017-09-13 15:51 ` Jakub Kicinski
2017-09-13 16:39 ` [PATCH net 0/3] nfp: wait more carefully for card init David Miller
3 siblings, 0 replies; 6+ messages in thread
From: Jakub Kicinski @ 2017-09-13 15:51 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
The control process (NSP) may take some time to complete its
initialization. This is not a problem on most servers, but
on very fast-booting machines it may not be ready for operation
when driver probes the device. There is also a version of the
flash in the wild where NSP tries to train the links as part
of init. To wait for NSP initialization we should make sure
its resource has already been added to the resource table.
NSP adds itself there as last step of init.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_main.c | 4 ++
drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h | 2 +
.../ethernet/netronome/nfp/nfpcore/nfp_resource.c | 45 ++++++++++++++++++++++
3 files changed, 51 insertions(+)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index 424707d41fbd..1c17b261a21c 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -390,6 +390,10 @@ static void nfp_fw_unload(struct nfp_pf *pf)
struct nfp_nsp *nsp;
int err;
+ err = nfp_resource_wait(pf->cpp, NFP_RESOURCE_NSP, 30);
+ if (err)
+ return err;
+
nsp = nfp_nsp_open(pf->cpp);
if (IS_ERR(nsp)) {
nfp_err(pf->cpp, "Reset failed, can't open NSP\n");
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
index 1a8d04a1e113..3ce51f03126f 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
@@ -97,6 +97,8 @@ nfp_resource_acquire(struct nfp_cpp *cpp, const char *name);
void nfp_resource_release(struct nfp_resource *res);
+int nfp_resource_wait(struct nfp_cpp *cpp, const char *name, unsigned int secs);
+
u32 nfp_resource_cpp_id(struct nfp_resource *res);
const char *nfp_resource_name(struct nfp_resource *res);
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
index 072612263dab..b1dd13ff282b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
@@ -249,6 +249,51 @@ void nfp_resource_release(struct nfp_resource *res)
kfree(res);
}
+/**
+ * nfp_resource_wait() - Wait for resource to appear
+ * @cpp: NFP CPP handle
+ * @name: Name of the resource
+ * @secs: Number of seconds to wait
+ *
+ * Wait for resource to appear in the resource table, grab and release
+ * its lock. The wait is jiffies-based, don't expect fine granularity.
+ *
+ * Return: 0 on success, errno otherwise.
+ */
+int nfp_resource_wait(struct nfp_cpp *cpp, const char *name, unsigned int secs)
+{
+ unsigned long warn_at = jiffies + NFP_MUTEX_WAIT_FIRST_WARN * HZ;
+ unsigned long err_at = jiffies + secs * HZ;
+ struct nfp_resource *res;
+
+ while (true) {
+ res = nfp_resource_acquire(cpp, name);
+ if (!IS_ERR(res)) {
+ nfp_resource_release(res);
+ return 0;
+ }
+
+ if (PTR_ERR(res) != -ENOENT) {
+ nfp_err(cpp, "error waiting for resource %s: %ld\n",
+ name, PTR_ERR(res));
+ return PTR_ERR(res);
+ }
+ if (time_is_before_eq_jiffies(err_at)) {
+ nfp_err(cpp, "timeout waiting for resource %s\n", name);
+ return -ETIMEDOUT;
+ }
+ if (time_is_before_eq_jiffies(warn_at)) {
+ warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
+ nfp_info(cpp, "waiting for NFP resource %s\n", name);
+ }
+ if (msleep_interruptible(10)) {
+ nfp_err(cpp, "wait for resource %s interrupted\n",
+ name);
+ return -ERESTARTSYS;
+ }
+ }
+}
+
/**
* nfp_resource_cpp_id() - Return the cpp_id of a resource handle
* @res: NFP Resource handle
--
2.14.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH net 0/3] nfp: wait more carefully for card init
2017-09-13 15:51 [PATCH net 0/3] nfp: wait more carefully for card init Jakub Kicinski
` (2 preceding siblings ...)
2017-09-13 15:51 ` [PATCH net 3/3] nfp: wait for the NSP resource to appear on boot Jakub Kicinski
@ 2017-09-13 16:39 ` David Miller
2017-09-13 16:53 ` Jakub Kicinski
3 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2017-09-13 16:39 UTC (permalink / raw)
To: jakub.kicinski; +Cc: netdev, oss-drivers
From: Jakub Kicinski <jakub.kicinski@netronome.com>
Date: Wed, 13 Sep 2017 08:51:28 -0700
> The first patch is a small fix for flower offload, we need a whitelist
> of supported matches, otherwise the unsupported ones will be ignored.
>
> The second and the third patch are adding wait/polling to the probe path.
> We had reports of driver failing probe because it couldn't find the
> control process (NSP) on the card. Turns out the NSP will only announce
> its existence after it's fully initialized. Until now we assumed it
> will be reachable, just not processing commands (hence we wait for
> a NOOP command to execute successfully).
Please build test your changes and look at what the compiler says:
drivers/net/ethernet/netronome/nfp/nfp_main.c: In function ‘nfp_fw_unload’:
drivers/net/ethernet/netronome/nfp/nfp_main.c:395:10: warning: ‘return’ with a value, in function returning void
return err;
^~~
drivers/net/ethernet/netronome/nfp/nfp_main.c:388:13: note: declared here
static void nfp_fw_unload(struct nfp_pf *pf)
^~~~~~~~~~~~~
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH net 0/3] nfp: wait more carefully for card init
2017-09-13 16:39 ` [PATCH net 0/3] nfp: wait more carefully for card init David Miller
@ 2017-09-13 16:53 ` Jakub Kicinski
0 siblings, 0 replies; 6+ messages in thread
From: Jakub Kicinski @ 2017-09-13 16:53 UTC (permalink / raw)
To: David Miller; +Cc: netdev, oss-drivers
On Wed, 13 Sep 2017 09:39:02 -0700 (PDT), David Miller wrote:
> From: Jakub Kicinski <jakub.kicinski@netronome.com>
> Date: Wed, 13 Sep 2017 08:51:28 -0700
>
> > The first patch is a small fix for flower offload, we need a whitelist
> > of supported matches, otherwise the unsupported ones will be ignored.
> >
> > The second and the third patch are adding wait/polling to the probe path.
> > We had reports of driver failing probe because it couldn't find the
> > control process (NSP) on the card. Turns out the NSP will only announce
> > its existence after it's fully initialized. Until now we assumed it
> > will be reachable, just not processing commands (hence we wait for
> > a NOOP command to execute successfully).
>
> Please build test your changes and look at what the compiler says:
>
> drivers/net/ethernet/netronome/nfp/nfp_main.c: In function ‘nfp_fw_unload’:
> drivers/net/ethernet/netronome/nfp/nfp_main.c:395:10: warning: ‘return’ with a value, in function returning void
> return err;
> ^~~
> drivers/net/ethernet/netronome/nfp/nfp_main.c:388:13: note: declared here
> static void nfp_fw_unload(struct nfp_pf *pf)
> ^~~~~~~~~~~~~
Sorry about that!
^ permalink raw reply [flat|nested] 6+ messages in thread