1 /*******************************************************************************
3 Intel(R) Gigabit Ethernet Linux driver
4 Copyright(c) 2007-2012 Intel Corporation.
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
23 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
24 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26 *******************************************************************************/
29 * net/core/ethtool.c - Ethtool ioctl handler
30 * Copyright (c) 2003 Matthew Wilcox <matthew@wil.cx>
32 * This file is where we call all the ethtool_ops commands to get
33 * the information ethtool needs. We fall back to calling do_ioctl()
34 * for drivers which haven't been converted to ethtool_ops yet.
38 * Modification by sfeldma@pobox.com to work as backward compat
39 * solution for pre-ethtool_ops kernels.
40 * - copied struct ethtool_ops from ethtool.h
41 * - defined SET_ETHTOOL_OPS
42 * - put in some #ifndef NETIF_F_xxx wrappers
43 * - changes refs to dev->ethtool_ops to ethtool_ops
44 * - changed dev_ethtool to ethtool_ioctl
45 * - remove EXPORT_SYMBOL()s
46 * - added _kc_ prefix in built-in ethtool_op_xxx ops.
49 #include <linux/module.h>
50 #include <linux/types.h>
51 #include <linux/errno.h>
52 #include <linux/mii.h>
53 #include <linux/ethtool.h>
54 #include <linux/netdevice.h>
55 #include <asm/uaccess.h>
59 #undef SUPPORTED_10000baseT_Full
60 #define SUPPORTED_10000baseT_Full (1 << 12)
61 #undef ADVERTISED_10000baseT_Full
62 #define ADVERTISED_10000baseT_Full (1 << 12)
64 #define SPEED_10000 10000
67 #define ethtool_ops _kc_ethtool_ops
69 struct _kc_ethtool_ops {
70 int (*get_settings)(struct net_device *, struct ethtool_cmd *);
71 int (*set_settings)(struct net_device *, struct ethtool_cmd *);
72 void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);
73 int (*get_regs_len)(struct net_device *);
74 void (*get_regs)(struct net_device *, struct ethtool_regs *, void *);
75 void (*get_wol)(struct net_device *, struct ethtool_wolinfo *);
76 int (*set_wol)(struct net_device *, struct ethtool_wolinfo *);
77 u32 (*get_msglevel)(struct net_device *);
78 void (*set_msglevel)(struct net_device *, u32);
79 int (*nway_reset)(struct net_device *);
80 u32 (*get_link)(struct net_device *);
81 int (*get_eeprom_len)(struct net_device *);
82 int (*get_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *);
83 int (*set_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *);
84 int (*get_coalesce)(struct net_device *, struct ethtool_coalesce *);
85 int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *);
86 void (*get_ringparam)(struct net_device *, struct ethtool_ringparam *);
87 int (*set_ringparam)(struct net_device *, struct ethtool_ringparam *);
88 void (*get_pauseparam)(struct net_device *,
89 struct ethtool_pauseparam*);
90 int (*set_pauseparam)(struct net_device *,
91 struct ethtool_pauseparam*);
92 u32 (*get_rx_csum)(struct net_device *);
93 int (*set_rx_csum)(struct net_device *, u32);
94 u32 (*get_tx_csum)(struct net_device *);
95 int (*set_tx_csum)(struct net_device *, u32);
96 u32 (*get_sg)(struct net_device *);
97 int (*set_sg)(struct net_device *, u32);
98 u32 (*get_tso)(struct net_device *);
99 int (*set_tso)(struct net_device *, u32);
100 int (*self_test_count)(struct net_device *);
101 void (*self_test)(struct net_device *, struct ethtool_test *, u64 *);
102 void (*get_strings)(struct net_device *, u32 stringset, u8 *);
103 int (*phys_id)(struct net_device *, u32);
104 int (*get_stats_count)(struct net_device *);
105 void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *,
107 } *ethtool_ops = NULL;
109 #undef SET_ETHTOOL_OPS
110 #define SET_ETHTOOL_OPS(netdev, ops) (ethtool_ops = (ops))
113 * Some useful ethtool_ops methods that are device independent. If we find that
114 * all drivers want to do the same thing here, we can turn these into dev_()
118 #undef ethtool_op_get_link
119 #define ethtool_op_get_link _kc_ethtool_op_get_link
120 u32 _kc_ethtool_op_get_link(struct net_device *dev)
122 return netif_carrier_ok(dev) ? 1 : 0;
125 #undef ethtool_op_get_tx_csum
126 #define ethtool_op_get_tx_csum _kc_ethtool_op_get_tx_csum
127 u32 _kc_ethtool_op_get_tx_csum(struct net_device *dev)
129 #ifdef NETIF_F_IP_CSUM
130 return (dev->features & NETIF_F_IP_CSUM) != 0;
136 #undef ethtool_op_set_tx_csum
137 #define ethtool_op_set_tx_csum _kc_ethtool_op_set_tx_csum
138 int _kc_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
140 #ifdef NETIF_F_IP_CSUM
142 #ifdef NETIF_F_IPV6_CSUM
143 dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
145 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
147 dev->features |= NETIF_F_IP_CSUM;
149 dev->features &= ~NETIF_F_IP_CSUM;
156 #undef ethtool_op_get_sg
157 #define ethtool_op_get_sg _kc_ethtool_op_get_sg
158 u32 _kc_ethtool_op_get_sg(struct net_device *dev)
161 return (dev->features & NETIF_F_SG) != 0;
167 #undef ethtool_op_set_sg
168 #define ethtool_op_set_sg _kc_ethtool_op_set_sg
169 int _kc_ethtool_op_set_sg(struct net_device *dev, u32 data)
173 dev->features |= NETIF_F_SG;
175 dev->features &= ~NETIF_F_SG;
181 #undef ethtool_op_get_tso
182 #define ethtool_op_get_tso _kc_ethtool_op_get_tso
183 u32 _kc_ethtool_op_get_tso(struct net_device *dev)
186 return (dev->features & NETIF_F_TSO) != 0;
192 #undef ethtool_op_set_tso
193 #define ethtool_op_set_tso _kc_ethtool_op_set_tso
194 int _kc_ethtool_op_set_tso(struct net_device *dev, u32 data)
198 dev->features |= NETIF_F_TSO;
200 dev->features &= ~NETIF_F_TSO;
206 /* Handlers for each ethtool command */
208 static int ethtool_get_settings(struct net_device *dev, void *useraddr)
210 struct ethtool_cmd cmd = { ETHTOOL_GSET };
213 if (!ethtool_ops->get_settings)
216 err = ethtool_ops->get_settings(dev, &cmd);
220 if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
225 static int ethtool_set_settings(struct net_device *dev, void *useraddr)
227 struct ethtool_cmd cmd;
229 if (!ethtool_ops->set_settings)
232 if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
235 return ethtool_ops->set_settings(dev, &cmd);
238 static int ethtool_get_drvinfo(struct net_device *dev, void *useraddr)
240 struct ethtool_drvinfo info;
241 struct ethtool_ops *ops = ethtool_ops;
243 if (!ops->get_drvinfo)
246 memset(&info, 0, sizeof(info));
247 info.cmd = ETHTOOL_GDRVINFO;
248 ops->get_drvinfo(dev, &info);
250 if (ops->self_test_count)
251 info.testinfo_len = ops->self_test_count(dev);
252 if (ops->get_stats_count)
253 info.n_stats = ops->get_stats_count(dev);
254 if (ops->get_regs_len)
255 info.regdump_len = ops->get_regs_len(dev);
256 if (ops->get_eeprom_len)
257 info.eedump_len = ops->get_eeprom_len(dev);
259 if (copy_to_user(useraddr, &info, sizeof(info)))
264 static int ethtool_get_regs(struct net_device *dev, char *useraddr)
266 struct ethtool_regs regs;
267 struct ethtool_ops *ops = ethtool_ops;
271 if (!ops->get_regs || !ops->get_regs_len)
274 if (copy_from_user(®s, useraddr, sizeof(regs)))
277 reglen = ops->get_regs_len(dev);
278 if (regs.len > reglen)
281 regbuf = kmalloc(reglen, GFP_USER);
285 ops->get_regs(dev, ®s, regbuf);
288 if (copy_to_user(useraddr, ®s, sizeof(regs)))
290 useraddr += offsetof(struct ethtool_regs, data);
291 if (copy_to_user(useraddr, regbuf, reglen))
300 static int ethtool_get_wol(struct net_device *dev, char *useraddr)
302 struct ethtool_wolinfo wol = { ETHTOOL_GWOL };
304 if (!ethtool_ops->get_wol)
307 ethtool_ops->get_wol(dev, &wol);
309 if (copy_to_user(useraddr, &wol, sizeof(wol)))
314 static int ethtool_set_wol(struct net_device *dev, char *useraddr)
316 struct ethtool_wolinfo wol;
318 if (!ethtool_ops->set_wol)
321 if (copy_from_user(&wol, useraddr, sizeof(wol)))
324 return ethtool_ops->set_wol(dev, &wol);
327 static int ethtool_get_msglevel(struct net_device *dev, char *useraddr)
329 struct ethtool_value edata = { ETHTOOL_GMSGLVL };
331 if (!ethtool_ops->get_msglevel)
334 edata.data = ethtool_ops->get_msglevel(dev);
336 if (copy_to_user(useraddr, &edata, sizeof(edata)))
341 static int ethtool_set_msglevel(struct net_device *dev, char *useraddr)
343 struct ethtool_value edata;
345 if (!ethtool_ops->set_msglevel)
348 if (copy_from_user(&edata, useraddr, sizeof(edata)))
351 ethtool_ops->set_msglevel(dev, edata.data);
355 static int ethtool_nway_reset(struct net_device *dev)
357 if (!ethtool_ops->nway_reset)
360 return ethtool_ops->nway_reset(dev);
363 static int ethtool_get_link(struct net_device *dev, void *useraddr)
365 struct ethtool_value edata = { ETHTOOL_GLINK };
367 if (!ethtool_ops->get_link)
370 edata.data = ethtool_ops->get_link(dev);
372 if (copy_to_user(useraddr, &edata, sizeof(edata)))
377 static int ethtool_get_eeprom(struct net_device *dev, void *useraddr)
379 struct ethtool_eeprom eeprom;
380 struct ethtool_ops *ops = ethtool_ops;
384 if (!ops->get_eeprom || !ops->get_eeprom_len)
387 if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
390 /* Check for wrap and zero */
391 if (eeprom.offset + eeprom.len <= eeprom.offset)
394 /* Check for exceeding total eeprom len */
395 if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
398 data = kmalloc(eeprom.len, GFP_USER);
403 if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len))
406 ret = ops->get_eeprom(dev, &eeprom, data);
411 if (copy_to_user(useraddr, &eeprom, sizeof(eeprom)))
413 if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len))
422 static int ethtool_set_eeprom(struct net_device *dev, void *useraddr)
424 struct ethtool_eeprom eeprom;
425 struct ethtool_ops *ops = ethtool_ops;
429 if (!ops->set_eeprom || !ops->get_eeprom_len)
432 if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
435 /* Check for wrap and zero */
436 if (eeprom.offset + eeprom.len <= eeprom.offset)
439 /* Check for exceeding total eeprom len */
440 if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
443 data = kmalloc(eeprom.len, GFP_USER);
448 if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len))
451 ret = ops->set_eeprom(dev, &eeprom, data);
455 if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len))
463 static int ethtool_get_coalesce(struct net_device *dev, void *useraddr)
465 struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE };
467 if (!ethtool_ops->get_coalesce)
470 ethtool_ops->get_coalesce(dev, &coalesce);
472 if (copy_to_user(useraddr, &coalesce, sizeof(coalesce)))
477 static int ethtool_set_coalesce(struct net_device *dev, void *useraddr)
479 struct ethtool_coalesce coalesce;
481 if (!ethtool_ops->get_coalesce)
484 if (copy_from_user(&coalesce, useraddr, sizeof(coalesce)))
487 return ethtool_ops->set_coalesce(dev, &coalesce);
490 static int ethtool_get_ringparam(struct net_device *dev, void *useraddr)
492 struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM };
494 if (!ethtool_ops->get_ringparam)
497 ethtool_ops->get_ringparam(dev, &ringparam);
499 if (copy_to_user(useraddr, &ringparam, sizeof(ringparam)))
504 static int ethtool_set_ringparam(struct net_device *dev, void *useraddr)
506 struct ethtool_ringparam ringparam;
508 if (!ethtool_ops->get_ringparam)
511 if (copy_from_user(&ringparam, useraddr, sizeof(ringparam)))
514 return ethtool_ops->set_ringparam(dev, &ringparam);
517 static int ethtool_get_pauseparam(struct net_device *dev, void *useraddr)
519 struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM };
521 if (!ethtool_ops->get_pauseparam)
524 ethtool_ops->get_pauseparam(dev, &pauseparam);
526 if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam)))
531 static int ethtool_set_pauseparam(struct net_device *dev, void *useraddr)
533 struct ethtool_pauseparam pauseparam;
535 if (!ethtool_ops->get_pauseparam)
538 if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam)))
541 return ethtool_ops->set_pauseparam(dev, &pauseparam);
544 static int ethtool_get_rx_csum(struct net_device *dev, char *useraddr)
546 struct ethtool_value edata = { ETHTOOL_GRXCSUM };
548 if (!ethtool_ops->get_rx_csum)
551 edata.data = ethtool_ops->get_rx_csum(dev);
553 if (copy_to_user(useraddr, &edata, sizeof(edata)))
558 static int ethtool_set_rx_csum(struct net_device *dev, char *useraddr)
560 struct ethtool_value edata;
562 if (!ethtool_ops->set_rx_csum)
565 if (copy_from_user(&edata, useraddr, sizeof(edata)))
568 ethtool_ops->set_rx_csum(dev, edata.data);
572 static int ethtool_get_tx_csum(struct net_device *dev, char *useraddr)
574 struct ethtool_value edata = { ETHTOOL_GTXCSUM };
576 if (!ethtool_ops->get_tx_csum)
579 edata.data = ethtool_ops->get_tx_csum(dev);
581 if (copy_to_user(useraddr, &edata, sizeof(edata)))
586 static int ethtool_set_tx_csum(struct net_device *dev, char *useraddr)
588 struct ethtool_value edata;
590 if (!ethtool_ops->set_tx_csum)
593 if (copy_from_user(&edata, useraddr, sizeof(edata)))
596 return ethtool_ops->set_tx_csum(dev, edata.data);
599 static int ethtool_get_sg(struct net_device *dev, char *useraddr)
601 struct ethtool_value edata = { ETHTOOL_GSG };
603 if (!ethtool_ops->get_sg)
606 edata.data = ethtool_ops->get_sg(dev);
608 if (copy_to_user(useraddr, &edata, sizeof(edata)))
613 static int ethtool_set_sg(struct net_device *dev, char *useraddr)
615 struct ethtool_value edata;
617 if (!ethtool_ops->set_sg)
620 if (copy_from_user(&edata, useraddr, sizeof(edata)))
623 return ethtool_ops->set_sg(dev, edata.data);
626 static int ethtool_get_tso(struct net_device *dev, char *useraddr)
628 struct ethtool_value edata = { ETHTOOL_GTSO };
630 if (!ethtool_ops->get_tso)
633 edata.data = ethtool_ops->get_tso(dev);
635 if (copy_to_user(useraddr, &edata, sizeof(edata)))
640 static int ethtool_set_tso(struct net_device *dev, char *useraddr)
642 struct ethtool_value edata;
644 if (!ethtool_ops->set_tso)
647 if (copy_from_user(&edata, useraddr, sizeof(edata)))
650 return ethtool_ops->set_tso(dev, edata.data);
653 static int ethtool_self_test(struct net_device *dev, char *useraddr)
655 struct ethtool_test test;
656 struct ethtool_ops *ops = ethtool_ops;
660 if (!ops->self_test || !ops->self_test_count)
663 if (copy_from_user(&test, useraddr, sizeof(test)))
666 test.len = ops->self_test_count(dev);
667 data = kmalloc(test.len * sizeof(u64), GFP_USER);
671 ops->self_test(dev, &test, data);
674 if (copy_to_user(useraddr, &test, sizeof(test)))
676 useraddr += sizeof(test);
677 if (copy_to_user(useraddr, data, test.len * sizeof(u64)))
686 static int ethtool_get_strings(struct net_device *dev, void *useraddr)
688 struct ethtool_gstrings gstrings;
689 struct ethtool_ops *ops = ethtool_ops;
693 if (!ops->get_strings)
696 if (copy_from_user(&gstrings, useraddr, sizeof(gstrings)))
699 switch (gstrings.string_set) {
701 if (!ops->self_test_count)
703 gstrings.len = ops->self_test_count(dev);
706 if (!ops->get_stats_count)
708 gstrings.len = ops->get_stats_count(dev);
714 data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
718 ops->get_strings(dev, gstrings.string_set, data);
721 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
723 useraddr += sizeof(gstrings);
724 if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
733 static int ethtool_phys_id(struct net_device *dev, void *useraddr)
735 struct ethtool_value id;
737 if (!ethtool_ops->phys_id)
740 if (copy_from_user(&id, useraddr, sizeof(id)))
743 return ethtool_ops->phys_id(dev, id.data);
746 static int ethtool_get_stats(struct net_device *dev, void *useraddr)
748 struct ethtool_stats stats;
749 struct ethtool_ops *ops = ethtool_ops;
753 if (!ops->get_ethtool_stats || !ops->get_stats_count)
756 if (copy_from_user(&stats, useraddr, sizeof(stats)))
759 stats.n_stats = ops->get_stats_count(dev);
760 data = kmalloc(stats.n_stats * sizeof(u64), GFP_USER);
764 ops->get_ethtool_stats(dev, &stats, data);
767 if (copy_to_user(useraddr, &stats, sizeof(stats)))
769 useraddr += sizeof(stats);
770 if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64)))
779 /* The main entry point in this file. Called from net/core/dev.c */
781 #define ETHTOOL_OPS_COMPAT
782 int ethtool_ioctl(struct ifreq *ifr)
784 struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
785 void *useraddr = (void *) ifr->ifr_data;
789 * XXX: This can be pushed down into the ethtool_* handlers that
790 * need it. Keep existing behavior for the moment.
792 if (!capable(CAP_NET_ADMIN))
795 if (!dev || !netif_device_present(dev))
798 if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd)))
803 return ethtool_get_settings(dev, useraddr);
805 return ethtool_set_settings(dev, useraddr);
806 case ETHTOOL_GDRVINFO:
807 return ethtool_get_drvinfo(dev, useraddr);
809 return ethtool_get_regs(dev, useraddr);
811 return ethtool_get_wol(dev, useraddr);
813 return ethtool_set_wol(dev, useraddr);
814 case ETHTOOL_GMSGLVL:
815 return ethtool_get_msglevel(dev, useraddr);
816 case ETHTOOL_SMSGLVL:
817 return ethtool_set_msglevel(dev, useraddr);
818 case ETHTOOL_NWAY_RST:
819 return ethtool_nway_reset(dev);
821 return ethtool_get_link(dev, useraddr);
822 case ETHTOOL_GEEPROM:
823 return ethtool_get_eeprom(dev, useraddr);
824 case ETHTOOL_SEEPROM:
825 return ethtool_set_eeprom(dev, useraddr);
826 case ETHTOOL_GCOALESCE:
827 return ethtool_get_coalesce(dev, useraddr);
828 case ETHTOOL_SCOALESCE:
829 return ethtool_set_coalesce(dev, useraddr);
830 case ETHTOOL_GRINGPARAM:
831 return ethtool_get_ringparam(dev, useraddr);
832 case ETHTOOL_SRINGPARAM:
833 return ethtool_set_ringparam(dev, useraddr);
834 case ETHTOOL_GPAUSEPARAM:
835 return ethtool_get_pauseparam(dev, useraddr);
836 case ETHTOOL_SPAUSEPARAM:
837 return ethtool_set_pauseparam(dev, useraddr);
838 case ETHTOOL_GRXCSUM:
839 return ethtool_get_rx_csum(dev, useraddr);
840 case ETHTOOL_SRXCSUM:
841 return ethtool_set_rx_csum(dev, useraddr);
842 case ETHTOOL_GTXCSUM:
843 return ethtool_get_tx_csum(dev, useraddr);
844 case ETHTOOL_STXCSUM:
845 return ethtool_set_tx_csum(dev, useraddr);
847 return ethtool_get_sg(dev, useraddr);
849 return ethtool_set_sg(dev, useraddr);
851 return ethtool_get_tso(dev, useraddr);
853 return ethtool_set_tso(dev, useraddr);
855 return ethtool_self_test(dev, useraddr);
856 case ETHTOOL_GSTRINGS:
857 return ethtool_get_strings(dev, useraddr);
858 case ETHTOOL_PHYS_ID:
859 return ethtool_phys_id(dev, useraddr);
861 return ethtool_get_stats(dev, useraddr);
869 #define mii_if_info _kc_mii_if_info
870 struct _kc_mii_if_info {
876 unsigned int full_duplex : 1; /* is full duplex? */
877 unsigned int force_media : 1; /* is autoneg. disabled? */
879 struct net_device *dev;
880 int (*mdio_read) (struct net_device *dev, int phy_id, int location);
881 void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);
885 struct mii_ioctl_data;
888 #define mii_link_ok _kc_mii_link_ok
889 #undef mii_nway_restart
890 #define mii_nway_restart _kc_mii_nway_restart
891 #undef mii_ethtool_gset
892 #define mii_ethtool_gset _kc_mii_ethtool_gset
893 #undef mii_ethtool_sset
894 #define mii_ethtool_sset _kc_mii_ethtool_sset
895 #undef mii_check_link
896 #define mii_check_link _kc_mii_check_link
897 extern int _kc_mii_link_ok (struct mii_if_info *mii);
898 extern int _kc_mii_nway_restart (struct mii_if_info *mii);
899 extern int _kc_mii_ethtool_gset(struct mii_if_info *mii,
900 struct ethtool_cmd *ecmd);
901 extern int _kc_mii_ethtool_sset(struct mii_if_info *mii,
902 struct ethtool_cmd *ecmd);
903 extern void _kc_mii_check_link (struct mii_if_info *mii);
904 #if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,4,6) )
905 #undef generic_mii_ioctl
906 #define generic_mii_ioctl _kc_generic_mii_ioctl
907 extern int _kc_generic_mii_ioctl(struct mii_if_info *mii_if,
908 struct mii_ioctl_data *mii_data, int cmd,
909 unsigned int *duplex_changed);
913 struct _kc_pci_dev_ext {
916 struct pci_driver *driver;
919 struct _kc_net_dev_ext {
920 struct net_device *dev;
921 unsigned int carrier;
925 /**************************************/
928 int _kc_mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
930 struct net_device *dev = mii->dev;
931 u32 advert, bmcr, lpa, nego;
934 (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
935 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
936 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
938 /* only supports twisted-pair */
939 ecmd->port = PORT_MII;
941 /* only supports internal transceiver */
942 ecmd->transceiver = XCVR_INTERNAL;
944 /* this isn't fully supported at higher layers */
945 ecmd->phy_address = mii->phy_id;
947 ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
948 advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
949 if (advert & ADVERTISE_10HALF)
950 ecmd->advertising |= ADVERTISED_10baseT_Half;
951 if (advert & ADVERTISE_10FULL)
952 ecmd->advertising |= ADVERTISED_10baseT_Full;
953 if (advert & ADVERTISE_100HALF)
954 ecmd->advertising |= ADVERTISED_100baseT_Half;
955 if (advert & ADVERTISE_100FULL)
956 ecmd->advertising |= ADVERTISED_100baseT_Full;
958 bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
959 lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA);
960 if (bmcr & BMCR_ANENABLE) {
961 ecmd->advertising |= ADVERTISED_Autoneg;
962 ecmd->autoneg = AUTONEG_ENABLE;
964 nego = mii_nway_result(advert & lpa);
965 if (nego == LPA_100FULL || nego == LPA_100HALF)
966 ecmd->speed = SPEED_100;
968 ecmd->speed = SPEED_10;
969 if (nego == LPA_100FULL || nego == LPA_10FULL) {
970 ecmd->duplex = DUPLEX_FULL;
971 mii->full_duplex = 1;
973 ecmd->duplex = DUPLEX_HALF;
974 mii->full_duplex = 0;
977 ecmd->autoneg = AUTONEG_DISABLE;
979 ecmd->speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
980 ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
983 /* ignore maxtxpkt, maxrxpkt for now */
988 int _kc_mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
990 struct net_device *dev = mii->dev;
992 if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100)
994 if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
996 if (ecmd->port != PORT_MII)
998 if (ecmd->transceiver != XCVR_INTERNAL)
1000 if (ecmd->phy_address != mii->phy_id)
1002 if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
1005 /* ignore supported, maxtxpkt, maxrxpkt */
1007 if (ecmd->autoneg == AUTONEG_ENABLE) {
1008 u32 bmcr, advert, tmp;
1010 if ((ecmd->advertising & (ADVERTISED_10baseT_Half |
1011 ADVERTISED_10baseT_Full |
1012 ADVERTISED_100baseT_Half |
1013 ADVERTISED_100baseT_Full)) == 0)
1016 /* advertise only what has been requested */
1017 advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
1018 tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
1019 if (ADVERTISED_10baseT_Half)
1020 tmp |= ADVERTISE_10HALF;
1021 if (ADVERTISED_10baseT_Full)
1022 tmp |= ADVERTISE_10FULL;
1023 if (ADVERTISED_100baseT_Half)
1024 tmp |= ADVERTISE_100HALF;
1025 if (ADVERTISED_100baseT_Full)
1026 tmp |= ADVERTISE_100FULL;
1027 if (advert != tmp) {
1028 mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
1029 mii->advertising = tmp;
1032 /* turn on autonegotiation, and force a renegotiate */
1033 bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
1034 bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
1035 mii->mdio_write(dev, mii->phy_id, MII_BMCR, bmcr);
1037 mii->force_media = 0;
1041 /* turn off auto negotiation, set speed and duplexity */
1042 bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
1043 tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX);
1044 if (ecmd->speed == SPEED_100)
1045 tmp |= BMCR_SPEED100;
1046 if (ecmd->duplex == DUPLEX_FULL) {
1047 tmp |= BMCR_FULLDPLX;
1048 mii->full_duplex = 1;
1050 mii->full_duplex = 0;
1052 mii->mdio_write(dev, mii->phy_id, MII_BMCR, tmp);
1054 mii->force_media = 1;
1059 int _kc_mii_link_ok (struct mii_if_info *mii)
1061 /* first, a dummy read, needed to latch some MII phys */
1062 mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
1063 if (mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_LSTATUS)
1068 int _kc_mii_nway_restart (struct mii_if_info *mii)
1073 /* if autoneg is off, it's an error */
1074 bmcr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMCR);
1076 if (bmcr & BMCR_ANENABLE) {
1077 bmcr |= BMCR_ANRESTART;
1078 mii->mdio_write(mii->dev, mii->phy_id, MII_BMCR, bmcr);
1085 void _kc_mii_check_link (struct mii_if_info *mii)
1087 int cur_link = mii_link_ok(mii);
1088 int prev_link = netif_carrier_ok(mii->dev);
1090 if (cur_link && !prev_link)
1091 netif_carrier_on(mii->dev);
1092 else if (prev_link && !cur_link)
1093 netif_carrier_off(mii->dev);
1096 #if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,4,6) )
1097 int _kc_generic_mii_ioctl(struct mii_if_info *mii_if,
1098 struct mii_ioctl_data *mii_data, int cmd,
1099 unsigned int *duplex_chg_out)
1102 unsigned int duplex_changed = 0;
1105 *duplex_chg_out = 0;
1107 mii_data->phy_id &= mii_if->phy_id_mask;
1108 mii_data->reg_num &= mii_if->reg_num_mask;
1111 case SIOCDEVPRIVATE: /* binary compat, remove in 2.5 */
1113 mii_data->phy_id = mii_if->phy_id;
1116 case SIOCDEVPRIVATE + 1:/* binary compat, remove in 2.5 */
1119 mii_if->mdio_read(mii_if->dev, mii_data->phy_id,
1123 case SIOCDEVPRIVATE + 2:/* binary compat, remove in 2.5 */
1125 u16 val = mii_data->val_in;
1127 if (!capable(CAP_NET_ADMIN))
1130 if (mii_data->phy_id == mii_if->phy_id) {
1131 switch(mii_data->reg_num) {
1133 unsigned int new_duplex = 0;
1134 if (val & (BMCR_RESET|BMCR_ANENABLE))
1135 mii_if->force_media = 0;
1137 mii_if->force_media = 1;
1138 if (mii_if->force_media &&
1139 (val & BMCR_FULLDPLX))
1141 if (mii_if->full_duplex != new_duplex) {
1143 mii_if->full_duplex = new_duplex;
1148 mii_if->advertising = val;
1156 mii_if->mdio_write(mii_if->dev, mii_data->phy_id,
1157 mii_data->reg_num, val);
1166 if ((rc == 0) && (duplex_chg_out) && (duplex_changed))
1167 *duplex_chg_out = 1;
1171 #endif /* > 2.4.6 */