aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/ethtool.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-08 11:25:42 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-08 11:26:00 -0400
commit5af8c4e0fac9838428bd718040b664043a05f37c (patch)
tree75a01d98ed244db45fe3c734c4a81c1a3d92ac37 /net/core/ethtool.c
parent46e0bb9c12f4bab539736f1714cbf16600f681ec (diff)
parent577c9c456f0e1371cbade38eaf91ae8e8a308555 (diff)
Merge commit 'v2.6.30-rc1' into sched/urgent
Merge reason: update to latest upstream to queue up fix Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/core/ethtool.c')
-rw-r--r--net/core/ethtool.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 947710a36ced..d9d5160610d5 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -209,34 +209,61 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
209 return 0; 209 return 0;
210} 210}
211 211
212static int ethtool_set_rxhash(struct net_device *dev, void __user *useraddr) 212static int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr)
213{ 213{
214 struct ethtool_rxnfc cmd; 214 struct ethtool_rxnfc cmd;
215 215
216 if (!dev->ethtool_ops->set_rxhash) 216 if (!dev->ethtool_ops->set_rxnfc)
217 return -EOPNOTSUPP; 217 return -EOPNOTSUPP;
218 218
219 if (copy_from_user(&cmd, useraddr, sizeof(cmd))) 219 if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
220 return -EFAULT; 220 return -EFAULT;
221 221
222 return dev->ethtool_ops->set_rxhash(dev, &cmd); 222 return dev->ethtool_ops->set_rxnfc(dev, &cmd);
223} 223}
224 224
225static int ethtool_get_rxhash(struct net_device *dev, void __user *useraddr) 225static int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
226{ 226{
227 struct ethtool_rxnfc info; 227 struct ethtool_rxnfc info;
228 const struct ethtool_ops *ops = dev->ethtool_ops;
229 int ret;
230 void *rule_buf = NULL;
228 231
229 if (!dev->ethtool_ops->get_rxhash) 232 if (!ops->get_rxnfc)
230 return -EOPNOTSUPP; 233 return -EOPNOTSUPP;
231 234
232 if (copy_from_user(&info, useraddr, sizeof(info))) 235 if (copy_from_user(&info, useraddr, sizeof(info)))
233 return -EFAULT; 236 return -EFAULT;
234 237
235 dev->ethtool_ops->get_rxhash(dev, &info); 238 if (info.cmd == ETHTOOL_GRXCLSRLALL) {
239 if (info.rule_cnt > 0) {
240 rule_buf = kmalloc(info.rule_cnt * sizeof(u32),
241 GFP_USER);
242 if (!rule_buf)
243 return -ENOMEM;
244 }
245 }
236 246
247 ret = ops->get_rxnfc(dev, &info, rule_buf);
248 if (ret < 0)
249 goto err_out;
250
251 ret = -EFAULT;
237 if (copy_to_user(useraddr, &info, sizeof(info))) 252 if (copy_to_user(useraddr, &info, sizeof(info)))
238 return -EFAULT; 253 goto err_out;
239 return 0; 254
255 if (rule_buf) {
256 useraddr += offsetof(struct ethtool_rxnfc, rule_locs);
257 if (copy_to_user(useraddr, rule_buf,
258 info.rule_cnt * sizeof(u32)))
259 goto err_out;
260 }
261 ret = 0;
262
263err_out:
264 kfree(rule_buf);
265
266 return ret;
240} 267}
241 268
242static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) 269static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
@@ -901,6 +928,10 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
901 case ETHTOOL_GFLAGS: 928 case ETHTOOL_GFLAGS:
902 case ETHTOOL_GPFLAGS: 929 case ETHTOOL_GPFLAGS:
903 case ETHTOOL_GRXFH: 930 case ETHTOOL_GRXFH:
931 case ETHTOOL_GRXRINGS:
932 case ETHTOOL_GRXCLSRLCNT:
933 case ETHTOOL_GRXCLSRULE:
934 case ETHTOOL_GRXCLSRLALL:
904 break; 935 break;
905 default: 936 default:
906 if (!capable(CAP_NET_ADMIN)) 937 if (!capable(CAP_NET_ADMIN))
@@ -1052,10 +1083,16 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1052 dev->ethtool_ops->set_priv_flags); 1083 dev->ethtool_ops->set_priv_flags);
1053 break; 1084 break;
1054 case ETHTOOL_GRXFH: 1085 case ETHTOOL_GRXFH:
1055 rc = ethtool_get_rxhash(dev, useraddr); 1086 case ETHTOOL_GRXRINGS:
1087 case ETHTOOL_GRXCLSRLCNT:
1088 case ETHTOOL_GRXCLSRULE:
1089 case ETHTOOL_GRXCLSRLALL:
1090 rc = ethtool_get_rxnfc(dev, useraddr);
1056 break; 1091 break;
1057 case ETHTOOL_SRXFH: 1092 case ETHTOOL_SRXFH:
1058 rc = ethtool_set_rxhash(dev, useraddr); 1093 case ETHTOOL_SRXCLSRLDEL:
1094 case ETHTOOL_SRXCLSRLINS:
1095 rc = ethtool_set_rxnfc(dev, useraddr);
1059 break; 1096 break;
1060 case ETHTOOL_GGRO: 1097 case ETHTOOL_GGRO:
1061 rc = ethtool_get_gro(dev, useraddr); 1098 rc = ethtool_get_gro(dev, useraddr);