at v2.6.34-rc1 1498 lines 36 kB view raw
1/* 2 * net/core/ethtool.c - Ethtool ioctl handler 3 * Copyright (c) 2003 Matthew Wilcox <matthew@wil.cx> 4 * 5 * This file is where we call all the ethtool_ops commands to get 6 * the information ethtool needs. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14#include <linux/module.h> 15#include <linux/types.h> 16#include <linux/capability.h> 17#include <linux/errno.h> 18#include <linux/ethtool.h> 19#include <linux/netdevice.h> 20#include <asm/uaccess.h> 21 22/* 23 * Some useful ethtool_ops methods that're device independent. 24 * If we find that all drivers want to do the same thing here, 25 * we can turn these into dev_() function calls. 26 */ 27 28u32 ethtool_op_get_link(struct net_device *dev) 29{ 30 return netif_carrier_ok(dev) ? 1 : 0; 31} 32 33u32 ethtool_op_get_rx_csum(struct net_device *dev) 34{ 35 return (dev->features & NETIF_F_ALL_CSUM) != 0; 36} 37EXPORT_SYMBOL(ethtool_op_get_rx_csum); 38 39u32 ethtool_op_get_tx_csum(struct net_device *dev) 40{ 41 return (dev->features & NETIF_F_ALL_CSUM) != 0; 42} 43EXPORT_SYMBOL(ethtool_op_get_tx_csum); 44 45int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) 46{ 47 if (data) 48 dev->features |= NETIF_F_IP_CSUM; 49 else 50 dev->features &= ~NETIF_F_IP_CSUM; 51 52 return 0; 53} 54 55int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) 56{ 57 if (data) 58 dev->features |= NETIF_F_HW_CSUM; 59 else 60 dev->features &= ~NETIF_F_HW_CSUM; 61 62 return 0; 63} 64 65int ethtool_op_set_tx_ipv6_csum(struct net_device *dev, u32 data) 66{ 67 if (data) 68 dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; 69 else 70 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); 71 72 return 0; 73} 74 75u32 ethtool_op_get_sg(struct net_device *dev) 76{ 77 return (dev->features & NETIF_F_SG) != 0; 78} 79 80int ethtool_op_set_sg(struct net_device *dev, u32 data) 81{ 82 if (data) 83 dev->features |= NETIF_F_SG; 84 else 85 dev->features &= ~NETIF_F_SG; 86 87 return 0; 88} 89 90u32 ethtool_op_get_tso(struct net_device *dev) 91{ 92 return (dev->features & NETIF_F_TSO) != 0; 93} 94 95int ethtool_op_set_tso(struct net_device *dev, u32 data) 96{ 97 if (data) 98 dev->features |= NETIF_F_TSO; 99 else 100 dev->features &= ~NETIF_F_TSO; 101 102 return 0; 103} 104 105u32 ethtool_op_get_ufo(struct net_device *dev) 106{ 107 return (dev->features & NETIF_F_UFO) != 0; 108} 109 110int ethtool_op_set_ufo(struct net_device *dev, u32 data) 111{ 112 if (data) 113 dev->features |= NETIF_F_UFO; 114 else 115 dev->features &= ~NETIF_F_UFO; 116 return 0; 117} 118 119/* the following list of flags are the same as their associated 120 * NETIF_F_xxx values in include/linux/netdevice.h 121 */ 122static const u32 flags_dup_features = 123 (ETH_FLAG_LRO | ETH_FLAG_NTUPLE); 124 125u32 ethtool_op_get_flags(struct net_device *dev) 126{ 127 /* in the future, this function will probably contain additional 128 * handling for flags which are not so easily handled 129 * by a simple masking operation 130 */ 131 132 return dev->features & flags_dup_features; 133} 134 135int ethtool_op_set_flags(struct net_device *dev, u32 data) 136{ 137 const struct ethtool_ops *ops = dev->ethtool_ops; 138 unsigned long features = dev->features; 139 140 if (data & ETH_FLAG_LRO) 141 features |= NETIF_F_LRO; 142 else 143 features &= ~NETIF_F_LRO; 144 145 if (data & ETH_FLAG_NTUPLE) { 146 if (!ops->set_rx_ntuple) 147 return -EOPNOTSUPP; 148 features |= NETIF_F_NTUPLE; 149 } else { 150 /* safe to clear regardless */ 151 features &= ~NETIF_F_NTUPLE; 152 } 153 154 dev->features = features; 155 return 0; 156} 157 158void ethtool_ntuple_flush(struct net_device *dev) 159{ 160 struct ethtool_rx_ntuple_flow_spec_container *fsc, *f; 161 162 list_for_each_entry_safe(fsc, f, &dev->ethtool_ntuple_list.list, list) { 163 list_del(&fsc->list); 164 kfree(fsc); 165 } 166 dev->ethtool_ntuple_list.count = 0; 167} 168EXPORT_SYMBOL(ethtool_ntuple_flush); 169 170/* Handlers for each ethtool command */ 171 172static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) 173{ 174 struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; 175 int err; 176 177 if (!dev->ethtool_ops->get_settings) 178 return -EOPNOTSUPP; 179 180 err = dev->ethtool_ops->get_settings(dev, &cmd); 181 if (err < 0) 182 return err; 183 184 if (copy_to_user(useraddr, &cmd, sizeof(cmd))) 185 return -EFAULT; 186 return 0; 187} 188 189static int ethtool_set_settings(struct net_device *dev, void __user *useraddr) 190{ 191 struct ethtool_cmd cmd; 192 193 if (!dev->ethtool_ops->set_settings) 194 return -EOPNOTSUPP; 195 196 if (copy_from_user(&cmd, useraddr, sizeof(cmd))) 197 return -EFAULT; 198 199 return dev->ethtool_ops->set_settings(dev, &cmd); 200} 201 202/* 203 * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() 204 */ 205static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) 206{ 207 struct ethtool_drvinfo info; 208 const struct ethtool_ops *ops = dev->ethtool_ops; 209 210 if (!ops->get_drvinfo) 211 return -EOPNOTSUPP; 212 213 memset(&info, 0, sizeof(info)); 214 info.cmd = ETHTOOL_GDRVINFO; 215 ops->get_drvinfo(dev, &info); 216 217 if (ops->get_sset_count) { 218 int rc; 219 220 rc = ops->get_sset_count(dev, ETH_SS_TEST); 221 if (rc >= 0) 222 info.testinfo_len = rc; 223 rc = ops->get_sset_count(dev, ETH_SS_STATS); 224 if (rc >= 0) 225 info.n_stats = rc; 226 rc = ops->get_sset_count(dev, ETH_SS_PRIV_FLAGS); 227 if (rc >= 0) 228 info.n_priv_flags = rc; 229 } 230 if (ops->get_regs_len) 231 info.regdump_len = ops->get_regs_len(dev); 232 if (ops->get_eeprom_len) 233 info.eedump_len = ops->get_eeprom_len(dev); 234 235 if (copy_to_user(useraddr, &info, sizeof(info))) 236 return -EFAULT; 237 return 0; 238} 239 240/* 241 * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() 242 */ 243static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) 244{ 245 struct ethtool_rxnfc cmd; 246 247 if (!dev->ethtool_ops->set_rxnfc) 248 return -EOPNOTSUPP; 249 250 if (copy_from_user(&cmd, useraddr, sizeof(cmd))) 251 return -EFAULT; 252 253 return dev->ethtool_ops->set_rxnfc(dev, &cmd); 254} 255 256/* 257 * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() 258 */ 259static noinline int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr) 260{ 261 struct ethtool_rxnfc info; 262 const struct ethtool_ops *ops = dev->ethtool_ops; 263 int ret; 264 void *rule_buf = NULL; 265 266 if (!ops->get_rxnfc) 267 return -EOPNOTSUPP; 268 269 if (copy_from_user(&info, useraddr, sizeof(info))) 270 return -EFAULT; 271 272 if (info.cmd == ETHTOOL_GRXCLSRLALL) { 273 if (info.rule_cnt > 0) { 274 rule_buf = kmalloc(info.rule_cnt * sizeof(u32), 275 GFP_USER); 276 if (!rule_buf) 277 return -ENOMEM; 278 } 279 } 280 281 ret = ops->get_rxnfc(dev, &info, rule_buf); 282 if (ret < 0) 283 goto err_out; 284 285 ret = -EFAULT; 286 if (copy_to_user(useraddr, &info, sizeof(info))) 287 goto err_out; 288 289 if (rule_buf) { 290 useraddr += offsetof(struct ethtool_rxnfc, rule_locs); 291 if (copy_to_user(useraddr, rule_buf, 292 info.rule_cnt * sizeof(u32))) 293 goto err_out; 294 } 295 ret = 0; 296 297err_out: 298 kfree(rule_buf); 299 300 return ret; 301} 302 303static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list, 304 struct ethtool_rx_ntuple_flow_spec *spec, 305 struct ethtool_rx_ntuple_flow_spec_container *fsc) 306{ 307 308 /* don't add filters forever */ 309 if (list->count >= ETHTOOL_MAX_NTUPLE_LIST_ENTRY) { 310 /* free the container */ 311 kfree(fsc); 312 return; 313 } 314 315 /* Copy the whole filter over */ 316 fsc->fs.flow_type = spec->flow_type; 317 memcpy(&fsc->fs.h_u, &spec->h_u, sizeof(spec->h_u)); 318 memcpy(&fsc->fs.m_u, &spec->m_u, sizeof(spec->m_u)); 319 320 fsc->fs.vlan_tag = spec->vlan_tag; 321 fsc->fs.vlan_tag_mask = spec->vlan_tag_mask; 322 fsc->fs.data = spec->data; 323 fsc->fs.data_mask = spec->data_mask; 324 fsc->fs.action = spec->action; 325 326 /* add to the list */ 327 list_add_tail_rcu(&fsc->list, &list->list); 328 list->count++; 329} 330 331/* 332 * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() 333 */ 334static noinline int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr) 335{ 336 struct ethtool_rx_ntuple cmd; 337 const struct ethtool_ops *ops = dev->ethtool_ops; 338 struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL; 339 int ret; 340 341 if (!(dev->features & NETIF_F_NTUPLE)) 342 return -EINVAL; 343 344 if (copy_from_user(&cmd, useraddr, sizeof(cmd))) 345 return -EFAULT; 346 347 /* 348 * Cache filter in dev struct for GET operation only if 349 * the underlying driver doesn't have its own GET operation, and 350 * only if the filter was added successfully. First make sure we 351 * can allocate the filter, then continue if successful. 352 */ 353 if (!ops->get_rx_ntuple) { 354 fsc = kmalloc(sizeof(*fsc), GFP_ATOMIC); 355 if (!fsc) 356 return -ENOMEM; 357 } 358 359 ret = ops->set_rx_ntuple(dev, &cmd); 360 if (ret) { 361 kfree(fsc); 362 return ret; 363 } 364 365 if (!ops->get_rx_ntuple) 366 __rx_ntuple_filter_add(&dev->ethtool_ntuple_list, &cmd.fs, fsc); 367 368 return ret; 369} 370 371static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr) 372{ 373 struct ethtool_gstrings gstrings; 374 const struct ethtool_ops *ops = dev->ethtool_ops; 375 struct ethtool_rx_ntuple_flow_spec_container *fsc; 376 u8 *data; 377 char *p; 378 int ret, i, num_strings = 0; 379 380 if (!ops->get_sset_count) 381 return -EOPNOTSUPP; 382 383 if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) 384 return -EFAULT; 385 386 ret = ops->get_sset_count(dev, gstrings.string_set); 387 if (ret < 0) 388 return ret; 389 390 gstrings.len = ret; 391 392 data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); 393 if (!data) 394 return -ENOMEM; 395 396 if (ops->get_rx_ntuple) { 397 /* driver-specific filter grab */ 398 ret = ops->get_rx_ntuple(dev, gstrings.string_set, data); 399 goto copy; 400 } 401 402 /* default ethtool filter grab */ 403 i = 0; 404 p = (char *)data; 405 list_for_each_entry(fsc, &dev->ethtool_ntuple_list.list, list) { 406 sprintf(p, "Filter %d:\n", i); 407 p += ETH_GSTRING_LEN; 408 num_strings++; 409 410 switch (fsc->fs.flow_type) { 411 case TCP_V4_FLOW: 412 sprintf(p, "\tFlow Type: TCP\n"); 413 p += ETH_GSTRING_LEN; 414 num_strings++; 415 break; 416 case UDP_V4_FLOW: 417 sprintf(p, "\tFlow Type: UDP\n"); 418 p += ETH_GSTRING_LEN; 419 num_strings++; 420 break; 421 case SCTP_V4_FLOW: 422 sprintf(p, "\tFlow Type: SCTP\n"); 423 p += ETH_GSTRING_LEN; 424 num_strings++; 425 break; 426 case AH_ESP_V4_FLOW: 427 sprintf(p, "\tFlow Type: AH ESP\n"); 428 p += ETH_GSTRING_LEN; 429 num_strings++; 430 break; 431 case ESP_V4_FLOW: 432 sprintf(p, "\tFlow Type: ESP\n"); 433 p += ETH_GSTRING_LEN; 434 num_strings++; 435 break; 436 case IP_USER_FLOW: 437 sprintf(p, "\tFlow Type: Raw IP\n"); 438 p += ETH_GSTRING_LEN; 439 num_strings++; 440 break; 441 case IPV4_FLOW: 442 sprintf(p, "\tFlow Type: IPv4\n"); 443 p += ETH_GSTRING_LEN; 444 num_strings++; 445 break; 446 default: 447 sprintf(p, "\tFlow Type: Unknown\n"); 448 p += ETH_GSTRING_LEN; 449 num_strings++; 450 goto unknown_filter; 451 }; 452 453 /* now the rest of the filters */ 454 switch (fsc->fs.flow_type) { 455 case TCP_V4_FLOW: 456 case UDP_V4_FLOW: 457 case SCTP_V4_FLOW: 458 sprintf(p, "\tSrc IP addr: 0x%x\n", 459 fsc->fs.h_u.tcp_ip4_spec.ip4src); 460 p += ETH_GSTRING_LEN; 461 num_strings++; 462 sprintf(p, "\tSrc IP mask: 0x%x\n", 463 fsc->fs.m_u.tcp_ip4_spec.ip4src); 464 p += ETH_GSTRING_LEN; 465 num_strings++; 466 sprintf(p, "\tDest IP addr: 0x%x\n", 467 fsc->fs.h_u.tcp_ip4_spec.ip4dst); 468 p += ETH_GSTRING_LEN; 469 num_strings++; 470 sprintf(p, "\tDest IP mask: 0x%x\n", 471 fsc->fs.m_u.tcp_ip4_spec.ip4dst); 472 p += ETH_GSTRING_LEN; 473 num_strings++; 474 sprintf(p, "\tSrc Port: %d, mask: 0x%x\n", 475 fsc->fs.h_u.tcp_ip4_spec.psrc, 476 fsc->fs.m_u.tcp_ip4_spec.psrc); 477 p += ETH_GSTRING_LEN; 478 num_strings++; 479 sprintf(p, "\tDest Port: %d, mask: 0x%x\n", 480 fsc->fs.h_u.tcp_ip4_spec.pdst, 481 fsc->fs.m_u.tcp_ip4_spec.pdst); 482 p += ETH_GSTRING_LEN; 483 num_strings++; 484 sprintf(p, "\tTOS: %d, mask: 0x%x\n", 485 fsc->fs.h_u.tcp_ip4_spec.tos, 486 fsc->fs.m_u.tcp_ip4_spec.tos); 487 p += ETH_GSTRING_LEN; 488 num_strings++; 489 break; 490 case AH_ESP_V4_FLOW: 491 case ESP_V4_FLOW: 492 sprintf(p, "\tSrc IP addr: 0x%x\n", 493 fsc->fs.h_u.ah_ip4_spec.ip4src); 494 p += ETH_GSTRING_LEN; 495 num_strings++; 496 sprintf(p, "\tSrc IP mask: 0x%x\n", 497 fsc->fs.m_u.ah_ip4_spec.ip4src); 498 p += ETH_GSTRING_LEN; 499 num_strings++; 500 sprintf(p, "\tDest IP addr: 0x%x\n", 501 fsc->fs.h_u.ah_ip4_spec.ip4dst); 502 p += ETH_GSTRING_LEN; 503 num_strings++; 504 sprintf(p, "\tDest IP mask: 0x%x\n", 505 fsc->fs.m_u.ah_ip4_spec.ip4dst); 506 p += ETH_GSTRING_LEN; 507 num_strings++; 508 sprintf(p, "\tSPI: %d, mask: 0x%x\n", 509 fsc->fs.h_u.ah_ip4_spec.spi, 510 fsc->fs.m_u.ah_ip4_spec.spi); 511 p += ETH_GSTRING_LEN; 512 num_strings++; 513 sprintf(p, "\tTOS: %d, mask: 0x%x\n", 514 fsc->fs.h_u.ah_ip4_spec.tos, 515 fsc->fs.m_u.ah_ip4_spec.tos); 516 p += ETH_GSTRING_LEN; 517 num_strings++; 518 break; 519 case IP_USER_FLOW: 520 sprintf(p, "\tSrc IP addr: 0x%x\n", 521 fsc->fs.h_u.raw_ip4_spec.ip4src); 522 p += ETH_GSTRING_LEN; 523 num_strings++; 524 sprintf(p, "\tSrc IP mask: 0x%x\n", 525 fsc->fs.m_u.raw_ip4_spec.ip4src); 526 p += ETH_GSTRING_LEN; 527 num_strings++; 528 sprintf(p, "\tDest IP addr: 0x%x\n", 529 fsc->fs.h_u.raw_ip4_spec.ip4dst); 530 p += ETH_GSTRING_LEN; 531 num_strings++; 532 sprintf(p, "\tDest IP mask: 0x%x\n", 533 fsc->fs.m_u.raw_ip4_spec.ip4dst); 534 p += ETH_GSTRING_LEN; 535 num_strings++; 536 break; 537 case IPV4_FLOW: 538 sprintf(p, "\tSrc IP addr: 0x%x\n", 539 fsc->fs.h_u.usr_ip4_spec.ip4src); 540 p += ETH_GSTRING_LEN; 541 num_strings++; 542 sprintf(p, "\tSrc IP mask: 0x%x\n", 543 fsc->fs.m_u.usr_ip4_spec.ip4src); 544 p += ETH_GSTRING_LEN; 545 num_strings++; 546 sprintf(p, "\tDest IP addr: 0x%x\n", 547 fsc->fs.h_u.usr_ip4_spec.ip4dst); 548 p += ETH_GSTRING_LEN; 549 num_strings++; 550 sprintf(p, "\tDest IP mask: 0x%x\n", 551 fsc->fs.m_u.usr_ip4_spec.ip4dst); 552 p += ETH_GSTRING_LEN; 553 num_strings++; 554 sprintf(p, "\tL4 bytes: 0x%x, mask: 0x%x\n", 555 fsc->fs.h_u.usr_ip4_spec.l4_4_bytes, 556 fsc->fs.m_u.usr_ip4_spec.l4_4_bytes); 557 p += ETH_GSTRING_LEN; 558 num_strings++; 559 sprintf(p, "\tTOS: %d, mask: 0x%x\n", 560 fsc->fs.h_u.usr_ip4_spec.tos, 561 fsc->fs.m_u.usr_ip4_spec.tos); 562 p += ETH_GSTRING_LEN; 563 num_strings++; 564 sprintf(p, "\tIP Version: %d, mask: 0x%x\n", 565 fsc->fs.h_u.usr_ip4_spec.ip_ver, 566 fsc->fs.m_u.usr_ip4_spec.ip_ver); 567 p += ETH_GSTRING_LEN; 568 num_strings++; 569 sprintf(p, "\tProtocol: %d, mask: 0x%x\n", 570 fsc->fs.h_u.usr_ip4_spec.proto, 571 fsc->fs.m_u.usr_ip4_spec.proto); 572 p += ETH_GSTRING_LEN; 573 num_strings++; 574 break; 575 }; 576 sprintf(p, "\tVLAN: %d, mask: 0x%x\n", 577 fsc->fs.vlan_tag, fsc->fs.vlan_tag_mask); 578 p += ETH_GSTRING_LEN; 579 num_strings++; 580 sprintf(p, "\tUser-defined: 0x%Lx\n", fsc->fs.data); 581 p += ETH_GSTRING_LEN; 582 num_strings++; 583 sprintf(p, "\tUser-defined mask: 0x%Lx\n", fsc->fs.data_mask); 584 p += ETH_GSTRING_LEN; 585 num_strings++; 586 if (fsc->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) 587 sprintf(p, "\tAction: Drop\n"); 588 else 589 sprintf(p, "\tAction: Direct to queue %d\n", 590 fsc->fs.action); 591 p += ETH_GSTRING_LEN; 592 num_strings++; 593unknown_filter: 594 i++; 595 } 596copy: 597 /* indicate to userspace how many strings we actually have */ 598 gstrings.len = num_strings; 599 ret = -EFAULT; 600 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) 601 goto out; 602 useraddr += sizeof(gstrings); 603 if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) 604 goto out; 605 ret = 0; 606 607out: 608 kfree(data); 609 return ret; 610} 611 612static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) 613{ 614 struct ethtool_regs regs; 615 const struct ethtool_ops *ops = dev->ethtool_ops; 616 void *regbuf; 617 int reglen, ret; 618 619 if (!ops->get_regs || !ops->get_regs_len) 620 return -EOPNOTSUPP; 621 622 if (copy_from_user(&regs, useraddr, sizeof(regs))) 623 return -EFAULT; 624 625 reglen = ops->get_regs_len(dev); 626 if (regs.len > reglen) 627 regs.len = reglen; 628 629 regbuf = kmalloc(reglen, GFP_USER); 630 if (!regbuf) 631 return -ENOMEM; 632 633 ops->get_regs(dev, &regs, regbuf); 634 635 ret = -EFAULT; 636 if (copy_to_user(useraddr, &regs, sizeof(regs))) 637 goto out; 638 useraddr += offsetof(struct ethtool_regs, data); 639 if (copy_to_user(useraddr, regbuf, regs.len)) 640 goto out; 641 ret = 0; 642 643 out: 644 kfree(regbuf); 645 return ret; 646} 647 648static int ethtool_reset(struct net_device *dev, char __user *useraddr) 649{ 650 struct ethtool_value reset; 651 int ret; 652 653 if (!dev->ethtool_ops->reset) 654 return -EOPNOTSUPP; 655 656 if (copy_from_user(&reset, useraddr, sizeof(reset))) 657 return -EFAULT; 658 659 ret = dev->ethtool_ops->reset(dev, &reset.data); 660 if (ret) 661 return ret; 662 663 if (copy_to_user(useraddr, &reset, sizeof(reset))) 664 return -EFAULT; 665 return 0; 666} 667 668static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) 669{ 670 struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; 671 672 if (!dev->ethtool_ops->get_wol) 673 return -EOPNOTSUPP; 674 675 dev->ethtool_ops->get_wol(dev, &wol); 676 677 if (copy_to_user(useraddr, &wol, sizeof(wol))) 678 return -EFAULT; 679 return 0; 680} 681 682static int ethtool_set_wol(struct net_device *dev, char __user *useraddr) 683{ 684 struct ethtool_wolinfo wol; 685 686 if (!dev->ethtool_ops->set_wol) 687 return -EOPNOTSUPP; 688 689 if (copy_from_user(&wol, useraddr, sizeof(wol))) 690 return -EFAULT; 691 692 return dev->ethtool_ops->set_wol(dev, &wol); 693} 694 695static int ethtool_nway_reset(struct net_device *dev) 696{ 697 if (!dev->ethtool_ops->nway_reset) 698 return -EOPNOTSUPP; 699 700 return dev->ethtool_ops->nway_reset(dev); 701} 702 703static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) 704{ 705 struct ethtool_eeprom eeprom; 706 const struct ethtool_ops *ops = dev->ethtool_ops; 707 void __user *userbuf = useraddr + sizeof(eeprom); 708 u32 bytes_remaining; 709 u8 *data; 710 int ret = 0; 711 712 if (!ops->get_eeprom || !ops->get_eeprom_len) 713 return -EOPNOTSUPP; 714 715 if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) 716 return -EFAULT; 717 718 /* Check for wrap and zero */ 719 if (eeprom.offset + eeprom.len <= eeprom.offset) 720 return -EINVAL; 721 722 /* Check for exceeding total eeprom len */ 723 if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) 724 return -EINVAL; 725 726 data = kmalloc(PAGE_SIZE, GFP_USER); 727 if (!data) 728 return -ENOMEM; 729 730 bytes_remaining = eeprom.len; 731 while (bytes_remaining > 0) { 732 eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE); 733 734 ret = ops->get_eeprom(dev, &eeprom, data); 735 if (ret) 736 break; 737 if (copy_to_user(userbuf, data, eeprom.len)) { 738 ret = -EFAULT; 739 break; 740 } 741 userbuf += eeprom.len; 742 eeprom.offset += eeprom.len; 743 bytes_remaining -= eeprom.len; 744 } 745 746 eeprom.len = userbuf - (useraddr + sizeof(eeprom)); 747 eeprom.offset -= eeprom.len; 748 if (copy_to_user(useraddr, &eeprom, sizeof(eeprom))) 749 ret = -EFAULT; 750 751 kfree(data); 752 return ret; 753} 754 755static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr) 756{ 757 struct ethtool_eeprom eeprom; 758 const struct ethtool_ops *ops = dev->ethtool_ops; 759 void __user *userbuf = useraddr + sizeof(eeprom); 760 u32 bytes_remaining; 761 u8 *data; 762 int ret = 0; 763 764 if (!ops->set_eeprom || !ops->get_eeprom_len) 765 return -EOPNOTSUPP; 766 767 if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) 768 return -EFAULT; 769 770 /* Check for wrap and zero */ 771 if (eeprom.offset + eeprom.len <= eeprom.offset) 772 return -EINVAL; 773 774 /* Check for exceeding total eeprom len */ 775 if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) 776 return -EINVAL; 777 778 data = kmalloc(PAGE_SIZE, GFP_USER); 779 if (!data) 780 return -ENOMEM; 781 782 bytes_remaining = eeprom.len; 783 while (bytes_remaining > 0) { 784 eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE); 785 786 if (copy_from_user(data, userbuf, eeprom.len)) { 787 ret = -EFAULT; 788 break; 789 } 790 ret = ops->set_eeprom(dev, &eeprom, data); 791 if (ret) 792 break; 793 userbuf += eeprom.len; 794 eeprom.offset += eeprom.len; 795 bytes_remaining -= eeprom.len; 796 } 797 798 kfree(data); 799 return ret; 800} 801 802/* 803 * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() 804 */ 805static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr) 806{ 807 struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE }; 808 809 if (!dev->ethtool_ops->get_coalesce) 810 return -EOPNOTSUPP; 811 812 dev->ethtool_ops->get_coalesce(dev, &coalesce); 813 814 if (copy_to_user(useraddr, &coalesce, sizeof(coalesce))) 815 return -EFAULT; 816 return 0; 817} 818 819/* 820 * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() 821 */ 822static noinline int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) 823{ 824 struct ethtool_coalesce coalesce; 825 826 if (!dev->ethtool_ops->set_coalesce) 827 return -EOPNOTSUPP; 828 829 if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) 830 return -EFAULT; 831 832 return dev->ethtool_ops->set_coalesce(dev, &coalesce); 833} 834 835static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr) 836{ 837 struct ethtool_ringparam ringparam = { .cmd = ETHTOOL_GRINGPARAM }; 838 839 if (!dev->ethtool_ops->get_ringparam) 840 return -EOPNOTSUPP; 841 842 dev->ethtool_ops->get_ringparam(dev, &ringparam); 843 844 if (copy_to_user(useraddr, &ringparam, sizeof(ringparam))) 845 return -EFAULT; 846 return 0; 847} 848 849static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr) 850{ 851 struct ethtool_ringparam ringparam; 852 853 if (!dev->ethtool_ops->set_ringparam) 854 return -EOPNOTSUPP; 855 856 if (copy_from_user(&ringparam, useraddr, sizeof(ringparam))) 857 return -EFAULT; 858 859 return dev->ethtool_ops->set_ringparam(dev, &ringparam); 860} 861 862static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr) 863{ 864 struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; 865 866 if (!dev->ethtool_ops->get_pauseparam) 867 return -EOPNOTSUPP; 868 869 dev->ethtool_ops->get_pauseparam(dev, &pauseparam); 870 871 if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam))) 872 return -EFAULT; 873 return 0; 874} 875 876static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr) 877{ 878 struct ethtool_pauseparam pauseparam; 879 880 if (!dev->ethtool_ops->set_pauseparam) 881 return -EOPNOTSUPP; 882 883 if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) 884 return -EFAULT; 885 886 return dev->ethtool_ops->set_pauseparam(dev, &pauseparam); 887} 888 889static int __ethtool_set_sg(struct net_device *dev, u32 data) 890{ 891 int err; 892 893 if (!data && dev->ethtool_ops->set_tso) { 894 err = dev->ethtool_ops->set_tso(dev, 0); 895 if (err) 896 return err; 897 } 898 899 if (!data && dev->ethtool_ops->set_ufo) { 900 err = dev->ethtool_ops->set_ufo(dev, 0); 901 if (err) 902 return err; 903 } 904 return dev->ethtool_ops->set_sg(dev, data); 905} 906 907static int ethtool_set_tx_csum(struct net_device *dev, char __user *useraddr) 908{ 909 struct ethtool_value edata; 910 int err; 911 912 if (!dev->ethtool_ops->set_tx_csum) 913 return -EOPNOTSUPP; 914 915 if (copy_from_user(&edata, useraddr, sizeof(edata))) 916 return -EFAULT; 917 918 if (!edata.data && dev->ethtool_ops->set_sg) { 919 err = __ethtool_set_sg(dev, 0); 920 if (err) 921 return err; 922 } 923 924 return dev->ethtool_ops->set_tx_csum(dev, edata.data); 925} 926 927static int ethtool_set_rx_csum(struct net_device *dev, char __user *useraddr) 928{ 929 struct ethtool_value edata; 930 931 if (!dev->ethtool_ops->set_rx_csum) 932 return -EOPNOTSUPP; 933 934 if (copy_from_user(&edata, useraddr, sizeof(edata))) 935 return -EFAULT; 936 937 if (!edata.data && dev->ethtool_ops->set_sg) 938 dev->features &= ~NETIF_F_GRO; 939 940 return dev->ethtool_ops->set_rx_csum(dev, edata.data); 941} 942 943static int ethtool_set_sg(struct net_device *dev, char __user *useraddr) 944{ 945 struct ethtool_value edata; 946 947 if (!dev->ethtool_ops->set_sg) 948 return -EOPNOTSUPP; 949 950 if (copy_from_user(&edata, useraddr, sizeof(edata))) 951 return -EFAULT; 952 953 if (edata.data && 954 !(dev->features & NETIF_F_ALL_CSUM)) 955 return -EINVAL; 956 957 return __ethtool_set_sg(dev, edata.data); 958} 959 960static int ethtool_set_tso(struct net_device *dev, char __user *useraddr) 961{ 962 struct ethtool_value edata; 963 964 if (!dev->ethtool_ops->set_tso) 965 return -EOPNOTSUPP; 966 967 if (copy_from_user(&edata, useraddr, sizeof(edata))) 968 return -EFAULT; 969 970 if (edata.data && !(dev->features & NETIF_F_SG)) 971 return -EINVAL; 972 973 return dev->ethtool_ops->set_tso(dev, edata.data); 974} 975 976static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr) 977{ 978 struct ethtool_value edata; 979 980 if (!dev->ethtool_ops->set_ufo) 981 return -EOPNOTSUPP; 982 if (copy_from_user(&edata, useraddr, sizeof(edata))) 983 return -EFAULT; 984 if (edata.data && !(dev->features & NETIF_F_SG)) 985 return -EINVAL; 986 if (edata.data && !(dev->features & NETIF_F_HW_CSUM)) 987 return -EINVAL; 988 return dev->ethtool_ops->set_ufo(dev, edata.data); 989} 990 991static int ethtool_get_gso(struct net_device *dev, char __user *useraddr) 992{ 993 struct ethtool_value edata = { ETHTOOL_GGSO }; 994 995 edata.data = dev->features & NETIF_F_GSO; 996 if (copy_to_user(useraddr, &edata, sizeof(edata))) 997 return -EFAULT; 998 return 0; 999} 1000 1001static int ethtool_set_gso(struct net_device *dev, char __user *useraddr) 1002{ 1003 struct ethtool_value edata; 1004 1005 if (copy_from_user(&edata, useraddr, sizeof(edata))) 1006 return -EFAULT; 1007 if (edata.data) 1008 dev->features |= NETIF_F_GSO; 1009 else 1010 dev->features &= ~NETIF_F_GSO; 1011 return 0; 1012} 1013 1014static int ethtool_get_gro(struct net_device *dev, char __user *useraddr) 1015{ 1016 struct ethtool_value edata = { ETHTOOL_GGRO }; 1017 1018 edata.data = dev->features & NETIF_F_GRO; 1019 if (copy_to_user(useraddr, &edata, sizeof(edata))) 1020 return -EFAULT; 1021 return 0; 1022} 1023 1024static int ethtool_set_gro(struct net_device *dev, char __user *useraddr) 1025{ 1026 struct ethtool_value edata; 1027 1028 if (copy_from_user(&edata, useraddr, sizeof(edata))) 1029 return -EFAULT; 1030 1031 if (edata.data) { 1032 if (!dev->ethtool_ops->get_rx_csum || 1033 !dev->ethtool_ops->get_rx_csum(dev)) 1034 return -EINVAL; 1035 dev->features |= NETIF_F_GRO; 1036 } else 1037 dev->features &= ~NETIF_F_GRO; 1038 1039 return 0; 1040} 1041 1042static int ethtool_self_test(struct net_device *dev, char __user *useraddr) 1043{ 1044 struct ethtool_test test; 1045 const struct ethtool_ops *ops = dev->ethtool_ops; 1046 u64 *data; 1047 int ret, test_len; 1048 1049 if (!ops->self_test || !ops->get_sset_count) 1050 return -EOPNOTSUPP; 1051 1052 test_len = ops->get_sset_count(dev, ETH_SS_TEST); 1053 if (test_len < 0) 1054 return test_len; 1055 WARN_ON(test_len == 0); 1056 1057 if (copy_from_user(&test, useraddr, sizeof(test))) 1058 return -EFAULT; 1059 1060 test.len = test_len; 1061 data = kmalloc(test_len * sizeof(u64), GFP_USER); 1062 if (!data) 1063 return -ENOMEM; 1064 1065 ops->self_test(dev, &test, data); 1066 1067 ret = -EFAULT; 1068 if (copy_to_user(useraddr, &test, sizeof(test))) 1069 goto out; 1070 useraddr += sizeof(test); 1071 if (copy_to_user(useraddr, data, test.len * sizeof(u64))) 1072 goto out; 1073 ret = 0; 1074 1075 out: 1076 kfree(data); 1077 return ret; 1078} 1079 1080static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) 1081{ 1082 struct ethtool_gstrings gstrings; 1083 const struct ethtool_ops *ops = dev->ethtool_ops; 1084 u8 *data; 1085 int ret; 1086 1087 if (!ops->get_strings || !ops->get_sset_count) 1088 return -EOPNOTSUPP; 1089 1090 if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) 1091 return -EFAULT; 1092 1093 ret = ops->get_sset_count(dev, gstrings.string_set); 1094 if (ret < 0) 1095 return ret; 1096 1097 gstrings.len = ret; 1098 1099 data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); 1100 if (!data) 1101 return -ENOMEM; 1102 1103 ops->get_strings(dev, gstrings.string_set, data); 1104 1105 ret = -EFAULT; 1106 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) 1107 goto out; 1108 useraddr += sizeof(gstrings); 1109 if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) 1110 goto out; 1111 ret = 0; 1112 1113 out: 1114 kfree(data); 1115 return ret; 1116} 1117 1118static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) 1119{ 1120 struct ethtool_value id; 1121 1122 if (!dev->ethtool_ops->phys_id) 1123 return -EOPNOTSUPP; 1124 1125 if (copy_from_user(&id, useraddr, sizeof(id))) 1126 return -EFAULT; 1127 1128 return dev->ethtool_ops->phys_id(dev, id.data); 1129} 1130 1131static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) 1132{ 1133 struct ethtool_stats stats; 1134 const struct ethtool_ops *ops = dev->ethtool_ops; 1135 u64 *data; 1136 int ret, n_stats; 1137 1138 if (!ops->get_ethtool_stats || !ops->get_sset_count) 1139 return -EOPNOTSUPP; 1140 1141 n_stats = ops->get_sset_count(dev, ETH_SS_STATS); 1142 if (n_stats < 0) 1143 return n_stats; 1144 WARN_ON(n_stats == 0); 1145 1146 if (copy_from_user(&stats, useraddr, sizeof(stats))) 1147 return -EFAULT; 1148 1149 stats.n_stats = n_stats; 1150 data = kmalloc(n_stats * sizeof(u64), GFP_USER); 1151 if (!data) 1152 return -ENOMEM; 1153 1154 ops->get_ethtool_stats(dev, &stats, data); 1155 1156 ret = -EFAULT; 1157 if (copy_to_user(useraddr, &stats, sizeof(stats))) 1158 goto out; 1159 useraddr += sizeof(stats); 1160 if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64))) 1161 goto out; 1162 ret = 0; 1163 1164 out: 1165 kfree(data); 1166 return ret; 1167} 1168 1169static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr) 1170{ 1171 struct ethtool_perm_addr epaddr; 1172 1173 if (copy_from_user(&epaddr, useraddr, sizeof(epaddr))) 1174 return -EFAULT; 1175 1176 if (epaddr.size < dev->addr_len) 1177 return -ETOOSMALL; 1178 epaddr.size = dev->addr_len; 1179 1180 if (copy_to_user(useraddr, &epaddr, sizeof(epaddr))) 1181 return -EFAULT; 1182 useraddr += sizeof(epaddr); 1183 if (copy_to_user(useraddr, dev->perm_addr, epaddr.size)) 1184 return -EFAULT; 1185 return 0; 1186} 1187 1188static int ethtool_get_value(struct net_device *dev, char __user *useraddr, 1189 u32 cmd, u32 (*actor)(struct net_device *)) 1190{ 1191 struct ethtool_value edata = { .cmd = cmd }; 1192 1193 if (!actor) 1194 return -EOPNOTSUPP; 1195 1196 edata.data = actor(dev); 1197 1198 if (copy_to_user(useraddr, &edata, sizeof(edata))) 1199 return -EFAULT; 1200 return 0; 1201} 1202 1203static int ethtool_set_value_void(struct net_device *dev, char __user *useraddr, 1204 void (*actor)(struct net_device *, u32)) 1205{ 1206 struct ethtool_value edata; 1207 1208 if (!actor) 1209 return -EOPNOTSUPP; 1210 1211 if (copy_from_user(&edata, useraddr, sizeof(edata))) 1212 return -EFAULT; 1213 1214 actor(dev, edata.data); 1215 return 0; 1216} 1217 1218static int ethtool_set_value(struct net_device *dev, char __user *useraddr, 1219 int (*actor)(struct net_device *, u32)) 1220{ 1221 struct ethtool_value edata; 1222 1223 if (!actor) 1224 return -EOPNOTSUPP; 1225 1226 if (copy_from_user(&edata, useraddr, sizeof(edata))) 1227 return -EFAULT; 1228 1229 return actor(dev, edata.data); 1230} 1231 1232/* 1233 * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() 1234 */ 1235static noinline int ethtool_flash_device(struct net_device *dev, char __user *useraddr) 1236{ 1237 struct ethtool_flash efl; 1238 1239 if (copy_from_user(&efl, useraddr, sizeof(efl))) 1240 return -EFAULT; 1241 1242 if (!dev->ethtool_ops->flash_device) 1243 return -EOPNOTSUPP; 1244 1245 return dev->ethtool_ops->flash_device(dev, &efl); 1246} 1247 1248/* The main entry point in this file. Called from net/core/dev.c */ 1249 1250int dev_ethtool(struct net *net, struct ifreq *ifr) 1251{ 1252 struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name); 1253 void __user *useraddr = ifr->ifr_data; 1254 u32 ethcmd; 1255 int rc; 1256 unsigned long old_features; 1257 1258 if (!dev || !netif_device_present(dev)) 1259 return -ENODEV; 1260 1261 if (!dev->ethtool_ops) 1262 return -EOPNOTSUPP; 1263 1264 if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd))) 1265 return -EFAULT; 1266 1267 /* Allow some commands to be done by anyone */ 1268 switch(ethcmd) { 1269 case ETHTOOL_GDRVINFO: 1270 case ETHTOOL_GMSGLVL: 1271 case ETHTOOL_GCOALESCE: 1272 case ETHTOOL_GRINGPARAM: 1273 case ETHTOOL_GPAUSEPARAM: 1274 case ETHTOOL_GRXCSUM: 1275 case ETHTOOL_GTXCSUM: 1276 case ETHTOOL_GSG: 1277 case ETHTOOL_GSTRINGS: 1278 case ETHTOOL_GTSO: 1279 case ETHTOOL_GPERMADDR: 1280 case ETHTOOL_GUFO: 1281 case ETHTOOL_GGSO: 1282 case ETHTOOL_GGRO: 1283 case ETHTOOL_GFLAGS: 1284 case ETHTOOL_GPFLAGS: 1285 case ETHTOOL_GRXFH: 1286 case ETHTOOL_GRXRINGS: 1287 case ETHTOOL_GRXCLSRLCNT: 1288 case ETHTOOL_GRXCLSRULE: 1289 case ETHTOOL_GRXCLSRLALL: 1290 break; 1291 default: 1292 if (!capable(CAP_NET_ADMIN)) 1293 return -EPERM; 1294 } 1295 1296 if (dev->ethtool_ops->begin) 1297 if ((rc = dev->ethtool_ops->begin(dev)) < 0) 1298 return rc; 1299 1300 old_features = dev->features; 1301 1302 switch (ethcmd) { 1303 case ETHTOOL_GSET: 1304 rc = ethtool_get_settings(dev, useraddr); 1305 break; 1306 case ETHTOOL_SSET: 1307 rc = ethtool_set_settings(dev, useraddr); 1308 break; 1309 case ETHTOOL_GDRVINFO: 1310 rc = ethtool_get_drvinfo(dev, useraddr); 1311 break; 1312 case ETHTOOL_GREGS: 1313 rc = ethtool_get_regs(dev, useraddr); 1314 break; 1315 case ETHTOOL_GWOL: 1316 rc = ethtool_get_wol(dev, useraddr); 1317 break; 1318 case ETHTOOL_SWOL: 1319 rc = ethtool_set_wol(dev, useraddr); 1320 break; 1321 case ETHTOOL_GMSGLVL: 1322 rc = ethtool_get_value(dev, useraddr, ethcmd, 1323 dev->ethtool_ops->get_msglevel); 1324 break; 1325 case ETHTOOL_SMSGLVL: 1326 rc = ethtool_set_value_void(dev, useraddr, 1327 dev->ethtool_ops->set_msglevel); 1328 break; 1329 case ETHTOOL_NWAY_RST: 1330 rc = ethtool_nway_reset(dev); 1331 break; 1332 case ETHTOOL_GLINK: 1333 rc = ethtool_get_value(dev, useraddr, ethcmd, 1334 dev->ethtool_ops->get_link); 1335 break; 1336 case ETHTOOL_GEEPROM: 1337 rc = ethtool_get_eeprom(dev, useraddr); 1338 break; 1339 case ETHTOOL_SEEPROM: 1340 rc = ethtool_set_eeprom(dev, useraddr); 1341 break; 1342 case ETHTOOL_GCOALESCE: 1343 rc = ethtool_get_coalesce(dev, useraddr); 1344 break; 1345 case ETHTOOL_SCOALESCE: 1346 rc = ethtool_set_coalesce(dev, useraddr); 1347 break; 1348 case ETHTOOL_GRINGPARAM: 1349 rc = ethtool_get_ringparam(dev, useraddr); 1350 break; 1351 case ETHTOOL_SRINGPARAM: 1352 rc = ethtool_set_ringparam(dev, useraddr); 1353 break; 1354 case ETHTOOL_GPAUSEPARAM: 1355 rc = ethtool_get_pauseparam(dev, useraddr); 1356 break; 1357 case ETHTOOL_SPAUSEPARAM: 1358 rc = ethtool_set_pauseparam(dev, useraddr); 1359 break; 1360 case ETHTOOL_GRXCSUM: 1361 rc = ethtool_get_value(dev, useraddr, ethcmd, 1362 (dev->ethtool_ops->get_rx_csum ? 1363 dev->ethtool_ops->get_rx_csum : 1364 ethtool_op_get_rx_csum)); 1365 break; 1366 case ETHTOOL_SRXCSUM: 1367 rc = ethtool_set_rx_csum(dev, useraddr); 1368 break; 1369 case ETHTOOL_GTXCSUM: 1370 rc = ethtool_get_value(dev, useraddr, ethcmd, 1371 (dev->ethtool_ops->get_tx_csum ? 1372 dev->ethtool_ops->get_tx_csum : 1373 ethtool_op_get_tx_csum)); 1374 break; 1375 case ETHTOOL_STXCSUM: 1376 rc = ethtool_set_tx_csum(dev, useraddr); 1377 break; 1378 case ETHTOOL_GSG: 1379 rc = ethtool_get_value(dev, useraddr, ethcmd, 1380 (dev->ethtool_ops->get_sg ? 1381 dev->ethtool_ops->get_sg : 1382 ethtool_op_get_sg)); 1383 break; 1384 case ETHTOOL_SSG: 1385 rc = ethtool_set_sg(dev, useraddr); 1386 break; 1387 case ETHTOOL_GTSO: 1388 rc = ethtool_get_value(dev, useraddr, ethcmd, 1389 (dev->ethtool_ops->get_tso ? 1390 dev->ethtool_ops->get_tso : 1391 ethtool_op_get_tso)); 1392 break; 1393 case ETHTOOL_STSO: 1394 rc = ethtool_set_tso(dev, useraddr); 1395 break; 1396 case ETHTOOL_TEST: 1397 rc = ethtool_self_test(dev, useraddr); 1398 break; 1399 case ETHTOOL_GSTRINGS: 1400 rc = ethtool_get_strings(dev, useraddr); 1401 break; 1402 case ETHTOOL_PHYS_ID: 1403 rc = ethtool_phys_id(dev, useraddr); 1404 break; 1405 case ETHTOOL_GSTATS: 1406 rc = ethtool_get_stats(dev, useraddr); 1407 break; 1408 case ETHTOOL_GPERMADDR: 1409 rc = ethtool_get_perm_addr(dev, useraddr); 1410 break; 1411 case ETHTOOL_GUFO: 1412 rc = ethtool_get_value(dev, useraddr, ethcmd, 1413 (dev->ethtool_ops->get_ufo ? 1414 dev->ethtool_ops->get_ufo : 1415 ethtool_op_get_ufo)); 1416 break; 1417 case ETHTOOL_SUFO: 1418 rc = ethtool_set_ufo(dev, useraddr); 1419 break; 1420 case ETHTOOL_GGSO: 1421 rc = ethtool_get_gso(dev, useraddr); 1422 break; 1423 case ETHTOOL_SGSO: 1424 rc = ethtool_set_gso(dev, useraddr); 1425 break; 1426 case ETHTOOL_GFLAGS: 1427 rc = ethtool_get_value(dev, useraddr, ethcmd, 1428 (dev->ethtool_ops->get_flags ? 1429 dev->ethtool_ops->get_flags : 1430 ethtool_op_get_flags)); 1431 break; 1432 case ETHTOOL_SFLAGS: 1433 rc = ethtool_set_value(dev, useraddr, 1434 dev->ethtool_ops->set_flags); 1435 break; 1436 case ETHTOOL_GPFLAGS: 1437 rc = ethtool_get_value(dev, useraddr, ethcmd, 1438 dev->ethtool_ops->get_priv_flags); 1439 break; 1440 case ETHTOOL_SPFLAGS: 1441 rc = ethtool_set_value(dev, useraddr, 1442 dev->ethtool_ops->set_priv_flags); 1443 break; 1444 case ETHTOOL_GRXFH: 1445 case ETHTOOL_GRXRINGS: 1446 case ETHTOOL_GRXCLSRLCNT: 1447 case ETHTOOL_GRXCLSRULE: 1448 case ETHTOOL_GRXCLSRLALL: 1449 rc = ethtool_get_rxnfc(dev, useraddr); 1450 break; 1451 case ETHTOOL_SRXFH: 1452 case ETHTOOL_SRXCLSRLDEL: 1453 case ETHTOOL_SRXCLSRLINS: 1454 rc = ethtool_set_rxnfc(dev, useraddr); 1455 break; 1456 case ETHTOOL_GGRO: 1457 rc = ethtool_get_gro(dev, useraddr); 1458 break; 1459 case ETHTOOL_SGRO: 1460 rc = ethtool_set_gro(dev, useraddr); 1461 break; 1462 case ETHTOOL_FLASHDEV: 1463 rc = ethtool_flash_device(dev, useraddr); 1464 break; 1465 case ETHTOOL_RESET: 1466 rc = ethtool_reset(dev, useraddr); 1467 break; 1468 case ETHTOOL_SRXNTUPLE: 1469 rc = ethtool_set_rx_ntuple(dev, useraddr); 1470 break; 1471 case ETHTOOL_GRXNTUPLE: 1472 rc = ethtool_get_rx_ntuple(dev, useraddr); 1473 break; 1474 default: 1475 rc = -EOPNOTSUPP; 1476 } 1477 1478 if (dev->ethtool_ops->complete) 1479 dev->ethtool_ops->complete(dev); 1480 1481 if (old_features != dev->features) 1482 netdev_features_change(dev); 1483 1484 return rc; 1485} 1486 1487EXPORT_SYMBOL(ethtool_op_get_link); 1488EXPORT_SYMBOL(ethtool_op_get_sg); 1489EXPORT_SYMBOL(ethtool_op_get_tso); 1490EXPORT_SYMBOL(ethtool_op_set_sg); 1491EXPORT_SYMBOL(ethtool_op_set_tso); 1492EXPORT_SYMBOL(ethtool_op_set_tx_csum); 1493EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum); 1494EXPORT_SYMBOL(ethtool_op_set_tx_ipv6_csum); 1495EXPORT_SYMBOL(ethtool_op_set_ufo); 1496EXPORT_SYMBOL(ethtool_op_get_ufo); 1497EXPORT_SYMBOL(ethtool_op_set_flags); 1498EXPORT_SYMBOL(ethtool_op_get_flags);