aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ethtool.h32
-rw-r--r--net/core/ethtool.c23
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 */
697enum 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
305static 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
305static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) 325static 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 }