diff options
| -rw-r--r-- | include/linux/ethtool.h | 32 | ||||
| -rw-r--r-- | net/core/ethtool.c | 23 |
2 files changed, 55 insertions, 0 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index aa0dcb3833d1..eb1a48da2d43 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
| @@ -498,6 +498,7 @@ struct ethtool_ops { | |||
| 498 | int (*get_rxnfc)(struct net_device *, struct ethtool_rxnfc *, void *); | 498 | int (*get_rxnfc)(struct net_device *, struct ethtool_rxnfc *, void *); |
| 499 | int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *); | 499 | int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *); |
| 500 | int (*flash_device)(struct net_device *, struct ethtool_flash *); | 500 | int (*flash_device)(struct net_device *, struct ethtool_flash *); |
| 501 | int (*reset)(struct net_device *, u32 *); | ||
| 501 | }; | 502 | }; |
| 502 | #endif /* __KERNEL__ */ | 503 | #endif /* __KERNEL__ */ |
| 503 | 504 | ||
| @@ -555,6 +556,7 @@ struct ethtool_ops { | |||
| 555 | #define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */ | 556 | #define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */ |
| 556 | #define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */ | 557 | #define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */ |
| 557 | #define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */ | 558 | #define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */ |
| 559 | #define ETHTOOL_RESET 0x00000034 /* Reset hardware */ | ||
| 558 | 560 | ||
| 559 | /* compatibility with older code */ | 561 | /* compatibility with older code */ |
| 560 | #define SPARC_ETH_GSET ETHTOOL_GSET | 562 | #define SPARC_ETH_GSET ETHTOOL_GSET |
| @@ -685,4 +687,34 @@ struct ethtool_ops { | |||
| 685 | 687 | ||
| 686 | #define RX_CLS_FLOW_DISC 0xffffffffffffffffULL | 688 | #define RX_CLS_FLOW_DISC 0xffffffffffffffffULL |
| 687 | 689 | ||
| 690 | /* Reset flags */ | ||
| 691 | /* The reset() operation must clear the flags for the components which | ||
| 692 | * were actually reset. On successful return, the flags indicate the | ||
| 693 | * components which were not reset, either because they do not exist | ||
| 694 | * in the hardware or because they cannot be reset independently. The | ||
| 695 | * driver must never reset any components that were not requested. | ||
| 696 | */ | ||
| 697 | enum ethtool_reset_flags { | ||
| 698 | /* These flags represent components dedicated to the interface | ||
| 699 | * the command is addressed to. Shift any flag left by | ||
| 700 | * ETH_RESET_SHARED_SHIFT to reset a shared component of the | ||
| 701 | * same type. | ||
| 702 | */ | ||
| 703 | ETH_RESET_MGMT = 1 << 0, /* Management processor */ | ||
| 704 | ETH_RESET_IRQ = 1 << 1, /* Interrupt requester */ | ||
| 705 | ETH_RESET_DMA = 1 << 2, /* DMA engine */ | ||
| 706 | ETH_RESET_FILTER = 1 << 3, /* Filtering/flow direction */ | ||
| 707 | ETH_RESET_OFFLOAD = 1 << 4, /* Protocol offload */ | ||
| 708 | ETH_RESET_MAC = 1 << 5, /* Media access controller */ | ||
| 709 | ETH_RESET_PHY = 1 << 6, /* Transceiver/PHY */ | ||
| 710 | ETH_RESET_RAM = 1 << 7, /* RAM shared between | ||
| 711 | * multiple components */ | ||
| 712 | |||
| 713 | ETH_RESET_DEDICATED = 0x0000ffff, /* All components dedicated to | ||
| 714 | * this interface */ | ||
| 715 | ETH_RESET_ALL = 0xffffffff, /* All components used by this | ||
| 716 | * interface, even if shared */ | ||
| 717 | }; | ||
| 718 | #define ETH_RESET_SHARED_SHIFT 16 | ||
| 719 | |||
| 688 | #endif /* _LINUX_ETHTOOL_H */ | 720 | #endif /* _LINUX_ETHTOOL_H */ |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index e1951084b973..d8aee584e8d1 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -302,6 +302,26 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) | |||
| 302 | return ret; | 302 | return ret; |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | static int ethtool_reset(struct net_device *dev, char __user *useraddr) | ||
| 306 | { | ||
| 307 | struct ethtool_value reset; | ||
| 308 | int ret; | ||
| 309 | |||
| 310 | if (!dev->ethtool_ops->reset) | ||
| 311 | return -EOPNOTSUPP; | ||
| 312 | |||
| 313 | if (copy_from_user(&reset, useraddr, sizeof(reset))) | ||
| 314 | return -EFAULT; | ||
| 315 | |||
| 316 | ret = dev->ethtool_ops->reset(dev, &reset.data); | ||
| 317 | if (ret) | ||
| 318 | return ret; | ||
| 319 | |||
| 320 | if (copy_to_user(useraddr, &reset, sizeof(reset))) | ||
| 321 | return -EFAULT; | ||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 305 | static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) | 325 | static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) |
| 306 | { | 326 | { |
| 307 | struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; | 327 | struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; |
| @@ -1089,6 +1109,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
| 1089 | case ETHTOOL_FLASHDEV: | 1109 | case ETHTOOL_FLASHDEV: |
| 1090 | rc = ethtool_flash_device(dev, useraddr); | 1110 | rc = ethtool_flash_device(dev, useraddr); |
| 1091 | break; | 1111 | break; |
| 1112 | case ETHTOOL_RESET: | ||
| 1113 | rc = ethtool_reset(dev, useraddr); | ||
| 1114 | break; | ||
| 1092 | default: | 1115 | default: |
| 1093 | rc = -EOPNOTSUPP; | 1116 | rc = -EOPNOTSUPP; |
| 1094 | } | 1117 | } |
