Skip to content

Commit

Permalink
nfp: move refresh tracking into the port structure
Browse files Browse the repository at this point in the history
Track whether physical port's state have changed since last refresh
inside the nfp_port structure instead of the vNIC structure.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jakub Kicinski authored and David S. Miller committed May 22, 2017
1 parent 3d4ed1e commit 6d4f8cb
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 25 deletions.
4 changes: 0 additions & 4 deletions drivers/net/ethernet/netronome/nfp/nfp_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,6 @@ struct nfp_net_dp {
* @reconfig_sync_present: Some thread is performing synchronous reconfig
* @reconfig_timer: Timer for async reading of reconfig results
* @link_up: Is the link up?
* @link_changed: Has link state changes since last port refresh?
* @link_status_lock: Protects @link_* and ensures atomicity with BAR reading
* @rx_coalesce_usecs: RX interrupt moderation usecs delay parameter
* @rx_coalesce_max_frames: RX interrupt moderation frame count parameter
Expand Down Expand Up @@ -601,7 +600,6 @@ struct nfp_net {
u32 me_freq_mhz;

bool link_up;
bool link_changed;
spinlock_t link_status_lock;

spinlock_t reconfig_lock;
Expand Down Expand Up @@ -842,8 +840,6 @@ struct nfp_net_dp *nfp_net_clone_dp(struct nfp_net *nn);
int nfp_net_ring_reconfig(struct nfp_net *nn, struct nfp_net_dp *new,
struct netlink_ext_ack *extack);

bool nfp_net_link_changed_read_clear(struct nfp_net *nn);

#ifdef CONFIG_NFP_DEBUG
void nfp_net_debugfs_create(void);
void nfp_net_debugfs_destroy(void);
Expand Down
16 changes: 2 additions & 14 deletions drivers/net/ethernet/netronome/nfp/nfp_net_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,19 +392,6 @@ static irqreturn_t nfp_net_irq_rxtx(int irq, void *data)
return IRQ_HANDLED;
}

bool nfp_net_link_changed_read_clear(struct nfp_net *nn)
{
unsigned long flags;
bool ret;

spin_lock_irqsave(&nn->link_status_lock, flags);
ret = nn->link_changed;
nn->link_changed = false;
spin_unlock_irqrestore(&nn->link_status_lock, flags);

return ret;
}

/**
* nfp_net_read_link_status() - Reread link status from control BAR
* @nn: NFP Network structure
Expand All @@ -424,7 +411,8 @@ static void nfp_net_read_link_status(struct nfp_net *nn)
goto out;

nn->link_up = link_up;
nn->link_changed = true;
if (nn->port)
set_bit(NFP_PORT_CHANGED, &nn->port->flags);

if (nn->link_up) {
netif_carrier_on(nn->dp.netdev);
Expand Down
10 changes: 5 additions & 5 deletions drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,11 @@ nfp_net_get_link_ksettings(struct net_device *netdev,
if (!netif_carrier_ok(netdev))
return 0;

if (!nfp_netdev_is_nfp_net(netdev))
return -EOPNOTSUPP;
nn = netdev_priv(netdev);

/* Use link speed from ETH table if available, otherwise try the BAR */
if (eth_port) {
int err;

if (nfp_net_link_changed_read_clear(nn)) {
if (test_bit(NFP_PORT_CHANGED, &port->flags)) {
err = nfp_net_refresh_eth_port(port);
if (err)
return err;
Expand All @@ -237,6 +233,10 @@ nfp_net_get_link_ksettings(struct net_device *netdev,
return 0;
}

if (!nfp_netdev_is_nfp_net(netdev))
return -EOPNOTSUPP;
nn = netdev_priv(netdev);

sts = nn_readl(nn, NFP_NET_CFG_STS);

ls = FIELD_GET(NFP_NET_CFG_STS_LINK_RATE, sts);
Expand Down
10 changes: 8 additions & 2 deletions drivers/net/ethernet/netronome/nfp/nfp_net_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,16 +555,19 @@ static void nfp_net_refresh_vnics(struct work_struct *work)
if (list_empty(&pf->vnics))
goto out;

/* Update state of all ports */
rtnl_lock();
list_for_each_entry(nn, &pf->vnics, vnic_list)
nfp_net_link_changed_read_clear(nn);
if (nn->port)
clear_bit(NFP_PORT_CHANGED, &nn->port->flags);

eth_table = nfp_eth_read_ports(pf->cpp);
if (!eth_table) {
rtnl_unlock();
nfp_err(pf->cpp, "Error refreshing port config!\n");
goto out;
}

rtnl_lock();
list_for_each_entry(nn, &pf->vnics, vnic_list) {
if (!__nfp_port_get_eth_port(nn->port))
continue;
Expand All @@ -575,6 +578,7 @@ static void nfp_net_refresh_vnics(struct work_struct *work)

kfree(eth_table);

/* Shoot off the ports which became invalid */
list_for_each_entry_safe(nn, next, &pf->vnics, vnic_list) {
if (!nn->port || nn->port->type != NFP_PORT_INVALID)
continue;
Expand Down Expand Up @@ -604,6 +608,8 @@ int nfp_net_refresh_eth_port(struct nfp_port *port)
struct nfp_eth_table *eth_table;
int ret;

clear_bit(NFP_PORT_CHANGED, &port->flags);

eth_table = nfp_eth_read_ports(cpp);
if (!eth_table) {
nfp_err(cpp, "Error refreshing port state table!\n");
Expand Down
13 changes: 13 additions & 0 deletions drivers/net/ethernet/netronome/nfp/nfp_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,21 @@ enum nfp_port_type {
NFP_PORT_PHYS_PORT,
};

/**
* enum nfp_port_flags - port flags (can be type-specific)
* @NFP_PORT_CHANGED: port state has changed since last eth table refresh;
* for NFP_PORT_PHYS_PORT, never set otherwise; must hold
* rtnl_lock to clear
*/
enum nfp_port_flags {
NFP_PORT_CHANGED = 0,
};

/**
* struct nfp_port - structure representing NFP port
* @netdev: backpointer to associated netdev
* @type: what port type does the entity represent
* @flags: port flags
* @app: backpointer to the app structure
* @eth_id: for %NFP_PORT_PHYS_PORT port ID in NFP enumeration scheme
* @eth_port: for %NFP_PORT_PHYS_PORT translated ETH Table port entry
Expand All @@ -62,6 +73,8 @@ struct nfp_port {
struct net_device *netdev;
enum nfp_port_type type;

unsigned long flags;

struct nfp_app *app;

unsigned int eth_id;
Expand Down

0 comments on commit 6d4f8cb

Please sign in to comment.