Skip to content

Commit

Permalink
Merge branch 'hwtstamp'
Browse files Browse the repository at this point in the history
Ben Hutchings says:

====================
net_tstamp: Validate hwtstamp_config completely before applying it

This series fixes very similar bugs in 6 implementations of
SIOCSHWTSTAMP.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Nov 14, 2013
2 parents b4e09b2 + a5be8cd commit 6afae64
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 54 deletions.
16 changes: 7 additions & 9 deletions drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -13618,16 +13618,9 @@ static int tg3_hwtstamp_ioctl(struct net_device *dev,
if (stmpconf.flags)
return -EINVAL;

switch (stmpconf.tx_type) {
case HWTSTAMP_TX_ON:
tg3_flag_set(tp, TX_TSTAMP_EN);
break;
case HWTSTAMP_TX_OFF:
tg3_flag_clear(tp, TX_TSTAMP_EN);
break;
default:
if (stmpconf.tx_type != HWTSTAMP_TX_ON &&
stmpconf.tx_type != HWTSTAMP_TX_OFF)
return -ERANGE;
}

switch (stmpconf.rx_filter) {
case HWTSTAMP_FILTER_NONE:
Expand Down Expand Up @@ -13689,6 +13682,11 @@ static int tg3_hwtstamp_ioctl(struct net_device *dev,
tw32(TG3_RX_PTP_CTL,
tp->rxptpctl | TG3_RX_PTP_CTL_HWTS_INTERLOCK);

if (stmpconf.tx_type == HWTSTAMP_TX_ON)
tg3_flag_set(tp, TX_TSTAMP_EN);
else
tg3_flag_clear(tp, TX_TSTAMP_EN);

return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ?
-EFAULT : 0;
}
Expand Down
14 changes: 6 additions & 8 deletions drivers/net/ethernet/intel/e1000e/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -3482,10 +3482,10 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
* specified. Matching the kind of event packet is not supported, with the
* exception of "all V2 events regardless of level 2 or 4".
**/
static int e1000e_config_hwtstamp(struct e1000_adapter *adapter)
static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
struct hwtstamp_config *config)
{
struct e1000_hw *hw = &adapter->hw;
struct hwtstamp_config *config = &adapter->hwtstamp_config;
u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
u32 rxmtrl = 0;
Expand Down Expand Up @@ -3586,6 +3586,8 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter)
return -ERANGE;
}

adapter->hwtstamp_config = *config;

/* enable/disable Tx h/w time stamping */
regval = er32(TSYNCTXCTL);
regval &= ~E1000_TSYNCTXCTL_ENABLED;
Expand Down Expand Up @@ -3874,7 +3876,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
e1000e_reset_adaptive(hw);

/* initialize systim and reset the ns time counter */
e1000e_config_hwtstamp(adapter);
e1000e_config_hwtstamp(adapter, &adapter->hwtstamp_config);

/* Set EEE advertisement as appropriate */
if (adapter->flags2 & FLAG2_HAS_EEE) {
Expand Down Expand Up @@ -5797,14 +5799,10 @@ static int e1000e_hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;

adapter->hwtstamp_config = config;

ret_val = e1000e_config_hwtstamp(adapter);
ret_val = e1000e_config_hwtstamp(adapter, &config);
if (ret_val)
return ret_val;

config = adapter->hwtstamp_config;

switch (config.rx_filter) {
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
Expand Down
12 changes: 3 additions & 9 deletions drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,16 +245,8 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
/* Get ieee1588's dev information */
pdev = adapter->ptp_pdev;

switch (cfg.tx_type) {
case HWTSTAMP_TX_OFF:
adapter->hwts_tx_en = 0;
break;
case HWTSTAMP_TX_ON:
adapter->hwts_tx_en = 1;
break;
default:
if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON)
return -ERANGE;
}

switch (cfg.rx_filter) {
case HWTSTAMP_FILTER_NONE:
Expand Down Expand Up @@ -284,6 +276,8 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
return -ERANGE;
}

adapter->hwts_tx_en = cfg.tx_type == HWTSTAMP_TX_ON;

/* Clear out any old time stamps. */
pch_ch_event_write(pdev, TX_SNAPSHOT_LOCKED | RX_SNAPSHOT_LOCKED);

Expand Down
12 changes: 3 additions & 9 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,16 +435,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
if (config.flags)
return -EINVAL;

switch (config.tx_type) {
case HWTSTAMP_TX_OFF:
priv->hwts_tx_en = 0;
break;
case HWTSTAMP_TX_ON:
priv->hwts_tx_en = 1;
break;
default:
if (config.tx_type != HWTSTAMP_TX_OFF &&
config.tx_type != HWTSTAMP_TX_ON)
return -ERANGE;
}

if (priv->adv_ts) {
switch (config.rx_filter) {
Expand Down Expand Up @@ -576,6 +569,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
}
}
priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1);
priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;

if (!priv->hwts_tx_en && !priv->hwts_rx_en)
priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0);
Expand Down
18 changes: 8 additions & 10 deletions drivers/net/ethernet/ti/cpsw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1323,23 +1323,19 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
struct cpts *cpts = priv->cpts;
struct hwtstamp_config cfg;

if (priv->version != CPSW_VERSION_1 &&
priv->version != CPSW_VERSION_2)
return -EOPNOTSUPP;

if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
return -EFAULT;

/* reserved for future extensions */
if (cfg.flags)
return -EINVAL;

switch (cfg.tx_type) {
case HWTSTAMP_TX_OFF:
cpts->tx_enable = 0;
break;
case HWTSTAMP_TX_ON:
cpts->tx_enable = 1;
break;
default:
if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON)
return -ERANGE;
}

switch (cfg.rx_filter) {
case HWTSTAMP_FILTER_NONE:
Expand All @@ -1366,6 +1362,8 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
return -ERANGE;
}

cpts->tx_enable = cfg.tx_type == HWTSTAMP_TX_ON;

switch (priv->version) {
case CPSW_VERSION_1:
cpsw_hwtstamp_v1(priv);
Expand All @@ -1374,7 +1372,7 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
cpsw_hwtstamp_v2(priv);
break;
default:
return -ENOTSUPP;
WARN_ON(1);
}

return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
Expand Down
12 changes: 3 additions & 9 deletions drivers/net/ethernet/xscale/ixp4xx_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,16 +389,8 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
ch = PORT2CHANNEL(port);
regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT;

switch (cfg.tx_type) {
case HWTSTAMP_TX_OFF:
port->hwts_tx_en = 0;
break;
case HWTSTAMP_TX_ON:
port->hwts_tx_en = 1;
break;
default:
if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON)
return -ERANGE;
}

switch (cfg.rx_filter) {
case HWTSTAMP_FILTER_NONE:
Expand All @@ -416,6 +408,8 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
return -ERANGE;
}

port->hwts_tx_en = cfg.tx_type == HWTSTAMP_TX_ON;

/* Clear out any old time stamps. */
__raw_writel(TX_SNAPSHOT_LOCKED | RX_SNAPSHOT_LOCKED,
&regs->channel[ch].ch_event);
Expand Down

0 comments on commit 6afae64

Please sign in to comment.