aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2013-11-13 19:47:36 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-14 16:22:10 -0500
commit2ee91e54bd5367bf4123719a4f7203857b28e046 (patch)
tree6f41e8ce1a25163f0a809131a1a73c2cbfe4f59b
parent5f3da3281932a795b80cddd1887291515a7e324d (diff)
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>
-rw-r--r--drivers/net/ethernet/ti/cpsw.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 90d41d26ec6d..30b0c032e5fc 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1323,6 +1323,10 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
1323 struct cpts *cpts = priv->cpts; 1323 struct cpts *cpts = priv->cpts;
1324 struct hwtstamp_config cfg; 1324 struct hwtstamp_config cfg;
1325 1325
1326 if (priv->version != CPSW_VERSION_1 &&
1327 priv->version != CPSW_VERSION_2)
1328 return -EOPNOTSUPP;
1329
1326 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 1330 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
1327 return -EFAULT; 1331 return -EFAULT;
1328 1332
@@ -1330,16 +1334,8 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
1330 if (cfg.flags) 1334 if (cfg.flags)
1331 return -EINVAL; 1335 return -EINVAL;
1332 1336
1333 switch (cfg.tx_type) { 1337 if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON)
1334 case HWTSTAMP_TX_OFF:
1335 cpts->tx_enable = 0;
1336 break;
1337 case HWTSTAMP_TX_ON:
1338 cpts->tx_enable = 1;
1339 break;
1340 default:
1341 return -ERANGE; 1338 return -ERANGE;
1342 }
1343 1339
1344 switch (cfg.rx_filter) { 1340 switch (cfg.rx_filter) {
1345 case HWTSTAMP_FILTER_NONE: 1341 case HWTSTAMP_FILTER_NONE:
@@ -1366,6 +1362,8 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
1366 return -ERANGE; 1362 return -ERANGE;
1367 } 1363 }
1368 1364
1365 cpts->tx_enable = cfg.tx_type == HWTSTAMP_TX_ON;
1366
1369 switch (priv->version) { 1367 switch (priv->version) {
1370 case CPSW_VERSION_1: 1368 case CPSW_VERSION_1:
1371 cpsw_hwtstamp_v1(priv); 1369 cpsw_hwtstamp_v1(priv);
@@ -1374,7 +1372,7 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
1374 cpsw_hwtstamp_v2(priv); 1372 cpsw_hwtstamp_v2(priv);
1375 break; 1373 break;
1376 default: 1374 default:
1377 return -ENOTSUPP; 1375 WARN_ON(1);
1378 } 1376 }
1379 1377
1380 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 1378 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;