Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 447e9ebf authored by Dirk van der Merwe's avatar Dirk van der Merwe Committed by David S. Miller
Browse files

nfp: set config bit (ifup/ifdown) on netdev open/close



When a netdev (PF netdev or representor) is opened or closed, set the
physical port config bit appropriately - which powers UP/DOWN the PHY
module for the physical interface.

The PHY is powered first in the HW/FW configuration step when opening
the netdev and again last in the HW/FW configuration step when closing
the netdev.

This is only applicable when there is a physical port associated with
the netdev and if the NSP support this. Otherwise we silently ignore
this step.

The 'nfp_eth_set_configured' can actually return positive values -
updated the function documentation appropriately.

Signed-off-by: default avatarDirk van der Merwe <dirk.vandermerwe@netronome.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 81fc9b5c
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -2658,6 +2658,7 @@ static int nfp_net_netdev_close(struct net_device *netdev)
	/* Step 2: Tell NFP
	 */
	nfp_net_clear_config_and_disable(nn);
	nfp_port_configure(netdev, false);

	/* Step 3: Free resources
	 */
@@ -2775,16 +2776,21 @@ static int nfp_net_netdev_open(struct net_device *netdev)
		goto err_free_all;

	/* Step 2: Configure the NFP
	 * - Ifup the physical interface if it exists
	 * - Enable rings from 0 to tx_rings/rx_rings - 1.
	 * - Write MAC address (in case it changed)
	 * - Set the MTU
	 * - Set the Freelist buffer size
	 * - Enable the FW
	 */
	err = nfp_net_set_config_and_enable(nn);
	err = nfp_port_configure(netdev, true);
	if (err)
		goto err_free_all;

	err = nfp_net_set_config_and_enable(nn);
	if (err)
		goto err_port_disable;

	/* Step 3: Enable for kernel
	 * - put some freelist descriptors on each RX ring
	 * - enable NAPI on each ring
@@ -2795,6 +2801,8 @@ static int nfp_net_netdev_open(struct net_device *netdev)

	return 0;

err_port_disable:
	nfp_port_configure(netdev, false);
err_free_all:
	nfp_net_close_free_all(nn);
	return err;
+21 −2
Original line number Diff line number Diff line
@@ -239,15 +239,34 @@ static netdev_tx_t nfp_repr_xmit(struct sk_buff *skb, struct net_device *netdev)
static int nfp_repr_stop(struct net_device *netdev)
{
	struct nfp_repr *repr = netdev_priv(netdev);
	int err;

	err = nfp_app_repr_stop(repr->app, repr);
	if (err)
		return err;

	return nfp_app_repr_stop(repr->app, repr);
	nfp_port_configure(netdev, false);
	return 0;
}

static int nfp_repr_open(struct net_device *netdev)
{
	struct nfp_repr *repr = netdev_priv(netdev);
	int err;

	err = nfp_port_configure(netdev, true);
	if (err)
		return err;

	err = nfp_app_repr_open(repr->app, repr);
	if (err)
		goto err_port_disable;

	return nfp_app_repr_open(repr->app, repr);
	return 0;

err_port_disable:
	nfp_port_configure(netdev, false);
	return err;
}

const struct net_device_ops nfp_repr_netdev_ops = {
+27 −0
Original line number Diff line number Diff line
@@ -181,6 +181,33 @@ nfp_port_get_phys_port_name(struct net_device *netdev, char *name, size_t len)
	return 0;
}

/**
 * nfp_port_configure() - helper to set the interface configured bit
 * @netdev:	net_device instance
 * @configed:	Desired state
 *
 * Helper to set the ifup/ifdown state on the PHY only if there is a physical
 * interface associated with the netdev.
 *
 * Return:
 * 0 - configuration successful (or no change);
 * -ERRNO - configuration failed.
 */
int nfp_port_configure(struct net_device *netdev, bool configed)
{
	struct nfp_eth_table_port *eth_port;
	struct nfp_port *port;
	int err;

	port = nfp_port_from_netdev(netdev);
	eth_port = __nfp_port_get_eth_port(port);
	if (!eth_port)
		return 0;

	err = nfp_eth_set_configured(port->app->cpp, eth_port->index, configed);
	return err < 0 && err != -EOPNOTSUPP ? err : 0;
}

int nfp_port_init_phy_port(struct nfp_pf *pf, struct nfp_app *app,
			   struct nfp_port *port, unsigned int id)
{
+1 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ struct nfp_eth_table_port *nfp_port_get_eth_port(struct nfp_port *port);

int
nfp_port_get_phys_port_name(struct net_device *netdev, char *name, size_t len);
int nfp_port_configure(struct net_device *netdev, bool configed);

struct nfp_port *
nfp_port_alloc(struct nfp_app *app, enum nfp_port_type type,
+16 −2
Original line number Diff line number Diff line
@@ -391,7 +391,10 @@ int nfp_eth_config_commit_end(struct nfp_nsp *nsp)
 * Enable or disable PHY module (this usually means setting the TX lanes
 * disable bits).
 *
 * Return: 0 or -ERRNO.
 * Return:
 * 0 - configuration successful;
 * 1 - no changes were needed;
 * -ERRNO - configuration failed.
 */
int nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, bool enable)
{
@@ -427,7 +430,10 @@ int nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, bool enable)
 *
 * Set the ifup/ifdown state on the PHY.
 *
 * Return: 0 or -ERRNO.
 * Return:
 * 0 - configuration successful;
 * 1 - no changes were needed;
 * -ERRNO - configuration failed.
 */
int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx, bool configed)
{
@@ -439,6 +445,14 @@ int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx, bool configed)
	if (IS_ERR(nsp))
		return PTR_ERR(nsp);

	/* Older ABI versions did support this feature, however this has only
	 * been reliable since ABI 20.
	 */
	if (nfp_nsp_get_abi_ver_minor(nsp) < 20) {
		nfp_eth_config_cleanup_end(nsp);
		return -EOPNOTSUPP;
	}

	entries = nfp_nsp_config_entries(nsp);

	/* Check if we are already in requested state */