ti_cpsw: Validate hwtstamp_config completely before applying it
cpsw_hwtstamp_ioctl() should validate all fields of hwtstamp_config,
and the hardware version, before making any changes. Currently it
sets the TX configuration before validating the rx_filter field
or that the hardware supports timestamping.
Also correct the error code for hardware versions that don't
support timestamping. ENOTSUPP is used by the NFS implementation
and is not part of userland API; we want EOPNOTSUPP (which glibc
also calls ENOTSUP, with one 'P').
Untested as I don't have a cross-compiler to hand.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Acked-by: Mugunthan V N <mugunthanvnm@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 90d41d2..30b0c03 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1323,6 +1323,10 @@
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;
@@ -1330,16 +1334,8 @@
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:
@@ -1366,6 +1362,8 @@
return -ERANGE;
}
+ cpts->tx_enable = cfg.tx_type == HWTSTAMP_TX_ON;
+
switch (priv->version) {
case CPSW_VERSION_1:
cpsw_hwtstamp_v1(priv);
@@ -1374,7 +1372,7 @@
cpsw_hwtstamp_v2(priv);
break;
default:
- return -ENOTSUPP;
+ WARN_ON(1);
}
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;