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 | } |