2 * net/core/ethtool.c - Ethtool ioctl handler
3 * Copyright (c) 2003 Matthew Wilcox <matthew@wil.cx>
5 * This file is where we call all the ethtool_ops commands to get
6 * the information ethtool needs. We fall back to calling do_ioctl()
7 * for drivers which haven't been converted to ethtool_ops yet.
12 #include <linux/module.h>
13 #include <linux/types.h>
14 #include <linux/errno.h>
15 #include <linux/ethtool.h>
16 #include <linux/netdevice.h>
17 #include <asm/uaccess.h>
20 * Some useful ethtool_ops methods that're device independent.
21 * If we find that all drivers want to do the same thing here,
22 * we can turn these into dev_() function calls.
25 u32
ethtool_op_get_link(struct net_device
*dev
)
27 return netif_carrier_ok(dev
) ? 1 : 0;
30 u32
ethtool_op_get_tx_csum(struct net_device
*dev
)
32 return (dev
->features
& NETIF_F_IP_CSUM
) != 0;
35 int ethtool_op_set_tx_csum(struct net_device
*dev
, u32 data
)
38 dev
->features
|= NETIF_F_IP_CSUM
;
40 dev
->features
&= ~NETIF_F_IP_CSUM
;
45 u32
ethtool_op_get_sg(struct net_device
*dev
)
47 return (dev
->features
& NETIF_F_SG
) != 0;
50 int ethtool_op_set_sg(struct net_device
*dev
, u32 data
)
53 dev
->features
|= NETIF_F_SG
;
55 dev
->features
&= ~NETIF_F_SG
;
60 u32
ethtool_op_get_tso(struct net_device
*dev
)
62 return (dev
->features
& NETIF_F_TSO
) != 0;
65 int ethtool_op_set_tso(struct net_device
*dev
, u32 data
)
68 dev
->features
|= NETIF_F_TSO
;
70 dev
->features
&= ~NETIF_F_TSO
;
75 /* Handlers for each ethtool command */
77 static int ethtool_get_settings(struct net_device
*dev
, void __user
*useraddr
)
79 struct ethtool_cmd cmd
= { ETHTOOL_GSET
};
82 if (!dev
->ethtool_ops
->get_settings
)
85 err
= dev
->ethtool_ops
->get_settings(dev
, &cmd
);
89 if (copy_to_user(useraddr
, &cmd
, sizeof(cmd
)))
94 static int ethtool_set_settings(struct net_device
*dev
, void __user
*useraddr
)
96 struct ethtool_cmd cmd
;
98 if (!dev
->ethtool_ops
->set_settings
)
101 if (copy_from_user(&cmd
, useraddr
, sizeof(cmd
)))
104 return dev
->ethtool_ops
->set_settings(dev
, &cmd
);
107 static int ethtool_get_drvinfo(struct net_device
*dev
, void __user
*useraddr
)
109 struct ethtool_drvinfo info
;
110 struct ethtool_ops
*ops
= dev
->ethtool_ops
;
112 if (!ops
->get_drvinfo
)
115 memset(&info
, 0, sizeof(info
));
116 info
.cmd
= ETHTOOL_GDRVINFO
;
117 ops
->get_drvinfo(dev
, &info
);
119 if (ops
->self_test_count
)
120 info
.testinfo_len
= ops
->self_test_count(dev
);
121 if (ops
->get_stats_count
)
122 info
.n_stats
= ops
->get_stats_count(dev
);
123 if (ops
->get_regs_len
)
124 info
.regdump_len
= ops
->get_regs_len(dev
);
125 if (ops
->get_eeprom_len
)
126 info
.eedump_len
= ops
->get_eeprom_len(dev
);
128 if (copy_to_user(useraddr
, &info
, sizeof(info
)))
133 static int ethtool_get_regs(struct net_device
*dev
, char __user
*useraddr
)
135 struct ethtool_regs regs
;
136 struct ethtool_ops
*ops
= dev
->ethtool_ops
;
140 if (!ops
->get_regs
|| !ops
->get_regs_len
)
143 if (copy_from_user(®s
, useraddr
, sizeof(regs
)))
146 reglen
= ops
->get_regs_len(dev
);
147 if (regs
.len
> reglen
)
150 regbuf
= kmalloc(reglen
, GFP_USER
);
154 ops
->get_regs(dev
, ®s
, regbuf
);
157 if (copy_to_user(useraddr
, ®s
, sizeof(regs
)))
159 useraddr
+= offsetof(struct ethtool_regs
, data
);
160 if (copy_to_user(useraddr
, regbuf
, regs
.len
))
169 static int ethtool_get_wol(struct net_device
*dev
, char __user
*useraddr
)
171 struct ethtool_wolinfo wol
= { ETHTOOL_GWOL
};
173 if (!dev
->ethtool_ops
->get_wol
)
176 dev
->ethtool_ops
->get_wol(dev
, &wol
);
178 if (copy_to_user(useraddr
, &wol
, sizeof(wol
)))
183 static int ethtool_set_wol(struct net_device
*dev
, char __user
*useraddr
)
185 struct ethtool_wolinfo wol
;
187 if (!dev
->ethtool_ops
->set_wol
)
190 if (copy_from_user(&wol
, useraddr
, sizeof(wol
)))
193 return dev
->ethtool_ops
->set_wol(dev
, &wol
);
196 static int ethtool_get_msglevel(struct net_device
*dev
, char __user
*useraddr
)
198 struct ethtool_value edata
= { ETHTOOL_GMSGLVL
};
200 if (!dev
->ethtool_ops
->get_msglevel
)
203 edata
.data
= dev
->ethtool_ops
->get_msglevel(dev
);
205 if (copy_to_user(useraddr
, &edata
, sizeof(edata
)))
210 static int ethtool_set_msglevel(struct net_device
*dev
, char __user
*useraddr
)
212 struct ethtool_value edata
;
214 if (!dev
->ethtool_ops
->set_msglevel
)
217 if (copy_from_user(&edata
, useraddr
, sizeof(edata
)))
220 dev
->ethtool_ops
->set_msglevel(dev
, edata
.data
);
224 static int ethtool_nway_reset(struct net_device
*dev
)
226 if (!dev
->ethtool_ops
->nway_reset
)
229 return dev
->ethtool_ops
->nway_reset(dev
);
232 static int ethtool_get_link(struct net_device
*dev
, void __user
*useraddr
)
234 struct ethtool_value edata
= { ETHTOOL_GLINK
};
236 if (!dev
->ethtool_ops
->get_link
)
239 edata
.data
= dev
->ethtool_ops
->get_link(dev
);
241 if (copy_to_user(useraddr
, &edata
, sizeof(edata
)))
246 static int ethtool_get_eeprom(struct net_device
*dev
, void __user
*useraddr
)
248 struct ethtool_eeprom eeprom
;
249 struct ethtool_ops
*ops
= dev
->ethtool_ops
;
253 if (!ops
->get_eeprom
|| !ops
->get_eeprom_len
)
256 if (copy_from_user(&eeprom
, useraddr
, sizeof(eeprom
)))
259 /* Check for wrap and zero */
260 if (eeprom
.offset
+ eeprom
.len
<= eeprom
.offset
)
263 /* Check for exceeding total eeprom len */
264 if (eeprom
.offset
+ eeprom
.len
> ops
->get_eeprom_len(dev
))
267 data
= kmalloc(eeprom
.len
, GFP_USER
);
272 if (copy_from_user(data
, useraddr
+ sizeof(eeprom
), eeprom
.len
))
275 ret
= ops
->get_eeprom(dev
, &eeprom
, data
);
280 if (copy_to_user(useraddr
, &eeprom
, sizeof(eeprom
)))
282 if (copy_to_user(useraddr
+ sizeof(eeprom
), data
, eeprom
.len
))
291 static int ethtool_set_eeprom(struct net_device
*dev
, void __user
*useraddr
)
293 struct ethtool_eeprom eeprom
;
294 struct ethtool_ops
*ops
= dev
->ethtool_ops
;
298 if (!ops
->set_eeprom
|| !ops
->get_eeprom_len
)
301 if (copy_from_user(&eeprom
, useraddr
, sizeof(eeprom
)))
304 /* Check for wrap and zero */
305 if (eeprom
.offset
+ eeprom
.len
<= eeprom
.offset
)
308 /* Check for exceeding total eeprom len */
309 if (eeprom
.offset
+ eeprom
.len
> ops
->get_eeprom_len(dev
))
312 data
= kmalloc(eeprom
.len
, GFP_USER
);
317 if (copy_from_user(data
, useraddr
+ sizeof(eeprom
), eeprom
.len
))
320 ret
= ops
->set_eeprom(dev
, &eeprom
, data
);
324 if (copy_to_user(useraddr
+ sizeof(eeprom
), data
, eeprom
.len
))
332 static int ethtool_get_coalesce(struct net_device
*dev
, void __user
*useraddr
)
334 struct ethtool_coalesce coalesce
= { ETHTOOL_GCOALESCE
};
336 if (!dev
->ethtool_ops
->get_coalesce
)
339 dev
->ethtool_ops
->get_coalesce(dev
, &coalesce
);
341 if (copy_to_user(useraddr
, &coalesce
, sizeof(coalesce
)))
346 static int ethtool_set_coalesce(struct net_device
*dev
, void __user
*useraddr
)
348 struct ethtool_coalesce coalesce
;
350 if (!dev
->ethtool_ops
->get_coalesce
)
353 if (copy_from_user(&coalesce
, useraddr
, sizeof(coalesce
)))
356 return dev
->ethtool_ops
->set_coalesce(dev
, &coalesce
);
359 static int ethtool_get_ringparam(struct net_device
*dev
, void __user
*useraddr
)
361 struct ethtool_ringparam ringparam
= { ETHTOOL_GRINGPARAM
};
363 if (!dev
->ethtool_ops
->get_ringparam
)
366 dev
->ethtool_ops
->get_ringparam(dev
, &ringparam
);
368 if (copy_to_user(useraddr
, &ringparam
, sizeof(ringparam
)))
373 static int ethtool_set_ringparam(struct net_device
*dev
, void __user
*useraddr
)
375 struct ethtool_ringparam ringparam
;
377 if (!dev
->ethtool_ops
->set_ringparam
)
380 if (copy_from_user(&ringparam
, useraddr
, sizeof(ringparam
)))
383 return dev
->ethtool_ops
->set_ringparam(dev
, &ringparam
);
386 static int ethtool_get_pauseparam(struct net_device
*dev
, void __user
*useraddr
)
388 struct ethtool_pauseparam pauseparam
= { ETHTOOL_GPAUSEPARAM
};
390 if (!dev
->ethtool_ops
->get_pauseparam
)
393 dev
->ethtool_ops
->get_pauseparam(dev
, &pauseparam
);
395 if (copy_to_user(useraddr
, &pauseparam
, sizeof(pauseparam
)))
400 static int ethtool_set_pauseparam(struct net_device
*dev
, void __user
*useraddr
)
402 struct ethtool_pauseparam pauseparam
;
404 if (!dev
->ethtool_ops
->get_pauseparam
)
407 if (copy_from_user(&pauseparam
, useraddr
, sizeof(pauseparam
)))
410 return dev
->ethtool_ops
->set_pauseparam(dev
, &pauseparam
);
413 static int ethtool_get_rx_csum(struct net_device
*dev
, char __user
*useraddr
)
415 struct ethtool_value edata
= { ETHTOOL_GRXCSUM
};
417 if (!dev
->ethtool_ops
->get_rx_csum
)
420 edata
.data
= dev
->ethtool_ops
->get_rx_csum(dev
);
422 if (copy_to_user(useraddr
, &edata
, sizeof(edata
)))
427 static int ethtool_set_rx_csum(struct net_device
*dev
, char __user
*useraddr
)
429 struct ethtool_value edata
;
431 if (!dev
->ethtool_ops
->set_rx_csum
)
434 if (copy_from_user(&edata
, useraddr
, sizeof(edata
)))
437 dev
->ethtool_ops
->set_rx_csum(dev
, edata
.data
);
441 static int ethtool_get_tx_csum(struct net_device
*dev
, char __user
*useraddr
)
443 struct ethtool_value edata
= { ETHTOOL_GTXCSUM
};
445 if (!dev
->ethtool_ops
->get_tx_csum
)
448 edata
.data
= dev
->ethtool_ops
->get_tx_csum(dev
);
450 if (copy_to_user(useraddr
, &edata
, sizeof(edata
)))
455 static int __ethtool_set_sg(struct net_device
*dev
, u32 data
)
459 if (!data
&& dev
->ethtool_ops
->set_tso
) {
460 err
= dev
->ethtool_ops
->set_tso(dev
, 0);
465 return dev
->ethtool_ops
->set_sg(dev
, data
);
468 static int ethtool_set_tx_csum(struct net_device
*dev
, char __user
*useraddr
)
470 struct ethtool_value edata
;
473 if (!dev
->ethtool_ops
->set_tx_csum
)
476 if (copy_from_user(&edata
, useraddr
, sizeof(edata
)))
479 if (!edata
.data
&& dev
->ethtool_ops
->set_sg
) {
480 err
= __ethtool_set_sg(dev
, 0);
485 return dev
->ethtool_ops
->set_tx_csum(dev
, edata
.data
);
488 static int ethtool_get_sg(struct net_device
*dev
, char __user
*useraddr
)
490 struct ethtool_value edata
= { ETHTOOL_GSG
};
492 if (!dev
->ethtool_ops
->get_sg
)
495 edata
.data
= dev
->ethtool_ops
->get_sg(dev
);
497 if (copy_to_user(useraddr
, &edata
, sizeof(edata
)))
502 static int ethtool_set_sg(struct net_device
*dev
, char __user
*useraddr
)
504 struct ethtool_value edata
;
506 if (!dev
->ethtool_ops
->set_sg
)
509 if (copy_from_user(&edata
, useraddr
, sizeof(edata
)))
513 !(dev
->features
& (NETIF_F_IP_CSUM
|
518 return __ethtool_set_sg(dev
, edata
.data
);
521 static int ethtool_get_tso(struct net_device
*dev
, char __user
*useraddr
)
523 struct ethtool_value edata
= { ETHTOOL_GTSO
};
525 if (!dev
->ethtool_ops
->get_tso
)
528 edata
.data
= dev
->ethtool_ops
->get_tso(dev
);
530 if (copy_to_user(useraddr
, &edata
, sizeof(edata
)))
535 static int ethtool_set_tso(struct net_device
*dev
, char __user
*useraddr
)
537 struct ethtool_value edata
;
539 if (!dev
->ethtool_ops
->set_tso
)
542 if (copy_from_user(&edata
, useraddr
, sizeof(edata
)))
545 if (edata
.data
&& !(dev
->features
& NETIF_F_SG
))
548 return dev
->ethtool_ops
->set_tso(dev
, edata
.data
);
551 static int ethtool_self_test(struct net_device
*dev
, char __user
*useraddr
)
553 struct ethtool_test test
;
554 struct ethtool_ops
*ops
= dev
->ethtool_ops
;
558 if (!ops
->self_test
|| !ops
->self_test_count
)
561 if (copy_from_user(&test
, useraddr
, sizeof(test
)))
564 test
.len
= ops
->self_test_count(dev
);
565 data
= kmalloc(test
.len
* sizeof(u64
), GFP_USER
);
569 ops
->self_test(dev
, &test
, data
);
572 if (copy_to_user(useraddr
, &test
, sizeof(test
)))
574 useraddr
+= sizeof(test
);
575 if (copy_to_user(useraddr
, data
, test
.len
* sizeof(u64
)))
584 static int ethtool_get_strings(struct net_device
*dev
, void __user
*useraddr
)
586 struct ethtool_gstrings gstrings
;
587 struct ethtool_ops
*ops
= dev
->ethtool_ops
;
591 if (!ops
->get_strings
)
594 if (copy_from_user(&gstrings
, useraddr
, sizeof(gstrings
)))
597 switch (gstrings
.string_set
) {
599 if (!ops
->self_test_count
)
601 gstrings
.len
= ops
->self_test_count(dev
);
604 if (!ops
->get_stats_count
)
606 gstrings
.len
= ops
->get_stats_count(dev
);
612 data
= kmalloc(gstrings
.len
* ETH_GSTRING_LEN
, GFP_USER
);
616 ops
->get_strings(dev
, gstrings
.string_set
, data
);
619 if (copy_to_user(useraddr
, &gstrings
, sizeof(gstrings
)))
621 useraddr
+= sizeof(gstrings
);
622 if (copy_to_user(useraddr
, data
, gstrings
.len
* ETH_GSTRING_LEN
))
631 static int ethtool_phys_id(struct net_device
*dev
, void __user
*useraddr
)
633 struct ethtool_value id
;
635 if (!dev
->ethtool_ops
->phys_id
)
638 if (copy_from_user(&id
, useraddr
, sizeof(id
)))
641 return dev
->ethtool_ops
->phys_id(dev
, id
.data
);
644 static int ethtool_get_stats(struct net_device
*dev
, void __user
*useraddr
)
646 struct ethtool_stats stats
;
647 struct ethtool_ops
*ops
= dev
->ethtool_ops
;
651 if (!ops
->get_ethtool_stats
|| !ops
->get_stats_count
)
654 if (copy_from_user(&stats
, useraddr
, sizeof(stats
)))
657 stats
.n_stats
= ops
->get_stats_count(dev
);
658 data
= kmalloc(stats
.n_stats
* sizeof(u64
), GFP_USER
);
662 ops
->get_ethtool_stats(dev
, &stats
, data
);
665 if (copy_to_user(useraddr
, &stats
, sizeof(stats
)))
667 useraddr
+= sizeof(stats
);
668 if (copy_to_user(useraddr
, data
, stats
.n_stats
* sizeof(u64
)))
677 /* The main entry point in this file. Called from net/core/dev.c */
679 int dev_ethtool(struct ifreq
*ifr
)
681 struct net_device
*dev
= __dev_get_by_name(ifr
->ifr_name
);
682 void __user
*useraddr
= ifr
->ifr_data
;
687 * XXX: This can be pushed down into the ethtool_* handlers that
688 * need it. Keep existing behaviour for the moment.
690 if (!capable(CAP_NET_ADMIN
))
693 if (!dev
|| !netif_device_present(dev
))
696 if (!dev
->ethtool_ops
)
699 if (copy_from_user(ðcmd
, useraddr
, sizeof (ethcmd
)))
702 if(dev
->ethtool_ops
->begin
)
703 if ((rc
= dev
->ethtool_ops
->begin(dev
)) < 0)
708 rc
= ethtool_get_settings(dev
, useraddr
);
711 rc
= ethtool_set_settings(dev
, useraddr
);
713 case ETHTOOL_GDRVINFO
:
714 rc
= ethtool_get_drvinfo(dev
, useraddr
);
718 rc
= ethtool_get_regs(dev
, useraddr
);
721 rc
= ethtool_get_wol(dev
, useraddr
);
724 rc
= ethtool_set_wol(dev
, useraddr
);
726 case ETHTOOL_GMSGLVL
:
727 rc
= ethtool_get_msglevel(dev
, useraddr
);
729 case ETHTOOL_SMSGLVL
:
730 rc
= ethtool_set_msglevel(dev
, useraddr
);
732 case ETHTOOL_NWAY_RST
:
733 rc
= ethtool_nway_reset(dev
);
736 rc
= ethtool_get_link(dev
, useraddr
);
738 case ETHTOOL_GEEPROM
:
739 rc
= ethtool_get_eeprom(dev
, useraddr
);
741 case ETHTOOL_SEEPROM
:
742 rc
= ethtool_set_eeprom(dev
, useraddr
);
744 case ETHTOOL_GCOALESCE
:
745 rc
= ethtool_get_coalesce(dev
, useraddr
);
747 case ETHTOOL_SCOALESCE
:
748 rc
= ethtool_set_coalesce(dev
, useraddr
);
750 case ETHTOOL_GRINGPARAM
:
751 rc
= ethtool_get_ringparam(dev
, useraddr
);
753 case ETHTOOL_SRINGPARAM
:
754 rc
= ethtool_set_ringparam(dev
, useraddr
);
756 case ETHTOOL_GPAUSEPARAM
:
757 rc
= ethtool_get_pauseparam(dev
, useraddr
);
759 case ETHTOOL_SPAUSEPARAM
:
760 rc
= ethtool_set_pauseparam(dev
, useraddr
);
762 case ETHTOOL_GRXCSUM
:
763 rc
= ethtool_get_rx_csum(dev
, useraddr
);
765 case ETHTOOL_SRXCSUM
:
766 rc
= ethtool_set_rx_csum(dev
, useraddr
);
768 case ETHTOOL_GTXCSUM
:
769 rc
= ethtool_get_tx_csum(dev
, useraddr
);
771 case ETHTOOL_STXCSUM
:
772 rc
= ethtool_set_tx_csum(dev
, useraddr
);
775 rc
= ethtool_get_sg(dev
, useraddr
);
778 rc
= ethtool_set_sg(dev
, useraddr
);
781 rc
= ethtool_get_tso(dev
, useraddr
);
784 rc
= ethtool_set_tso(dev
, useraddr
);
787 rc
= ethtool_self_test(dev
, useraddr
);
789 case ETHTOOL_GSTRINGS
:
790 rc
= ethtool_get_strings(dev
, useraddr
);
792 case ETHTOOL_PHYS_ID
:
793 rc
= ethtool_phys_id(dev
, useraddr
);
796 rc
= ethtool_get_stats(dev
, useraddr
);
802 if(dev
->ethtool_ops
->complete
)
803 dev
->ethtool_ops
->complete(dev
);
808 return dev
->do_ioctl(dev
, ifr
, SIOCETHTOOL
);
812 EXPORT_SYMBOL(dev_ethtool
);
813 EXPORT_SYMBOL(ethtool_op_get_link
);
814 EXPORT_SYMBOL(ethtool_op_get_sg
);
815 EXPORT_SYMBOL(ethtool_op_get_tso
);
816 EXPORT_SYMBOL(ethtool_op_get_tx_csum
);
817 EXPORT_SYMBOL(ethtool_op_set_sg
);
818 EXPORT_SYMBOL(ethtool_op_set_tso
);
819 EXPORT_SYMBOL(ethtool_op_set_tx_csum
);