diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2011-12-15 08:55:01 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-16 13:52:47 -0500 |
commit | 7850f63f1620512631445b901ae11cd149e7375c (patch) | |
tree | d26a5f049dcf3634c4bf9e1b86915d201fab3836 /drivers/net/ethernet/sfc/ethtool.c | |
parent | 14596f7006297b67516e2b6a2b26bcb11fe08fb3 (diff) |
ethtool: Centralise validation of ETHTOOL_{G, S}RXFHINDIR parameters
Add a new ethtool operation (get_rxfh_indir_size) to get the
indirectional table size. Use this to validate the user buffer size
before calling get_rxfh_indir or set_rxfh_indir. Use get_rxnfc to get
the number of RX rings, and validate the contents of the new
indirection table before calling set_rxfh_indir. Remove this
validation from drivers.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Acked-by: Dimitris Michailidis <dm@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/sfc/ethtool.c')
-rw-r--r-- | drivers/net/ethernet/sfc/ethtool.c | 35 |
1 files changed, 12 insertions, 23 deletions
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index f3cd96dfa398..1be51b2bfa42 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c | |||
@@ -956,40 +956,28 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev, | |||
956 | return rc < 0 ? rc : 0; | 956 | return rc < 0 ? rc : 0; |
957 | } | 957 | } |
958 | 958 | ||
959 | static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, | 959 | static u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev) |
960 | struct ethtool_rxfh_indir *indir) | ||
961 | { | 960 | { |
962 | struct efx_nic *efx = netdev_priv(net_dev); | 961 | struct efx_nic *efx = netdev_priv(net_dev); |
963 | size_t copy_size = | ||
964 | min_t(size_t, indir->size, ARRAY_SIZE(efx->rx_indir_table)); | ||
965 | 962 | ||
966 | if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) | 963 | return (efx_nic_rev(efx) < EFX_REV_FALCON_B0 ? |
967 | return -EOPNOTSUPP; | 964 | 0 : ARRAY_SIZE(efx->rx_indir_table)); |
965 | } | ||
966 | |||
967 | static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, u32 *indir) | ||
968 | { | ||
969 | struct efx_nic *efx = netdev_priv(net_dev); | ||
968 | 970 | ||
969 | indir->size = ARRAY_SIZE(efx->rx_indir_table); | 971 | memcpy(indir, efx->rx_indir_table, sizeof(efx->rx_indir_table)); |
970 | memcpy(indir->ring_index, efx->rx_indir_table, | ||
971 | copy_size * sizeof(indir->ring_index[0])); | ||
972 | return 0; | 972 | return 0; |
973 | } | 973 | } |
974 | 974 | ||
975 | static int efx_ethtool_set_rxfh_indir(struct net_device *net_dev, | 975 | static int efx_ethtool_set_rxfh_indir(struct net_device *net_dev, |
976 | const struct ethtool_rxfh_indir *indir) | 976 | const u32 *indir) |
977 | { | 977 | { |
978 | struct efx_nic *efx = netdev_priv(net_dev); | 978 | struct efx_nic *efx = netdev_priv(net_dev); |
979 | size_t i; | ||
980 | |||
981 | if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) | ||
982 | return -EOPNOTSUPP; | ||
983 | |||
984 | /* Validate size and indices */ | ||
985 | if (indir->size != ARRAY_SIZE(efx->rx_indir_table)) | ||
986 | return -EINVAL; | ||
987 | for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++) | ||
988 | if (indir->ring_index[i] >= efx->n_rx_channels) | ||
989 | return -EINVAL; | ||
990 | 979 | ||
991 | memcpy(efx->rx_indir_table, indir->ring_index, | 980 | memcpy(efx->rx_indir_table, indir, sizeof(efx->rx_indir_table)); |
992 | sizeof(efx->rx_indir_table)); | ||
993 | efx_nic_push_rx_indir_table(efx); | 981 | efx_nic_push_rx_indir_table(efx); |
994 | return 0; | 982 | return 0; |
995 | } | 983 | } |
@@ -1020,6 +1008,7 @@ const struct ethtool_ops efx_ethtool_ops = { | |||
1020 | .reset = efx_ethtool_reset, | 1008 | .reset = efx_ethtool_reset, |
1021 | .get_rxnfc = efx_ethtool_get_rxnfc, | 1009 | .get_rxnfc = efx_ethtool_get_rxnfc, |
1022 | .set_rx_ntuple = efx_ethtool_set_rx_ntuple, | 1010 | .set_rx_ntuple = efx_ethtool_set_rx_ntuple, |
1011 | .get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size, | ||
1023 | .get_rxfh_indir = efx_ethtool_get_rxfh_indir, | 1012 | .get_rxfh_indir = efx_ethtool_get_rxfh_indir, |
1024 | .set_rxfh_indir = efx_ethtool_set_rxfh_indir, | 1013 | .set_rxfh_indir = efx_ethtool_set_rxfh_indir, |
1025 | }; | 1014 | }; |