forked from Minki/linux
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: Dirk van der Merwe <dirk.vandermerwe@netronome.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
81fc9b5ccf
commit
447e9ebfc1
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
return nfp_app_repr_stop(repr->app, repr);
|
||||
err = nfp_app_repr_stop(repr->app, repr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
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;
|
||||
|
||||
return nfp_app_repr_open(repr->app, repr);
|
||||
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 0;
|
||||
|
||||
err_port_disable:
|
||||
nfp_port_configure(netdev, false);
|
||||
return err;
|
||||
}
|
||||
|
||||
const struct net_device_ops nfp_repr_netdev_ops = {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user