Skip to content

Commit 5093406

Browse files
vladimirolteankuba-moo
authored andcommitted
net: enetc: implement ring reconfiguration procedure for PTP RX timestamping
The crude enetc_stop() -> enetc_open() mechanism suffers from 2 problems: 1. improper error checking 2. it involves phylink_stop() -> phylink_start() which loses the link Right now, the driver is prepared to offer a better alternative: a ring reconfiguration procedure which takes the RX BD size (normal or extended) as argument. It allocates new resources (failing if that fails), stops the traffic, and assigns the new resources to the rings. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 598ca0d commit 5093406

File tree

1 file changed

+56
-12
lines changed
  • drivers/net/ethernet/freescale/enetc

1 file changed

+56
-12
lines changed

drivers/net/ethernet/freescale/enetc/enetc.c

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2489,6 +2489,46 @@ int enetc_close(struct net_device *ndev)
24892489
return 0;
24902490
}
24912491

2492+
static int enetc_reconfigure(struct enetc_ndev_priv *priv, bool extended)
2493+
{
2494+
struct enetc_bdr_resource *tx_res, *rx_res;
2495+
int err;
2496+
2497+
ASSERT_RTNL();
2498+
2499+
/* If the interface is down, do nothing. */
2500+
if (!netif_running(priv->ndev))
2501+
return 0;
2502+
2503+
tx_res = enetc_alloc_tx_resources(priv);
2504+
if (IS_ERR(tx_res)) {
2505+
err = PTR_ERR(tx_res);
2506+
goto out;
2507+
}
2508+
2509+
rx_res = enetc_alloc_rx_resources(priv, extended);
2510+
if (IS_ERR(rx_res)) {
2511+
err = PTR_ERR(rx_res);
2512+
goto out_free_tx_res;
2513+
}
2514+
2515+
enetc_stop(priv->ndev);
2516+
enetc_clear_bdrs(priv);
2517+
enetc_free_rxtx_rings(priv);
2518+
2519+
enetc_assign_tx_resources(priv, tx_res);
2520+
enetc_assign_rx_resources(priv, rx_res);
2521+
enetc_setup_bdrs(priv, extended);
2522+
enetc_start(priv->ndev);
2523+
2524+
return 0;
2525+
2526+
out_free_tx_res:
2527+
enetc_free_tx_resources(tx_res, priv->num_tx_rings);
2528+
out:
2529+
return err;
2530+
}
2531+
24922532
int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
24932533
{
24942534
struct enetc_ndev_priv *priv = netdev_priv(ndev);
@@ -2681,43 +2721,47 @@ void enetc_set_features(struct net_device *ndev, netdev_features_t features)
26812721
static int enetc_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
26822722
{
26832723
struct enetc_ndev_priv *priv = netdev_priv(ndev);
2724+
int err, new_offloads = priv->active_offloads;
26842725
struct hwtstamp_config config;
2685-
int ao;
26862726

26872727
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
26882728
return -EFAULT;
26892729

26902730
switch (config.tx_type) {
26912731
case HWTSTAMP_TX_OFF:
2692-
priv->active_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
2732+
new_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
26932733
break;
26942734
case HWTSTAMP_TX_ON:
2695-
priv->active_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
2696-
priv->active_offloads |= ENETC_F_TX_TSTAMP;
2735+
new_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
2736+
new_offloads |= ENETC_F_TX_TSTAMP;
26972737
break;
26982738
case HWTSTAMP_TX_ONESTEP_SYNC:
2699-
priv->active_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
2700-
priv->active_offloads |= ENETC_F_TX_ONESTEP_SYNC_TSTAMP;
2739+
new_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
2740+
new_offloads |= ENETC_F_TX_ONESTEP_SYNC_TSTAMP;
27012741
break;
27022742
default:
27032743
return -ERANGE;
27042744
}
27052745

2706-
ao = priv->active_offloads;
27072746
switch (config.rx_filter) {
27082747
case HWTSTAMP_FILTER_NONE:
2709-
priv->active_offloads &= ~ENETC_F_RX_TSTAMP;
2748+
new_offloads &= ~ENETC_F_RX_TSTAMP;
27102749
break;
27112750
default:
2712-
priv->active_offloads |= ENETC_F_RX_TSTAMP;
2751+
new_offloads |= ENETC_F_RX_TSTAMP;
27132752
config.rx_filter = HWTSTAMP_FILTER_ALL;
27142753
}
27152754

2716-
if (netif_running(ndev) && ao != priv->active_offloads) {
2717-
enetc_close(ndev);
2718-
enetc_open(ndev);
2755+
if ((new_offloads ^ priv->active_offloads) & ENETC_F_RX_TSTAMP) {
2756+
bool extended = !!(new_offloads & ENETC_F_RX_TSTAMP);
2757+
2758+
err = enetc_reconfigure(priv, extended);
2759+
if (err)
2760+
return err;
27192761
}
27202762

2763+
priv->active_offloads = new_offloads;
2764+
27212765
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
27222766
-EFAULT : 0;
27232767
}

0 commit comments

Comments
 (0)