From 2a5fcae954f992cf558eb91c83aa4c5a880a6bdc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:50:40 +0200 Subject: Adding upstream version 1:6.1. Signed-off-by: Daniel Baumann --- AUTHORS | 9 + COPYING | 339 +++ ChangeLog | 353 +++ INSTALL | 368 +++ LICENSE | 3 + Makefile.am | 64 + Makefile.in | 3952 +++++++++++++++++++++++++ NEWS | 695 +++++ README | 2 + aclocal.m4 | 1464 ++++++++++ amd8111e.c | 306 ++ at76c50x-usb.c | 32 + autogen.sh | 11 + bnxt.c | 97 + cmis.c | 1002 +++++++ cmis.h | 235 ++ common.c | 175 ++ common.h | 45 + compile | 348 +++ configure | 6050 ++++++++++++++++++++++++++++++++++++++ configure.ac | 82 + cpsw.c | 193 ++ de2104x.c | 783 +++++ depcomp | 791 +++++ dsa.c | 882 ++++++ e100.c | 238 ++ e1000.c | 640 ++++ et131x.c | 124 + ethtool-config.h.in | 43 + ethtool.8 | 1531 ++++++++++ ethtool.8.in | 1531 ++++++++++ ethtool.c | 6428 +++++++++++++++++++++++++++++++++++++++++ ethtool.spec | 41 + ethtool.spec.in | 41 + fec.c | 220 ++ fec_8xx.c | 82 + fjes.c | 90 + fsl_enetc.c | 259 ++ ibm_emac.c | 334 +++ igb.c | 876 ++++++ igc.c | 284 ++ install-sh | 501 ++++ internal.h | 424 +++ ixgb.c | 147 + ixgbe.c | 1296 +++++++++ ixgbevf.c | 181 ++ json_print.c | 228 ++ json_print.h | 67 + json_writer.c | 391 +++ json_writer.h | 76 + lan743x.c | 73 + lan78xx.c | 88 + list.h | 34 + marvell.c | 455 +++ missing | 215 ++ natsemi.c | 987 +++++++ netlink/bitset.c | 259 ++ netlink/bitset.h | 28 + netlink/cable_test.c | 595 ++++ netlink/channels.c | 141 + netlink/coalesce.c | 285 ++ netlink/desc-ethtool.c | 529 ++++ netlink/desc-genlctrl.c | 113 + netlink/desc-rtnl.c | 96 + netlink/eee.c | 189 ++ netlink/extapi.h | 120 + netlink/features.c | 557 ++++ netlink/fec.c | 360 +++ netlink/module-eeprom.c | 305 ++ netlink/module.c | 179 ++ netlink/monitor.c | 324 +++ netlink/msgbuff.c | 256 ++ netlink/msgbuff.h | 123 + netlink/netlink.c | 527 ++++ netlink/netlink.h | 164 ++ netlink/nlsock.c | 405 +++ netlink/nlsock.h | 45 + netlink/parser.c | 1141 ++++++++ netlink/parser.h | 153 + netlink/pause.c | 308 ++ netlink/permaddr.c | 114 + netlink/prettymsg.c | 262 ++ netlink/prettymsg.h | 146 + netlink/privflags.c | 158 + netlink/rings.c | 181 ++ netlink/settings.c | 1277 ++++++++ netlink/stats.c | 319 ++ netlink/strset.c | 297 ++ netlink/strset.h | 25 + netlink/tsinfo.c | 124 + netlink/tunnels.c | 236 ++ pcnet32.c | 249 ++ qsfp.c | 1024 +++++++ qsfp.h | 628 ++++ realtek.c | 689 +++++ rxclass.c | 1459 ++++++++++ sfc.c | 3928 +++++++++++++++++++++++++ sff-common.c | 361 +++ sff-common.h | 209 ++ sfpdiag.c | 281 ++ sfpid.c | 505 ++++ shell-completion/bash/ethtool | 1278 ++++++++ smsc911x.c | 91 + stmmac.c | 71 + test-cmdline.c | 340 +++ test-common.c | 385 +++ test-driver | 153 + test-features.c | 555 ++++ tg3.c | 42 + tse.c | 112 + uapi/linux/ethtool.h | 2154 ++++++++++++++ uapi/linux/ethtool_netlink.h | 888 ++++++ uapi/linux/genetlink.h | 103 + uapi/linux/if_link.h | 1387 +++++++++ uapi/linux/net_tstamp.h | 204 ++ uapi/linux/netlink.h | 374 +++ uapi/linux/rtnetlink.h | 824 ++++++ vioc.c | 34 + vmxnet3.c | 199 ++ 119 files changed, 65074 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 aclocal.m4 create mode 100644 amd8111e.c create mode 100644 at76c50x-usb.c create mode 100755 autogen.sh create mode 100644 bnxt.c create mode 100644 cmis.c create mode 100644 cmis.h create mode 100644 common.c create mode 100644 common.h create mode 100755 compile create mode 100755 configure create mode 100644 configure.ac create mode 100644 cpsw.c create mode 100644 de2104x.c create mode 100755 depcomp create mode 100644 dsa.c create mode 100644 e100.c create mode 100644 e1000.c create mode 100644 et131x.c create mode 100644 ethtool-config.h.in create mode 100644 ethtool.8 create mode 100644 ethtool.8.in create mode 100644 ethtool.c create mode 100644 ethtool.spec create mode 100644 ethtool.spec.in create mode 100644 fec.c create mode 100644 fec_8xx.c create mode 100644 fjes.c create mode 100644 fsl_enetc.c create mode 100644 ibm_emac.c create mode 100644 igb.c create mode 100644 igc.c create mode 100755 install-sh create mode 100644 internal.h create mode 100644 ixgb.c create mode 100644 ixgbe.c create mode 100644 ixgbevf.c create mode 100644 json_print.c create mode 100644 json_print.h create mode 100644 json_writer.c create mode 100644 json_writer.h create mode 100644 lan743x.c create mode 100644 lan78xx.c create mode 100644 list.h create mode 100644 marvell.c create mode 100755 missing create mode 100644 natsemi.c create mode 100644 netlink/bitset.c create mode 100644 netlink/bitset.h create mode 100644 netlink/cable_test.c create mode 100644 netlink/channels.c create mode 100644 netlink/coalesce.c create mode 100644 netlink/desc-ethtool.c create mode 100644 netlink/desc-genlctrl.c create mode 100644 netlink/desc-rtnl.c create mode 100644 netlink/eee.c create mode 100644 netlink/extapi.h create mode 100644 netlink/features.c create mode 100644 netlink/fec.c create mode 100644 netlink/module-eeprom.c create mode 100644 netlink/module.c create mode 100644 netlink/monitor.c create mode 100644 netlink/msgbuff.c create mode 100644 netlink/msgbuff.h create mode 100644 netlink/netlink.c create mode 100644 netlink/netlink.h create mode 100644 netlink/nlsock.c create mode 100644 netlink/nlsock.h create mode 100644 netlink/parser.c create mode 100644 netlink/parser.h create mode 100644 netlink/pause.c create mode 100644 netlink/permaddr.c create mode 100644 netlink/prettymsg.c create mode 100644 netlink/prettymsg.h create mode 100644 netlink/privflags.c create mode 100644 netlink/rings.c create mode 100644 netlink/settings.c create mode 100644 netlink/stats.c create mode 100644 netlink/strset.c create mode 100644 netlink/strset.h create mode 100644 netlink/tsinfo.c create mode 100644 netlink/tunnels.c create mode 100644 pcnet32.c create mode 100644 qsfp.c create mode 100644 qsfp.h create mode 100644 realtek.c create mode 100644 rxclass.c create mode 100644 sfc.c create mode 100644 sff-common.c create mode 100644 sff-common.h create mode 100644 sfpdiag.c create mode 100644 sfpid.c create mode 100644 shell-completion/bash/ethtool create mode 100644 smsc911x.c create mode 100644 stmmac.c create mode 100644 test-cmdline.c create mode 100644 test-common.c create mode 100755 test-driver create mode 100644 test-features.c create mode 100644 tg3.c create mode 100644 tse.c create mode 100644 uapi/linux/ethtool.h create mode 100644 uapi/linux/ethtool_netlink.h create mode 100644 uapi/linux/genetlink.h create mode 100644 uapi/linux/if_link.h create mode 100644 uapi/linux/net_tstamp.h create mode 100644 uapi/linux/netlink.h create mode 100644 uapi/linux/rtnetlink.h create mode 100644 vioc.c create mode 100644 vmxnet3.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..e1f0715 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,9 @@ +David Miller +Jakub Jelinek +Jeff Garzik +Tim Hockin +Eli Kupermann +Chris Leech +Scott Feldman +Andi Kleen +Ben Hutchings diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..1fd043e --- /dev/null +++ b/ChangeLog @@ -0,0 +1,353 @@ +The changelog after March 2005 can be obtained from the git repository +at . + +The changelog after version 2 up to March 2005 can be obtained from the +BitKeeper repository at . + + +Tue Aug 17 2004 Jeff Garzik + + * NEWS, configure.ac: Release version 2 + +Fri Jul 2 2004 Jeff Garzik + + Merged + * fec_8xx.c, ethtool-util.h, Makefile.am: Add fec_8xx register dump. + Contributed by Pantelis Antoniou + + * Update ethtool.c to iterate through a list of drivers + * Fixed fec_8xx.c warnings on 64-bit + +Fri Jul 2 2004 Jim Lewis + + * pcnet32.c, ethtool-util.h, Makefile.am: Add pcnet32 register dump. + +Fri Apr 9 2004 Jason Lunz + + * ethtool.c: Remove incorrect restriction on ethernet interface + names. + +Fri Apr 9 2004 OGAWA Hirofumi + + * ethtool.c: This fixes the bogus tail backslash that I did. + +Fri Apr 9 2004 Jim Lewis + + * ethtool.c: Return results of self-test back to OS, + via exit(2). + +Fri Apr 9 2004 Jeb Cramer + + * e1000.c: Update device id list and add printout of phy type in + register dump. Set default mac_type to 82543 since register offsets + haven't changed. + +Fri Apr 9 2004 Jeff Garzik + + * configure.ac, Makefile.am, ethtool.c, etc.: + convert to more recent autoconf. + +Sat Aug 30 2003 OGAWA Hirofumi + + * ethtool.8, ethtool.c: ethtool register dump raw mode + +Sat Jul 19 2003 Scott Feldman + + * ethtool.8, ethtool.c, ethtool-copy.h: + Add support for TSO get/set. Corresponds to NETIF_F_TSO. + Extended -k|K option to included tso, and changed meaning from + just "checksum/sg" to more general "offload". Now covers Rx/Tx + csum, SG, and TSO. + +Thu May 28 2003 Ganesh Venkatesan + + * ethtool-copy.h: new definitions for 10GbE + +Thu May 28 2003 Scott Feldman + + * ethtool.c: Add ethtool -E to write EEPROM byte. + * e100.c: Added MDI/MDI-X status to register dump. + +Thu May 28 2003 Reeja John + + * amd8111e.c: new file, support for AMD-8111e NICs + * ethtool.c: properly set ecmd.advertising + +Sat Mar 29 2003 OGAWA Hirofumi + + * realtek.c: clean up chip enumeration, support additional chips + +Fri Mar 28 2003 Jeb Cramer + + * e1000.c: Update supported devices (82541 & 82547). Add bus type, + speed and width to register dump printout. + * ethtool.c (show_usage): Add -S to printout of supported commands. + +Tue Jan 22 2003 Jeff Garzik + + * natsemi.c (PRINT_INTR, __print_intr): Decompose PRINT_INTR + macro into macro abuse and function call portions. Move the + actual function body to new static functoin __print_intr. + + This eliminates the annoying build warning :) + +Thu Jan 16 2003 Jeb Cramer + + * ethtool.c (do_regs, dump_eeprom): Fix memory leaks on failed + operations. Add error handling of dump_regs(). Modify printout of + eeprom dump to accomodate larger eeproms. + * e1000.c: Update supported devices. Add error conditions for + unsupported devices. + +Mon Oct 21 2002 Ben Collins + + * ethtool.c: Add new parameters to -e, for raw EEPROM output, and + offset and length options. + * natsemi.c (natsemi_dump_eeprom): Show correct offset using new + offset feature above. + * tg3.c: New file, implements tg3_dump_eeprom. + * Makefile.am: Add it to the build sources. + * ethtool-util.h: Prototype tg3_dump_eeprom. + * ethtool.8: Document new -e options. + +Thu Oct 17 2002 Tim Hockin + + * ethtool.c: make calls to strtol() use base 0 + +Wed Sep 18 2002 Scott Feldman + + * ethtool.c (dump_regs): call e100_dump_regs if e100 + * e100.c: new file + * ethtool-util.h: prototype e100_dump_regs + +Thu Jun 20 2002 Jeff Garzik + + * ethtool.8: document new -S stats dump argument + * configure.in, NEWS: release version 1.6 + +Fri Jun 14 2002 Jeff Garzik + + * realtek.c (realtek_dump_regs): dump legacy 8139 registers + * ethtool.c (do_gstats, doit, parse_cmdline): + support dumping of NIC-specific statistics + +Fri Jun 14 2002 Jeff Garzik + + * realtek.c (realtek_dump_regs): dump RTL8139C+ registers + +Fri Jun 14 2002 Jeff Garzik + + * realtek.c: new file, dumps RealTek RTL8169 PCI NIC's registers + * Makefile.am, ethtool.c, ethtool-util.h: use it + +Tue Jun 11 2002 Jeff Garzik + + * NEWS: list new commands added recently + * ethtool.c (do_gcoalesce, do_scoalesce, dump_coalesce): new + (parse_cmdline, doit): handle get/set coalesce parameters (-c,-C) + (do_[gs]*): convert to use table-driven cmd line parsing + * ethtool.8: document -c and -C + +Tue Jun 11 2002 Jeff Garzik + + * ethtool.c (do_gring, do_sring, dump_ring, + parse_ring_cmdline): new functions + (parse_cmdline, doit): handle get/set ring parameters (-g,-G) + (do_spause): fix off-by-one bugs + * ethtool.8: document -g and -G + +Tue Jun 11 2002 Jeff Garzik + + * ethtool.c (do_gpause, do_spause, dump_pause, + parse_pause_cmdline): new functions + (parse_cmdline, doit): handle get/set pause parameters (-a,-A) + * ethtool.8: document -a, -A, -e, and -p + +Wed May 22 2002 Chris Leech + Scott Feldman + + * ethtool-copy.h: add support for ETHTOOL_PHYS_ID function. + * ethtool.c: add support for ETHTOOL_PHYS_ID function, add + support for e1000 reg dump. + * Makefile.am: add e1000.c + * e1000.c: reg dump support for Intel(R) PRO/1000 adapters. + * ethtool-util.h: add e1000 reg dump support. + +Sat May 11 2002 Eli Kupermann + + * ethtool.c (do_test): add support for online/offline test modes + Elsewhere: document "-t" arg usage, and handle usage + +Sat May 11 2002 Jes Sorensen + + * ethtool.c (dump_ecmd): If unknown value is + encountered in speed, duplex, or port ETHTOOL_GSET + return data, print the numeric value returned. + +Wed May 1 2002 Eli Kupermann + + * ethtool.8: document new -t test option + +Wed May 1 2002 Christoph Hellwig + + * Makefile.am (dist-hook): Use $(top-srcdir) for refering to sources. + +Mon Apr 29 2002 Christoph Hellwig + + * Makefile.am (SUBDIRS): Remove. + (RPMSRCS): Likewise. + (TMPDIR): Likewise. + (rpm): Likewise. + (EXTRA_DIST): Add ethtool.spec.in. + (dist-hook): New rule. Create rpm specfile. + * configure.in (AC_OUTPUT): Add ethtool.spec. + * ethtool.spec.in: New file. Rpm specfile template. + * redhat/ethtool.spec.in: Removed. + * redhat/Makefile.am: Removed. + +Wed Mar 20 2002 Jeff Garzik + + * ethtool-copy.h: Merge coalescing param, ring + param, and pause param ioctl structs from kernel 2.5.7. + Merge ethtool_test changes fromkernel 2.5.7. + * ethtool: Update for ethtool_test cleanups. + +Wed Mar 20 2002 Eli Kupermann + + * ethtool.c: (do_test): new function + Elsewhere: add support for 'perform test' function, + via a new "-t" arg, by calling do_test. + +Sun Mar 3 2002 Brad Hards + + * ethtool.c (parse_cmdline): Support "usb" + as well as "eth" network interfaces. USB networking + uses a different prefix. + +Fri Feb 8 2002 "Noam, Amir" , + "Kupermann, Eli" + + * ethtool.c (dump_advertised): new function. + (dump_ecmd): Call it. + Elsewhere: reformat code. + +Wed Nov 28 2001 Jeff Garzik + + * configure.in, Makefile.am, redhat/Makefile.am: + make sure redhat spec is included in dist tarball. + +Tue Nov 27 2001 Tim Hockin + + * natsemi.c: strings changes + * ethtool.c: print messagelevel as hex (netif_msg_* shows better :) + +Sun Nov 18 2001 Jeff Garzik + + * NEWS: update with recent changes + * ethtool.8: phy address can be used if implemented in the + driver, so remove "Not used yet" remark. + +Sun Nov 18 2001 Jeff Garzik + + * Makefile.am, de2104x.c, ethtool-util.h, ethtool.c: + Support register dumps for de2104x driver. + +Tue Nov 13 2001 Tim Hockin + + * natsemi.c, ethtool.c: use u8 data for ethtool_regs + * ethtool-copy.h: latest from kernel + * natsemi.c, ethtool.c: support ETHTOOL_GEEPROM via -e param + +Mon Nov 12 2001 Tim Hockin + + * natsemi.c: check version, conditionally print RFCR-indexed data + +Wed Nov 07 2001 Tim Hockin + + * ethtool.c: print less errors for unsupported ioctl()s + * ethtool.c: warn if all ioctl()s are unsupported or failed + * ethtool.c: change autoneg-restart mechanism to -r (as per jgarzik) + * ethtool.c: check for "eth" in devicename (per jg) + * ethtool.c: remove 'extraneous' braces + +Wed Nov 07 2001 Jeff Garzik + + * ethtool.c, ethtool.8: support bnc port/media + +Tue Nov 06 2001 Tim Hockin + + * ethtool.c: clean up output for unhandled register dumps + * natsemi.c: finish pretty-printing register dumps + * ethtool.8: document -d option + * various: add copyright info, where applicable + * ethtool.c: be nicer about unsupported ioctl()s where possible + and be more verbose where nice is not an option. + +Mon Nov 05 2001 Tim Hockin + + * natsemi.c: first cut at 'pretty-printing' register dumps + +Fri Nov 02 2001 Tim Hockin + + * ethtool.c: add support for ETHTOOL_GREGS via -d (dump) flag + * ethtool.c: add support for device-specific dumps for known devices + * ethtool.c: make mode-specific handling allocate ifr_data + * Makefile.am: import ChangeLog to rpm specfile + * natsemi.c: added + * ethtool-util.h: added + +Thu Nov 01 2001 Tim Hockin + + * ethtool.c: add support for ETHTOOL_GLINK in output + * ethtool.c: add support for ETHTOOL_NWAY_RST via 'autoneg restart' + * ethtool.c: add support for ETHTOOL_[GS]MSGLVL via 'msglvl' param + * ethtool.8: add documentation for above + * ethtool-copy.h: updated to sync with kernel + +Fri Oct 26 2001 Jeff Garzik + + * ethtool.8: Update contributors list, home page URL. + * ethtool.8: Much cleanup, no content change. + Contributed by Andre Majorel. + * ethtool.c: Clean up '-h' usage message. + Contributed by Andre Majorel. + +Fri Oct 26 2001 Jeff Garzik + + * Configure.in: bump version to 1.4cvs + * Makefile.am: include ethtool-copy.h in list of sources + * ethtool-copy.h: + Import ethtool.h from kernel 2.4.13. + * ethtool.c: + Define SIOCETHTOOL if it is missing, + trim trailing whitespace. + * NEWS: update for these changes + +Wed Sep 19 2001 Jeff Garzik + + * ethtool.c, ethtool-copy.h: + Import copy of kernel 2.4.10-pre12's ethtool.h. + +Wed Sep 19 2001 Tim Hockin + + * Makefile.am, redhat/ethtool.spec.in: + Basic "make rpm" support. + +Wed Sep 19 2001 Tim Hockin + + * AUTHORS, NEWS, ethtool.8, ethtool.c: + Wake-on-LAN support. + +Thu May 17 2001 Jeff Garzik + + * configure.in, NEWS, README: Version 1.2 release + + * ethtool.c: Support ETHTOOL_GDRVINFO. + * ethtool.8: Document it. + +Fri Mar 20 2001 Jeff Garzik + + * Makefile.am, configure.in, autogen.sh, NEWS, + ChangeLog, AUTHORS, README: + Add autoconf/automake support. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..8865734 --- /dev/null +++ b/INSTALL @@ -0,0 +1,368 @@ +Installation Instructions +************************* + + Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software +Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell command './configure && make && make install' +should configure, build, and install this package. The following +more-detailed instructions are generic; see the 'README' file for +instructions specific to this package. Some packages provide this +'INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The 'configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a 'Makefile' in each directory of the package. +It may also create one or more '.h' files containing system-dependent +definitions. Finally, it creates a shell script 'config.status' that +you can run in the future to recreate the current configuration, and a +file 'config.log' containing compiler output (useful mainly for +debugging 'configure'). + + It can also use an optional file (typically called 'config.cache' and +enabled with '--cache-file=config.cache' or simply '-C') that saves the +results of its tests to speed up reconfiguring. Caching is disabled by +default to prevent problems with accidental use of stale cache files. + + If you need to do unusual things to compile the package, please try +to figure out how 'configure' could check whether to do them, and mail +diffs or instructions to the address given in the 'README' so they can +be considered for the next release. If you are using the cache, and at +some point 'config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file 'configure.ac' (or 'configure.in') is used to create +'configure' by a program called 'autoconf'. You need 'configure.ac' if +you want to change it or regenerate 'configure' using a newer version of +'autoconf'. + + The simplest way to compile this package is: + + 1. 'cd' to the directory containing the package's source code and type + './configure' to configure the package for your system. + + Running 'configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type 'make' to compile the package. + + 3. Optionally, type 'make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type 'make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the 'make install' phase executed with root + privileges. + + 5. Optionally, type 'make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior 'make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing 'make clean'. To also remove the + files that 'configure' created (so you can compile the package for + a different kind of computer), type 'make distclean'. There is + also a 'make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type 'make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide 'make + distcheck', which can by used by developers to test that all other + targets like 'make install' and 'make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the 'configure' script does not know about. Run './configure --help' +for details on some of the pertinent environment variables. + + You can give 'configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here is +an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU 'make'. 'cd' to the +directory where you want the object files and executables to go and run +the 'configure' script. 'configure' automatically checks for the source +code in the directory that 'configure' is in and in '..'. This is known +as a "VPATH" build. + + With a non-GNU 'make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use 'make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple '-arch' options to the +compiler but only a single '-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the 'lipo' tool if you have problems. + +Installation Names +================== + + By default, 'make install' installs the package's commands under +'/usr/local/bin', include files under '/usr/local/include', etc. You +can specify an installation prefix other than '/usr/local' by giving +'configure' the option '--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option '--exec-prefix=PREFIX' to 'configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like '--bindir=DIR' to specify different values for particular +kinds of files. Run 'configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the default +for these options is expressed in terms of '${prefix}', so that +specifying just '--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to 'configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +'make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, 'make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +'${prefix}'. Any directories that were specified during 'configure', +but not in terms of '${prefix}', must each be overridden at install time +for the entire installation to be relocated. The approach of makefile +variable overrides for each directory variable is required by the GNU +Coding Standards, and ideally causes no recompilation. However, some +platforms have known limitations with the semantics of shared libraries +that end up requiring recompilation when using this method, particularly +noticeable in packages that use GNU Libtool. + + The second method involves providing the 'DESTDIR' variable. For +example, 'make install DESTDIR=/alternate/directory' will prepend +'/alternate/directory' before all installation names. The approach of +'DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of '${prefix}' +at 'configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving 'configure' the +option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. + + Some packages pay attention to '--enable-FEATURE' options to +'configure', where FEATURE indicates an optional part of the package. +They may also pay attention to '--with-PACKAGE' options, where PACKAGE +is something like 'gnu-as' or 'x' (for the X Window System). The +'README' should mention any '--enable-' and '--with-' options that the +package recognizes. + + For packages that use the X Window System, 'configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the 'configure' options '--x-includes=DIR' and +'--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of 'make' will be. For these packages, running './configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with 'make V=1'; while running './configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with 'make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC +is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX 'make' updates targets which have the same time stamps as their +prerequisites, which makes it generally unusable when shipped generated +files such as 'configure' are involved. Use GNU 'make' instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its '' header file. The option '-nodtk' can be used as a +workaround. If GNU CC is not installed, it is therefore recommended to +try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put '/usr/ucb' early in your 'PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in '/usr/bin'. So, if you need '/usr/ucb' +in your 'PATH', put it _after_ '/usr/bin'. + + On Haiku, software installed for all users goes in '/boot/common', +not '/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features 'configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, 'configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +'--build=TYPE' option. TYPE can either be a short name for the system +type, such as 'sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file 'config.sub' for the possible values of each field. If +'config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option '--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with '--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for 'configure' scripts to share, +you can create a site shell script called 'config.site' that gives +default values for variables like 'CC', 'cache_file', and 'prefix'. +'configure' looks for 'PREFIX/share/config.site' if it exists, then +'PREFIX/etc/config.site' if it exists. Or, you can set the +'CONFIG_SITE' environment variable to the location of the site script. +A warning: not all 'configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to 'configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the 'configure' command line, using 'VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified 'gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an +Autoconf limitation. Until the limitation is lifted, you can use this +workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +'configure' Invocation +====================== + + 'configure' recognizes the following options to control how it +operates. + +'--help' +'-h' + Print a summary of all of the options to 'configure', and exit. + +'--help=short' +'--help=recursive' + Print a summary of the options unique to this package's + 'configure', and exit. The 'short' variant lists options used only + in the top level, while the 'recursive' variant lists options also + present in any nested packages. + +'--version' +'-V' + Print the version of Autoconf used to generate the 'configure' + script, and exit. + +'--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally 'config.cache'. FILE defaults to '/dev/null' to + disable caching. + +'--config-cache' +'-C' + Alias for '--cache-file=config.cache'. + +'--quiet' +'--silent' +'-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to '/dev/null' (any error + messages will still be shown). + +'--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + 'configure' can determine that directory automatically. + +'--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: for + more details, including other options available for fine-tuning the + installation locations. + +'--no-create' +'-n' + Run the configure checks, but stop before creating any output + files. + +'configure' also accepts some other, not widely useful, options. Run +'configure --help' for more details. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d68dccb --- /dev/null +++ b/LICENSE @@ -0,0 +1,3 @@ +ethtool is available under the terms of the GNU Public License version 2. + +See COPYING for details. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..663f40a --- /dev/null +++ b/Makefile.am @@ -0,0 +1,64 @@ +AM_CFLAGS = -Wall -Wextra -D_POSIX_C_SOURCE=200809L +AM_CPPFLAGS = -I$(top_srcdir)/uapi +LDADD = -lm + +man_MANS = ethtool.8 +EXTRA_DIST = LICENSE ethtool.8 ethtool.spec.in aclocal.m4 ChangeLog autogen.sh + +sbin_PROGRAMS = ethtool +ethtool_SOURCES = ethtool.c uapi/linux/ethtool.h internal.h \ + uapi/linux/net_tstamp.h rxclass.c common.c common.h \ + json_writer.c json_writer.h json_print.c json_print.h \ + list.h +if ETHTOOL_ENABLE_PRETTY_DUMP +ethtool_SOURCES += \ + amd8111e.c de2104x.c dsa.c e100.c e1000.c et131x.c igb.c \ + fec.c fec_8xx.c fsl_enetc.c ibm_emac.c ixgb.c ixgbe.c \ + natsemi.c pcnet32.c realtek.c tg3.c marvell.c vioc.c \ + smsc911x.c at76c50x-usb.c sfc.c stmmac.c \ + sff-common.c sff-common.h sfpid.c sfpdiag.c \ + ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h fjes.c lan78xx.c \ + igc.c cmis.c cmis.h bnxt.c cpsw.c lan743x.c +endif + +if ENABLE_BASH_COMPLETION +bashcompletiondir = $(BASH_COMPLETION_DIR) +dist_bashcompletion_DATA = shell-completion/bash/ethtool +endif + +if ETHTOOL_ENABLE_NETLINK +ethtool_SOURCES += \ + netlink/netlink.c netlink/netlink.h netlink/extapi.h \ + netlink/msgbuff.c netlink/msgbuff.h netlink/nlsock.c \ + netlink/nlsock.h netlink/strset.c netlink/strset.h \ + netlink/monitor.c netlink/bitset.c netlink/bitset.h \ + netlink/settings.c netlink/parser.c netlink/parser.h \ + netlink/permaddr.c netlink/prettymsg.c netlink/prettymsg.h \ + netlink/features.c netlink/privflags.c netlink/rings.c \ + netlink/channels.c netlink/coalesce.c netlink/pause.c \ + netlink/eee.c netlink/tsinfo.c netlink/fec.c \ + netlink/stats.c \ + netlink/desc-ethtool.c netlink/desc-genlctrl.c \ + netlink/module-eeprom.c netlink/module.c \ + netlink/desc-rtnl.c netlink/cable_test.c netlink/tunnels.c \ + uapi/linux/ethtool_netlink.h \ + uapi/linux/netlink.h uapi/linux/genetlink.h \ + uapi/linux/rtnetlink.h uapi/linux/if_link.h +AM_CPPFLAGS += @MNL_CFLAGS@ +LDADD += @MNL_LIBS@ +endif + +TESTS = test-cmdline +check_PROGRAMS = test-cmdline +test_cmdline_SOURCES = test-cmdline.c test-common.c $(ethtool_SOURCES) +test_cmdline_CFLAGS = -DTEST_ETHTOOL +if !ETHTOOL_ENABLE_NETLINK +TESTS += test-features +check_PROGRAMS += test-features +test_features_SOURCES = test-features.c test-common.c $(ethtool_SOURCES) +test_features_CFLAGS = -DTEST_ETHTOOL +endif + +dist-hook: + cp $(top_srcdir)/ethtool.spec $(distdir) + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..ff02ad3 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,3952 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +sbin_PROGRAMS = ethtool$(EXEEXT) +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@am__append_1 = \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ amd8111e.c de2104x.c dsa.c e100.c e1000.c et131x.c igb.c \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ fec.c fec_8xx.c fsl_enetc.c ibm_emac.c ixgb.c ixgbe.c \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ natsemi.c pcnet32.c realtek.c tg3.c marvell.c vioc.c \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ smsc911x.c at76c50x-usb.c sfc.c stmmac.c \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ sff-common.c sff-common.h sfpid.c sfpdiag.c \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h fjes.c lan78xx.c \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ igc.c cmis.c cmis.h bnxt.c cpsw.c lan743x.c + +@ETHTOOL_ENABLE_NETLINK_TRUE@am__append_2 = \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/netlink.c netlink/netlink.h netlink/extapi.h \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/msgbuff.c netlink/msgbuff.h netlink/nlsock.c \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/nlsock.h netlink/strset.c netlink/strset.h \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/monitor.c netlink/bitset.c netlink/bitset.h \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/settings.c netlink/parser.c netlink/parser.h \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/permaddr.c netlink/prettymsg.c netlink/prettymsg.h \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/features.c netlink/privflags.c netlink/rings.c \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/channels.c netlink/coalesce.c netlink/pause.c \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/eee.c netlink/tsinfo.c netlink/fec.c \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/stats.c \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-ethtool.c netlink/desc-genlctrl.c \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/module-eeprom.c netlink/module.c \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-rtnl.c netlink/cable_test.c netlink/tunnels.c \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ uapi/linux/ethtool_netlink.h \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ uapi/linux/netlink.h uapi/linux/genetlink.h \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ uapi/linux/rtnetlink.h uapi/linux/if_link.h + +@ETHTOOL_ENABLE_NETLINK_TRUE@am__append_3 = @MNL_CFLAGS@ +@ETHTOOL_ENABLE_NETLINK_TRUE@am__append_4 = @MNL_LIBS@ +TESTS = test-cmdline$(EXEEXT) $(am__EXEEXT_1) +check_PROGRAMS = test-cmdline$(EXEEXT) $(am__EXEEXT_1) +@ETHTOOL_ENABLE_NETLINK_FALSE@am__append_5 = test-features +@ETHTOOL_ENABLE_NETLINK_FALSE@am__append_6 = test-features +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__dist_bashcompletion_DATA_DIST) \ + $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = ethtool-config.h +CONFIG_CLEAN_FILES = ethtool.spec ethtool.8 +CONFIG_CLEAN_VPATH_FILES = +@ETHTOOL_ENABLE_NETLINK_FALSE@am__EXEEXT_1 = test-features$(EXEEXT) +am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" \ + "$(DESTDIR)$(bashcompletiondir)" +PROGRAMS = $(sbin_PROGRAMS) +am__ethtool_SOURCES_DIST = ethtool.c uapi/linux/ethtool.h internal.h \ + uapi/linux/net_tstamp.h rxclass.c common.c common.h \ + json_writer.c json_writer.h json_print.c json_print.h list.h \ + amd8111e.c de2104x.c dsa.c e100.c e1000.c et131x.c igb.c fec.c \ + fec_8xx.c fsl_enetc.c ibm_emac.c ixgb.c ixgbe.c natsemi.c \ + pcnet32.c realtek.c tg3.c marvell.c vioc.c smsc911x.c \ + at76c50x-usb.c sfc.c stmmac.c sff-common.c sff-common.h \ + sfpid.c sfpdiag.c ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h \ + fjes.c lan78xx.c igc.c cmis.c cmis.h bnxt.c cpsw.c lan743x.c \ + netlink/netlink.c netlink/netlink.h netlink/extapi.h \ + netlink/msgbuff.c netlink/msgbuff.h netlink/nlsock.c \ + netlink/nlsock.h netlink/strset.c netlink/strset.h \ + netlink/monitor.c netlink/bitset.c netlink/bitset.h \ + netlink/settings.c netlink/parser.c netlink/parser.h \ + netlink/permaddr.c netlink/prettymsg.c netlink/prettymsg.h \ + netlink/features.c netlink/privflags.c netlink/rings.c \ + netlink/channels.c netlink/coalesce.c netlink/pause.c \ + netlink/eee.c netlink/tsinfo.c netlink/fec.c netlink/stats.c \ + netlink/desc-ethtool.c netlink/desc-genlctrl.c \ + netlink/module-eeprom.c netlink/module.c netlink/desc-rtnl.c \ + netlink/cable_test.c netlink/tunnels.c \ + uapi/linux/ethtool_netlink.h uapi/linux/netlink.h \ + uapi/linux/genetlink.h uapi/linux/rtnetlink.h \ + uapi/linux/if_link.h +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@am__objects_1 = amd8111e.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ de2104x.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ dsa.$(OBJEXT) e100.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ e1000.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ et131x.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ igb.$(OBJEXT) fec.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ fec_8xx.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ fsl_enetc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ ibm_emac.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ ixgb.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ ixgbe.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ natsemi.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ pcnet32.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ realtek.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ tg3.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ marvell.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ vioc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ smsc911x.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ at76c50x-usb.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ sfc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ stmmac.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ sff-common.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ sfpid.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ sfpdiag.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ ixgbevf.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ tse.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ vmxnet3.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ qsfp.$(OBJEXT) fjes.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ lan78xx.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ igc.$(OBJEXT) cmis.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ bnxt.$(OBJEXT) cpsw.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ lan743x.$(OBJEXT) +am__dirstamp = $(am__leading_dot)dirstamp +@ETHTOOL_ENABLE_NETLINK_TRUE@am__objects_2 = \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/netlink.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/msgbuff.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/nlsock.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/strset.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/monitor.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/bitset.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/settings.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/parser.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/permaddr.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/prettymsg.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/features.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/privflags.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/rings.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/channels.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/coalesce.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/pause.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/eee.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/tsinfo.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/fec.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/stats.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-ethtool.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-genlctrl.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/module-eeprom.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/module.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/desc-rtnl.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/cable_test.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/tunnels.$(OBJEXT) +am_ethtool_OBJECTS = ethtool.$(OBJEXT) rxclass.$(OBJEXT) \ + common.$(OBJEXT) json_writer.$(OBJEXT) json_print.$(OBJEXT) \ + $(am__objects_1) $(am__objects_2) +ethtool_OBJECTS = $(am_ethtool_OBJECTS) +ethtool_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +ethtool_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__test_cmdline_SOURCES_DIST = test-cmdline.c test-common.c ethtool.c \ + uapi/linux/ethtool.h internal.h uapi/linux/net_tstamp.h \ + rxclass.c common.c common.h json_writer.c json_writer.h \ + json_print.c json_print.h list.h amd8111e.c de2104x.c dsa.c \ + e100.c e1000.c et131x.c igb.c fec.c fec_8xx.c fsl_enetc.c \ + ibm_emac.c ixgb.c ixgbe.c natsemi.c pcnet32.c realtek.c tg3.c \ + marvell.c vioc.c smsc911x.c at76c50x-usb.c sfc.c stmmac.c \ + sff-common.c sff-common.h sfpid.c sfpdiag.c ixgbevf.c tse.c \ + vmxnet3.c qsfp.c qsfp.h fjes.c lan78xx.c igc.c cmis.c cmis.h \ + bnxt.c cpsw.c lan743x.c netlink/netlink.c netlink/netlink.h \ + netlink/extapi.h netlink/msgbuff.c netlink/msgbuff.h \ + netlink/nlsock.c netlink/nlsock.h netlink/strset.c \ + netlink/strset.h netlink/monitor.c netlink/bitset.c \ + netlink/bitset.h netlink/settings.c netlink/parser.c \ + netlink/parser.h netlink/permaddr.c netlink/prettymsg.c \ + netlink/prettymsg.h netlink/features.c netlink/privflags.c \ + netlink/rings.c netlink/channels.c netlink/coalesce.c \ + netlink/pause.c netlink/eee.c netlink/tsinfo.c netlink/fec.c \ + netlink/stats.c netlink/desc-ethtool.c netlink/desc-genlctrl.c \ + netlink/module-eeprom.c netlink/module.c netlink/desc-rtnl.c \ + netlink/cable_test.c netlink/tunnels.c \ + uapi/linux/ethtool_netlink.h uapi/linux/netlink.h \ + uapi/linux/genetlink.h uapi/linux/rtnetlink.h \ + uapi/linux/if_link.h +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@am__objects_3 = test_cmdline-amd8111e.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-de2104x.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-dsa.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-e100.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-e1000.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-et131x.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-igb.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-fec.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-fec_8xx.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-fsl_enetc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-ibm_emac.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-ixgb.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-ixgbe.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-natsemi.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-pcnet32.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-realtek.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-tg3.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-marvell.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-vioc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-smsc911x.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-at76c50x-usb.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-sfc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-stmmac.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-sff-common.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-sfpid.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-sfpdiag.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-ixgbevf.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-tse.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-vmxnet3.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-qsfp.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-fjes.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-lan78xx.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-igc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-cmis.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-bnxt.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-cpsw.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_cmdline-lan743x.$(OBJEXT) +@ETHTOOL_ENABLE_NETLINK_TRUE@am__objects_4 = netlink/test_cmdline-netlink.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-msgbuff.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-nlsock.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-strset.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-monitor.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-bitset.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-settings.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-parser.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-permaddr.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-prettymsg.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-features.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-privflags.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-rings.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-channels.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-coalesce.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-pause.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-eee.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-tsinfo.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-fec.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-stats.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-desc-ethtool.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-desc-genlctrl.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-module-eeprom.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-module.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-desc-rtnl.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-cable_test.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_cmdline-tunnels.$(OBJEXT) +am__objects_5 = test_cmdline-ethtool.$(OBJEXT) \ + test_cmdline-rxclass.$(OBJEXT) test_cmdline-common.$(OBJEXT) \ + test_cmdline-json_writer.$(OBJEXT) \ + test_cmdline-json_print.$(OBJEXT) $(am__objects_3) \ + $(am__objects_4) +am_test_cmdline_OBJECTS = test_cmdline-test-cmdline.$(OBJEXT) \ + test_cmdline-test-common.$(OBJEXT) $(am__objects_5) +test_cmdline_OBJECTS = $(am_test_cmdline_OBJECTS) +test_cmdline_LDADD = $(LDADD) +test_cmdline_DEPENDENCIES = $(am__DEPENDENCIES_1) +test_cmdline_LINK = $(CCLD) $(test_cmdline_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__test_features_SOURCES_DIST = test-features.c test-common.c \ + ethtool.c uapi/linux/ethtool.h internal.h \ + uapi/linux/net_tstamp.h rxclass.c common.c common.h \ + json_writer.c json_writer.h json_print.c json_print.h list.h \ + amd8111e.c de2104x.c dsa.c e100.c e1000.c et131x.c igb.c fec.c \ + fec_8xx.c fsl_enetc.c ibm_emac.c ixgb.c ixgbe.c natsemi.c \ + pcnet32.c realtek.c tg3.c marvell.c vioc.c smsc911x.c \ + at76c50x-usb.c sfc.c stmmac.c sff-common.c sff-common.h \ + sfpid.c sfpdiag.c ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h \ + fjes.c lan78xx.c igc.c cmis.c cmis.h bnxt.c cpsw.c lan743x.c \ + netlink/netlink.c netlink/netlink.h netlink/extapi.h \ + netlink/msgbuff.c netlink/msgbuff.h netlink/nlsock.c \ + netlink/nlsock.h netlink/strset.c netlink/strset.h \ + netlink/monitor.c netlink/bitset.c netlink/bitset.h \ + netlink/settings.c netlink/parser.c netlink/parser.h \ + netlink/permaddr.c netlink/prettymsg.c netlink/prettymsg.h \ + netlink/features.c netlink/privflags.c netlink/rings.c \ + netlink/channels.c netlink/coalesce.c netlink/pause.c \ + netlink/eee.c netlink/tsinfo.c netlink/fec.c netlink/stats.c \ + netlink/desc-ethtool.c netlink/desc-genlctrl.c \ + netlink/module-eeprom.c netlink/module.c netlink/desc-rtnl.c \ + netlink/cable_test.c netlink/tunnels.c \ + uapi/linux/ethtool_netlink.h uapi/linux/netlink.h \ + uapi/linux/genetlink.h uapi/linux/rtnetlink.h \ + uapi/linux/if_link.h +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@am__objects_6 = test_features-amd8111e.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-de2104x.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-dsa.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-e100.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-e1000.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-et131x.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-igb.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-fec.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-fec_8xx.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-fsl_enetc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-ibm_emac.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-ixgb.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-ixgbe.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-natsemi.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-pcnet32.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-realtek.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-tg3.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-marvell.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-vioc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-smsc911x.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-at76c50x-usb.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-sfc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-stmmac.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-sff-common.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-sfpid.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-sfpdiag.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-ixgbevf.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-tse.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-vmxnet3.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-qsfp.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-fjes.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-lan78xx.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-igc.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-cmis.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-bnxt.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-cpsw.$(OBJEXT) \ +@ETHTOOL_ENABLE_PRETTY_DUMP_TRUE@ test_features-lan743x.$(OBJEXT) +@ETHTOOL_ENABLE_NETLINK_TRUE@am__objects_7 = netlink/test_features-netlink.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-msgbuff.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-nlsock.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-strset.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-monitor.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-bitset.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-settings.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-parser.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-permaddr.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-prettymsg.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-features.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-privflags.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-rings.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-channels.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-coalesce.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-pause.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-eee.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-tsinfo.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-fec.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-stats.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-desc-ethtool.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-desc-genlctrl.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-module-eeprom.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-module.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-desc-rtnl.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-cable_test.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_TRUE@ netlink/test_features-tunnels.$(OBJEXT) +am__objects_8 = test_features-ethtool.$(OBJEXT) \ + test_features-rxclass.$(OBJEXT) test_features-common.$(OBJEXT) \ + test_features-json_writer.$(OBJEXT) \ + test_features-json_print.$(OBJEXT) $(am__objects_6) \ + $(am__objects_7) +@ETHTOOL_ENABLE_NETLINK_FALSE@am_test_features_OBJECTS = test_features-test-features.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_FALSE@ test_features-test-common.$(OBJEXT) \ +@ETHTOOL_ENABLE_NETLINK_FALSE@ $(am__objects_8) +test_features_OBJECTS = $(am_test_features_OBJECTS) +test_features_LDADD = $(LDADD) +test_features_DEPENDENCIES = $(am__DEPENDENCIES_1) +test_features_LINK = $(CCLD) $(test_features_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(ethtool_SOURCES) $(test_cmdline_SOURCES) \ + $(test_features_SOURCES) +DIST_SOURCES = $(am__ethtool_SOURCES_DIST) \ + $(am__test_cmdline_SOURCES_DIST) \ + $(am__test_features_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man_MANS) +am__dist_bashcompletion_DATA_DIST = shell-completion/bash/ethtool +DATA = $(dist_bashcompletion_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)ethtool-config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +AM_RECURSIVE_TARGETS = cscope check recheck +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/ethtool-config.h.in \ + $(srcdir)/ethtool.8.in $(srcdir)/ethtool.spec.in AUTHORS \ + COPYING ChangeLog INSTALL NEWS README compile depcomp \ + install-sh missing test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASH_COMPLETION_DIR = @BASH_COMPLETION_DIR@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MNL_CFLAGS = @MNL_CFLAGS@ +MNL_LIBS = @MNL_LIBS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CFLAGS = -Wall -Wextra -D_POSIX_C_SOURCE=200809L +AM_CPPFLAGS = -I$(top_srcdir)/uapi $(am__append_3) +LDADD = -lm $(am__append_4) +man_MANS = ethtool.8 +EXTRA_DIST = LICENSE ethtool.8 ethtool.spec.in aclocal.m4 ChangeLog autogen.sh +ethtool_SOURCES = ethtool.c uapi/linux/ethtool.h internal.h \ + uapi/linux/net_tstamp.h rxclass.c common.c common.h \ + json_writer.c json_writer.h json_print.c json_print.h list.h \ + $(am__append_1) $(am__append_2) +@ENABLE_BASH_COMPLETION_TRUE@bashcompletiondir = $(BASH_COMPLETION_DIR) +@ENABLE_BASH_COMPLETION_TRUE@dist_bashcompletion_DATA = shell-completion/bash/ethtool +test_cmdline_SOURCES = test-cmdline.c test-common.c $(ethtool_SOURCES) +test_cmdline_CFLAGS = -DTEST_ETHTOOL +@ETHTOOL_ENABLE_NETLINK_FALSE@test_features_SOURCES = test-features.c test-common.c $(ethtool_SOURCES) +@ETHTOOL_ENABLE_NETLINK_FALSE@test_features_CFLAGS = -DTEST_ETHTOOL +all: ethtool-config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .log .o .obj .test .test$(EXEEXT) .trs +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +ethtool-config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/ethtool-config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status ethtool-config.h +$(srcdir)/ethtool-config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f ethtool-config.h stamp-h1 +ethtool.spec: $(top_builddir)/config.status $(srcdir)/ethtool.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +ethtool.8: $(top_builddir)/config.status $(srcdir)/ethtool.8.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +clean-checkPROGRAMS: + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) +netlink/$(am__dirstamp): + @$(MKDIR_P) netlink + @: > netlink/$(am__dirstamp) +netlink/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) netlink/$(DEPDIR) + @: > netlink/$(DEPDIR)/$(am__dirstamp) +netlink/netlink.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/msgbuff.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/nlsock.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/strset.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/monitor.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/bitset.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/settings.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/parser.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/permaddr.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/prettymsg.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/features.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/privflags.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/rings.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/channels.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/coalesce.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/pause.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/eee.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/tsinfo.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/fec.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/stats.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/desc-ethtool.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/desc-genlctrl.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/module-eeprom.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/module.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/desc-rtnl.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/cable_test.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/tunnels.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) + +ethtool$(EXEEXT): $(ethtool_OBJECTS) $(ethtool_DEPENDENCIES) $(EXTRA_ethtool_DEPENDENCIES) + @rm -f ethtool$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ethtool_OBJECTS) $(ethtool_LDADD) $(LIBS) +netlink/test_cmdline-netlink.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-msgbuff.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-nlsock.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-strset.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-monitor.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-bitset.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-settings.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-parser.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-permaddr.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-prettymsg.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-features.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-privflags.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-rings.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-channels.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-coalesce.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-pause.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-eee.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-tsinfo.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-fec.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-stats.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-desc-ethtool.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-desc-genlctrl.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-module-eeprom.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-module.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-desc-rtnl.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-cable_test.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_cmdline-tunnels.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) + +test-cmdline$(EXEEXT): $(test_cmdline_OBJECTS) $(test_cmdline_DEPENDENCIES) $(EXTRA_test_cmdline_DEPENDENCIES) + @rm -f test-cmdline$(EXEEXT) + $(AM_V_CCLD)$(test_cmdline_LINK) $(test_cmdline_OBJECTS) $(test_cmdline_LDADD) $(LIBS) +netlink/test_features-netlink.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-msgbuff.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-nlsock.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-strset.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-monitor.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-bitset.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-settings.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-parser.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-permaddr.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-prettymsg.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-features.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-privflags.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-rings.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-channels.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-coalesce.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-pause.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-eee.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-tsinfo.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-fec.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-stats.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-desc-ethtool.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-desc-genlctrl.$(OBJEXT): \ + netlink/$(am__dirstamp) netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-module-eeprom.$(OBJEXT): \ + netlink/$(am__dirstamp) netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-module.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-desc-rtnl.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-cable_test.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) +netlink/test_features-tunnels.$(OBJEXT): netlink/$(am__dirstamp) \ + netlink/$(DEPDIR)/$(am__dirstamp) + +test-features$(EXEEXT): $(test_features_OBJECTS) $(test_features_DEPENDENCIES) $(EXTRA_test_features_DEPENDENCIES) + @rm -f test-features$(EXEEXT) + $(AM_V_CCLD)$(test_features_LINK) $(test_features_OBJECTS) $(test_features_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f netlink/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd8111e.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/at76c50x-usb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bnxt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmis.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpsw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/de2104x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e100.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e1000.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/et131x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ethtool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fec_8xx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fjes.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsl_enetc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ibm_emac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ixgb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ixgbe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ixgbevf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json_print.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json_writer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lan743x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lan78xx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marvell.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/natsemi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcnet32.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qsfp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realtek.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rxclass.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sff-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfpdiag.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfpid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smsc911x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stmmac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-amd8111e.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-at76c50x-usb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-bnxt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-cmis.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-cpsw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-de2104x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-dsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-e100.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-e1000.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-et131x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-ethtool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-fec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-fec_8xx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-fjes.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-fsl_enetc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-ibm_emac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-igb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-igc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-ixgb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-ixgbe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-ixgbevf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-json_print.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-json_writer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-lan743x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-lan78xx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-marvell.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-natsemi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-pcnet32.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-qsfp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-realtek.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-rxclass.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-sfc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-sff-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-sfpdiag.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-sfpid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-smsc911x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-stmmac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-test-cmdline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-test-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-tg3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-tse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-vioc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cmdline-vmxnet3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-amd8111e.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-at76c50x-usb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-bnxt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-cmis.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-cpsw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-de2104x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-dsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-e100.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-e1000.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-et131x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-ethtool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-fec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-fec_8xx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-fjes.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-fsl_enetc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-ibm_emac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-igb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-igc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-ixgb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-ixgbe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-ixgbevf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-json_print.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-json_writer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-lan743x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-lan78xx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-marvell.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-natsemi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-pcnet32.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-qsfp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-realtek.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-rxclass.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-sfc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-sff-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-sfpdiag.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-sfpid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-smsc911x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-stmmac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-test-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-test-features.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-tg3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-tse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-vioc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_features-vmxnet3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tg3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vioc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmxnet3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/bitset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/cable_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/channels.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/coalesce.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/desc-ethtool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/desc-genlctrl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/desc-rtnl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/eee.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/features.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/fec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/module-eeprom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/module.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/monitor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/msgbuff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/netlink.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/nlsock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/pause.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/permaddr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/prettymsg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/privflags.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/rings.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/settings.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/stats.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/strset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-bitset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-cable_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-channels.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-coalesce.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-desc-ethtool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-desc-genlctrl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-eee.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-features.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-fec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-module-eeprom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-module.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-monitor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-msgbuff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-netlink.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-nlsock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-pause.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-permaddr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-prettymsg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-privflags.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-rings.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-settings.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-stats.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-strset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-tsinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_cmdline-tunnels.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-bitset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-cable_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-channels.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-coalesce.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-desc-ethtool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-desc-genlctrl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-desc-rtnl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-eee.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-features.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-fec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-module-eeprom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-module.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-monitor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-msgbuff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-netlink.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-nlsock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-pause.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-permaddr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-prettymsg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-privflags.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-rings.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-settings.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-stats.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-strset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-tsinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/test_features-tunnels.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/tsinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@netlink/$(DEPDIR)/tunnels.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +test_cmdline-test-cmdline.o: test-cmdline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-test-cmdline.o -MD -MP -MF $(DEPDIR)/test_cmdline-test-cmdline.Tpo -c -o test_cmdline-test-cmdline.o `test -f 'test-cmdline.c' || echo '$(srcdir)/'`test-cmdline.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-test-cmdline.Tpo $(DEPDIR)/test_cmdline-test-cmdline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-cmdline.c' object='test_cmdline-test-cmdline.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-test-cmdline.o `test -f 'test-cmdline.c' || echo '$(srcdir)/'`test-cmdline.c + +test_cmdline-test-cmdline.obj: test-cmdline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-test-cmdline.obj -MD -MP -MF $(DEPDIR)/test_cmdline-test-cmdline.Tpo -c -o test_cmdline-test-cmdline.obj `if test -f 'test-cmdline.c'; then $(CYGPATH_W) 'test-cmdline.c'; else $(CYGPATH_W) '$(srcdir)/test-cmdline.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-test-cmdline.Tpo $(DEPDIR)/test_cmdline-test-cmdline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-cmdline.c' object='test_cmdline-test-cmdline.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-test-cmdline.obj `if test -f 'test-cmdline.c'; then $(CYGPATH_W) 'test-cmdline.c'; else $(CYGPATH_W) '$(srcdir)/test-cmdline.c'; fi` + +test_cmdline-test-common.o: test-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-test-common.o -MD -MP -MF $(DEPDIR)/test_cmdline-test-common.Tpo -c -o test_cmdline-test-common.o `test -f 'test-common.c' || echo '$(srcdir)/'`test-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-test-common.Tpo $(DEPDIR)/test_cmdline-test-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-common.c' object='test_cmdline-test-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-test-common.o `test -f 'test-common.c' || echo '$(srcdir)/'`test-common.c + +test_cmdline-test-common.obj: test-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-test-common.obj -MD -MP -MF $(DEPDIR)/test_cmdline-test-common.Tpo -c -o test_cmdline-test-common.obj `if test -f 'test-common.c'; then $(CYGPATH_W) 'test-common.c'; else $(CYGPATH_W) '$(srcdir)/test-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-test-common.Tpo $(DEPDIR)/test_cmdline-test-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-common.c' object='test_cmdline-test-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-test-common.obj `if test -f 'test-common.c'; then $(CYGPATH_W) 'test-common.c'; else $(CYGPATH_W) '$(srcdir)/test-common.c'; fi` + +test_cmdline-ethtool.o: ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ethtool.o -MD -MP -MF $(DEPDIR)/test_cmdline-ethtool.Tpo -c -o test_cmdline-ethtool.o `test -f 'ethtool.c' || echo '$(srcdir)/'`ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ethtool.Tpo $(DEPDIR)/test_cmdline-ethtool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ethtool.c' object='test_cmdline-ethtool.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ethtool.o `test -f 'ethtool.c' || echo '$(srcdir)/'`ethtool.c + +test_cmdline-ethtool.obj: ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ethtool.obj -MD -MP -MF $(DEPDIR)/test_cmdline-ethtool.Tpo -c -o test_cmdline-ethtool.obj `if test -f 'ethtool.c'; then $(CYGPATH_W) 'ethtool.c'; else $(CYGPATH_W) '$(srcdir)/ethtool.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ethtool.Tpo $(DEPDIR)/test_cmdline-ethtool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ethtool.c' object='test_cmdline-ethtool.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ethtool.obj `if test -f 'ethtool.c'; then $(CYGPATH_W) 'ethtool.c'; else $(CYGPATH_W) '$(srcdir)/ethtool.c'; fi` + +test_cmdline-rxclass.o: rxclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-rxclass.o -MD -MP -MF $(DEPDIR)/test_cmdline-rxclass.Tpo -c -o test_cmdline-rxclass.o `test -f 'rxclass.c' || echo '$(srcdir)/'`rxclass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-rxclass.Tpo $(DEPDIR)/test_cmdline-rxclass.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rxclass.c' object='test_cmdline-rxclass.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-rxclass.o `test -f 'rxclass.c' || echo '$(srcdir)/'`rxclass.c + +test_cmdline-rxclass.obj: rxclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-rxclass.obj -MD -MP -MF $(DEPDIR)/test_cmdline-rxclass.Tpo -c -o test_cmdline-rxclass.obj `if test -f 'rxclass.c'; then $(CYGPATH_W) 'rxclass.c'; else $(CYGPATH_W) '$(srcdir)/rxclass.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-rxclass.Tpo $(DEPDIR)/test_cmdline-rxclass.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rxclass.c' object='test_cmdline-rxclass.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-rxclass.obj `if test -f 'rxclass.c'; then $(CYGPATH_W) 'rxclass.c'; else $(CYGPATH_W) '$(srcdir)/rxclass.c'; fi` + +test_cmdline-common.o: common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-common.o -MD -MP -MF $(DEPDIR)/test_cmdline-common.Tpo -c -o test_cmdline-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-common.Tpo $(DEPDIR)/test_cmdline-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='test_cmdline-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c + +test_cmdline-common.obj: common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-common.obj -MD -MP -MF $(DEPDIR)/test_cmdline-common.Tpo -c -o test_cmdline-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-common.Tpo $(DEPDIR)/test_cmdline-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='test_cmdline-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` + +test_cmdline-json_writer.o: json_writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-json_writer.o -MD -MP -MF $(DEPDIR)/test_cmdline-json_writer.Tpo -c -o test_cmdline-json_writer.o `test -f 'json_writer.c' || echo '$(srcdir)/'`json_writer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-json_writer.Tpo $(DEPDIR)/test_cmdline-json_writer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json_writer.c' object='test_cmdline-json_writer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-json_writer.o `test -f 'json_writer.c' || echo '$(srcdir)/'`json_writer.c + +test_cmdline-json_writer.obj: json_writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-json_writer.obj -MD -MP -MF $(DEPDIR)/test_cmdline-json_writer.Tpo -c -o test_cmdline-json_writer.obj `if test -f 'json_writer.c'; then $(CYGPATH_W) 'json_writer.c'; else $(CYGPATH_W) '$(srcdir)/json_writer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-json_writer.Tpo $(DEPDIR)/test_cmdline-json_writer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json_writer.c' object='test_cmdline-json_writer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-json_writer.obj `if test -f 'json_writer.c'; then $(CYGPATH_W) 'json_writer.c'; else $(CYGPATH_W) '$(srcdir)/json_writer.c'; fi` + +test_cmdline-json_print.o: json_print.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-json_print.o -MD -MP -MF $(DEPDIR)/test_cmdline-json_print.Tpo -c -o test_cmdline-json_print.o `test -f 'json_print.c' || echo '$(srcdir)/'`json_print.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-json_print.Tpo $(DEPDIR)/test_cmdline-json_print.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json_print.c' object='test_cmdline-json_print.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-json_print.o `test -f 'json_print.c' || echo '$(srcdir)/'`json_print.c + +test_cmdline-json_print.obj: json_print.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-json_print.obj -MD -MP -MF $(DEPDIR)/test_cmdline-json_print.Tpo -c -o test_cmdline-json_print.obj `if test -f 'json_print.c'; then $(CYGPATH_W) 'json_print.c'; else $(CYGPATH_W) '$(srcdir)/json_print.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-json_print.Tpo $(DEPDIR)/test_cmdline-json_print.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json_print.c' object='test_cmdline-json_print.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-json_print.obj `if test -f 'json_print.c'; then $(CYGPATH_W) 'json_print.c'; else $(CYGPATH_W) '$(srcdir)/json_print.c'; fi` + +test_cmdline-amd8111e.o: amd8111e.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-amd8111e.o -MD -MP -MF $(DEPDIR)/test_cmdline-amd8111e.Tpo -c -o test_cmdline-amd8111e.o `test -f 'amd8111e.c' || echo '$(srcdir)/'`amd8111e.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-amd8111e.Tpo $(DEPDIR)/test_cmdline-amd8111e.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='amd8111e.c' object='test_cmdline-amd8111e.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-amd8111e.o `test -f 'amd8111e.c' || echo '$(srcdir)/'`amd8111e.c + +test_cmdline-amd8111e.obj: amd8111e.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-amd8111e.obj -MD -MP -MF $(DEPDIR)/test_cmdline-amd8111e.Tpo -c -o test_cmdline-amd8111e.obj `if test -f 'amd8111e.c'; then $(CYGPATH_W) 'amd8111e.c'; else $(CYGPATH_W) '$(srcdir)/amd8111e.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-amd8111e.Tpo $(DEPDIR)/test_cmdline-amd8111e.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='amd8111e.c' object='test_cmdline-amd8111e.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-amd8111e.obj `if test -f 'amd8111e.c'; then $(CYGPATH_W) 'amd8111e.c'; else $(CYGPATH_W) '$(srcdir)/amd8111e.c'; fi` + +test_cmdline-de2104x.o: de2104x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-de2104x.o -MD -MP -MF $(DEPDIR)/test_cmdline-de2104x.Tpo -c -o test_cmdline-de2104x.o `test -f 'de2104x.c' || echo '$(srcdir)/'`de2104x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-de2104x.Tpo $(DEPDIR)/test_cmdline-de2104x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='de2104x.c' object='test_cmdline-de2104x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-de2104x.o `test -f 'de2104x.c' || echo '$(srcdir)/'`de2104x.c + +test_cmdline-de2104x.obj: de2104x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-de2104x.obj -MD -MP -MF $(DEPDIR)/test_cmdline-de2104x.Tpo -c -o test_cmdline-de2104x.obj `if test -f 'de2104x.c'; then $(CYGPATH_W) 'de2104x.c'; else $(CYGPATH_W) '$(srcdir)/de2104x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-de2104x.Tpo $(DEPDIR)/test_cmdline-de2104x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='de2104x.c' object='test_cmdline-de2104x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-de2104x.obj `if test -f 'de2104x.c'; then $(CYGPATH_W) 'de2104x.c'; else $(CYGPATH_W) '$(srcdir)/de2104x.c'; fi` + +test_cmdline-dsa.o: dsa.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-dsa.o -MD -MP -MF $(DEPDIR)/test_cmdline-dsa.Tpo -c -o test_cmdline-dsa.o `test -f 'dsa.c' || echo '$(srcdir)/'`dsa.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-dsa.Tpo $(DEPDIR)/test_cmdline-dsa.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa.c' object='test_cmdline-dsa.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-dsa.o `test -f 'dsa.c' || echo '$(srcdir)/'`dsa.c + +test_cmdline-dsa.obj: dsa.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-dsa.obj -MD -MP -MF $(DEPDIR)/test_cmdline-dsa.Tpo -c -o test_cmdline-dsa.obj `if test -f 'dsa.c'; then $(CYGPATH_W) 'dsa.c'; else $(CYGPATH_W) '$(srcdir)/dsa.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-dsa.Tpo $(DEPDIR)/test_cmdline-dsa.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa.c' object='test_cmdline-dsa.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-dsa.obj `if test -f 'dsa.c'; then $(CYGPATH_W) 'dsa.c'; else $(CYGPATH_W) '$(srcdir)/dsa.c'; fi` + +test_cmdline-e100.o: e100.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-e100.o -MD -MP -MF $(DEPDIR)/test_cmdline-e100.Tpo -c -o test_cmdline-e100.o `test -f 'e100.c' || echo '$(srcdir)/'`e100.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-e100.Tpo $(DEPDIR)/test_cmdline-e100.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e100.c' object='test_cmdline-e100.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-e100.o `test -f 'e100.c' || echo '$(srcdir)/'`e100.c + +test_cmdline-e100.obj: e100.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-e100.obj -MD -MP -MF $(DEPDIR)/test_cmdline-e100.Tpo -c -o test_cmdline-e100.obj `if test -f 'e100.c'; then $(CYGPATH_W) 'e100.c'; else $(CYGPATH_W) '$(srcdir)/e100.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-e100.Tpo $(DEPDIR)/test_cmdline-e100.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e100.c' object='test_cmdline-e100.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-e100.obj `if test -f 'e100.c'; then $(CYGPATH_W) 'e100.c'; else $(CYGPATH_W) '$(srcdir)/e100.c'; fi` + +test_cmdline-e1000.o: e1000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-e1000.o -MD -MP -MF $(DEPDIR)/test_cmdline-e1000.Tpo -c -o test_cmdline-e1000.o `test -f 'e1000.c' || echo '$(srcdir)/'`e1000.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-e1000.Tpo $(DEPDIR)/test_cmdline-e1000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e1000.c' object='test_cmdline-e1000.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-e1000.o `test -f 'e1000.c' || echo '$(srcdir)/'`e1000.c + +test_cmdline-e1000.obj: e1000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-e1000.obj -MD -MP -MF $(DEPDIR)/test_cmdline-e1000.Tpo -c -o test_cmdline-e1000.obj `if test -f 'e1000.c'; then $(CYGPATH_W) 'e1000.c'; else $(CYGPATH_W) '$(srcdir)/e1000.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-e1000.Tpo $(DEPDIR)/test_cmdline-e1000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e1000.c' object='test_cmdline-e1000.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-e1000.obj `if test -f 'e1000.c'; then $(CYGPATH_W) 'e1000.c'; else $(CYGPATH_W) '$(srcdir)/e1000.c'; fi` + +test_cmdline-et131x.o: et131x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-et131x.o -MD -MP -MF $(DEPDIR)/test_cmdline-et131x.Tpo -c -o test_cmdline-et131x.o `test -f 'et131x.c' || echo '$(srcdir)/'`et131x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-et131x.Tpo $(DEPDIR)/test_cmdline-et131x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='et131x.c' object='test_cmdline-et131x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-et131x.o `test -f 'et131x.c' || echo '$(srcdir)/'`et131x.c + +test_cmdline-et131x.obj: et131x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-et131x.obj -MD -MP -MF $(DEPDIR)/test_cmdline-et131x.Tpo -c -o test_cmdline-et131x.obj `if test -f 'et131x.c'; then $(CYGPATH_W) 'et131x.c'; else $(CYGPATH_W) '$(srcdir)/et131x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-et131x.Tpo $(DEPDIR)/test_cmdline-et131x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='et131x.c' object='test_cmdline-et131x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-et131x.obj `if test -f 'et131x.c'; then $(CYGPATH_W) 'et131x.c'; else $(CYGPATH_W) '$(srcdir)/et131x.c'; fi` + +test_cmdline-igb.o: igb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-igb.o -MD -MP -MF $(DEPDIR)/test_cmdline-igb.Tpo -c -o test_cmdline-igb.o `test -f 'igb.c' || echo '$(srcdir)/'`igb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-igb.Tpo $(DEPDIR)/test_cmdline-igb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='igb.c' object='test_cmdline-igb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-igb.o `test -f 'igb.c' || echo '$(srcdir)/'`igb.c + +test_cmdline-igb.obj: igb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-igb.obj -MD -MP -MF $(DEPDIR)/test_cmdline-igb.Tpo -c -o test_cmdline-igb.obj `if test -f 'igb.c'; then $(CYGPATH_W) 'igb.c'; else $(CYGPATH_W) '$(srcdir)/igb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-igb.Tpo $(DEPDIR)/test_cmdline-igb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='igb.c' object='test_cmdline-igb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-igb.obj `if test -f 'igb.c'; then $(CYGPATH_W) 'igb.c'; else $(CYGPATH_W) '$(srcdir)/igb.c'; fi` + +test_cmdline-fec.o: fec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-fec.o -MD -MP -MF $(DEPDIR)/test_cmdline-fec.Tpo -c -o test_cmdline-fec.o `test -f 'fec.c' || echo '$(srcdir)/'`fec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-fec.Tpo $(DEPDIR)/test_cmdline-fec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fec.c' object='test_cmdline-fec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-fec.o `test -f 'fec.c' || echo '$(srcdir)/'`fec.c + +test_cmdline-fec.obj: fec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-fec.obj -MD -MP -MF $(DEPDIR)/test_cmdline-fec.Tpo -c -o test_cmdline-fec.obj `if test -f 'fec.c'; then $(CYGPATH_W) 'fec.c'; else $(CYGPATH_W) '$(srcdir)/fec.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-fec.Tpo $(DEPDIR)/test_cmdline-fec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fec.c' object='test_cmdline-fec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-fec.obj `if test -f 'fec.c'; then $(CYGPATH_W) 'fec.c'; else $(CYGPATH_W) '$(srcdir)/fec.c'; fi` + +test_cmdline-fec_8xx.o: fec_8xx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-fec_8xx.o -MD -MP -MF $(DEPDIR)/test_cmdline-fec_8xx.Tpo -c -o test_cmdline-fec_8xx.o `test -f 'fec_8xx.c' || echo '$(srcdir)/'`fec_8xx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-fec_8xx.Tpo $(DEPDIR)/test_cmdline-fec_8xx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fec_8xx.c' object='test_cmdline-fec_8xx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-fec_8xx.o `test -f 'fec_8xx.c' || echo '$(srcdir)/'`fec_8xx.c + +test_cmdline-fec_8xx.obj: fec_8xx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-fec_8xx.obj -MD -MP -MF $(DEPDIR)/test_cmdline-fec_8xx.Tpo -c -o test_cmdline-fec_8xx.obj `if test -f 'fec_8xx.c'; then $(CYGPATH_W) 'fec_8xx.c'; else $(CYGPATH_W) '$(srcdir)/fec_8xx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-fec_8xx.Tpo $(DEPDIR)/test_cmdline-fec_8xx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fec_8xx.c' object='test_cmdline-fec_8xx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-fec_8xx.obj `if test -f 'fec_8xx.c'; then $(CYGPATH_W) 'fec_8xx.c'; else $(CYGPATH_W) '$(srcdir)/fec_8xx.c'; fi` + +test_cmdline-fsl_enetc.o: fsl_enetc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-fsl_enetc.o -MD -MP -MF $(DEPDIR)/test_cmdline-fsl_enetc.Tpo -c -o test_cmdline-fsl_enetc.o `test -f 'fsl_enetc.c' || echo '$(srcdir)/'`fsl_enetc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-fsl_enetc.Tpo $(DEPDIR)/test_cmdline-fsl_enetc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fsl_enetc.c' object='test_cmdline-fsl_enetc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-fsl_enetc.o `test -f 'fsl_enetc.c' || echo '$(srcdir)/'`fsl_enetc.c + +test_cmdline-fsl_enetc.obj: fsl_enetc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-fsl_enetc.obj -MD -MP -MF $(DEPDIR)/test_cmdline-fsl_enetc.Tpo -c -o test_cmdline-fsl_enetc.obj `if test -f 'fsl_enetc.c'; then $(CYGPATH_W) 'fsl_enetc.c'; else $(CYGPATH_W) '$(srcdir)/fsl_enetc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-fsl_enetc.Tpo $(DEPDIR)/test_cmdline-fsl_enetc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fsl_enetc.c' object='test_cmdline-fsl_enetc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-fsl_enetc.obj `if test -f 'fsl_enetc.c'; then $(CYGPATH_W) 'fsl_enetc.c'; else $(CYGPATH_W) '$(srcdir)/fsl_enetc.c'; fi` + +test_cmdline-ibm_emac.o: ibm_emac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ibm_emac.o -MD -MP -MF $(DEPDIR)/test_cmdline-ibm_emac.Tpo -c -o test_cmdline-ibm_emac.o `test -f 'ibm_emac.c' || echo '$(srcdir)/'`ibm_emac.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ibm_emac.Tpo $(DEPDIR)/test_cmdline-ibm_emac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ibm_emac.c' object='test_cmdline-ibm_emac.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ibm_emac.o `test -f 'ibm_emac.c' || echo '$(srcdir)/'`ibm_emac.c + +test_cmdline-ibm_emac.obj: ibm_emac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ibm_emac.obj -MD -MP -MF $(DEPDIR)/test_cmdline-ibm_emac.Tpo -c -o test_cmdline-ibm_emac.obj `if test -f 'ibm_emac.c'; then $(CYGPATH_W) 'ibm_emac.c'; else $(CYGPATH_W) '$(srcdir)/ibm_emac.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ibm_emac.Tpo $(DEPDIR)/test_cmdline-ibm_emac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ibm_emac.c' object='test_cmdline-ibm_emac.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ibm_emac.obj `if test -f 'ibm_emac.c'; then $(CYGPATH_W) 'ibm_emac.c'; else $(CYGPATH_W) '$(srcdir)/ibm_emac.c'; fi` + +test_cmdline-ixgb.o: ixgb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ixgb.o -MD -MP -MF $(DEPDIR)/test_cmdline-ixgb.Tpo -c -o test_cmdline-ixgb.o `test -f 'ixgb.c' || echo '$(srcdir)/'`ixgb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ixgb.Tpo $(DEPDIR)/test_cmdline-ixgb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgb.c' object='test_cmdline-ixgb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ixgb.o `test -f 'ixgb.c' || echo '$(srcdir)/'`ixgb.c + +test_cmdline-ixgb.obj: ixgb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ixgb.obj -MD -MP -MF $(DEPDIR)/test_cmdline-ixgb.Tpo -c -o test_cmdline-ixgb.obj `if test -f 'ixgb.c'; then $(CYGPATH_W) 'ixgb.c'; else $(CYGPATH_W) '$(srcdir)/ixgb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ixgb.Tpo $(DEPDIR)/test_cmdline-ixgb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgb.c' object='test_cmdline-ixgb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ixgb.obj `if test -f 'ixgb.c'; then $(CYGPATH_W) 'ixgb.c'; else $(CYGPATH_W) '$(srcdir)/ixgb.c'; fi` + +test_cmdline-ixgbe.o: ixgbe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ixgbe.o -MD -MP -MF $(DEPDIR)/test_cmdline-ixgbe.Tpo -c -o test_cmdline-ixgbe.o `test -f 'ixgbe.c' || echo '$(srcdir)/'`ixgbe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ixgbe.Tpo $(DEPDIR)/test_cmdline-ixgbe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgbe.c' object='test_cmdline-ixgbe.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ixgbe.o `test -f 'ixgbe.c' || echo '$(srcdir)/'`ixgbe.c + +test_cmdline-ixgbe.obj: ixgbe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ixgbe.obj -MD -MP -MF $(DEPDIR)/test_cmdline-ixgbe.Tpo -c -o test_cmdline-ixgbe.obj `if test -f 'ixgbe.c'; then $(CYGPATH_W) 'ixgbe.c'; else $(CYGPATH_W) '$(srcdir)/ixgbe.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ixgbe.Tpo $(DEPDIR)/test_cmdline-ixgbe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgbe.c' object='test_cmdline-ixgbe.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ixgbe.obj `if test -f 'ixgbe.c'; then $(CYGPATH_W) 'ixgbe.c'; else $(CYGPATH_W) '$(srcdir)/ixgbe.c'; fi` + +test_cmdline-natsemi.o: natsemi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-natsemi.o -MD -MP -MF $(DEPDIR)/test_cmdline-natsemi.Tpo -c -o test_cmdline-natsemi.o `test -f 'natsemi.c' || echo '$(srcdir)/'`natsemi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-natsemi.Tpo $(DEPDIR)/test_cmdline-natsemi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='natsemi.c' object='test_cmdline-natsemi.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-natsemi.o `test -f 'natsemi.c' || echo '$(srcdir)/'`natsemi.c + +test_cmdline-natsemi.obj: natsemi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-natsemi.obj -MD -MP -MF $(DEPDIR)/test_cmdline-natsemi.Tpo -c -o test_cmdline-natsemi.obj `if test -f 'natsemi.c'; then $(CYGPATH_W) 'natsemi.c'; else $(CYGPATH_W) '$(srcdir)/natsemi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-natsemi.Tpo $(DEPDIR)/test_cmdline-natsemi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='natsemi.c' object='test_cmdline-natsemi.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-natsemi.obj `if test -f 'natsemi.c'; then $(CYGPATH_W) 'natsemi.c'; else $(CYGPATH_W) '$(srcdir)/natsemi.c'; fi` + +test_cmdline-pcnet32.o: pcnet32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-pcnet32.o -MD -MP -MF $(DEPDIR)/test_cmdline-pcnet32.Tpo -c -o test_cmdline-pcnet32.o `test -f 'pcnet32.c' || echo '$(srcdir)/'`pcnet32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-pcnet32.Tpo $(DEPDIR)/test_cmdline-pcnet32.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcnet32.c' object='test_cmdline-pcnet32.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-pcnet32.o `test -f 'pcnet32.c' || echo '$(srcdir)/'`pcnet32.c + +test_cmdline-pcnet32.obj: pcnet32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-pcnet32.obj -MD -MP -MF $(DEPDIR)/test_cmdline-pcnet32.Tpo -c -o test_cmdline-pcnet32.obj `if test -f 'pcnet32.c'; then $(CYGPATH_W) 'pcnet32.c'; else $(CYGPATH_W) '$(srcdir)/pcnet32.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-pcnet32.Tpo $(DEPDIR)/test_cmdline-pcnet32.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcnet32.c' object='test_cmdline-pcnet32.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-pcnet32.obj `if test -f 'pcnet32.c'; then $(CYGPATH_W) 'pcnet32.c'; else $(CYGPATH_W) '$(srcdir)/pcnet32.c'; fi` + +test_cmdline-realtek.o: realtek.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-realtek.o -MD -MP -MF $(DEPDIR)/test_cmdline-realtek.Tpo -c -o test_cmdline-realtek.o `test -f 'realtek.c' || echo '$(srcdir)/'`realtek.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-realtek.Tpo $(DEPDIR)/test_cmdline-realtek.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='realtek.c' object='test_cmdline-realtek.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-realtek.o `test -f 'realtek.c' || echo '$(srcdir)/'`realtek.c + +test_cmdline-realtek.obj: realtek.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-realtek.obj -MD -MP -MF $(DEPDIR)/test_cmdline-realtek.Tpo -c -o test_cmdline-realtek.obj `if test -f 'realtek.c'; then $(CYGPATH_W) 'realtek.c'; else $(CYGPATH_W) '$(srcdir)/realtek.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-realtek.Tpo $(DEPDIR)/test_cmdline-realtek.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='realtek.c' object='test_cmdline-realtek.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-realtek.obj `if test -f 'realtek.c'; then $(CYGPATH_W) 'realtek.c'; else $(CYGPATH_W) '$(srcdir)/realtek.c'; fi` + +test_cmdline-tg3.o: tg3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-tg3.o -MD -MP -MF $(DEPDIR)/test_cmdline-tg3.Tpo -c -o test_cmdline-tg3.o `test -f 'tg3.c' || echo '$(srcdir)/'`tg3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-tg3.Tpo $(DEPDIR)/test_cmdline-tg3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tg3.c' object='test_cmdline-tg3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-tg3.o `test -f 'tg3.c' || echo '$(srcdir)/'`tg3.c + +test_cmdline-tg3.obj: tg3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-tg3.obj -MD -MP -MF $(DEPDIR)/test_cmdline-tg3.Tpo -c -o test_cmdline-tg3.obj `if test -f 'tg3.c'; then $(CYGPATH_W) 'tg3.c'; else $(CYGPATH_W) '$(srcdir)/tg3.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-tg3.Tpo $(DEPDIR)/test_cmdline-tg3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tg3.c' object='test_cmdline-tg3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-tg3.obj `if test -f 'tg3.c'; then $(CYGPATH_W) 'tg3.c'; else $(CYGPATH_W) '$(srcdir)/tg3.c'; fi` + +test_cmdline-marvell.o: marvell.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-marvell.o -MD -MP -MF $(DEPDIR)/test_cmdline-marvell.Tpo -c -o test_cmdline-marvell.o `test -f 'marvell.c' || echo '$(srcdir)/'`marvell.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-marvell.Tpo $(DEPDIR)/test_cmdline-marvell.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='marvell.c' object='test_cmdline-marvell.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-marvell.o `test -f 'marvell.c' || echo '$(srcdir)/'`marvell.c + +test_cmdline-marvell.obj: marvell.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-marvell.obj -MD -MP -MF $(DEPDIR)/test_cmdline-marvell.Tpo -c -o test_cmdline-marvell.obj `if test -f 'marvell.c'; then $(CYGPATH_W) 'marvell.c'; else $(CYGPATH_W) '$(srcdir)/marvell.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-marvell.Tpo $(DEPDIR)/test_cmdline-marvell.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='marvell.c' object='test_cmdline-marvell.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-marvell.obj `if test -f 'marvell.c'; then $(CYGPATH_W) 'marvell.c'; else $(CYGPATH_W) '$(srcdir)/marvell.c'; fi` + +test_cmdline-vioc.o: vioc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-vioc.o -MD -MP -MF $(DEPDIR)/test_cmdline-vioc.Tpo -c -o test_cmdline-vioc.o `test -f 'vioc.c' || echo '$(srcdir)/'`vioc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-vioc.Tpo $(DEPDIR)/test_cmdline-vioc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vioc.c' object='test_cmdline-vioc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-vioc.o `test -f 'vioc.c' || echo '$(srcdir)/'`vioc.c + +test_cmdline-vioc.obj: vioc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-vioc.obj -MD -MP -MF $(DEPDIR)/test_cmdline-vioc.Tpo -c -o test_cmdline-vioc.obj `if test -f 'vioc.c'; then $(CYGPATH_W) 'vioc.c'; else $(CYGPATH_W) '$(srcdir)/vioc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-vioc.Tpo $(DEPDIR)/test_cmdline-vioc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vioc.c' object='test_cmdline-vioc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-vioc.obj `if test -f 'vioc.c'; then $(CYGPATH_W) 'vioc.c'; else $(CYGPATH_W) '$(srcdir)/vioc.c'; fi` + +test_cmdline-smsc911x.o: smsc911x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-smsc911x.o -MD -MP -MF $(DEPDIR)/test_cmdline-smsc911x.Tpo -c -o test_cmdline-smsc911x.o `test -f 'smsc911x.c' || echo '$(srcdir)/'`smsc911x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-smsc911x.Tpo $(DEPDIR)/test_cmdline-smsc911x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smsc911x.c' object='test_cmdline-smsc911x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-smsc911x.o `test -f 'smsc911x.c' || echo '$(srcdir)/'`smsc911x.c + +test_cmdline-smsc911x.obj: smsc911x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-smsc911x.obj -MD -MP -MF $(DEPDIR)/test_cmdline-smsc911x.Tpo -c -o test_cmdline-smsc911x.obj `if test -f 'smsc911x.c'; then $(CYGPATH_W) 'smsc911x.c'; else $(CYGPATH_W) '$(srcdir)/smsc911x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-smsc911x.Tpo $(DEPDIR)/test_cmdline-smsc911x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smsc911x.c' object='test_cmdline-smsc911x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-smsc911x.obj `if test -f 'smsc911x.c'; then $(CYGPATH_W) 'smsc911x.c'; else $(CYGPATH_W) '$(srcdir)/smsc911x.c'; fi` + +test_cmdline-at76c50x-usb.o: at76c50x-usb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-at76c50x-usb.o -MD -MP -MF $(DEPDIR)/test_cmdline-at76c50x-usb.Tpo -c -o test_cmdline-at76c50x-usb.o `test -f 'at76c50x-usb.c' || echo '$(srcdir)/'`at76c50x-usb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-at76c50x-usb.Tpo $(DEPDIR)/test_cmdline-at76c50x-usb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='at76c50x-usb.c' object='test_cmdline-at76c50x-usb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-at76c50x-usb.o `test -f 'at76c50x-usb.c' || echo '$(srcdir)/'`at76c50x-usb.c + +test_cmdline-at76c50x-usb.obj: at76c50x-usb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-at76c50x-usb.obj -MD -MP -MF $(DEPDIR)/test_cmdline-at76c50x-usb.Tpo -c -o test_cmdline-at76c50x-usb.obj `if test -f 'at76c50x-usb.c'; then $(CYGPATH_W) 'at76c50x-usb.c'; else $(CYGPATH_W) '$(srcdir)/at76c50x-usb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-at76c50x-usb.Tpo $(DEPDIR)/test_cmdline-at76c50x-usb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='at76c50x-usb.c' object='test_cmdline-at76c50x-usb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-at76c50x-usb.obj `if test -f 'at76c50x-usb.c'; then $(CYGPATH_W) 'at76c50x-usb.c'; else $(CYGPATH_W) '$(srcdir)/at76c50x-usb.c'; fi` + +test_cmdline-sfc.o: sfc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-sfc.o -MD -MP -MF $(DEPDIR)/test_cmdline-sfc.Tpo -c -o test_cmdline-sfc.o `test -f 'sfc.c' || echo '$(srcdir)/'`sfc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-sfc.Tpo $(DEPDIR)/test_cmdline-sfc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfc.c' object='test_cmdline-sfc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-sfc.o `test -f 'sfc.c' || echo '$(srcdir)/'`sfc.c + +test_cmdline-sfc.obj: sfc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-sfc.obj -MD -MP -MF $(DEPDIR)/test_cmdline-sfc.Tpo -c -o test_cmdline-sfc.obj `if test -f 'sfc.c'; then $(CYGPATH_W) 'sfc.c'; else $(CYGPATH_W) '$(srcdir)/sfc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-sfc.Tpo $(DEPDIR)/test_cmdline-sfc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfc.c' object='test_cmdline-sfc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-sfc.obj `if test -f 'sfc.c'; then $(CYGPATH_W) 'sfc.c'; else $(CYGPATH_W) '$(srcdir)/sfc.c'; fi` + +test_cmdline-stmmac.o: stmmac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-stmmac.o -MD -MP -MF $(DEPDIR)/test_cmdline-stmmac.Tpo -c -o test_cmdline-stmmac.o `test -f 'stmmac.c' || echo '$(srcdir)/'`stmmac.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-stmmac.Tpo $(DEPDIR)/test_cmdline-stmmac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stmmac.c' object='test_cmdline-stmmac.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-stmmac.o `test -f 'stmmac.c' || echo '$(srcdir)/'`stmmac.c + +test_cmdline-stmmac.obj: stmmac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-stmmac.obj -MD -MP -MF $(DEPDIR)/test_cmdline-stmmac.Tpo -c -o test_cmdline-stmmac.obj `if test -f 'stmmac.c'; then $(CYGPATH_W) 'stmmac.c'; else $(CYGPATH_W) '$(srcdir)/stmmac.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-stmmac.Tpo $(DEPDIR)/test_cmdline-stmmac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stmmac.c' object='test_cmdline-stmmac.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-stmmac.obj `if test -f 'stmmac.c'; then $(CYGPATH_W) 'stmmac.c'; else $(CYGPATH_W) '$(srcdir)/stmmac.c'; fi` + +test_cmdline-sff-common.o: sff-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-sff-common.o -MD -MP -MF $(DEPDIR)/test_cmdline-sff-common.Tpo -c -o test_cmdline-sff-common.o `test -f 'sff-common.c' || echo '$(srcdir)/'`sff-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-sff-common.Tpo $(DEPDIR)/test_cmdline-sff-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sff-common.c' object='test_cmdline-sff-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-sff-common.o `test -f 'sff-common.c' || echo '$(srcdir)/'`sff-common.c + +test_cmdline-sff-common.obj: sff-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-sff-common.obj -MD -MP -MF $(DEPDIR)/test_cmdline-sff-common.Tpo -c -o test_cmdline-sff-common.obj `if test -f 'sff-common.c'; then $(CYGPATH_W) 'sff-common.c'; else $(CYGPATH_W) '$(srcdir)/sff-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-sff-common.Tpo $(DEPDIR)/test_cmdline-sff-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sff-common.c' object='test_cmdline-sff-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-sff-common.obj `if test -f 'sff-common.c'; then $(CYGPATH_W) 'sff-common.c'; else $(CYGPATH_W) '$(srcdir)/sff-common.c'; fi` + +test_cmdline-sfpid.o: sfpid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-sfpid.o -MD -MP -MF $(DEPDIR)/test_cmdline-sfpid.Tpo -c -o test_cmdline-sfpid.o `test -f 'sfpid.c' || echo '$(srcdir)/'`sfpid.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-sfpid.Tpo $(DEPDIR)/test_cmdline-sfpid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfpid.c' object='test_cmdline-sfpid.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-sfpid.o `test -f 'sfpid.c' || echo '$(srcdir)/'`sfpid.c + +test_cmdline-sfpid.obj: sfpid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-sfpid.obj -MD -MP -MF $(DEPDIR)/test_cmdline-sfpid.Tpo -c -o test_cmdline-sfpid.obj `if test -f 'sfpid.c'; then $(CYGPATH_W) 'sfpid.c'; else $(CYGPATH_W) '$(srcdir)/sfpid.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-sfpid.Tpo $(DEPDIR)/test_cmdline-sfpid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfpid.c' object='test_cmdline-sfpid.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-sfpid.obj `if test -f 'sfpid.c'; then $(CYGPATH_W) 'sfpid.c'; else $(CYGPATH_W) '$(srcdir)/sfpid.c'; fi` + +test_cmdline-sfpdiag.o: sfpdiag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-sfpdiag.o -MD -MP -MF $(DEPDIR)/test_cmdline-sfpdiag.Tpo -c -o test_cmdline-sfpdiag.o `test -f 'sfpdiag.c' || echo '$(srcdir)/'`sfpdiag.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-sfpdiag.Tpo $(DEPDIR)/test_cmdline-sfpdiag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfpdiag.c' object='test_cmdline-sfpdiag.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-sfpdiag.o `test -f 'sfpdiag.c' || echo '$(srcdir)/'`sfpdiag.c + +test_cmdline-sfpdiag.obj: sfpdiag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-sfpdiag.obj -MD -MP -MF $(DEPDIR)/test_cmdline-sfpdiag.Tpo -c -o test_cmdline-sfpdiag.obj `if test -f 'sfpdiag.c'; then $(CYGPATH_W) 'sfpdiag.c'; else $(CYGPATH_W) '$(srcdir)/sfpdiag.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-sfpdiag.Tpo $(DEPDIR)/test_cmdline-sfpdiag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfpdiag.c' object='test_cmdline-sfpdiag.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-sfpdiag.obj `if test -f 'sfpdiag.c'; then $(CYGPATH_W) 'sfpdiag.c'; else $(CYGPATH_W) '$(srcdir)/sfpdiag.c'; fi` + +test_cmdline-ixgbevf.o: ixgbevf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ixgbevf.o -MD -MP -MF $(DEPDIR)/test_cmdline-ixgbevf.Tpo -c -o test_cmdline-ixgbevf.o `test -f 'ixgbevf.c' || echo '$(srcdir)/'`ixgbevf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ixgbevf.Tpo $(DEPDIR)/test_cmdline-ixgbevf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgbevf.c' object='test_cmdline-ixgbevf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ixgbevf.o `test -f 'ixgbevf.c' || echo '$(srcdir)/'`ixgbevf.c + +test_cmdline-ixgbevf.obj: ixgbevf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-ixgbevf.obj -MD -MP -MF $(DEPDIR)/test_cmdline-ixgbevf.Tpo -c -o test_cmdline-ixgbevf.obj `if test -f 'ixgbevf.c'; then $(CYGPATH_W) 'ixgbevf.c'; else $(CYGPATH_W) '$(srcdir)/ixgbevf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-ixgbevf.Tpo $(DEPDIR)/test_cmdline-ixgbevf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgbevf.c' object='test_cmdline-ixgbevf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-ixgbevf.obj `if test -f 'ixgbevf.c'; then $(CYGPATH_W) 'ixgbevf.c'; else $(CYGPATH_W) '$(srcdir)/ixgbevf.c'; fi` + +test_cmdline-tse.o: tse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-tse.o -MD -MP -MF $(DEPDIR)/test_cmdline-tse.Tpo -c -o test_cmdline-tse.o `test -f 'tse.c' || echo '$(srcdir)/'`tse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-tse.Tpo $(DEPDIR)/test_cmdline-tse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tse.c' object='test_cmdline-tse.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-tse.o `test -f 'tse.c' || echo '$(srcdir)/'`tse.c + +test_cmdline-tse.obj: tse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-tse.obj -MD -MP -MF $(DEPDIR)/test_cmdline-tse.Tpo -c -o test_cmdline-tse.obj `if test -f 'tse.c'; then $(CYGPATH_W) 'tse.c'; else $(CYGPATH_W) '$(srcdir)/tse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-tse.Tpo $(DEPDIR)/test_cmdline-tse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tse.c' object='test_cmdline-tse.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-tse.obj `if test -f 'tse.c'; then $(CYGPATH_W) 'tse.c'; else $(CYGPATH_W) '$(srcdir)/tse.c'; fi` + +test_cmdline-vmxnet3.o: vmxnet3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-vmxnet3.o -MD -MP -MF $(DEPDIR)/test_cmdline-vmxnet3.Tpo -c -o test_cmdline-vmxnet3.o `test -f 'vmxnet3.c' || echo '$(srcdir)/'`vmxnet3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-vmxnet3.Tpo $(DEPDIR)/test_cmdline-vmxnet3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vmxnet3.c' object='test_cmdline-vmxnet3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-vmxnet3.o `test -f 'vmxnet3.c' || echo '$(srcdir)/'`vmxnet3.c + +test_cmdline-vmxnet3.obj: vmxnet3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-vmxnet3.obj -MD -MP -MF $(DEPDIR)/test_cmdline-vmxnet3.Tpo -c -o test_cmdline-vmxnet3.obj `if test -f 'vmxnet3.c'; then $(CYGPATH_W) 'vmxnet3.c'; else $(CYGPATH_W) '$(srcdir)/vmxnet3.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-vmxnet3.Tpo $(DEPDIR)/test_cmdline-vmxnet3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vmxnet3.c' object='test_cmdline-vmxnet3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-vmxnet3.obj `if test -f 'vmxnet3.c'; then $(CYGPATH_W) 'vmxnet3.c'; else $(CYGPATH_W) '$(srcdir)/vmxnet3.c'; fi` + +test_cmdline-qsfp.o: qsfp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-qsfp.o -MD -MP -MF $(DEPDIR)/test_cmdline-qsfp.Tpo -c -o test_cmdline-qsfp.o `test -f 'qsfp.c' || echo '$(srcdir)/'`qsfp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-qsfp.Tpo $(DEPDIR)/test_cmdline-qsfp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qsfp.c' object='test_cmdline-qsfp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-qsfp.o `test -f 'qsfp.c' || echo '$(srcdir)/'`qsfp.c + +test_cmdline-qsfp.obj: qsfp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-qsfp.obj -MD -MP -MF $(DEPDIR)/test_cmdline-qsfp.Tpo -c -o test_cmdline-qsfp.obj `if test -f 'qsfp.c'; then $(CYGPATH_W) 'qsfp.c'; else $(CYGPATH_W) '$(srcdir)/qsfp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-qsfp.Tpo $(DEPDIR)/test_cmdline-qsfp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qsfp.c' object='test_cmdline-qsfp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-qsfp.obj `if test -f 'qsfp.c'; then $(CYGPATH_W) 'qsfp.c'; else $(CYGPATH_W) '$(srcdir)/qsfp.c'; fi` + +test_cmdline-fjes.o: fjes.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-fjes.o -MD -MP -MF $(DEPDIR)/test_cmdline-fjes.Tpo -c -o test_cmdline-fjes.o `test -f 'fjes.c' || echo '$(srcdir)/'`fjes.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-fjes.Tpo $(DEPDIR)/test_cmdline-fjes.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fjes.c' object='test_cmdline-fjes.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-fjes.o `test -f 'fjes.c' || echo '$(srcdir)/'`fjes.c + +test_cmdline-fjes.obj: fjes.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-fjes.obj -MD -MP -MF $(DEPDIR)/test_cmdline-fjes.Tpo -c -o test_cmdline-fjes.obj `if test -f 'fjes.c'; then $(CYGPATH_W) 'fjes.c'; else $(CYGPATH_W) '$(srcdir)/fjes.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-fjes.Tpo $(DEPDIR)/test_cmdline-fjes.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fjes.c' object='test_cmdline-fjes.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-fjes.obj `if test -f 'fjes.c'; then $(CYGPATH_W) 'fjes.c'; else $(CYGPATH_W) '$(srcdir)/fjes.c'; fi` + +test_cmdline-lan78xx.o: lan78xx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-lan78xx.o -MD -MP -MF $(DEPDIR)/test_cmdline-lan78xx.Tpo -c -o test_cmdline-lan78xx.o `test -f 'lan78xx.c' || echo '$(srcdir)/'`lan78xx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-lan78xx.Tpo $(DEPDIR)/test_cmdline-lan78xx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lan78xx.c' object='test_cmdline-lan78xx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-lan78xx.o `test -f 'lan78xx.c' || echo '$(srcdir)/'`lan78xx.c + +test_cmdline-lan78xx.obj: lan78xx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-lan78xx.obj -MD -MP -MF $(DEPDIR)/test_cmdline-lan78xx.Tpo -c -o test_cmdline-lan78xx.obj `if test -f 'lan78xx.c'; then $(CYGPATH_W) 'lan78xx.c'; else $(CYGPATH_W) '$(srcdir)/lan78xx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-lan78xx.Tpo $(DEPDIR)/test_cmdline-lan78xx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lan78xx.c' object='test_cmdline-lan78xx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-lan78xx.obj `if test -f 'lan78xx.c'; then $(CYGPATH_W) 'lan78xx.c'; else $(CYGPATH_W) '$(srcdir)/lan78xx.c'; fi` + +test_cmdline-igc.o: igc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-igc.o -MD -MP -MF $(DEPDIR)/test_cmdline-igc.Tpo -c -o test_cmdline-igc.o `test -f 'igc.c' || echo '$(srcdir)/'`igc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-igc.Tpo $(DEPDIR)/test_cmdline-igc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='igc.c' object='test_cmdline-igc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-igc.o `test -f 'igc.c' || echo '$(srcdir)/'`igc.c + +test_cmdline-igc.obj: igc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-igc.obj -MD -MP -MF $(DEPDIR)/test_cmdline-igc.Tpo -c -o test_cmdline-igc.obj `if test -f 'igc.c'; then $(CYGPATH_W) 'igc.c'; else $(CYGPATH_W) '$(srcdir)/igc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-igc.Tpo $(DEPDIR)/test_cmdline-igc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='igc.c' object='test_cmdline-igc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-igc.obj `if test -f 'igc.c'; then $(CYGPATH_W) 'igc.c'; else $(CYGPATH_W) '$(srcdir)/igc.c'; fi` + +test_cmdline-cmis.o: cmis.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-cmis.o -MD -MP -MF $(DEPDIR)/test_cmdline-cmis.Tpo -c -o test_cmdline-cmis.o `test -f 'cmis.c' || echo '$(srcdir)/'`cmis.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-cmis.Tpo $(DEPDIR)/test_cmdline-cmis.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmis.c' object='test_cmdline-cmis.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-cmis.o `test -f 'cmis.c' || echo '$(srcdir)/'`cmis.c + +test_cmdline-cmis.obj: cmis.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-cmis.obj -MD -MP -MF $(DEPDIR)/test_cmdline-cmis.Tpo -c -o test_cmdline-cmis.obj `if test -f 'cmis.c'; then $(CYGPATH_W) 'cmis.c'; else $(CYGPATH_W) '$(srcdir)/cmis.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-cmis.Tpo $(DEPDIR)/test_cmdline-cmis.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmis.c' object='test_cmdline-cmis.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-cmis.obj `if test -f 'cmis.c'; then $(CYGPATH_W) 'cmis.c'; else $(CYGPATH_W) '$(srcdir)/cmis.c'; fi` + +test_cmdline-bnxt.o: bnxt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-bnxt.o -MD -MP -MF $(DEPDIR)/test_cmdline-bnxt.Tpo -c -o test_cmdline-bnxt.o `test -f 'bnxt.c' || echo '$(srcdir)/'`bnxt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-bnxt.Tpo $(DEPDIR)/test_cmdline-bnxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bnxt.c' object='test_cmdline-bnxt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-bnxt.o `test -f 'bnxt.c' || echo '$(srcdir)/'`bnxt.c + +test_cmdline-bnxt.obj: bnxt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-bnxt.obj -MD -MP -MF $(DEPDIR)/test_cmdline-bnxt.Tpo -c -o test_cmdline-bnxt.obj `if test -f 'bnxt.c'; then $(CYGPATH_W) 'bnxt.c'; else $(CYGPATH_W) '$(srcdir)/bnxt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-bnxt.Tpo $(DEPDIR)/test_cmdline-bnxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bnxt.c' object='test_cmdline-bnxt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-bnxt.obj `if test -f 'bnxt.c'; then $(CYGPATH_W) 'bnxt.c'; else $(CYGPATH_W) '$(srcdir)/bnxt.c'; fi` + +test_cmdline-cpsw.o: cpsw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-cpsw.o -MD -MP -MF $(DEPDIR)/test_cmdline-cpsw.Tpo -c -o test_cmdline-cpsw.o `test -f 'cpsw.c' || echo '$(srcdir)/'`cpsw.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-cpsw.Tpo $(DEPDIR)/test_cmdline-cpsw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpsw.c' object='test_cmdline-cpsw.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-cpsw.o `test -f 'cpsw.c' || echo '$(srcdir)/'`cpsw.c + +test_cmdline-cpsw.obj: cpsw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-cpsw.obj -MD -MP -MF $(DEPDIR)/test_cmdline-cpsw.Tpo -c -o test_cmdline-cpsw.obj `if test -f 'cpsw.c'; then $(CYGPATH_W) 'cpsw.c'; else $(CYGPATH_W) '$(srcdir)/cpsw.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-cpsw.Tpo $(DEPDIR)/test_cmdline-cpsw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpsw.c' object='test_cmdline-cpsw.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-cpsw.obj `if test -f 'cpsw.c'; then $(CYGPATH_W) 'cpsw.c'; else $(CYGPATH_W) '$(srcdir)/cpsw.c'; fi` + +test_cmdline-lan743x.o: lan743x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-lan743x.o -MD -MP -MF $(DEPDIR)/test_cmdline-lan743x.Tpo -c -o test_cmdline-lan743x.o `test -f 'lan743x.c' || echo '$(srcdir)/'`lan743x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-lan743x.Tpo $(DEPDIR)/test_cmdline-lan743x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lan743x.c' object='test_cmdline-lan743x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-lan743x.o `test -f 'lan743x.c' || echo '$(srcdir)/'`lan743x.c + +test_cmdline-lan743x.obj: lan743x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT test_cmdline-lan743x.obj -MD -MP -MF $(DEPDIR)/test_cmdline-lan743x.Tpo -c -o test_cmdline-lan743x.obj `if test -f 'lan743x.c'; then $(CYGPATH_W) 'lan743x.c'; else $(CYGPATH_W) '$(srcdir)/lan743x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_cmdline-lan743x.Tpo $(DEPDIR)/test_cmdline-lan743x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lan743x.c' object='test_cmdline-lan743x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o test_cmdline-lan743x.obj `if test -f 'lan743x.c'; then $(CYGPATH_W) 'lan743x.c'; else $(CYGPATH_W) '$(srcdir)/lan743x.c'; fi` + +netlink/test_cmdline-netlink.o: netlink/netlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-netlink.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-netlink.Tpo -c -o netlink/test_cmdline-netlink.o `test -f 'netlink/netlink.c' || echo '$(srcdir)/'`netlink/netlink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-netlink.Tpo netlink/$(DEPDIR)/test_cmdline-netlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/netlink.c' object='netlink/test_cmdline-netlink.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-netlink.o `test -f 'netlink/netlink.c' || echo '$(srcdir)/'`netlink/netlink.c + +netlink/test_cmdline-netlink.obj: netlink/netlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-netlink.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-netlink.Tpo -c -o netlink/test_cmdline-netlink.obj `if test -f 'netlink/netlink.c'; then $(CYGPATH_W) 'netlink/netlink.c'; else $(CYGPATH_W) '$(srcdir)/netlink/netlink.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-netlink.Tpo netlink/$(DEPDIR)/test_cmdline-netlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/netlink.c' object='netlink/test_cmdline-netlink.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-netlink.obj `if test -f 'netlink/netlink.c'; then $(CYGPATH_W) 'netlink/netlink.c'; else $(CYGPATH_W) '$(srcdir)/netlink/netlink.c'; fi` + +netlink/test_cmdline-msgbuff.o: netlink/msgbuff.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-msgbuff.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-msgbuff.Tpo -c -o netlink/test_cmdline-msgbuff.o `test -f 'netlink/msgbuff.c' || echo '$(srcdir)/'`netlink/msgbuff.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-msgbuff.Tpo netlink/$(DEPDIR)/test_cmdline-msgbuff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/msgbuff.c' object='netlink/test_cmdline-msgbuff.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-msgbuff.o `test -f 'netlink/msgbuff.c' || echo '$(srcdir)/'`netlink/msgbuff.c + +netlink/test_cmdline-msgbuff.obj: netlink/msgbuff.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-msgbuff.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-msgbuff.Tpo -c -o netlink/test_cmdline-msgbuff.obj `if test -f 'netlink/msgbuff.c'; then $(CYGPATH_W) 'netlink/msgbuff.c'; else $(CYGPATH_W) '$(srcdir)/netlink/msgbuff.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-msgbuff.Tpo netlink/$(DEPDIR)/test_cmdline-msgbuff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/msgbuff.c' object='netlink/test_cmdline-msgbuff.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-msgbuff.obj `if test -f 'netlink/msgbuff.c'; then $(CYGPATH_W) 'netlink/msgbuff.c'; else $(CYGPATH_W) '$(srcdir)/netlink/msgbuff.c'; fi` + +netlink/test_cmdline-nlsock.o: netlink/nlsock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-nlsock.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-nlsock.Tpo -c -o netlink/test_cmdline-nlsock.o `test -f 'netlink/nlsock.c' || echo '$(srcdir)/'`netlink/nlsock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-nlsock.Tpo netlink/$(DEPDIR)/test_cmdline-nlsock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/nlsock.c' object='netlink/test_cmdline-nlsock.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-nlsock.o `test -f 'netlink/nlsock.c' || echo '$(srcdir)/'`netlink/nlsock.c + +netlink/test_cmdline-nlsock.obj: netlink/nlsock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-nlsock.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-nlsock.Tpo -c -o netlink/test_cmdline-nlsock.obj `if test -f 'netlink/nlsock.c'; then $(CYGPATH_W) 'netlink/nlsock.c'; else $(CYGPATH_W) '$(srcdir)/netlink/nlsock.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-nlsock.Tpo netlink/$(DEPDIR)/test_cmdline-nlsock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/nlsock.c' object='netlink/test_cmdline-nlsock.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-nlsock.obj `if test -f 'netlink/nlsock.c'; then $(CYGPATH_W) 'netlink/nlsock.c'; else $(CYGPATH_W) '$(srcdir)/netlink/nlsock.c'; fi` + +netlink/test_cmdline-strset.o: netlink/strset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-strset.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-strset.Tpo -c -o netlink/test_cmdline-strset.o `test -f 'netlink/strset.c' || echo '$(srcdir)/'`netlink/strset.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-strset.Tpo netlink/$(DEPDIR)/test_cmdline-strset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/strset.c' object='netlink/test_cmdline-strset.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-strset.o `test -f 'netlink/strset.c' || echo '$(srcdir)/'`netlink/strset.c + +netlink/test_cmdline-strset.obj: netlink/strset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-strset.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-strset.Tpo -c -o netlink/test_cmdline-strset.obj `if test -f 'netlink/strset.c'; then $(CYGPATH_W) 'netlink/strset.c'; else $(CYGPATH_W) '$(srcdir)/netlink/strset.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-strset.Tpo netlink/$(DEPDIR)/test_cmdline-strset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/strset.c' object='netlink/test_cmdline-strset.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-strset.obj `if test -f 'netlink/strset.c'; then $(CYGPATH_W) 'netlink/strset.c'; else $(CYGPATH_W) '$(srcdir)/netlink/strset.c'; fi` + +netlink/test_cmdline-monitor.o: netlink/monitor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-monitor.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-monitor.Tpo -c -o netlink/test_cmdline-monitor.o `test -f 'netlink/monitor.c' || echo '$(srcdir)/'`netlink/monitor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-monitor.Tpo netlink/$(DEPDIR)/test_cmdline-monitor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/monitor.c' object='netlink/test_cmdline-monitor.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-monitor.o `test -f 'netlink/monitor.c' || echo '$(srcdir)/'`netlink/monitor.c + +netlink/test_cmdline-monitor.obj: netlink/monitor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-monitor.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-monitor.Tpo -c -o netlink/test_cmdline-monitor.obj `if test -f 'netlink/monitor.c'; then $(CYGPATH_W) 'netlink/monitor.c'; else $(CYGPATH_W) '$(srcdir)/netlink/monitor.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-monitor.Tpo netlink/$(DEPDIR)/test_cmdline-monitor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/monitor.c' object='netlink/test_cmdline-monitor.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-monitor.obj `if test -f 'netlink/monitor.c'; then $(CYGPATH_W) 'netlink/monitor.c'; else $(CYGPATH_W) '$(srcdir)/netlink/monitor.c'; fi` + +netlink/test_cmdline-bitset.o: netlink/bitset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-bitset.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-bitset.Tpo -c -o netlink/test_cmdline-bitset.o `test -f 'netlink/bitset.c' || echo '$(srcdir)/'`netlink/bitset.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-bitset.Tpo netlink/$(DEPDIR)/test_cmdline-bitset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/bitset.c' object='netlink/test_cmdline-bitset.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-bitset.o `test -f 'netlink/bitset.c' || echo '$(srcdir)/'`netlink/bitset.c + +netlink/test_cmdline-bitset.obj: netlink/bitset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-bitset.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-bitset.Tpo -c -o netlink/test_cmdline-bitset.obj `if test -f 'netlink/bitset.c'; then $(CYGPATH_W) 'netlink/bitset.c'; else $(CYGPATH_W) '$(srcdir)/netlink/bitset.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-bitset.Tpo netlink/$(DEPDIR)/test_cmdline-bitset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/bitset.c' object='netlink/test_cmdline-bitset.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-bitset.obj `if test -f 'netlink/bitset.c'; then $(CYGPATH_W) 'netlink/bitset.c'; else $(CYGPATH_W) '$(srcdir)/netlink/bitset.c'; fi` + +netlink/test_cmdline-settings.o: netlink/settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-settings.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-settings.Tpo -c -o netlink/test_cmdline-settings.o `test -f 'netlink/settings.c' || echo '$(srcdir)/'`netlink/settings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-settings.Tpo netlink/$(DEPDIR)/test_cmdline-settings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/settings.c' object='netlink/test_cmdline-settings.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-settings.o `test -f 'netlink/settings.c' || echo '$(srcdir)/'`netlink/settings.c + +netlink/test_cmdline-settings.obj: netlink/settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-settings.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-settings.Tpo -c -o netlink/test_cmdline-settings.obj `if test -f 'netlink/settings.c'; then $(CYGPATH_W) 'netlink/settings.c'; else $(CYGPATH_W) '$(srcdir)/netlink/settings.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-settings.Tpo netlink/$(DEPDIR)/test_cmdline-settings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/settings.c' object='netlink/test_cmdline-settings.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-settings.obj `if test -f 'netlink/settings.c'; then $(CYGPATH_W) 'netlink/settings.c'; else $(CYGPATH_W) '$(srcdir)/netlink/settings.c'; fi` + +netlink/test_cmdline-parser.o: netlink/parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-parser.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-parser.Tpo -c -o netlink/test_cmdline-parser.o `test -f 'netlink/parser.c' || echo '$(srcdir)/'`netlink/parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-parser.Tpo netlink/$(DEPDIR)/test_cmdline-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/parser.c' object='netlink/test_cmdline-parser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-parser.o `test -f 'netlink/parser.c' || echo '$(srcdir)/'`netlink/parser.c + +netlink/test_cmdline-parser.obj: netlink/parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-parser.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-parser.Tpo -c -o netlink/test_cmdline-parser.obj `if test -f 'netlink/parser.c'; then $(CYGPATH_W) 'netlink/parser.c'; else $(CYGPATH_W) '$(srcdir)/netlink/parser.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-parser.Tpo netlink/$(DEPDIR)/test_cmdline-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/parser.c' object='netlink/test_cmdline-parser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-parser.obj `if test -f 'netlink/parser.c'; then $(CYGPATH_W) 'netlink/parser.c'; else $(CYGPATH_W) '$(srcdir)/netlink/parser.c'; fi` + +netlink/test_cmdline-permaddr.o: netlink/permaddr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-permaddr.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-permaddr.Tpo -c -o netlink/test_cmdline-permaddr.o `test -f 'netlink/permaddr.c' || echo '$(srcdir)/'`netlink/permaddr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-permaddr.Tpo netlink/$(DEPDIR)/test_cmdline-permaddr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/permaddr.c' object='netlink/test_cmdline-permaddr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-permaddr.o `test -f 'netlink/permaddr.c' || echo '$(srcdir)/'`netlink/permaddr.c + +netlink/test_cmdline-permaddr.obj: netlink/permaddr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-permaddr.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-permaddr.Tpo -c -o netlink/test_cmdline-permaddr.obj `if test -f 'netlink/permaddr.c'; then $(CYGPATH_W) 'netlink/permaddr.c'; else $(CYGPATH_W) '$(srcdir)/netlink/permaddr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-permaddr.Tpo netlink/$(DEPDIR)/test_cmdline-permaddr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/permaddr.c' object='netlink/test_cmdline-permaddr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-permaddr.obj `if test -f 'netlink/permaddr.c'; then $(CYGPATH_W) 'netlink/permaddr.c'; else $(CYGPATH_W) '$(srcdir)/netlink/permaddr.c'; fi` + +netlink/test_cmdline-prettymsg.o: netlink/prettymsg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-prettymsg.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-prettymsg.Tpo -c -o netlink/test_cmdline-prettymsg.o `test -f 'netlink/prettymsg.c' || echo '$(srcdir)/'`netlink/prettymsg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-prettymsg.Tpo netlink/$(DEPDIR)/test_cmdline-prettymsg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/prettymsg.c' object='netlink/test_cmdline-prettymsg.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-prettymsg.o `test -f 'netlink/prettymsg.c' || echo '$(srcdir)/'`netlink/prettymsg.c + +netlink/test_cmdline-prettymsg.obj: netlink/prettymsg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-prettymsg.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-prettymsg.Tpo -c -o netlink/test_cmdline-prettymsg.obj `if test -f 'netlink/prettymsg.c'; then $(CYGPATH_W) 'netlink/prettymsg.c'; else $(CYGPATH_W) '$(srcdir)/netlink/prettymsg.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-prettymsg.Tpo netlink/$(DEPDIR)/test_cmdline-prettymsg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/prettymsg.c' object='netlink/test_cmdline-prettymsg.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-prettymsg.obj `if test -f 'netlink/prettymsg.c'; then $(CYGPATH_W) 'netlink/prettymsg.c'; else $(CYGPATH_W) '$(srcdir)/netlink/prettymsg.c'; fi` + +netlink/test_cmdline-features.o: netlink/features.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-features.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-features.Tpo -c -o netlink/test_cmdline-features.o `test -f 'netlink/features.c' || echo '$(srcdir)/'`netlink/features.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-features.Tpo netlink/$(DEPDIR)/test_cmdline-features.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/features.c' object='netlink/test_cmdline-features.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-features.o `test -f 'netlink/features.c' || echo '$(srcdir)/'`netlink/features.c + +netlink/test_cmdline-features.obj: netlink/features.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-features.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-features.Tpo -c -o netlink/test_cmdline-features.obj `if test -f 'netlink/features.c'; then $(CYGPATH_W) 'netlink/features.c'; else $(CYGPATH_W) '$(srcdir)/netlink/features.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-features.Tpo netlink/$(DEPDIR)/test_cmdline-features.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/features.c' object='netlink/test_cmdline-features.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-features.obj `if test -f 'netlink/features.c'; then $(CYGPATH_W) 'netlink/features.c'; else $(CYGPATH_W) '$(srcdir)/netlink/features.c'; fi` + +netlink/test_cmdline-privflags.o: netlink/privflags.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-privflags.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-privflags.Tpo -c -o netlink/test_cmdline-privflags.o `test -f 'netlink/privflags.c' || echo '$(srcdir)/'`netlink/privflags.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-privflags.Tpo netlink/$(DEPDIR)/test_cmdline-privflags.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/privflags.c' object='netlink/test_cmdline-privflags.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-privflags.o `test -f 'netlink/privflags.c' || echo '$(srcdir)/'`netlink/privflags.c + +netlink/test_cmdline-privflags.obj: netlink/privflags.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-privflags.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-privflags.Tpo -c -o netlink/test_cmdline-privflags.obj `if test -f 'netlink/privflags.c'; then $(CYGPATH_W) 'netlink/privflags.c'; else $(CYGPATH_W) '$(srcdir)/netlink/privflags.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-privflags.Tpo netlink/$(DEPDIR)/test_cmdline-privflags.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/privflags.c' object='netlink/test_cmdline-privflags.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-privflags.obj `if test -f 'netlink/privflags.c'; then $(CYGPATH_W) 'netlink/privflags.c'; else $(CYGPATH_W) '$(srcdir)/netlink/privflags.c'; fi` + +netlink/test_cmdline-rings.o: netlink/rings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-rings.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-rings.Tpo -c -o netlink/test_cmdline-rings.o `test -f 'netlink/rings.c' || echo '$(srcdir)/'`netlink/rings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-rings.Tpo netlink/$(DEPDIR)/test_cmdline-rings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/rings.c' object='netlink/test_cmdline-rings.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-rings.o `test -f 'netlink/rings.c' || echo '$(srcdir)/'`netlink/rings.c + +netlink/test_cmdline-rings.obj: netlink/rings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-rings.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-rings.Tpo -c -o netlink/test_cmdline-rings.obj `if test -f 'netlink/rings.c'; then $(CYGPATH_W) 'netlink/rings.c'; else $(CYGPATH_W) '$(srcdir)/netlink/rings.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-rings.Tpo netlink/$(DEPDIR)/test_cmdline-rings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/rings.c' object='netlink/test_cmdline-rings.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-rings.obj `if test -f 'netlink/rings.c'; then $(CYGPATH_W) 'netlink/rings.c'; else $(CYGPATH_W) '$(srcdir)/netlink/rings.c'; fi` + +netlink/test_cmdline-channels.o: netlink/channels.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-channels.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-channels.Tpo -c -o netlink/test_cmdline-channels.o `test -f 'netlink/channels.c' || echo '$(srcdir)/'`netlink/channels.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-channels.Tpo netlink/$(DEPDIR)/test_cmdline-channels.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/channels.c' object='netlink/test_cmdline-channels.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-channels.o `test -f 'netlink/channels.c' || echo '$(srcdir)/'`netlink/channels.c + +netlink/test_cmdline-channels.obj: netlink/channels.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-channels.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-channels.Tpo -c -o netlink/test_cmdline-channels.obj `if test -f 'netlink/channels.c'; then $(CYGPATH_W) 'netlink/channels.c'; else $(CYGPATH_W) '$(srcdir)/netlink/channels.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-channels.Tpo netlink/$(DEPDIR)/test_cmdline-channels.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/channels.c' object='netlink/test_cmdline-channels.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-channels.obj `if test -f 'netlink/channels.c'; then $(CYGPATH_W) 'netlink/channels.c'; else $(CYGPATH_W) '$(srcdir)/netlink/channels.c'; fi` + +netlink/test_cmdline-coalesce.o: netlink/coalesce.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-coalesce.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-coalesce.Tpo -c -o netlink/test_cmdline-coalesce.o `test -f 'netlink/coalesce.c' || echo '$(srcdir)/'`netlink/coalesce.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-coalesce.Tpo netlink/$(DEPDIR)/test_cmdline-coalesce.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/coalesce.c' object='netlink/test_cmdline-coalesce.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-coalesce.o `test -f 'netlink/coalesce.c' || echo '$(srcdir)/'`netlink/coalesce.c + +netlink/test_cmdline-coalesce.obj: netlink/coalesce.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-coalesce.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-coalesce.Tpo -c -o netlink/test_cmdline-coalesce.obj `if test -f 'netlink/coalesce.c'; then $(CYGPATH_W) 'netlink/coalesce.c'; else $(CYGPATH_W) '$(srcdir)/netlink/coalesce.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-coalesce.Tpo netlink/$(DEPDIR)/test_cmdline-coalesce.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/coalesce.c' object='netlink/test_cmdline-coalesce.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-coalesce.obj `if test -f 'netlink/coalesce.c'; then $(CYGPATH_W) 'netlink/coalesce.c'; else $(CYGPATH_W) '$(srcdir)/netlink/coalesce.c'; fi` + +netlink/test_cmdline-pause.o: netlink/pause.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-pause.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-pause.Tpo -c -o netlink/test_cmdline-pause.o `test -f 'netlink/pause.c' || echo '$(srcdir)/'`netlink/pause.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-pause.Tpo netlink/$(DEPDIR)/test_cmdline-pause.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/pause.c' object='netlink/test_cmdline-pause.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-pause.o `test -f 'netlink/pause.c' || echo '$(srcdir)/'`netlink/pause.c + +netlink/test_cmdline-pause.obj: netlink/pause.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-pause.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-pause.Tpo -c -o netlink/test_cmdline-pause.obj `if test -f 'netlink/pause.c'; then $(CYGPATH_W) 'netlink/pause.c'; else $(CYGPATH_W) '$(srcdir)/netlink/pause.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-pause.Tpo netlink/$(DEPDIR)/test_cmdline-pause.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/pause.c' object='netlink/test_cmdline-pause.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-pause.obj `if test -f 'netlink/pause.c'; then $(CYGPATH_W) 'netlink/pause.c'; else $(CYGPATH_W) '$(srcdir)/netlink/pause.c'; fi` + +netlink/test_cmdline-eee.o: netlink/eee.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-eee.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-eee.Tpo -c -o netlink/test_cmdline-eee.o `test -f 'netlink/eee.c' || echo '$(srcdir)/'`netlink/eee.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-eee.Tpo netlink/$(DEPDIR)/test_cmdline-eee.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/eee.c' object='netlink/test_cmdline-eee.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-eee.o `test -f 'netlink/eee.c' || echo '$(srcdir)/'`netlink/eee.c + +netlink/test_cmdline-eee.obj: netlink/eee.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-eee.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-eee.Tpo -c -o netlink/test_cmdline-eee.obj `if test -f 'netlink/eee.c'; then $(CYGPATH_W) 'netlink/eee.c'; else $(CYGPATH_W) '$(srcdir)/netlink/eee.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-eee.Tpo netlink/$(DEPDIR)/test_cmdline-eee.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/eee.c' object='netlink/test_cmdline-eee.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-eee.obj `if test -f 'netlink/eee.c'; then $(CYGPATH_W) 'netlink/eee.c'; else $(CYGPATH_W) '$(srcdir)/netlink/eee.c'; fi` + +netlink/test_cmdline-tsinfo.o: netlink/tsinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-tsinfo.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-tsinfo.Tpo -c -o netlink/test_cmdline-tsinfo.o `test -f 'netlink/tsinfo.c' || echo '$(srcdir)/'`netlink/tsinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-tsinfo.Tpo netlink/$(DEPDIR)/test_cmdline-tsinfo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/tsinfo.c' object='netlink/test_cmdline-tsinfo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-tsinfo.o `test -f 'netlink/tsinfo.c' || echo '$(srcdir)/'`netlink/tsinfo.c + +netlink/test_cmdline-tsinfo.obj: netlink/tsinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-tsinfo.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-tsinfo.Tpo -c -o netlink/test_cmdline-tsinfo.obj `if test -f 'netlink/tsinfo.c'; then $(CYGPATH_W) 'netlink/tsinfo.c'; else $(CYGPATH_W) '$(srcdir)/netlink/tsinfo.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-tsinfo.Tpo netlink/$(DEPDIR)/test_cmdline-tsinfo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/tsinfo.c' object='netlink/test_cmdline-tsinfo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-tsinfo.obj `if test -f 'netlink/tsinfo.c'; then $(CYGPATH_W) 'netlink/tsinfo.c'; else $(CYGPATH_W) '$(srcdir)/netlink/tsinfo.c'; fi` + +netlink/test_cmdline-fec.o: netlink/fec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-fec.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-fec.Tpo -c -o netlink/test_cmdline-fec.o `test -f 'netlink/fec.c' || echo '$(srcdir)/'`netlink/fec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-fec.Tpo netlink/$(DEPDIR)/test_cmdline-fec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/fec.c' object='netlink/test_cmdline-fec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-fec.o `test -f 'netlink/fec.c' || echo '$(srcdir)/'`netlink/fec.c + +netlink/test_cmdline-fec.obj: netlink/fec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-fec.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-fec.Tpo -c -o netlink/test_cmdline-fec.obj `if test -f 'netlink/fec.c'; then $(CYGPATH_W) 'netlink/fec.c'; else $(CYGPATH_W) '$(srcdir)/netlink/fec.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-fec.Tpo netlink/$(DEPDIR)/test_cmdline-fec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/fec.c' object='netlink/test_cmdline-fec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-fec.obj `if test -f 'netlink/fec.c'; then $(CYGPATH_W) 'netlink/fec.c'; else $(CYGPATH_W) '$(srcdir)/netlink/fec.c'; fi` + +netlink/test_cmdline-stats.o: netlink/stats.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-stats.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-stats.Tpo -c -o netlink/test_cmdline-stats.o `test -f 'netlink/stats.c' || echo '$(srcdir)/'`netlink/stats.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-stats.Tpo netlink/$(DEPDIR)/test_cmdline-stats.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/stats.c' object='netlink/test_cmdline-stats.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-stats.o `test -f 'netlink/stats.c' || echo '$(srcdir)/'`netlink/stats.c + +netlink/test_cmdline-stats.obj: netlink/stats.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-stats.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-stats.Tpo -c -o netlink/test_cmdline-stats.obj `if test -f 'netlink/stats.c'; then $(CYGPATH_W) 'netlink/stats.c'; else $(CYGPATH_W) '$(srcdir)/netlink/stats.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-stats.Tpo netlink/$(DEPDIR)/test_cmdline-stats.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/stats.c' object='netlink/test_cmdline-stats.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-stats.obj `if test -f 'netlink/stats.c'; then $(CYGPATH_W) 'netlink/stats.c'; else $(CYGPATH_W) '$(srcdir)/netlink/stats.c'; fi` + +netlink/test_cmdline-desc-ethtool.o: netlink/desc-ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-desc-ethtool.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-desc-ethtool.Tpo -c -o netlink/test_cmdline-desc-ethtool.o `test -f 'netlink/desc-ethtool.c' || echo '$(srcdir)/'`netlink/desc-ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-desc-ethtool.Tpo netlink/$(DEPDIR)/test_cmdline-desc-ethtool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-ethtool.c' object='netlink/test_cmdline-desc-ethtool.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-desc-ethtool.o `test -f 'netlink/desc-ethtool.c' || echo '$(srcdir)/'`netlink/desc-ethtool.c + +netlink/test_cmdline-desc-ethtool.obj: netlink/desc-ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-desc-ethtool.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-desc-ethtool.Tpo -c -o netlink/test_cmdline-desc-ethtool.obj `if test -f 'netlink/desc-ethtool.c'; then $(CYGPATH_W) 'netlink/desc-ethtool.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-ethtool.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-desc-ethtool.Tpo netlink/$(DEPDIR)/test_cmdline-desc-ethtool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-ethtool.c' object='netlink/test_cmdline-desc-ethtool.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-desc-ethtool.obj `if test -f 'netlink/desc-ethtool.c'; then $(CYGPATH_W) 'netlink/desc-ethtool.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-ethtool.c'; fi` + +netlink/test_cmdline-desc-genlctrl.o: netlink/desc-genlctrl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-desc-genlctrl.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-desc-genlctrl.Tpo -c -o netlink/test_cmdline-desc-genlctrl.o `test -f 'netlink/desc-genlctrl.c' || echo '$(srcdir)/'`netlink/desc-genlctrl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-desc-genlctrl.Tpo netlink/$(DEPDIR)/test_cmdline-desc-genlctrl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-genlctrl.c' object='netlink/test_cmdline-desc-genlctrl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-desc-genlctrl.o `test -f 'netlink/desc-genlctrl.c' || echo '$(srcdir)/'`netlink/desc-genlctrl.c + +netlink/test_cmdline-desc-genlctrl.obj: netlink/desc-genlctrl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-desc-genlctrl.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-desc-genlctrl.Tpo -c -o netlink/test_cmdline-desc-genlctrl.obj `if test -f 'netlink/desc-genlctrl.c'; then $(CYGPATH_W) 'netlink/desc-genlctrl.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-genlctrl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-desc-genlctrl.Tpo netlink/$(DEPDIR)/test_cmdline-desc-genlctrl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-genlctrl.c' object='netlink/test_cmdline-desc-genlctrl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-desc-genlctrl.obj `if test -f 'netlink/desc-genlctrl.c'; then $(CYGPATH_W) 'netlink/desc-genlctrl.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-genlctrl.c'; fi` + +netlink/test_cmdline-module-eeprom.o: netlink/module-eeprom.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-module-eeprom.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-module-eeprom.Tpo -c -o netlink/test_cmdline-module-eeprom.o `test -f 'netlink/module-eeprom.c' || echo '$(srcdir)/'`netlink/module-eeprom.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-module-eeprom.Tpo netlink/$(DEPDIR)/test_cmdline-module-eeprom.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module-eeprom.c' object='netlink/test_cmdline-module-eeprom.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-module-eeprom.o `test -f 'netlink/module-eeprom.c' || echo '$(srcdir)/'`netlink/module-eeprom.c + +netlink/test_cmdline-module-eeprom.obj: netlink/module-eeprom.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-module-eeprom.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-module-eeprom.Tpo -c -o netlink/test_cmdline-module-eeprom.obj `if test -f 'netlink/module-eeprom.c'; then $(CYGPATH_W) 'netlink/module-eeprom.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module-eeprom.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-module-eeprom.Tpo netlink/$(DEPDIR)/test_cmdline-module-eeprom.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module-eeprom.c' object='netlink/test_cmdline-module-eeprom.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-module-eeprom.obj `if test -f 'netlink/module-eeprom.c'; then $(CYGPATH_W) 'netlink/module-eeprom.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module-eeprom.c'; fi` + +netlink/test_cmdline-module.o: netlink/module.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-module.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-module.Tpo -c -o netlink/test_cmdline-module.o `test -f 'netlink/module.c' || echo '$(srcdir)/'`netlink/module.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-module.Tpo netlink/$(DEPDIR)/test_cmdline-module.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module.c' object='netlink/test_cmdline-module.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-module.o `test -f 'netlink/module.c' || echo '$(srcdir)/'`netlink/module.c + +netlink/test_cmdline-module.obj: netlink/module.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-module.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-module.Tpo -c -o netlink/test_cmdline-module.obj `if test -f 'netlink/module.c'; then $(CYGPATH_W) 'netlink/module.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-module.Tpo netlink/$(DEPDIR)/test_cmdline-module.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module.c' object='netlink/test_cmdline-module.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-module.obj `if test -f 'netlink/module.c'; then $(CYGPATH_W) 'netlink/module.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module.c'; fi` + +netlink/test_cmdline-desc-rtnl.o: netlink/desc-rtnl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-desc-rtnl.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Tpo -c -o netlink/test_cmdline-desc-rtnl.o `test -f 'netlink/desc-rtnl.c' || echo '$(srcdir)/'`netlink/desc-rtnl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Tpo netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-rtnl.c' object='netlink/test_cmdline-desc-rtnl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-desc-rtnl.o `test -f 'netlink/desc-rtnl.c' || echo '$(srcdir)/'`netlink/desc-rtnl.c + +netlink/test_cmdline-desc-rtnl.obj: netlink/desc-rtnl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-desc-rtnl.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Tpo -c -o netlink/test_cmdline-desc-rtnl.obj `if test -f 'netlink/desc-rtnl.c'; then $(CYGPATH_W) 'netlink/desc-rtnl.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-rtnl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Tpo netlink/$(DEPDIR)/test_cmdline-desc-rtnl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-rtnl.c' object='netlink/test_cmdline-desc-rtnl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-desc-rtnl.obj `if test -f 'netlink/desc-rtnl.c'; then $(CYGPATH_W) 'netlink/desc-rtnl.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-rtnl.c'; fi` + +netlink/test_cmdline-cable_test.o: netlink/cable_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-cable_test.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-cable_test.Tpo -c -o netlink/test_cmdline-cable_test.o `test -f 'netlink/cable_test.c' || echo '$(srcdir)/'`netlink/cable_test.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-cable_test.Tpo netlink/$(DEPDIR)/test_cmdline-cable_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/cable_test.c' object='netlink/test_cmdline-cable_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-cable_test.o `test -f 'netlink/cable_test.c' || echo '$(srcdir)/'`netlink/cable_test.c + +netlink/test_cmdline-cable_test.obj: netlink/cable_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-cable_test.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-cable_test.Tpo -c -o netlink/test_cmdline-cable_test.obj `if test -f 'netlink/cable_test.c'; then $(CYGPATH_W) 'netlink/cable_test.c'; else $(CYGPATH_W) '$(srcdir)/netlink/cable_test.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-cable_test.Tpo netlink/$(DEPDIR)/test_cmdline-cable_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/cable_test.c' object='netlink/test_cmdline-cable_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-cable_test.obj `if test -f 'netlink/cable_test.c'; then $(CYGPATH_W) 'netlink/cable_test.c'; else $(CYGPATH_W) '$(srcdir)/netlink/cable_test.c'; fi` + +netlink/test_cmdline-tunnels.o: netlink/tunnels.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-tunnels.o -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-tunnels.Tpo -c -o netlink/test_cmdline-tunnels.o `test -f 'netlink/tunnels.c' || echo '$(srcdir)/'`netlink/tunnels.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-tunnels.Tpo netlink/$(DEPDIR)/test_cmdline-tunnels.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/tunnels.c' object='netlink/test_cmdline-tunnels.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-tunnels.o `test -f 'netlink/tunnels.c' || echo '$(srcdir)/'`netlink/tunnels.c + +netlink/test_cmdline-tunnels.obj: netlink/tunnels.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -MT netlink/test_cmdline-tunnels.obj -MD -MP -MF netlink/$(DEPDIR)/test_cmdline-tunnels.Tpo -c -o netlink/test_cmdline-tunnels.obj `if test -f 'netlink/tunnels.c'; then $(CYGPATH_W) 'netlink/tunnels.c'; else $(CYGPATH_W) '$(srcdir)/netlink/tunnels.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_cmdline-tunnels.Tpo netlink/$(DEPDIR)/test_cmdline-tunnels.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/tunnels.c' object='netlink/test_cmdline-tunnels.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cmdline_CFLAGS) $(CFLAGS) -c -o netlink/test_cmdline-tunnels.obj `if test -f 'netlink/tunnels.c'; then $(CYGPATH_W) 'netlink/tunnels.c'; else $(CYGPATH_W) '$(srcdir)/netlink/tunnels.c'; fi` + +test_features-test-features.o: test-features.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-test-features.o -MD -MP -MF $(DEPDIR)/test_features-test-features.Tpo -c -o test_features-test-features.o `test -f 'test-features.c' || echo '$(srcdir)/'`test-features.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-test-features.Tpo $(DEPDIR)/test_features-test-features.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-features.c' object='test_features-test-features.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-test-features.o `test -f 'test-features.c' || echo '$(srcdir)/'`test-features.c + +test_features-test-features.obj: test-features.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-test-features.obj -MD -MP -MF $(DEPDIR)/test_features-test-features.Tpo -c -o test_features-test-features.obj `if test -f 'test-features.c'; then $(CYGPATH_W) 'test-features.c'; else $(CYGPATH_W) '$(srcdir)/test-features.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-test-features.Tpo $(DEPDIR)/test_features-test-features.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-features.c' object='test_features-test-features.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-test-features.obj `if test -f 'test-features.c'; then $(CYGPATH_W) 'test-features.c'; else $(CYGPATH_W) '$(srcdir)/test-features.c'; fi` + +test_features-test-common.o: test-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-test-common.o -MD -MP -MF $(DEPDIR)/test_features-test-common.Tpo -c -o test_features-test-common.o `test -f 'test-common.c' || echo '$(srcdir)/'`test-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-test-common.Tpo $(DEPDIR)/test_features-test-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-common.c' object='test_features-test-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-test-common.o `test -f 'test-common.c' || echo '$(srcdir)/'`test-common.c + +test_features-test-common.obj: test-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-test-common.obj -MD -MP -MF $(DEPDIR)/test_features-test-common.Tpo -c -o test_features-test-common.obj `if test -f 'test-common.c'; then $(CYGPATH_W) 'test-common.c'; else $(CYGPATH_W) '$(srcdir)/test-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-test-common.Tpo $(DEPDIR)/test_features-test-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-common.c' object='test_features-test-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-test-common.obj `if test -f 'test-common.c'; then $(CYGPATH_W) 'test-common.c'; else $(CYGPATH_W) '$(srcdir)/test-common.c'; fi` + +test_features-ethtool.o: ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ethtool.o -MD -MP -MF $(DEPDIR)/test_features-ethtool.Tpo -c -o test_features-ethtool.o `test -f 'ethtool.c' || echo '$(srcdir)/'`ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ethtool.Tpo $(DEPDIR)/test_features-ethtool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ethtool.c' object='test_features-ethtool.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ethtool.o `test -f 'ethtool.c' || echo '$(srcdir)/'`ethtool.c + +test_features-ethtool.obj: ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ethtool.obj -MD -MP -MF $(DEPDIR)/test_features-ethtool.Tpo -c -o test_features-ethtool.obj `if test -f 'ethtool.c'; then $(CYGPATH_W) 'ethtool.c'; else $(CYGPATH_W) '$(srcdir)/ethtool.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ethtool.Tpo $(DEPDIR)/test_features-ethtool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ethtool.c' object='test_features-ethtool.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ethtool.obj `if test -f 'ethtool.c'; then $(CYGPATH_W) 'ethtool.c'; else $(CYGPATH_W) '$(srcdir)/ethtool.c'; fi` + +test_features-rxclass.o: rxclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-rxclass.o -MD -MP -MF $(DEPDIR)/test_features-rxclass.Tpo -c -o test_features-rxclass.o `test -f 'rxclass.c' || echo '$(srcdir)/'`rxclass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-rxclass.Tpo $(DEPDIR)/test_features-rxclass.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rxclass.c' object='test_features-rxclass.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-rxclass.o `test -f 'rxclass.c' || echo '$(srcdir)/'`rxclass.c + +test_features-rxclass.obj: rxclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-rxclass.obj -MD -MP -MF $(DEPDIR)/test_features-rxclass.Tpo -c -o test_features-rxclass.obj `if test -f 'rxclass.c'; then $(CYGPATH_W) 'rxclass.c'; else $(CYGPATH_W) '$(srcdir)/rxclass.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-rxclass.Tpo $(DEPDIR)/test_features-rxclass.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rxclass.c' object='test_features-rxclass.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-rxclass.obj `if test -f 'rxclass.c'; then $(CYGPATH_W) 'rxclass.c'; else $(CYGPATH_W) '$(srcdir)/rxclass.c'; fi` + +test_features-common.o: common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-common.o -MD -MP -MF $(DEPDIR)/test_features-common.Tpo -c -o test_features-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-common.Tpo $(DEPDIR)/test_features-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='test_features-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c + +test_features-common.obj: common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-common.obj -MD -MP -MF $(DEPDIR)/test_features-common.Tpo -c -o test_features-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-common.Tpo $(DEPDIR)/test_features-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='test_features-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` + +test_features-json_writer.o: json_writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-json_writer.o -MD -MP -MF $(DEPDIR)/test_features-json_writer.Tpo -c -o test_features-json_writer.o `test -f 'json_writer.c' || echo '$(srcdir)/'`json_writer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-json_writer.Tpo $(DEPDIR)/test_features-json_writer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json_writer.c' object='test_features-json_writer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-json_writer.o `test -f 'json_writer.c' || echo '$(srcdir)/'`json_writer.c + +test_features-json_writer.obj: json_writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-json_writer.obj -MD -MP -MF $(DEPDIR)/test_features-json_writer.Tpo -c -o test_features-json_writer.obj `if test -f 'json_writer.c'; then $(CYGPATH_W) 'json_writer.c'; else $(CYGPATH_W) '$(srcdir)/json_writer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-json_writer.Tpo $(DEPDIR)/test_features-json_writer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json_writer.c' object='test_features-json_writer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-json_writer.obj `if test -f 'json_writer.c'; then $(CYGPATH_W) 'json_writer.c'; else $(CYGPATH_W) '$(srcdir)/json_writer.c'; fi` + +test_features-json_print.o: json_print.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-json_print.o -MD -MP -MF $(DEPDIR)/test_features-json_print.Tpo -c -o test_features-json_print.o `test -f 'json_print.c' || echo '$(srcdir)/'`json_print.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-json_print.Tpo $(DEPDIR)/test_features-json_print.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json_print.c' object='test_features-json_print.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-json_print.o `test -f 'json_print.c' || echo '$(srcdir)/'`json_print.c + +test_features-json_print.obj: json_print.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-json_print.obj -MD -MP -MF $(DEPDIR)/test_features-json_print.Tpo -c -o test_features-json_print.obj `if test -f 'json_print.c'; then $(CYGPATH_W) 'json_print.c'; else $(CYGPATH_W) '$(srcdir)/json_print.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-json_print.Tpo $(DEPDIR)/test_features-json_print.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json_print.c' object='test_features-json_print.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-json_print.obj `if test -f 'json_print.c'; then $(CYGPATH_W) 'json_print.c'; else $(CYGPATH_W) '$(srcdir)/json_print.c'; fi` + +test_features-amd8111e.o: amd8111e.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-amd8111e.o -MD -MP -MF $(DEPDIR)/test_features-amd8111e.Tpo -c -o test_features-amd8111e.o `test -f 'amd8111e.c' || echo '$(srcdir)/'`amd8111e.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-amd8111e.Tpo $(DEPDIR)/test_features-amd8111e.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='amd8111e.c' object='test_features-amd8111e.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-amd8111e.o `test -f 'amd8111e.c' || echo '$(srcdir)/'`amd8111e.c + +test_features-amd8111e.obj: amd8111e.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-amd8111e.obj -MD -MP -MF $(DEPDIR)/test_features-amd8111e.Tpo -c -o test_features-amd8111e.obj `if test -f 'amd8111e.c'; then $(CYGPATH_W) 'amd8111e.c'; else $(CYGPATH_W) '$(srcdir)/amd8111e.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-amd8111e.Tpo $(DEPDIR)/test_features-amd8111e.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='amd8111e.c' object='test_features-amd8111e.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-amd8111e.obj `if test -f 'amd8111e.c'; then $(CYGPATH_W) 'amd8111e.c'; else $(CYGPATH_W) '$(srcdir)/amd8111e.c'; fi` + +test_features-de2104x.o: de2104x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-de2104x.o -MD -MP -MF $(DEPDIR)/test_features-de2104x.Tpo -c -o test_features-de2104x.o `test -f 'de2104x.c' || echo '$(srcdir)/'`de2104x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-de2104x.Tpo $(DEPDIR)/test_features-de2104x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='de2104x.c' object='test_features-de2104x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-de2104x.o `test -f 'de2104x.c' || echo '$(srcdir)/'`de2104x.c + +test_features-de2104x.obj: de2104x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-de2104x.obj -MD -MP -MF $(DEPDIR)/test_features-de2104x.Tpo -c -o test_features-de2104x.obj `if test -f 'de2104x.c'; then $(CYGPATH_W) 'de2104x.c'; else $(CYGPATH_W) '$(srcdir)/de2104x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-de2104x.Tpo $(DEPDIR)/test_features-de2104x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='de2104x.c' object='test_features-de2104x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-de2104x.obj `if test -f 'de2104x.c'; then $(CYGPATH_W) 'de2104x.c'; else $(CYGPATH_W) '$(srcdir)/de2104x.c'; fi` + +test_features-dsa.o: dsa.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-dsa.o -MD -MP -MF $(DEPDIR)/test_features-dsa.Tpo -c -o test_features-dsa.o `test -f 'dsa.c' || echo '$(srcdir)/'`dsa.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-dsa.Tpo $(DEPDIR)/test_features-dsa.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa.c' object='test_features-dsa.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-dsa.o `test -f 'dsa.c' || echo '$(srcdir)/'`dsa.c + +test_features-dsa.obj: dsa.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-dsa.obj -MD -MP -MF $(DEPDIR)/test_features-dsa.Tpo -c -o test_features-dsa.obj `if test -f 'dsa.c'; then $(CYGPATH_W) 'dsa.c'; else $(CYGPATH_W) '$(srcdir)/dsa.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-dsa.Tpo $(DEPDIR)/test_features-dsa.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa.c' object='test_features-dsa.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-dsa.obj `if test -f 'dsa.c'; then $(CYGPATH_W) 'dsa.c'; else $(CYGPATH_W) '$(srcdir)/dsa.c'; fi` + +test_features-e100.o: e100.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-e100.o -MD -MP -MF $(DEPDIR)/test_features-e100.Tpo -c -o test_features-e100.o `test -f 'e100.c' || echo '$(srcdir)/'`e100.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-e100.Tpo $(DEPDIR)/test_features-e100.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e100.c' object='test_features-e100.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-e100.o `test -f 'e100.c' || echo '$(srcdir)/'`e100.c + +test_features-e100.obj: e100.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-e100.obj -MD -MP -MF $(DEPDIR)/test_features-e100.Tpo -c -o test_features-e100.obj `if test -f 'e100.c'; then $(CYGPATH_W) 'e100.c'; else $(CYGPATH_W) '$(srcdir)/e100.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-e100.Tpo $(DEPDIR)/test_features-e100.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e100.c' object='test_features-e100.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-e100.obj `if test -f 'e100.c'; then $(CYGPATH_W) 'e100.c'; else $(CYGPATH_W) '$(srcdir)/e100.c'; fi` + +test_features-e1000.o: e1000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-e1000.o -MD -MP -MF $(DEPDIR)/test_features-e1000.Tpo -c -o test_features-e1000.o `test -f 'e1000.c' || echo '$(srcdir)/'`e1000.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-e1000.Tpo $(DEPDIR)/test_features-e1000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e1000.c' object='test_features-e1000.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-e1000.o `test -f 'e1000.c' || echo '$(srcdir)/'`e1000.c + +test_features-e1000.obj: e1000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-e1000.obj -MD -MP -MF $(DEPDIR)/test_features-e1000.Tpo -c -o test_features-e1000.obj `if test -f 'e1000.c'; then $(CYGPATH_W) 'e1000.c'; else $(CYGPATH_W) '$(srcdir)/e1000.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-e1000.Tpo $(DEPDIR)/test_features-e1000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e1000.c' object='test_features-e1000.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-e1000.obj `if test -f 'e1000.c'; then $(CYGPATH_W) 'e1000.c'; else $(CYGPATH_W) '$(srcdir)/e1000.c'; fi` + +test_features-et131x.o: et131x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-et131x.o -MD -MP -MF $(DEPDIR)/test_features-et131x.Tpo -c -o test_features-et131x.o `test -f 'et131x.c' || echo '$(srcdir)/'`et131x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-et131x.Tpo $(DEPDIR)/test_features-et131x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='et131x.c' object='test_features-et131x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-et131x.o `test -f 'et131x.c' || echo '$(srcdir)/'`et131x.c + +test_features-et131x.obj: et131x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-et131x.obj -MD -MP -MF $(DEPDIR)/test_features-et131x.Tpo -c -o test_features-et131x.obj `if test -f 'et131x.c'; then $(CYGPATH_W) 'et131x.c'; else $(CYGPATH_W) '$(srcdir)/et131x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-et131x.Tpo $(DEPDIR)/test_features-et131x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='et131x.c' object='test_features-et131x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-et131x.obj `if test -f 'et131x.c'; then $(CYGPATH_W) 'et131x.c'; else $(CYGPATH_W) '$(srcdir)/et131x.c'; fi` + +test_features-igb.o: igb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-igb.o -MD -MP -MF $(DEPDIR)/test_features-igb.Tpo -c -o test_features-igb.o `test -f 'igb.c' || echo '$(srcdir)/'`igb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-igb.Tpo $(DEPDIR)/test_features-igb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='igb.c' object='test_features-igb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-igb.o `test -f 'igb.c' || echo '$(srcdir)/'`igb.c + +test_features-igb.obj: igb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-igb.obj -MD -MP -MF $(DEPDIR)/test_features-igb.Tpo -c -o test_features-igb.obj `if test -f 'igb.c'; then $(CYGPATH_W) 'igb.c'; else $(CYGPATH_W) '$(srcdir)/igb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-igb.Tpo $(DEPDIR)/test_features-igb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='igb.c' object='test_features-igb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-igb.obj `if test -f 'igb.c'; then $(CYGPATH_W) 'igb.c'; else $(CYGPATH_W) '$(srcdir)/igb.c'; fi` + +test_features-fec.o: fec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-fec.o -MD -MP -MF $(DEPDIR)/test_features-fec.Tpo -c -o test_features-fec.o `test -f 'fec.c' || echo '$(srcdir)/'`fec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-fec.Tpo $(DEPDIR)/test_features-fec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fec.c' object='test_features-fec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-fec.o `test -f 'fec.c' || echo '$(srcdir)/'`fec.c + +test_features-fec.obj: fec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-fec.obj -MD -MP -MF $(DEPDIR)/test_features-fec.Tpo -c -o test_features-fec.obj `if test -f 'fec.c'; then $(CYGPATH_W) 'fec.c'; else $(CYGPATH_W) '$(srcdir)/fec.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-fec.Tpo $(DEPDIR)/test_features-fec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fec.c' object='test_features-fec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-fec.obj `if test -f 'fec.c'; then $(CYGPATH_W) 'fec.c'; else $(CYGPATH_W) '$(srcdir)/fec.c'; fi` + +test_features-fec_8xx.o: fec_8xx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-fec_8xx.o -MD -MP -MF $(DEPDIR)/test_features-fec_8xx.Tpo -c -o test_features-fec_8xx.o `test -f 'fec_8xx.c' || echo '$(srcdir)/'`fec_8xx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-fec_8xx.Tpo $(DEPDIR)/test_features-fec_8xx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fec_8xx.c' object='test_features-fec_8xx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-fec_8xx.o `test -f 'fec_8xx.c' || echo '$(srcdir)/'`fec_8xx.c + +test_features-fec_8xx.obj: fec_8xx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-fec_8xx.obj -MD -MP -MF $(DEPDIR)/test_features-fec_8xx.Tpo -c -o test_features-fec_8xx.obj `if test -f 'fec_8xx.c'; then $(CYGPATH_W) 'fec_8xx.c'; else $(CYGPATH_W) '$(srcdir)/fec_8xx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-fec_8xx.Tpo $(DEPDIR)/test_features-fec_8xx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fec_8xx.c' object='test_features-fec_8xx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-fec_8xx.obj `if test -f 'fec_8xx.c'; then $(CYGPATH_W) 'fec_8xx.c'; else $(CYGPATH_W) '$(srcdir)/fec_8xx.c'; fi` + +test_features-fsl_enetc.o: fsl_enetc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-fsl_enetc.o -MD -MP -MF $(DEPDIR)/test_features-fsl_enetc.Tpo -c -o test_features-fsl_enetc.o `test -f 'fsl_enetc.c' || echo '$(srcdir)/'`fsl_enetc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-fsl_enetc.Tpo $(DEPDIR)/test_features-fsl_enetc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fsl_enetc.c' object='test_features-fsl_enetc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-fsl_enetc.o `test -f 'fsl_enetc.c' || echo '$(srcdir)/'`fsl_enetc.c + +test_features-fsl_enetc.obj: fsl_enetc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-fsl_enetc.obj -MD -MP -MF $(DEPDIR)/test_features-fsl_enetc.Tpo -c -o test_features-fsl_enetc.obj `if test -f 'fsl_enetc.c'; then $(CYGPATH_W) 'fsl_enetc.c'; else $(CYGPATH_W) '$(srcdir)/fsl_enetc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-fsl_enetc.Tpo $(DEPDIR)/test_features-fsl_enetc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fsl_enetc.c' object='test_features-fsl_enetc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-fsl_enetc.obj `if test -f 'fsl_enetc.c'; then $(CYGPATH_W) 'fsl_enetc.c'; else $(CYGPATH_W) '$(srcdir)/fsl_enetc.c'; fi` + +test_features-ibm_emac.o: ibm_emac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ibm_emac.o -MD -MP -MF $(DEPDIR)/test_features-ibm_emac.Tpo -c -o test_features-ibm_emac.o `test -f 'ibm_emac.c' || echo '$(srcdir)/'`ibm_emac.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ibm_emac.Tpo $(DEPDIR)/test_features-ibm_emac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ibm_emac.c' object='test_features-ibm_emac.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ibm_emac.o `test -f 'ibm_emac.c' || echo '$(srcdir)/'`ibm_emac.c + +test_features-ibm_emac.obj: ibm_emac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ibm_emac.obj -MD -MP -MF $(DEPDIR)/test_features-ibm_emac.Tpo -c -o test_features-ibm_emac.obj `if test -f 'ibm_emac.c'; then $(CYGPATH_W) 'ibm_emac.c'; else $(CYGPATH_W) '$(srcdir)/ibm_emac.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ibm_emac.Tpo $(DEPDIR)/test_features-ibm_emac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ibm_emac.c' object='test_features-ibm_emac.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ibm_emac.obj `if test -f 'ibm_emac.c'; then $(CYGPATH_W) 'ibm_emac.c'; else $(CYGPATH_W) '$(srcdir)/ibm_emac.c'; fi` + +test_features-ixgb.o: ixgb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ixgb.o -MD -MP -MF $(DEPDIR)/test_features-ixgb.Tpo -c -o test_features-ixgb.o `test -f 'ixgb.c' || echo '$(srcdir)/'`ixgb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ixgb.Tpo $(DEPDIR)/test_features-ixgb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgb.c' object='test_features-ixgb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ixgb.o `test -f 'ixgb.c' || echo '$(srcdir)/'`ixgb.c + +test_features-ixgb.obj: ixgb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ixgb.obj -MD -MP -MF $(DEPDIR)/test_features-ixgb.Tpo -c -o test_features-ixgb.obj `if test -f 'ixgb.c'; then $(CYGPATH_W) 'ixgb.c'; else $(CYGPATH_W) '$(srcdir)/ixgb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ixgb.Tpo $(DEPDIR)/test_features-ixgb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgb.c' object='test_features-ixgb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ixgb.obj `if test -f 'ixgb.c'; then $(CYGPATH_W) 'ixgb.c'; else $(CYGPATH_W) '$(srcdir)/ixgb.c'; fi` + +test_features-ixgbe.o: ixgbe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ixgbe.o -MD -MP -MF $(DEPDIR)/test_features-ixgbe.Tpo -c -o test_features-ixgbe.o `test -f 'ixgbe.c' || echo '$(srcdir)/'`ixgbe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ixgbe.Tpo $(DEPDIR)/test_features-ixgbe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgbe.c' object='test_features-ixgbe.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ixgbe.o `test -f 'ixgbe.c' || echo '$(srcdir)/'`ixgbe.c + +test_features-ixgbe.obj: ixgbe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ixgbe.obj -MD -MP -MF $(DEPDIR)/test_features-ixgbe.Tpo -c -o test_features-ixgbe.obj `if test -f 'ixgbe.c'; then $(CYGPATH_W) 'ixgbe.c'; else $(CYGPATH_W) '$(srcdir)/ixgbe.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ixgbe.Tpo $(DEPDIR)/test_features-ixgbe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgbe.c' object='test_features-ixgbe.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ixgbe.obj `if test -f 'ixgbe.c'; then $(CYGPATH_W) 'ixgbe.c'; else $(CYGPATH_W) '$(srcdir)/ixgbe.c'; fi` + +test_features-natsemi.o: natsemi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-natsemi.o -MD -MP -MF $(DEPDIR)/test_features-natsemi.Tpo -c -o test_features-natsemi.o `test -f 'natsemi.c' || echo '$(srcdir)/'`natsemi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-natsemi.Tpo $(DEPDIR)/test_features-natsemi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='natsemi.c' object='test_features-natsemi.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-natsemi.o `test -f 'natsemi.c' || echo '$(srcdir)/'`natsemi.c + +test_features-natsemi.obj: natsemi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-natsemi.obj -MD -MP -MF $(DEPDIR)/test_features-natsemi.Tpo -c -o test_features-natsemi.obj `if test -f 'natsemi.c'; then $(CYGPATH_W) 'natsemi.c'; else $(CYGPATH_W) '$(srcdir)/natsemi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-natsemi.Tpo $(DEPDIR)/test_features-natsemi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='natsemi.c' object='test_features-natsemi.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-natsemi.obj `if test -f 'natsemi.c'; then $(CYGPATH_W) 'natsemi.c'; else $(CYGPATH_W) '$(srcdir)/natsemi.c'; fi` + +test_features-pcnet32.o: pcnet32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-pcnet32.o -MD -MP -MF $(DEPDIR)/test_features-pcnet32.Tpo -c -o test_features-pcnet32.o `test -f 'pcnet32.c' || echo '$(srcdir)/'`pcnet32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-pcnet32.Tpo $(DEPDIR)/test_features-pcnet32.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcnet32.c' object='test_features-pcnet32.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-pcnet32.o `test -f 'pcnet32.c' || echo '$(srcdir)/'`pcnet32.c + +test_features-pcnet32.obj: pcnet32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-pcnet32.obj -MD -MP -MF $(DEPDIR)/test_features-pcnet32.Tpo -c -o test_features-pcnet32.obj `if test -f 'pcnet32.c'; then $(CYGPATH_W) 'pcnet32.c'; else $(CYGPATH_W) '$(srcdir)/pcnet32.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-pcnet32.Tpo $(DEPDIR)/test_features-pcnet32.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcnet32.c' object='test_features-pcnet32.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-pcnet32.obj `if test -f 'pcnet32.c'; then $(CYGPATH_W) 'pcnet32.c'; else $(CYGPATH_W) '$(srcdir)/pcnet32.c'; fi` + +test_features-realtek.o: realtek.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-realtek.o -MD -MP -MF $(DEPDIR)/test_features-realtek.Tpo -c -o test_features-realtek.o `test -f 'realtek.c' || echo '$(srcdir)/'`realtek.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-realtek.Tpo $(DEPDIR)/test_features-realtek.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='realtek.c' object='test_features-realtek.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-realtek.o `test -f 'realtek.c' || echo '$(srcdir)/'`realtek.c + +test_features-realtek.obj: realtek.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-realtek.obj -MD -MP -MF $(DEPDIR)/test_features-realtek.Tpo -c -o test_features-realtek.obj `if test -f 'realtek.c'; then $(CYGPATH_W) 'realtek.c'; else $(CYGPATH_W) '$(srcdir)/realtek.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-realtek.Tpo $(DEPDIR)/test_features-realtek.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='realtek.c' object='test_features-realtek.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-realtek.obj `if test -f 'realtek.c'; then $(CYGPATH_W) 'realtek.c'; else $(CYGPATH_W) '$(srcdir)/realtek.c'; fi` + +test_features-tg3.o: tg3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-tg3.o -MD -MP -MF $(DEPDIR)/test_features-tg3.Tpo -c -o test_features-tg3.o `test -f 'tg3.c' || echo '$(srcdir)/'`tg3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-tg3.Tpo $(DEPDIR)/test_features-tg3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tg3.c' object='test_features-tg3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-tg3.o `test -f 'tg3.c' || echo '$(srcdir)/'`tg3.c + +test_features-tg3.obj: tg3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-tg3.obj -MD -MP -MF $(DEPDIR)/test_features-tg3.Tpo -c -o test_features-tg3.obj `if test -f 'tg3.c'; then $(CYGPATH_W) 'tg3.c'; else $(CYGPATH_W) '$(srcdir)/tg3.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-tg3.Tpo $(DEPDIR)/test_features-tg3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tg3.c' object='test_features-tg3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-tg3.obj `if test -f 'tg3.c'; then $(CYGPATH_W) 'tg3.c'; else $(CYGPATH_W) '$(srcdir)/tg3.c'; fi` + +test_features-marvell.o: marvell.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-marvell.o -MD -MP -MF $(DEPDIR)/test_features-marvell.Tpo -c -o test_features-marvell.o `test -f 'marvell.c' || echo '$(srcdir)/'`marvell.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-marvell.Tpo $(DEPDIR)/test_features-marvell.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='marvell.c' object='test_features-marvell.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-marvell.o `test -f 'marvell.c' || echo '$(srcdir)/'`marvell.c + +test_features-marvell.obj: marvell.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-marvell.obj -MD -MP -MF $(DEPDIR)/test_features-marvell.Tpo -c -o test_features-marvell.obj `if test -f 'marvell.c'; then $(CYGPATH_W) 'marvell.c'; else $(CYGPATH_W) '$(srcdir)/marvell.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-marvell.Tpo $(DEPDIR)/test_features-marvell.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='marvell.c' object='test_features-marvell.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-marvell.obj `if test -f 'marvell.c'; then $(CYGPATH_W) 'marvell.c'; else $(CYGPATH_W) '$(srcdir)/marvell.c'; fi` + +test_features-vioc.o: vioc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-vioc.o -MD -MP -MF $(DEPDIR)/test_features-vioc.Tpo -c -o test_features-vioc.o `test -f 'vioc.c' || echo '$(srcdir)/'`vioc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-vioc.Tpo $(DEPDIR)/test_features-vioc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vioc.c' object='test_features-vioc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-vioc.o `test -f 'vioc.c' || echo '$(srcdir)/'`vioc.c + +test_features-vioc.obj: vioc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-vioc.obj -MD -MP -MF $(DEPDIR)/test_features-vioc.Tpo -c -o test_features-vioc.obj `if test -f 'vioc.c'; then $(CYGPATH_W) 'vioc.c'; else $(CYGPATH_W) '$(srcdir)/vioc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-vioc.Tpo $(DEPDIR)/test_features-vioc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vioc.c' object='test_features-vioc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-vioc.obj `if test -f 'vioc.c'; then $(CYGPATH_W) 'vioc.c'; else $(CYGPATH_W) '$(srcdir)/vioc.c'; fi` + +test_features-smsc911x.o: smsc911x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-smsc911x.o -MD -MP -MF $(DEPDIR)/test_features-smsc911x.Tpo -c -o test_features-smsc911x.o `test -f 'smsc911x.c' || echo '$(srcdir)/'`smsc911x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-smsc911x.Tpo $(DEPDIR)/test_features-smsc911x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smsc911x.c' object='test_features-smsc911x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-smsc911x.o `test -f 'smsc911x.c' || echo '$(srcdir)/'`smsc911x.c + +test_features-smsc911x.obj: smsc911x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-smsc911x.obj -MD -MP -MF $(DEPDIR)/test_features-smsc911x.Tpo -c -o test_features-smsc911x.obj `if test -f 'smsc911x.c'; then $(CYGPATH_W) 'smsc911x.c'; else $(CYGPATH_W) '$(srcdir)/smsc911x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-smsc911x.Tpo $(DEPDIR)/test_features-smsc911x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smsc911x.c' object='test_features-smsc911x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-smsc911x.obj `if test -f 'smsc911x.c'; then $(CYGPATH_W) 'smsc911x.c'; else $(CYGPATH_W) '$(srcdir)/smsc911x.c'; fi` + +test_features-at76c50x-usb.o: at76c50x-usb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-at76c50x-usb.o -MD -MP -MF $(DEPDIR)/test_features-at76c50x-usb.Tpo -c -o test_features-at76c50x-usb.o `test -f 'at76c50x-usb.c' || echo '$(srcdir)/'`at76c50x-usb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-at76c50x-usb.Tpo $(DEPDIR)/test_features-at76c50x-usb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='at76c50x-usb.c' object='test_features-at76c50x-usb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-at76c50x-usb.o `test -f 'at76c50x-usb.c' || echo '$(srcdir)/'`at76c50x-usb.c + +test_features-at76c50x-usb.obj: at76c50x-usb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-at76c50x-usb.obj -MD -MP -MF $(DEPDIR)/test_features-at76c50x-usb.Tpo -c -o test_features-at76c50x-usb.obj `if test -f 'at76c50x-usb.c'; then $(CYGPATH_W) 'at76c50x-usb.c'; else $(CYGPATH_W) '$(srcdir)/at76c50x-usb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-at76c50x-usb.Tpo $(DEPDIR)/test_features-at76c50x-usb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='at76c50x-usb.c' object='test_features-at76c50x-usb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-at76c50x-usb.obj `if test -f 'at76c50x-usb.c'; then $(CYGPATH_W) 'at76c50x-usb.c'; else $(CYGPATH_W) '$(srcdir)/at76c50x-usb.c'; fi` + +test_features-sfc.o: sfc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-sfc.o -MD -MP -MF $(DEPDIR)/test_features-sfc.Tpo -c -o test_features-sfc.o `test -f 'sfc.c' || echo '$(srcdir)/'`sfc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-sfc.Tpo $(DEPDIR)/test_features-sfc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfc.c' object='test_features-sfc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-sfc.o `test -f 'sfc.c' || echo '$(srcdir)/'`sfc.c + +test_features-sfc.obj: sfc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-sfc.obj -MD -MP -MF $(DEPDIR)/test_features-sfc.Tpo -c -o test_features-sfc.obj `if test -f 'sfc.c'; then $(CYGPATH_W) 'sfc.c'; else $(CYGPATH_W) '$(srcdir)/sfc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-sfc.Tpo $(DEPDIR)/test_features-sfc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfc.c' object='test_features-sfc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-sfc.obj `if test -f 'sfc.c'; then $(CYGPATH_W) 'sfc.c'; else $(CYGPATH_W) '$(srcdir)/sfc.c'; fi` + +test_features-stmmac.o: stmmac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-stmmac.o -MD -MP -MF $(DEPDIR)/test_features-stmmac.Tpo -c -o test_features-stmmac.o `test -f 'stmmac.c' || echo '$(srcdir)/'`stmmac.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-stmmac.Tpo $(DEPDIR)/test_features-stmmac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stmmac.c' object='test_features-stmmac.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-stmmac.o `test -f 'stmmac.c' || echo '$(srcdir)/'`stmmac.c + +test_features-stmmac.obj: stmmac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-stmmac.obj -MD -MP -MF $(DEPDIR)/test_features-stmmac.Tpo -c -o test_features-stmmac.obj `if test -f 'stmmac.c'; then $(CYGPATH_W) 'stmmac.c'; else $(CYGPATH_W) '$(srcdir)/stmmac.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-stmmac.Tpo $(DEPDIR)/test_features-stmmac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stmmac.c' object='test_features-stmmac.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-stmmac.obj `if test -f 'stmmac.c'; then $(CYGPATH_W) 'stmmac.c'; else $(CYGPATH_W) '$(srcdir)/stmmac.c'; fi` + +test_features-sff-common.o: sff-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-sff-common.o -MD -MP -MF $(DEPDIR)/test_features-sff-common.Tpo -c -o test_features-sff-common.o `test -f 'sff-common.c' || echo '$(srcdir)/'`sff-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-sff-common.Tpo $(DEPDIR)/test_features-sff-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sff-common.c' object='test_features-sff-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-sff-common.o `test -f 'sff-common.c' || echo '$(srcdir)/'`sff-common.c + +test_features-sff-common.obj: sff-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-sff-common.obj -MD -MP -MF $(DEPDIR)/test_features-sff-common.Tpo -c -o test_features-sff-common.obj `if test -f 'sff-common.c'; then $(CYGPATH_W) 'sff-common.c'; else $(CYGPATH_W) '$(srcdir)/sff-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-sff-common.Tpo $(DEPDIR)/test_features-sff-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sff-common.c' object='test_features-sff-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-sff-common.obj `if test -f 'sff-common.c'; then $(CYGPATH_W) 'sff-common.c'; else $(CYGPATH_W) '$(srcdir)/sff-common.c'; fi` + +test_features-sfpid.o: sfpid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-sfpid.o -MD -MP -MF $(DEPDIR)/test_features-sfpid.Tpo -c -o test_features-sfpid.o `test -f 'sfpid.c' || echo '$(srcdir)/'`sfpid.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-sfpid.Tpo $(DEPDIR)/test_features-sfpid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfpid.c' object='test_features-sfpid.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-sfpid.o `test -f 'sfpid.c' || echo '$(srcdir)/'`sfpid.c + +test_features-sfpid.obj: sfpid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-sfpid.obj -MD -MP -MF $(DEPDIR)/test_features-sfpid.Tpo -c -o test_features-sfpid.obj `if test -f 'sfpid.c'; then $(CYGPATH_W) 'sfpid.c'; else $(CYGPATH_W) '$(srcdir)/sfpid.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-sfpid.Tpo $(DEPDIR)/test_features-sfpid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfpid.c' object='test_features-sfpid.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-sfpid.obj `if test -f 'sfpid.c'; then $(CYGPATH_W) 'sfpid.c'; else $(CYGPATH_W) '$(srcdir)/sfpid.c'; fi` + +test_features-sfpdiag.o: sfpdiag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-sfpdiag.o -MD -MP -MF $(DEPDIR)/test_features-sfpdiag.Tpo -c -o test_features-sfpdiag.o `test -f 'sfpdiag.c' || echo '$(srcdir)/'`sfpdiag.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-sfpdiag.Tpo $(DEPDIR)/test_features-sfpdiag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfpdiag.c' object='test_features-sfpdiag.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-sfpdiag.o `test -f 'sfpdiag.c' || echo '$(srcdir)/'`sfpdiag.c + +test_features-sfpdiag.obj: sfpdiag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-sfpdiag.obj -MD -MP -MF $(DEPDIR)/test_features-sfpdiag.Tpo -c -o test_features-sfpdiag.obj `if test -f 'sfpdiag.c'; then $(CYGPATH_W) 'sfpdiag.c'; else $(CYGPATH_W) '$(srcdir)/sfpdiag.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-sfpdiag.Tpo $(DEPDIR)/test_features-sfpdiag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sfpdiag.c' object='test_features-sfpdiag.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-sfpdiag.obj `if test -f 'sfpdiag.c'; then $(CYGPATH_W) 'sfpdiag.c'; else $(CYGPATH_W) '$(srcdir)/sfpdiag.c'; fi` + +test_features-ixgbevf.o: ixgbevf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ixgbevf.o -MD -MP -MF $(DEPDIR)/test_features-ixgbevf.Tpo -c -o test_features-ixgbevf.o `test -f 'ixgbevf.c' || echo '$(srcdir)/'`ixgbevf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ixgbevf.Tpo $(DEPDIR)/test_features-ixgbevf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgbevf.c' object='test_features-ixgbevf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ixgbevf.o `test -f 'ixgbevf.c' || echo '$(srcdir)/'`ixgbevf.c + +test_features-ixgbevf.obj: ixgbevf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-ixgbevf.obj -MD -MP -MF $(DEPDIR)/test_features-ixgbevf.Tpo -c -o test_features-ixgbevf.obj `if test -f 'ixgbevf.c'; then $(CYGPATH_W) 'ixgbevf.c'; else $(CYGPATH_W) '$(srcdir)/ixgbevf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-ixgbevf.Tpo $(DEPDIR)/test_features-ixgbevf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ixgbevf.c' object='test_features-ixgbevf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-ixgbevf.obj `if test -f 'ixgbevf.c'; then $(CYGPATH_W) 'ixgbevf.c'; else $(CYGPATH_W) '$(srcdir)/ixgbevf.c'; fi` + +test_features-tse.o: tse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-tse.o -MD -MP -MF $(DEPDIR)/test_features-tse.Tpo -c -o test_features-tse.o `test -f 'tse.c' || echo '$(srcdir)/'`tse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-tse.Tpo $(DEPDIR)/test_features-tse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tse.c' object='test_features-tse.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-tse.o `test -f 'tse.c' || echo '$(srcdir)/'`tse.c + +test_features-tse.obj: tse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-tse.obj -MD -MP -MF $(DEPDIR)/test_features-tse.Tpo -c -o test_features-tse.obj `if test -f 'tse.c'; then $(CYGPATH_W) 'tse.c'; else $(CYGPATH_W) '$(srcdir)/tse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-tse.Tpo $(DEPDIR)/test_features-tse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tse.c' object='test_features-tse.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-tse.obj `if test -f 'tse.c'; then $(CYGPATH_W) 'tse.c'; else $(CYGPATH_W) '$(srcdir)/tse.c'; fi` + +test_features-vmxnet3.o: vmxnet3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-vmxnet3.o -MD -MP -MF $(DEPDIR)/test_features-vmxnet3.Tpo -c -o test_features-vmxnet3.o `test -f 'vmxnet3.c' || echo '$(srcdir)/'`vmxnet3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-vmxnet3.Tpo $(DEPDIR)/test_features-vmxnet3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vmxnet3.c' object='test_features-vmxnet3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-vmxnet3.o `test -f 'vmxnet3.c' || echo '$(srcdir)/'`vmxnet3.c + +test_features-vmxnet3.obj: vmxnet3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-vmxnet3.obj -MD -MP -MF $(DEPDIR)/test_features-vmxnet3.Tpo -c -o test_features-vmxnet3.obj `if test -f 'vmxnet3.c'; then $(CYGPATH_W) 'vmxnet3.c'; else $(CYGPATH_W) '$(srcdir)/vmxnet3.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-vmxnet3.Tpo $(DEPDIR)/test_features-vmxnet3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vmxnet3.c' object='test_features-vmxnet3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-vmxnet3.obj `if test -f 'vmxnet3.c'; then $(CYGPATH_W) 'vmxnet3.c'; else $(CYGPATH_W) '$(srcdir)/vmxnet3.c'; fi` + +test_features-qsfp.o: qsfp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-qsfp.o -MD -MP -MF $(DEPDIR)/test_features-qsfp.Tpo -c -o test_features-qsfp.o `test -f 'qsfp.c' || echo '$(srcdir)/'`qsfp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-qsfp.Tpo $(DEPDIR)/test_features-qsfp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qsfp.c' object='test_features-qsfp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-qsfp.o `test -f 'qsfp.c' || echo '$(srcdir)/'`qsfp.c + +test_features-qsfp.obj: qsfp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-qsfp.obj -MD -MP -MF $(DEPDIR)/test_features-qsfp.Tpo -c -o test_features-qsfp.obj `if test -f 'qsfp.c'; then $(CYGPATH_W) 'qsfp.c'; else $(CYGPATH_W) '$(srcdir)/qsfp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-qsfp.Tpo $(DEPDIR)/test_features-qsfp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qsfp.c' object='test_features-qsfp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-qsfp.obj `if test -f 'qsfp.c'; then $(CYGPATH_W) 'qsfp.c'; else $(CYGPATH_W) '$(srcdir)/qsfp.c'; fi` + +test_features-fjes.o: fjes.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-fjes.o -MD -MP -MF $(DEPDIR)/test_features-fjes.Tpo -c -o test_features-fjes.o `test -f 'fjes.c' || echo '$(srcdir)/'`fjes.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-fjes.Tpo $(DEPDIR)/test_features-fjes.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fjes.c' object='test_features-fjes.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-fjes.o `test -f 'fjes.c' || echo '$(srcdir)/'`fjes.c + +test_features-fjes.obj: fjes.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-fjes.obj -MD -MP -MF $(DEPDIR)/test_features-fjes.Tpo -c -o test_features-fjes.obj `if test -f 'fjes.c'; then $(CYGPATH_W) 'fjes.c'; else $(CYGPATH_W) '$(srcdir)/fjes.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-fjes.Tpo $(DEPDIR)/test_features-fjes.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fjes.c' object='test_features-fjes.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-fjes.obj `if test -f 'fjes.c'; then $(CYGPATH_W) 'fjes.c'; else $(CYGPATH_W) '$(srcdir)/fjes.c'; fi` + +test_features-lan78xx.o: lan78xx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-lan78xx.o -MD -MP -MF $(DEPDIR)/test_features-lan78xx.Tpo -c -o test_features-lan78xx.o `test -f 'lan78xx.c' || echo '$(srcdir)/'`lan78xx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-lan78xx.Tpo $(DEPDIR)/test_features-lan78xx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lan78xx.c' object='test_features-lan78xx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-lan78xx.o `test -f 'lan78xx.c' || echo '$(srcdir)/'`lan78xx.c + +test_features-lan78xx.obj: lan78xx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-lan78xx.obj -MD -MP -MF $(DEPDIR)/test_features-lan78xx.Tpo -c -o test_features-lan78xx.obj `if test -f 'lan78xx.c'; then $(CYGPATH_W) 'lan78xx.c'; else $(CYGPATH_W) '$(srcdir)/lan78xx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-lan78xx.Tpo $(DEPDIR)/test_features-lan78xx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lan78xx.c' object='test_features-lan78xx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-lan78xx.obj `if test -f 'lan78xx.c'; then $(CYGPATH_W) 'lan78xx.c'; else $(CYGPATH_W) '$(srcdir)/lan78xx.c'; fi` + +test_features-igc.o: igc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-igc.o -MD -MP -MF $(DEPDIR)/test_features-igc.Tpo -c -o test_features-igc.o `test -f 'igc.c' || echo '$(srcdir)/'`igc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-igc.Tpo $(DEPDIR)/test_features-igc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='igc.c' object='test_features-igc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-igc.o `test -f 'igc.c' || echo '$(srcdir)/'`igc.c + +test_features-igc.obj: igc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-igc.obj -MD -MP -MF $(DEPDIR)/test_features-igc.Tpo -c -o test_features-igc.obj `if test -f 'igc.c'; then $(CYGPATH_W) 'igc.c'; else $(CYGPATH_W) '$(srcdir)/igc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-igc.Tpo $(DEPDIR)/test_features-igc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='igc.c' object='test_features-igc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-igc.obj `if test -f 'igc.c'; then $(CYGPATH_W) 'igc.c'; else $(CYGPATH_W) '$(srcdir)/igc.c'; fi` + +test_features-cmis.o: cmis.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-cmis.o -MD -MP -MF $(DEPDIR)/test_features-cmis.Tpo -c -o test_features-cmis.o `test -f 'cmis.c' || echo '$(srcdir)/'`cmis.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-cmis.Tpo $(DEPDIR)/test_features-cmis.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmis.c' object='test_features-cmis.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-cmis.o `test -f 'cmis.c' || echo '$(srcdir)/'`cmis.c + +test_features-cmis.obj: cmis.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-cmis.obj -MD -MP -MF $(DEPDIR)/test_features-cmis.Tpo -c -o test_features-cmis.obj `if test -f 'cmis.c'; then $(CYGPATH_W) 'cmis.c'; else $(CYGPATH_W) '$(srcdir)/cmis.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-cmis.Tpo $(DEPDIR)/test_features-cmis.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmis.c' object='test_features-cmis.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-cmis.obj `if test -f 'cmis.c'; then $(CYGPATH_W) 'cmis.c'; else $(CYGPATH_W) '$(srcdir)/cmis.c'; fi` + +test_features-bnxt.o: bnxt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-bnxt.o -MD -MP -MF $(DEPDIR)/test_features-bnxt.Tpo -c -o test_features-bnxt.o `test -f 'bnxt.c' || echo '$(srcdir)/'`bnxt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-bnxt.Tpo $(DEPDIR)/test_features-bnxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bnxt.c' object='test_features-bnxt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-bnxt.o `test -f 'bnxt.c' || echo '$(srcdir)/'`bnxt.c + +test_features-bnxt.obj: bnxt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-bnxt.obj -MD -MP -MF $(DEPDIR)/test_features-bnxt.Tpo -c -o test_features-bnxt.obj `if test -f 'bnxt.c'; then $(CYGPATH_W) 'bnxt.c'; else $(CYGPATH_W) '$(srcdir)/bnxt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-bnxt.Tpo $(DEPDIR)/test_features-bnxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bnxt.c' object='test_features-bnxt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-bnxt.obj `if test -f 'bnxt.c'; then $(CYGPATH_W) 'bnxt.c'; else $(CYGPATH_W) '$(srcdir)/bnxt.c'; fi` + +test_features-cpsw.o: cpsw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-cpsw.o -MD -MP -MF $(DEPDIR)/test_features-cpsw.Tpo -c -o test_features-cpsw.o `test -f 'cpsw.c' || echo '$(srcdir)/'`cpsw.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-cpsw.Tpo $(DEPDIR)/test_features-cpsw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpsw.c' object='test_features-cpsw.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-cpsw.o `test -f 'cpsw.c' || echo '$(srcdir)/'`cpsw.c + +test_features-cpsw.obj: cpsw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-cpsw.obj -MD -MP -MF $(DEPDIR)/test_features-cpsw.Tpo -c -o test_features-cpsw.obj `if test -f 'cpsw.c'; then $(CYGPATH_W) 'cpsw.c'; else $(CYGPATH_W) '$(srcdir)/cpsw.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-cpsw.Tpo $(DEPDIR)/test_features-cpsw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpsw.c' object='test_features-cpsw.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-cpsw.obj `if test -f 'cpsw.c'; then $(CYGPATH_W) 'cpsw.c'; else $(CYGPATH_W) '$(srcdir)/cpsw.c'; fi` + +test_features-lan743x.o: lan743x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-lan743x.o -MD -MP -MF $(DEPDIR)/test_features-lan743x.Tpo -c -o test_features-lan743x.o `test -f 'lan743x.c' || echo '$(srcdir)/'`lan743x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-lan743x.Tpo $(DEPDIR)/test_features-lan743x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lan743x.c' object='test_features-lan743x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-lan743x.o `test -f 'lan743x.c' || echo '$(srcdir)/'`lan743x.c + +test_features-lan743x.obj: lan743x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT test_features-lan743x.obj -MD -MP -MF $(DEPDIR)/test_features-lan743x.Tpo -c -o test_features-lan743x.obj `if test -f 'lan743x.c'; then $(CYGPATH_W) 'lan743x.c'; else $(CYGPATH_W) '$(srcdir)/lan743x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_features-lan743x.Tpo $(DEPDIR)/test_features-lan743x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lan743x.c' object='test_features-lan743x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o test_features-lan743x.obj `if test -f 'lan743x.c'; then $(CYGPATH_W) 'lan743x.c'; else $(CYGPATH_W) '$(srcdir)/lan743x.c'; fi` + +netlink/test_features-netlink.o: netlink/netlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-netlink.o -MD -MP -MF netlink/$(DEPDIR)/test_features-netlink.Tpo -c -o netlink/test_features-netlink.o `test -f 'netlink/netlink.c' || echo '$(srcdir)/'`netlink/netlink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-netlink.Tpo netlink/$(DEPDIR)/test_features-netlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/netlink.c' object='netlink/test_features-netlink.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-netlink.o `test -f 'netlink/netlink.c' || echo '$(srcdir)/'`netlink/netlink.c + +netlink/test_features-netlink.obj: netlink/netlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-netlink.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-netlink.Tpo -c -o netlink/test_features-netlink.obj `if test -f 'netlink/netlink.c'; then $(CYGPATH_W) 'netlink/netlink.c'; else $(CYGPATH_W) '$(srcdir)/netlink/netlink.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-netlink.Tpo netlink/$(DEPDIR)/test_features-netlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/netlink.c' object='netlink/test_features-netlink.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-netlink.obj `if test -f 'netlink/netlink.c'; then $(CYGPATH_W) 'netlink/netlink.c'; else $(CYGPATH_W) '$(srcdir)/netlink/netlink.c'; fi` + +netlink/test_features-msgbuff.o: netlink/msgbuff.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-msgbuff.o -MD -MP -MF netlink/$(DEPDIR)/test_features-msgbuff.Tpo -c -o netlink/test_features-msgbuff.o `test -f 'netlink/msgbuff.c' || echo '$(srcdir)/'`netlink/msgbuff.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-msgbuff.Tpo netlink/$(DEPDIR)/test_features-msgbuff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/msgbuff.c' object='netlink/test_features-msgbuff.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-msgbuff.o `test -f 'netlink/msgbuff.c' || echo '$(srcdir)/'`netlink/msgbuff.c + +netlink/test_features-msgbuff.obj: netlink/msgbuff.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-msgbuff.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-msgbuff.Tpo -c -o netlink/test_features-msgbuff.obj `if test -f 'netlink/msgbuff.c'; then $(CYGPATH_W) 'netlink/msgbuff.c'; else $(CYGPATH_W) '$(srcdir)/netlink/msgbuff.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-msgbuff.Tpo netlink/$(DEPDIR)/test_features-msgbuff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/msgbuff.c' object='netlink/test_features-msgbuff.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-msgbuff.obj `if test -f 'netlink/msgbuff.c'; then $(CYGPATH_W) 'netlink/msgbuff.c'; else $(CYGPATH_W) '$(srcdir)/netlink/msgbuff.c'; fi` + +netlink/test_features-nlsock.o: netlink/nlsock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-nlsock.o -MD -MP -MF netlink/$(DEPDIR)/test_features-nlsock.Tpo -c -o netlink/test_features-nlsock.o `test -f 'netlink/nlsock.c' || echo '$(srcdir)/'`netlink/nlsock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-nlsock.Tpo netlink/$(DEPDIR)/test_features-nlsock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/nlsock.c' object='netlink/test_features-nlsock.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-nlsock.o `test -f 'netlink/nlsock.c' || echo '$(srcdir)/'`netlink/nlsock.c + +netlink/test_features-nlsock.obj: netlink/nlsock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-nlsock.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-nlsock.Tpo -c -o netlink/test_features-nlsock.obj `if test -f 'netlink/nlsock.c'; then $(CYGPATH_W) 'netlink/nlsock.c'; else $(CYGPATH_W) '$(srcdir)/netlink/nlsock.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-nlsock.Tpo netlink/$(DEPDIR)/test_features-nlsock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/nlsock.c' object='netlink/test_features-nlsock.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-nlsock.obj `if test -f 'netlink/nlsock.c'; then $(CYGPATH_W) 'netlink/nlsock.c'; else $(CYGPATH_W) '$(srcdir)/netlink/nlsock.c'; fi` + +netlink/test_features-strset.o: netlink/strset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-strset.o -MD -MP -MF netlink/$(DEPDIR)/test_features-strset.Tpo -c -o netlink/test_features-strset.o `test -f 'netlink/strset.c' || echo '$(srcdir)/'`netlink/strset.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-strset.Tpo netlink/$(DEPDIR)/test_features-strset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/strset.c' object='netlink/test_features-strset.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-strset.o `test -f 'netlink/strset.c' || echo '$(srcdir)/'`netlink/strset.c + +netlink/test_features-strset.obj: netlink/strset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-strset.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-strset.Tpo -c -o netlink/test_features-strset.obj `if test -f 'netlink/strset.c'; then $(CYGPATH_W) 'netlink/strset.c'; else $(CYGPATH_W) '$(srcdir)/netlink/strset.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-strset.Tpo netlink/$(DEPDIR)/test_features-strset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/strset.c' object='netlink/test_features-strset.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-strset.obj `if test -f 'netlink/strset.c'; then $(CYGPATH_W) 'netlink/strset.c'; else $(CYGPATH_W) '$(srcdir)/netlink/strset.c'; fi` + +netlink/test_features-monitor.o: netlink/monitor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-monitor.o -MD -MP -MF netlink/$(DEPDIR)/test_features-monitor.Tpo -c -o netlink/test_features-monitor.o `test -f 'netlink/monitor.c' || echo '$(srcdir)/'`netlink/monitor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-monitor.Tpo netlink/$(DEPDIR)/test_features-monitor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/monitor.c' object='netlink/test_features-monitor.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-monitor.o `test -f 'netlink/monitor.c' || echo '$(srcdir)/'`netlink/monitor.c + +netlink/test_features-monitor.obj: netlink/monitor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-monitor.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-monitor.Tpo -c -o netlink/test_features-monitor.obj `if test -f 'netlink/monitor.c'; then $(CYGPATH_W) 'netlink/monitor.c'; else $(CYGPATH_W) '$(srcdir)/netlink/monitor.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-monitor.Tpo netlink/$(DEPDIR)/test_features-monitor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/monitor.c' object='netlink/test_features-monitor.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-monitor.obj `if test -f 'netlink/monitor.c'; then $(CYGPATH_W) 'netlink/monitor.c'; else $(CYGPATH_W) '$(srcdir)/netlink/monitor.c'; fi` + +netlink/test_features-bitset.o: netlink/bitset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-bitset.o -MD -MP -MF netlink/$(DEPDIR)/test_features-bitset.Tpo -c -o netlink/test_features-bitset.o `test -f 'netlink/bitset.c' || echo '$(srcdir)/'`netlink/bitset.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-bitset.Tpo netlink/$(DEPDIR)/test_features-bitset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/bitset.c' object='netlink/test_features-bitset.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-bitset.o `test -f 'netlink/bitset.c' || echo '$(srcdir)/'`netlink/bitset.c + +netlink/test_features-bitset.obj: netlink/bitset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-bitset.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-bitset.Tpo -c -o netlink/test_features-bitset.obj `if test -f 'netlink/bitset.c'; then $(CYGPATH_W) 'netlink/bitset.c'; else $(CYGPATH_W) '$(srcdir)/netlink/bitset.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-bitset.Tpo netlink/$(DEPDIR)/test_features-bitset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/bitset.c' object='netlink/test_features-bitset.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-bitset.obj `if test -f 'netlink/bitset.c'; then $(CYGPATH_W) 'netlink/bitset.c'; else $(CYGPATH_W) '$(srcdir)/netlink/bitset.c'; fi` + +netlink/test_features-settings.o: netlink/settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-settings.o -MD -MP -MF netlink/$(DEPDIR)/test_features-settings.Tpo -c -o netlink/test_features-settings.o `test -f 'netlink/settings.c' || echo '$(srcdir)/'`netlink/settings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-settings.Tpo netlink/$(DEPDIR)/test_features-settings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/settings.c' object='netlink/test_features-settings.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-settings.o `test -f 'netlink/settings.c' || echo '$(srcdir)/'`netlink/settings.c + +netlink/test_features-settings.obj: netlink/settings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-settings.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-settings.Tpo -c -o netlink/test_features-settings.obj `if test -f 'netlink/settings.c'; then $(CYGPATH_W) 'netlink/settings.c'; else $(CYGPATH_W) '$(srcdir)/netlink/settings.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-settings.Tpo netlink/$(DEPDIR)/test_features-settings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/settings.c' object='netlink/test_features-settings.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-settings.obj `if test -f 'netlink/settings.c'; then $(CYGPATH_W) 'netlink/settings.c'; else $(CYGPATH_W) '$(srcdir)/netlink/settings.c'; fi` + +netlink/test_features-parser.o: netlink/parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-parser.o -MD -MP -MF netlink/$(DEPDIR)/test_features-parser.Tpo -c -o netlink/test_features-parser.o `test -f 'netlink/parser.c' || echo '$(srcdir)/'`netlink/parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-parser.Tpo netlink/$(DEPDIR)/test_features-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/parser.c' object='netlink/test_features-parser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-parser.o `test -f 'netlink/parser.c' || echo '$(srcdir)/'`netlink/parser.c + +netlink/test_features-parser.obj: netlink/parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-parser.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-parser.Tpo -c -o netlink/test_features-parser.obj `if test -f 'netlink/parser.c'; then $(CYGPATH_W) 'netlink/parser.c'; else $(CYGPATH_W) '$(srcdir)/netlink/parser.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-parser.Tpo netlink/$(DEPDIR)/test_features-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/parser.c' object='netlink/test_features-parser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-parser.obj `if test -f 'netlink/parser.c'; then $(CYGPATH_W) 'netlink/parser.c'; else $(CYGPATH_W) '$(srcdir)/netlink/parser.c'; fi` + +netlink/test_features-permaddr.o: netlink/permaddr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-permaddr.o -MD -MP -MF netlink/$(DEPDIR)/test_features-permaddr.Tpo -c -o netlink/test_features-permaddr.o `test -f 'netlink/permaddr.c' || echo '$(srcdir)/'`netlink/permaddr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-permaddr.Tpo netlink/$(DEPDIR)/test_features-permaddr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/permaddr.c' object='netlink/test_features-permaddr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-permaddr.o `test -f 'netlink/permaddr.c' || echo '$(srcdir)/'`netlink/permaddr.c + +netlink/test_features-permaddr.obj: netlink/permaddr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-permaddr.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-permaddr.Tpo -c -o netlink/test_features-permaddr.obj `if test -f 'netlink/permaddr.c'; then $(CYGPATH_W) 'netlink/permaddr.c'; else $(CYGPATH_W) '$(srcdir)/netlink/permaddr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-permaddr.Tpo netlink/$(DEPDIR)/test_features-permaddr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/permaddr.c' object='netlink/test_features-permaddr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-permaddr.obj `if test -f 'netlink/permaddr.c'; then $(CYGPATH_W) 'netlink/permaddr.c'; else $(CYGPATH_W) '$(srcdir)/netlink/permaddr.c'; fi` + +netlink/test_features-prettymsg.o: netlink/prettymsg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-prettymsg.o -MD -MP -MF netlink/$(DEPDIR)/test_features-prettymsg.Tpo -c -o netlink/test_features-prettymsg.o `test -f 'netlink/prettymsg.c' || echo '$(srcdir)/'`netlink/prettymsg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-prettymsg.Tpo netlink/$(DEPDIR)/test_features-prettymsg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/prettymsg.c' object='netlink/test_features-prettymsg.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-prettymsg.o `test -f 'netlink/prettymsg.c' || echo '$(srcdir)/'`netlink/prettymsg.c + +netlink/test_features-prettymsg.obj: netlink/prettymsg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-prettymsg.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-prettymsg.Tpo -c -o netlink/test_features-prettymsg.obj `if test -f 'netlink/prettymsg.c'; then $(CYGPATH_W) 'netlink/prettymsg.c'; else $(CYGPATH_W) '$(srcdir)/netlink/prettymsg.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-prettymsg.Tpo netlink/$(DEPDIR)/test_features-prettymsg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/prettymsg.c' object='netlink/test_features-prettymsg.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-prettymsg.obj `if test -f 'netlink/prettymsg.c'; then $(CYGPATH_W) 'netlink/prettymsg.c'; else $(CYGPATH_W) '$(srcdir)/netlink/prettymsg.c'; fi` + +netlink/test_features-features.o: netlink/features.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-features.o -MD -MP -MF netlink/$(DEPDIR)/test_features-features.Tpo -c -o netlink/test_features-features.o `test -f 'netlink/features.c' || echo '$(srcdir)/'`netlink/features.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-features.Tpo netlink/$(DEPDIR)/test_features-features.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/features.c' object='netlink/test_features-features.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-features.o `test -f 'netlink/features.c' || echo '$(srcdir)/'`netlink/features.c + +netlink/test_features-features.obj: netlink/features.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-features.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-features.Tpo -c -o netlink/test_features-features.obj `if test -f 'netlink/features.c'; then $(CYGPATH_W) 'netlink/features.c'; else $(CYGPATH_W) '$(srcdir)/netlink/features.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-features.Tpo netlink/$(DEPDIR)/test_features-features.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/features.c' object='netlink/test_features-features.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-features.obj `if test -f 'netlink/features.c'; then $(CYGPATH_W) 'netlink/features.c'; else $(CYGPATH_W) '$(srcdir)/netlink/features.c'; fi` + +netlink/test_features-privflags.o: netlink/privflags.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-privflags.o -MD -MP -MF netlink/$(DEPDIR)/test_features-privflags.Tpo -c -o netlink/test_features-privflags.o `test -f 'netlink/privflags.c' || echo '$(srcdir)/'`netlink/privflags.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-privflags.Tpo netlink/$(DEPDIR)/test_features-privflags.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/privflags.c' object='netlink/test_features-privflags.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-privflags.o `test -f 'netlink/privflags.c' || echo '$(srcdir)/'`netlink/privflags.c + +netlink/test_features-privflags.obj: netlink/privflags.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-privflags.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-privflags.Tpo -c -o netlink/test_features-privflags.obj `if test -f 'netlink/privflags.c'; then $(CYGPATH_W) 'netlink/privflags.c'; else $(CYGPATH_W) '$(srcdir)/netlink/privflags.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-privflags.Tpo netlink/$(DEPDIR)/test_features-privflags.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/privflags.c' object='netlink/test_features-privflags.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-privflags.obj `if test -f 'netlink/privflags.c'; then $(CYGPATH_W) 'netlink/privflags.c'; else $(CYGPATH_W) '$(srcdir)/netlink/privflags.c'; fi` + +netlink/test_features-rings.o: netlink/rings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-rings.o -MD -MP -MF netlink/$(DEPDIR)/test_features-rings.Tpo -c -o netlink/test_features-rings.o `test -f 'netlink/rings.c' || echo '$(srcdir)/'`netlink/rings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-rings.Tpo netlink/$(DEPDIR)/test_features-rings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/rings.c' object='netlink/test_features-rings.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-rings.o `test -f 'netlink/rings.c' || echo '$(srcdir)/'`netlink/rings.c + +netlink/test_features-rings.obj: netlink/rings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-rings.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-rings.Tpo -c -o netlink/test_features-rings.obj `if test -f 'netlink/rings.c'; then $(CYGPATH_W) 'netlink/rings.c'; else $(CYGPATH_W) '$(srcdir)/netlink/rings.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-rings.Tpo netlink/$(DEPDIR)/test_features-rings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/rings.c' object='netlink/test_features-rings.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-rings.obj `if test -f 'netlink/rings.c'; then $(CYGPATH_W) 'netlink/rings.c'; else $(CYGPATH_W) '$(srcdir)/netlink/rings.c'; fi` + +netlink/test_features-channels.o: netlink/channels.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-channels.o -MD -MP -MF netlink/$(DEPDIR)/test_features-channels.Tpo -c -o netlink/test_features-channels.o `test -f 'netlink/channels.c' || echo '$(srcdir)/'`netlink/channels.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-channels.Tpo netlink/$(DEPDIR)/test_features-channels.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/channels.c' object='netlink/test_features-channels.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-channels.o `test -f 'netlink/channels.c' || echo '$(srcdir)/'`netlink/channels.c + +netlink/test_features-channels.obj: netlink/channels.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-channels.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-channels.Tpo -c -o netlink/test_features-channels.obj `if test -f 'netlink/channels.c'; then $(CYGPATH_W) 'netlink/channels.c'; else $(CYGPATH_W) '$(srcdir)/netlink/channels.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-channels.Tpo netlink/$(DEPDIR)/test_features-channels.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/channels.c' object='netlink/test_features-channels.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-channels.obj `if test -f 'netlink/channels.c'; then $(CYGPATH_W) 'netlink/channels.c'; else $(CYGPATH_W) '$(srcdir)/netlink/channels.c'; fi` + +netlink/test_features-coalesce.o: netlink/coalesce.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-coalesce.o -MD -MP -MF netlink/$(DEPDIR)/test_features-coalesce.Tpo -c -o netlink/test_features-coalesce.o `test -f 'netlink/coalesce.c' || echo '$(srcdir)/'`netlink/coalesce.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-coalesce.Tpo netlink/$(DEPDIR)/test_features-coalesce.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/coalesce.c' object='netlink/test_features-coalesce.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-coalesce.o `test -f 'netlink/coalesce.c' || echo '$(srcdir)/'`netlink/coalesce.c + +netlink/test_features-coalesce.obj: netlink/coalesce.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-coalesce.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-coalesce.Tpo -c -o netlink/test_features-coalesce.obj `if test -f 'netlink/coalesce.c'; then $(CYGPATH_W) 'netlink/coalesce.c'; else $(CYGPATH_W) '$(srcdir)/netlink/coalesce.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-coalesce.Tpo netlink/$(DEPDIR)/test_features-coalesce.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/coalesce.c' object='netlink/test_features-coalesce.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-coalesce.obj `if test -f 'netlink/coalesce.c'; then $(CYGPATH_W) 'netlink/coalesce.c'; else $(CYGPATH_W) '$(srcdir)/netlink/coalesce.c'; fi` + +netlink/test_features-pause.o: netlink/pause.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-pause.o -MD -MP -MF netlink/$(DEPDIR)/test_features-pause.Tpo -c -o netlink/test_features-pause.o `test -f 'netlink/pause.c' || echo '$(srcdir)/'`netlink/pause.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-pause.Tpo netlink/$(DEPDIR)/test_features-pause.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/pause.c' object='netlink/test_features-pause.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-pause.o `test -f 'netlink/pause.c' || echo '$(srcdir)/'`netlink/pause.c + +netlink/test_features-pause.obj: netlink/pause.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-pause.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-pause.Tpo -c -o netlink/test_features-pause.obj `if test -f 'netlink/pause.c'; then $(CYGPATH_W) 'netlink/pause.c'; else $(CYGPATH_W) '$(srcdir)/netlink/pause.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-pause.Tpo netlink/$(DEPDIR)/test_features-pause.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/pause.c' object='netlink/test_features-pause.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-pause.obj `if test -f 'netlink/pause.c'; then $(CYGPATH_W) 'netlink/pause.c'; else $(CYGPATH_W) '$(srcdir)/netlink/pause.c'; fi` + +netlink/test_features-eee.o: netlink/eee.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-eee.o -MD -MP -MF netlink/$(DEPDIR)/test_features-eee.Tpo -c -o netlink/test_features-eee.o `test -f 'netlink/eee.c' || echo '$(srcdir)/'`netlink/eee.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-eee.Tpo netlink/$(DEPDIR)/test_features-eee.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/eee.c' object='netlink/test_features-eee.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-eee.o `test -f 'netlink/eee.c' || echo '$(srcdir)/'`netlink/eee.c + +netlink/test_features-eee.obj: netlink/eee.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-eee.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-eee.Tpo -c -o netlink/test_features-eee.obj `if test -f 'netlink/eee.c'; then $(CYGPATH_W) 'netlink/eee.c'; else $(CYGPATH_W) '$(srcdir)/netlink/eee.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-eee.Tpo netlink/$(DEPDIR)/test_features-eee.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/eee.c' object='netlink/test_features-eee.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-eee.obj `if test -f 'netlink/eee.c'; then $(CYGPATH_W) 'netlink/eee.c'; else $(CYGPATH_W) '$(srcdir)/netlink/eee.c'; fi` + +netlink/test_features-tsinfo.o: netlink/tsinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-tsinfo.o -MD -MP -MF netlink/$(DEPDIR)/test_features-tsinfo.Tpo -c -o netlink/test_features-tsinfo.o `test -f 'netlink/tsinfo.c' || echo '$(srcdir)/'`netlink/tsinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-tsinfo.Tpo netlink/$(DEPDIR)/test_features-tsinfo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/tsinfo.c' object='netlink/test_features-tsinfo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-tsinfo.o `test -f 'netlink/tsinfo.c' || echo '$(srcdir)/'`netlink/tsinfo.c + +netlink/test_features-tsinfo.obj: netlink/tsinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-tsinfo.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-tsinfo.Tpo -c -o netlink/test_features-tsinfo.obj `if test -f 'netlink/tsinfo.c'; then $(CYGPATH_W) 'netlink/tsinfo.c'; else $(CYGPATH_W) '$(srcdir)/netlink/tsinfo.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-tsinfo.Tpo netlink/$(DEPDIR)/test_features-tsinfo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/tsinfo.c' object='netlink/test_features-tsinfo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-tsinfo.obj `if test -f 'netlink/tsinfo.c'; then $(CYGPATH_W) 'netlink/tsinfo.c'; else $(CYGPATH_W) '$(srcdir)/netlink/tsinfo.c'; fi` + +netlink/test_features-fec.o: netlink/fec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-fec.o -MD -MP -MF netlink/$(DEPDIR)/test_features-fec.Tpo -c -o netlink/test_features-fec.o `test -f 'netlink/fec.c' || echo '$(srcdir)/'`netlink/fec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-fec.Tpo netlink/$(DEPDIR)/test_features-fec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/fec.c' object='netlink/test_features-fec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-fec.o `test -f 'netlink/fec.c' || echo '$(srcdir)/'`netlink/fec.c + +netlink/test_features-fec.obj: netlink/fec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-fec.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-fec.Tpo -c -o netlink/test_features-fec.obj `if test -f 'netlink/fec.c'; then $(CYGPATH_W) 'netlink/fec.c'; else $(CYGPATH_W) '$(srcdir)/netlink/fec.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-fec.Tpo netlink/$(DEPDIR)/test_features-fec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/fec.c' object='netlink/test_features-fec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-fec.obj `if test -f 'netlink/fec.c'; then $(CYGPATH_W) 'netlink/fec.c'; else $(CYGPATH_W) '$(srcdir)/netlink/fec.c'; fi` + +netlink/test_features-stats.o: netlink/stats.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-stats.o -MD -MP -MF netlink/$(DEPDIR)/test_features-stats.Tpo -c -o netlink/test_features-stats.o `test -f 'netlink/stats.c' || echo '$(srcdir)/'`netlink/stats.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-stats.Tpo netlink/$(DEPDIR)/test_features-stats.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/stats.c' object='netlink/test_features-stats.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-stats.o `test -f 'netlink/stats.c' || echo '$(srcdir)/'`netlink/stats.c + +netlink/test_features-stats.obj: netlink/stats.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-stats.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-stats.Tpo -c -o netlink/test_features-stats.obj `if test -f 'netlink/stats.c'; then $(CYGPATH_W) 'netlink/stats.c'; else $(CYGPATH_W) '$(srcdir)/netlink/stats.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-stats.Tpo netlink/$(DEPDIR)/test_features-stats.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/stats.c' object='netlink/test_features-stats.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-stats.obj `if test -f 'netlink/stats.c'; then $(CYGPATH_W) 'netlink/stats.c'; else $(CYGPATH_W) '$(srcdir)/netlink/stats.c'; fi` + +netlink/test_features-desc-ethtool.o: netlink/desc-ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-desc-ethtool.o -MD -MP -MF netlink/$(DEPDIR)/test_features-desc-ethtool.Tpo -c -o netlink/test_features-desc-ethtool.o `test -f 'netlink/desc-ethtool.c' || echo '$(srcdir)/'`netlink/desc-ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-desc-ethtool.Tpo netlink/$(DEPDIR)/test_features-desc-ethtool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-ethtool.c' object='netlink/test_features-desc-ethtool.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-desc-ethtool.o `test -f 'netlink/desc-ethtool.c' || echo '$(srcdir)/'`netlink/desc-ethtool.c + +netlink/test_features-desc-ethtool.obj: netlink/desc-ethtool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-desc-ethtool.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-desc-ethtool.Tpo -c -o netlink/test_features-desc-ethtool.obj `if test -f 'netlink/desc-ethtool.c'; then $(CYGPATH_W) 'netlink/desc-ethtool.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-ethtool.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-desc-ethtool.Tpo netlink/$(DEPDIR)/test_features-desc-ethtool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-ethtool.c' object='netlink/test_features-desc-ethtool.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-desc-ethtool.obj `if test -f 'netlink/desc-ethtool.c'; then $(CYGPATH_W) 'netlink/desc-ethtool.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-ethtool.c'; fi` + +netlink/test_features-desc-genlctrl.o: netlink/desc-genlctrl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-desc-genlctrl.o -MD -MP -MF netlink/$(DEPDIR)/test_features-desc-genlctrl.Tpo -c -o netlink/test_features-desc-genlctrl.o `test -f 'netlink/desc-genlctrl.c' || echo '$(srcdir)/'`netlink/desc-genlctrl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-desc-genlctrl.Tpo netlink/$(DEPDIR)/test_features-desc-genlctrl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-genlctrl.c' object='netlink/test_features-desc-genlctrl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-desc-genlctrl.o `test -f 'netlink/desc-genlctrl.c' || echo '$(srcdir)/'`netlink/desc-genlctrl.c + +netlink/test_features-desc-genlctrl.obj: netlink/desc-genlctrl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-desc-genlctrl.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-desc-genlctrl.Tpo -c -o netlink/test_features-desc-genlctrl.obj `if test -f 'netlink/desc-genlctrl.c'; then $(CYGPATH_W) 'netlink/desc-genlctrl.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-genlctrl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-desc-genlctrl.Tpo netlink/$(DEPDIR)/test_features-desc-genlctrl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-genlctrl.c' object='netlink/test_features-desc-genlctrl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-desc-genlctrl.obj `if test -f 'netlink/desc-genlctrl.c'; then $(CYGPATH_W) 'netlink/desc-genlctrl.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-genlctrl.c'; fi` + +netlink/test_features-module-eeprom.o: netlink/module-eeprom.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-module-eeprom.o -MD -MP -MF netlink/$(DEPDIR)/test_features-module-eeprom.Tpo -c -o netlink/test_features-module-eeprom.o `test -f 'netlink/module-eeprom.c' || echo '$(srcdir)/'`netlink/module-eeprom.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-module-eeprom.Tpo netlink/$(DEPDIR)/test_features-module-eeprom.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module-eeprom.c' object='netlink/test_features-module-eeprom.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-module-eeprom.o `test -f 'netlink/module-eeprom.c' || echo '$(srcdir)/'`netlink/module-eeprom.c + +netlink/test_features-module-eeprom.obj: netlink/module-eeprom.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-module-eeprom.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-module-eeprom.Tpo -c -o netlink/test_features-module-eeprom.obj `if test -f 'netlink/module-eeprom.c'; then $(CYGPATH_W) 'netlink/module-eeprom.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module-eeprom.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-module-eeprom.Tpo netlink/$(DEPDIR)/test_features-module-eeprom.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module-eeprom.c' object='netlink/test_features-module-eeprom.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-module-eeprom.obj `if test -f 'netlink/module-eeprom.c'; then $(CYGPATH_W) 'netlink/module-eeprom.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module-eeprom.c'; fi` + +netlink/test_features-module.o: netlink/module.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-module.o -MD -MP -MF netlink/$(DEPDIR)/test_features-module.Tpo -c -o netlink/test_features-module.o `test -f 'netlink/module.c' || echo '$(srcdir)/'`netlink/module.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-module.Tpo netlink/$(DEPDIR)/test_features-module.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module.c' object='netlink/test_features-module.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-module.o `test -f 'netlink/module.c' || echo '$(srcdir)/'`netlink/module.c + +netlink/test_features-module.obj: netlink/module.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-module.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-module.Tpo -c -o netlink/test_features-module.obj `if test -f 'netlink/module.c'; then $(CYGPATH_W) 'netlink/module.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-module.Tpo netlink/$(DEPDIR)/test_features-module.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/module.c' object='netlink/test_features-module.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-module.obj `if test -f 'netlink/module.c'; then $(CYGPATH_W) 'netlink/module.c'; else $(CYGPATH_W) '$(srcdir)/netlink/module.c'; fi` + +netlink/test_features-desc-rtnl.o: netlink/desc-rtnl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-desc-rtnl.o -MD -MP -MF netlink/$(DEPDIR)/test_features-desc-rtnl.Tpo -c -o netlink/test_features-desc-rtnl.o `test -f 'netlink/desc-rtnl.c' || echo '$(srcdir)/'`netlink/desc-rtnl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-desc-rtnl.Tpo netlink/$(DEPDIR)/test_features-desc-rtnl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-rtnl.c' object='netlink/test_features-desc-rtnl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-desc-rtnl.o `test -f 'netlink/desc-rtnl.c' || echo '$(srcdir)/'`netlink/desc-rtnl.c + +netlink/test_features-desc-rtnl.obj: netlink/desc-rtnl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-desc-rtnl.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-desc-rtnl.Tpo -c -o netlink/test_features-desc-rtnl.obj `if test -f 'netlink/desc-rtnl.c'; then $(CYGPATH_W) 'netlink/desc-rtnl.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-rtnl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-desc-rtnl.Tpo netlink/$(DEPDIR)/test_features-desc-rtnl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/desc-rtnl.c' object='netlink/test_features-desc-rtnl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-desc-rtnl.obj `if test -f 'netlink/desc-rtnl.c'; then $(CYGPATH_W) 'netlink/desc-rtnl.c'; else $(CYGPATH_W) '$(srcdir)/netlink/desc-rtnl.c'; fi` + +netlink/test_features-cable_test.o: netlink/cable_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-cable_test.o -MD -MP -MF netlink/$(DEPDIR)/test_features-cable_test.Tpo -c -o netlink/test_features-cable_test.o `test -f 'netlink/cable_test.c' || echo '$(srcdir)/'`netlink/cable_test.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-cable_test.Tpo netlink/$(DEPDIR)/test_features-cable_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/cable_test.c' object='netlink/test_features-cable_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-cable_test.o `test -f 'netlink/cable_test.c' || echo '$(srcdir)/'`netlink/cable_test.c + +netlink/test_features-cable_test.obj: netlink/cable_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-cable_test.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-cable_test.Tpo -c -o netlink/test_features-cable_test.obj `if test -f 'netlink/cable_test.c'; then $(CYGPATH_W) 'netlink/cable_test.c'; else $(CYGPATH_W) '$(srcdir)/netlink/cable_test.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-cable_test.Tpo netlink/$(DEPDIR)/test_features-cable_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/cable_test.c' object='netlink/test_features-cable_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-cable_test.obj `if test -f 'netlink/cable_test.c'; then $(CYGPATH_W) 'netlink/cable_test.c'; else $(CYGPATH_W) '$(srcdir)/netlink/cable_test.c'; fi` + +netlink/test_features-tunnels.o: netlink/tunnels.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-tunnels.o -MD -MP -MF netlink/$(DEPDIR)/test_features-tunnels.Tpo -c -o netlink/test_features-tunnels.o `test -f 'netlink/tunnels.c' || echo '$(srcdir)/'`netlink/tunnels.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-tunnels.Tpo netlink/$(DEPDIR)/test_features-tunnels.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/tunnels.c' object='netlink/test_features-tunnels.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-tunnels.o `test -f 'netlink/tunnels.c' || echo '$(srcdir)/'`netlink/tunnels.c + +netlink/test_features-tunnels.obj: netlink/tunnels.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -MT netlink/test_features-tunnels.obj -MD -MP -MF netlink/$(DEPDIR)/test_features-tunnels.Tpo -c -o netlink/test_features-tunnels.obj `if test -f 'netlink/tunnels.c'; then $(CYGPATH_W) 'netlink/tunnels.c'; else $(CYGPATH_W) '$(srcdir)/netlink/tunnels.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) netlink/$(DEPDIR)/test_features-tunnels.Tpo netlink/$(DEPDIR)/test_features-tunnels.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlink/tunnels.c' object='netlink/test_features-tunnels.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_features_CFLAGS) $(CFLAGS) -c -o netlink/test_features-tunnels.obj `if test -f 'netlink/tunnels.c'; then $(CYGPATH_W) 'netlink/tunnels.c'; else $(CYGPATH_W) '$(srcdir)/netlink/tunnels.c'; fi` +install-man8: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) +install-dist_bashcompletionDATA: $(dist_bashcompletion_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_bashcompletion_DATA)'; test -n "$(bashcompletiondir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bashcompletiondir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bashcompletiondir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(bashcompletiondir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(bashcompletiondir)" || exit $$?; \ + done + +uninstall-dist_bashcompletionDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_bashcompletion_DATA)'; test -n "$(bashcompletiondir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(bashcompletiondir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +test-cmdline.log: test-cmdline$(EXEEXT) + @p='test-cmdline$(EXEEXT)'; \ + b='test-cmdline'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +test-features.log: test-features$(EXEEXT) + @p='test-features$(EXEEXT)'; \ + b='test-features'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) ethtool-config.h +installdirs: + for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(bashcompletiondir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f netlink/$(DEPDIR)/$(am__dirstamp) + -rm -f netlink/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) netlink/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_bashcompletionDATA install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-sbinPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) netlink/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_bashcompletionDATA uninstall-man \ + uninstall-sbinPROGRAMS + +uninstall-man: uninstall-man8 + +.MAKE: all check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \ + check-am clean clean-checkPROGRAMS clean-cscope clean-generic \ + clean-sbinPROGRAMS cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_bashcompletionDATA \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-man8 install-pdf install-pdf-am install-ps \ + install-ps-am install-sbinPROGRAMS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am recheck tags tags-am \ + uninstall uninstall-am uninstall-dist_bashcompletionDATA \ + uninstall-man uninstall-man8 uninstall-sbinPROGRAMS + +.PRECIOUS: Makefile + + +dist-hook: + cp $(top_srcdir)/ethtool.spec $(distdir) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..5687c69 --- /dev/null +++ b/NEWS @@ -0,0 +1,695 @@ +Version 6.1 - December 19, 2022 + * Feature: update link mode tables + * Feature: register dump for NXP ENETC driver (-d) + * Feature: report TCP header-data split (-g) + * Feature: support new message types in pretty print + * Fix: fix compiler warnings + * Fix: man page syntax fixes + +Version 6.0 - October 10, 2022 + * Fix: advertisement modes autoselection by lanes (-s) + +Version 5.19 - August 22, 2022 + * Feature: get/set tx push (-g and -G) + * Feature: register dump support for TI CPSW (-d) + * Feature: register dump support for lan743x chipset (-d) + * Fix: fix missing sff-8472 output in netlink path (-m) + * Fix: fix EEPROM byte write (-E) + +Version 5.18 - June 14, 2022 + * Feature: get/set cqe size (-g and -G) + * Fix: fix typo in man page + * Fix: fix help text alignment + * Fix: improve attribute label (--show-fec) + +Version 5.17 - April 4, 2022 + * Feature: transceiver module power mode (--set-module) + * Feature: transceiver module extended state (--show-module) + * Feature: get/set rx buffer length (-g and -G) + * Feature: tx copybreak buffer size (--get-tunable and --set-tunable) + * Feature: JSON output for features (-k) + * Feature: support OSFP transceiver modules (-m) + * Fix: add missing free() calls (--get-tunable and --set-tunable) + +Version 5.16 - January 19, 2022 + * Feature: use memory maps for module EEPROM parsing (-m) + * Feature: show CMIS diagnostic information (-m) + * Fix: fix dumping advertised FEC modes (--show-fec) + * Fix: ignore cable test notifications from other devices (--cable-test) + * Fix: do not show duplicate options in help text (--help) + +Version 5.15 - November 9, 2021 + * Feature: new extended link substates for bad signal (no arg) + * Feature: coalesce cqe mode attributes (-c and -C) + * Fix: multiple fixes of EEPROM module data parsing (-m) + * Fix: fix condition to display MDI-X info (no arg) + +Version 5.14 - September 12, 2021 + * Feature: do not silently ignore --json if unsupported + * Feature: support new message types in pretty print + +Version 5.13 - July 9, 2021 + * Feature: netlink handler for FEC (--show-fec and --set-fec) + * Feature: FEC stats support (--show-fec) + * Feature: standard based stats support (-S) + * Feature: netlink handler for module EEPROM dump (-m) + * Feature: page, bank and i2c selection in module dump (-m) + +Version 5.12 - May 2, 2021 + * Feature: support lanes count (no option and -s) + * Fix: fix help message for master-slave parameter (-s) + * Fix: better error message for master-slave in ioctl code path + * Fix: get rid of compiler warnings in "make check" + +Version 5.10 - Dec 16, 2020 + * Feature: infrastructure for JSON output + * Feature: separate FLAGS in -h output + * Feature: use policy dumps to check flags support + * Feature: show pause stats (-a) + * Feature: pretty printing of policy dumps + * Feature: improve error message when SFP module is missing + * Fix: use after free in netlink_run_handler() + * Fix: leaked instances of struct nl_socket + * Fix: improve compatibility between netlink and ioctl (-s) + +Version 5.9 - Oct 15, 2020 + * Feature: extended link state + * Feature: QSFP-DD support + * Feature: tunnel information (--show-tunnels) + * Feature: Broadcom bnxt support + * Fix: improve compatibility between ioctl and netlink output + * Fix: cable test TDR amplitude output + * Fix: get rid of build warnings + * Fix: null pointer dereference running against old kernel (no arg) + * Fix: update link mode tables + * Fix: fix memory leaks and error handling found by static analysis + +Version 5.8 - Aug 4, 2020 + * Feature: more ethtool netlink message format descriptions + * Feature: omit test-features if netlink is enabled + * Feature: netlink handler for gfeatures (-k) + * Feature: netlink handler for sfeatures (-K) + * Feature: netlink handler for gprivflags (--show-priv-flags) + * Feature: netlink handler for sprivflags (--set-priv-flags) + * Feature: netlink handler for gring (-g) + * Feature: netlink handler for sring (-G) + * Feature: netlink handler for gchannels (-l) + * Feature: netlink handler for schannels (-L) + * Feature: netlink handler for gcoalesce (-c) + * Feature: netlink handler for scoalesce (-C) + * Feature: netlink handler for gpause (-a) + * Feature: netlink handler for spause (-A) + * Feature: netlink handler for geee (--show-eee) + * Feature: netlink handler for seee (--set-eee) + * Feature: netlink handler for tsinfo (-T) + * Feature: master/slave configuration support + * Feature: LINKSTATE SQI support + * Feature: cable test support + * Feature: cable test TDR support + * Feature: JSON output for cable test commands + * Feature: igc driver support + * Feature: support for get/set ethtool_tunable + * Feature: dsa: mv88e6xxx: add pretty dump for 88E6352 SERDES + * Fix: fix build warnings + * Fix: fix nest type grouping in parser + * Fix: fix msgbuff_append() helper + * Fix: fix unwanted switch fall through in family_info_cb() + * Fix: fix netlink error message suppression + * Fix: fix netlink bitmasks when sent as NOMASK + * Fix: use "Not reported" when no FEC modes are provided + * Fix: ioctl: do not pass transceiver value back to kernel + * Fix: ethtool.spec: Add bash completion script + +Version 5.7 - Jun 4, 2020 + * Feature: ethtool: Add support for Low Latency Reed Solomon + * Fix: ethtool.c: Report transceiver correctly + * Feature: features: accept long legacy flag names when setting features + * Feature: refactor interface between ioctl and netlink code + * Feature: netlink: use genetlink ops information to decide about fallback + * Feature: netlink: show netlink error even without extack + * Feature: ethtool: add support for newer SFF-8024 compliance codes + * Feature: Rewrite printf() due to -Werror=format-security + +Version 5.6 - May 12, 2020 + * Feature: add --debug option to control debugging messages + * Feature: use named initializers in command line option list + * Feature: netlink: add netlink related UAPI header files + * Feature: netlink: introduce the netlink interface + * Feature: netlink: message buffer and composition helpers + * Feature: netlink: netlink socket wrapper and helpers + * Feature: netlink: initialize ethtool netlink socket + * Feature: netlink: add support for string sets + * Feature: netlink: add notification monitor + * Feature: netlink: add bitset helpers + * Feature: netlink: partial netlink handler for gset (no option) + * Feature: netlink: support getting wake-on-lan and debugging settings + * Feature: netlink: add basic command line parsing helpers + * Feature: netlink: add bitset command line parser handlers + * Feature: netlink: add netlink handler for sset (-s) + * Feature: netlink: support tests with netlink enabled + * Feature: netlink: add handler for permaddr (-P) + * Feature: netlink: support for pretty printing netlink messages + * Feature: netlink: message format description for ethtool netlink + * Feature: netlink: message format descriptions for genetlink control + * Feature: netlink: message format descriptions for rtnetlink + * Feature: netlink: use pretty printing for ethtool netlink messages + +Version 5.4 - January 10, 2020 + + * Feature: ethtool: implement support for Energy Detect Power Down + * Fix: fix arithmetic on pointer to void is a GNU extension warning + * Fix: fix unused parameter warnings in do_version() and show_usage() + * Fix: fix unused parameter warning in find_option() + * Fix: fix unused parameter warning in dump_eeprom() + * Fix: fix unused parameter warning in altera_tse_dump_regs() + * Fix: fix unused parameter warning in sfc_dump_regs() + * Fix: fix unused parameter warning in print_simple_table() + * Fix: fix unused parameter warning in natsemi_dump_regs() + * Fix: fix unused parameter warning in netsemi_dump_eeprom() + * Fix: fix unused parameter warning in ixgbe_dump_regs() + * Fix: fix unused parameter warning in realtek_dump_regs() + * Fix: fix unused parameter warning in lan78xx_dump_regs() + * Fix: fix unused parameter warning in {skge, sky2}_dump_regs() + * Fix: fix unused parameter warning in dsa_dump_regs() + * Fix: fix unused parameter warning in vmxnet3_dump_regs() + * Fix: fix unused parameter warning in st_{mac100, gmac}_dump_regs() + * Fix: fix unused parameter warning in ixgbevf_dump_regs() + * Fix: fix unused parameter warning in fec_8xx_dump_regs() + * Fix: fix unused parameter warning in tg3_dump_{eeprom, regs}() + * Fix: fix unused parameter warning in vioc_dump_regs() + * Fix: fix unused parameter warning in e100_dump_regs() + * Fix: fix unused parameter warning in de2104[01]_dump_regs() + * Fix: fix unused parameter warning in igb_dump_regs() + * Fix: fix unused parameter warning in e1000_dump_regs() + * Fix: fix unused parameter warning in smsc911x_dump_regs() + * Fix: fix unused parameter warning in at76c50x_usb_dump_regs() + * Fix: fix unused parameter warning in fec_dump_regs() + * Fix: fix unused parameter warning in amd8111e_dump_regs() + * Fix: fix unused parameter warning in et131x_dump_regs() + * Fix: fix unused parameter warning in ibm_emac_dump_regs() + * Fix: fix unused parameter warning in ixgb_dump_regs() + * Fix: fix unused parameter warning in fjes_dump_regs() + * Fix: fix unused parameter warning in e1000_get_mac_type() + * Fix: ethtool: correctly interpret bitrate of 255 + * Fix: ethtool: mark 10G Base-ER as SFF-8472 revision 10.4 onwards + * Fix: ethtool: add 0x16 and 0x1c extended compliance codes + +Version 5.3 - September 23, 2019 + * Feature: igb: dump RR2DCDELAY register + * Feature: dump nested registers + +Version 5.2 - July 25, 2019 + * Feature: Add 100BaseT1 and 1000BaseT1 link modes + * Feature: Use standard file location macros in ethtool.spec + +Version 5.1 - May 17, 2019 + * Feature: Add support for 200Gbps (50Gbps per lane) link mode + * Feature: simplify handling of PHY tunable downshift + * Feature: add support for PHY tunable Fast Link Down + * Feature: add PHY Fast Link Down tunable to man page + * Feature: Add a 'start N' option when specifying the Rx flow hash indirection table. + * Feature: Add bash-completion script + * Feature: add 10000baseR_FEC link mode name + * Fix: qsfp: fix special value comparison + * Feature: move option parsing related code into function + * Feature: move cmdline_coalesce out of do_scoalesce + * Feature: introduce new ioctl for per-queue settings + * Feature: support per-queue sub command --show-coalesce + * Feature: support per-queue sub command --coalesce + * Fix: fix up dump_coalesce output to match actual option names + * Feature: fec: add pretty dump + +Version 5.0 - March 13, 2019 + * Feature: don't report UFO on kernels v4.14 and above + * Fix: zero initialize coalesce struct + * Feature: dsa: add pretty dump + * Feature: dsa: mv88e6xxx: add pretty dump + * Feature: dsa: mv88e6xxx: add pretty dump for 88E6185 + * Feature: dsa: mv88e6xxx: add pretty dump for 88E6161 + * Feature: dsa: mv88e6xxx: add pretty dump for 88E6352 + * Feature: dsa: mv88e6xxx: add pretty dump for 88E6390 + * Feature: dsa: mv88e6xxx: add pretty dump for others + +Version 4.19 - November 2, 2018 + * Feature: support combinations of FEC modes + * Feature: better syntax for combinations of FEC modes + * Fix: Fix uninitialized variable use at qsfp dump + +Version 4.18 - August 24, 2018 + * Feature: Add support for WAKE_FILTER (WoL using filters) + * Feature: Add support for action value -2 (wake-up filter) + * Fix: document WoL filters option also in help message + * Feature: ixgbe dump strings for security registers + +Version 4.17 - June 15, 2018 + + * Fix: In ethtool.8, remove superfluous and incorrect \c. + * Fix: fix uninitialized return value + * Fix: fix RING_VF assignment + * Fix: remove unused global variable + * Fix: several fixes in do_gregs() + * Fix: correctly free hkey when get_stringset() fails + * Fix: remove unreachable code + * Fix: fix stack clash in do_get_phy_tunable and do_set_phy_tunable + * Feature: Add register dump support for MICROCHIP LAN78xx + +Version 4.16 - April 13, 2018 + + * Feature: add support for extra RSS contexts and RSS steering filters + * Feature: Document RSS context control and RSS filters + * Fix: don't fall back to grxfhindir when context was specified + * Fix: correct display of VF when showing vf/queue filters + * Fix: show VF and queue in the help for -N + * Fix: correct VF index values for the ring_cookie parameter + * Feature: Add SFF 8636 date code parsing support + +Version 4.15 - February 1, 2018 + + * Feature: Support for FEC encoding control + * Fix: Fix coding style warnings and errors reported by checkpatch + * Feature: Add extended compliance codes parsing to sfp modules + * Fix: Revert "ethtool: Add DMA Coalescing support" + * Feature: Add ETHTOOL_RESET support via --reset command + * Fix: fix MFLCN register dump for 82599 and newer + +Version 4.13 - October 27, 2017 + + * Fix: Do not return error code if no changes were attempted. + * Fix: Fix formatting of advertise bitmask + * Feature: Document 56000 advertise link modes + * Fix: fix the rx vs tx mixup in set channel message + * Feature: add support for HWTSTAMP_FILTER_NTP_ALL + * Feature: Add DMA Coalescing support + * Feature: Remove UDP Fragmentation Offload error prints + * Feature: stmmac: Add macros for number of registers + * Feature: stmmac: Add DMA HW Feature Register + +Version 4.11 - June 2, 2017 + + * Feature: Support for configurable RSS hash function + * Feature: support queue and VF fields for rxclass filters + * Feature: Add support for 2500baseT/5000baseT link modes + * Fix: Fix SFF 8079 cable technology bit parsing + * Fix: sync help output for -x/-X with man page + +Version 4.10 - March 24, 2017 + + * Fix: Fix the "advertise" parameter logic. + * Feature: Implement ETHTOOL_PHY_GTUNABLE/ETHTOOL_PHY_STUNABLE and PHY downshift + * Feature: add register dump support for fjes driver (-d option) + +Version 4.8 - October 3, 2016 + + * Feature: QSFP Plus/QSFP28 Diagnostics Information Support + * Feature: Enhancing link mode bits to support 25G/50G/100G + * Feature: add support for 1000BaseX and missing 10G link mode + * Fixes: address Coverity issues 1363118 - 1363125 + +Version 4.6 - June 26, 2016 + + * Feature: Support register dump on Intel X550 NICs (-d option) + * Fix: Correct some reported register offsets on Intel 10GbE NICs + (-d option) + * Feature: Add IPv6 support to NFC (-n, -N, -u and -U options) + * Feature: Add support for ETHTOOL_xLINKSETTINGS ioctls (no option + and -s option) + * Feature: Use netlink socket when AF_INET not available + +Version 4.5 - March 14, 2016 + + * Tests: Fix missing function declarations when building tests + * Tests: Fix return type of test_free() prorotype + * Feature: Add PHY statistics support (--phy-statistics option) + * Doc: Properly indent sub-options in man page + * Feature: Support setting default Rx flow indirection table + (-X option) + * Fix: Use 'sane' kernel type definitions on 64-bit architectures + * Fix: Don't ignore fread() return value (-d option) + * Fix: Heap corruption when dumping registers from a file (-d option) + * Fix: Stricter input validation for EEPROM setting (-E option) + * Fix: Fix strict-aliasing compiler warnings in marvell.c + * Tests: Fix use of uninitialised variable in test_realloc() + * Tests: Fix compiler warning in test-features.c + +Version 4.2 - October 9, 2015 + + * Feature: Support soldered-on modules in module EEPROM dump (-m option) + * Feature: Add register dump support for VMware vmxnet3 (-d option) + * Feature: Update register dump support for IBM EMAC (-d option) + (requires Linux 4.3 or a future stable update to 4.1 or 4.2) + * Doc: Fix typo in man page + +Version 4.0 - May 31, 2015 + + * Fix: Formatting of RX flow hash indirection table when size not + divisible by 8 (-x option) + * Fix: Add missing Advertised speeds (no option and -s option) + * Feature: Add support to get expansion ROM version (-i option) + * Feature: Include SFP serial number and date in EEPROM dump + (-m option) + +Version 3.18 - December 14, 2014 + + * Fix: Lookup of SFP Tx bias in SFF-8472 module diagnostics (-m option) + * Fix: Build with musl by using more common typedefs + +Version 3.16 - September 22, 2014 + + * Feature: Support for configurable RSS hash key (-x/-X options) + +Version 3.15 - July 20, 2014 + + * Feature: Add register dump support for Altera Triple Speed Ethernet + (-d option) + +Version 3.14 - April 21, 2014 + + * Fix: Report Backplane as supported port (no option) + * Feature: Allow building a smaller executable without pretty- + printing of register/EEPROM dumps (./configure --disable-pretty-dump) + * Fix: Typo in channel parameter format in an error message (-L option) + +Version 3.13 - January 27, 2014 + + * Doc: Update GPL text to include current address of the FSF + * Fix: Spelling fixes + * Doc: Fix advertising flag values in manual page for 20G link modes, + and add missing 1G, 10G and 40G link modes + +Version 3.12.1 - November 8, 2013 + + * Fix: Memory corruption when applying external calibration to + SFF-8472 module diagnostics (-m option) + * Feature: Add Intel 82599 and x540 DCB registers to dump + (-d option) + +Version 3.12 - November 7, 2013 + + * Fix: Remove alternate method to check for VLAN tag offload on Linux + < 2.6.37 (-k/-K options) + * Fix: Hide state of VLAN tag offload and LRO if the kernel is too old + for us to reliably detect them (-k option) + * Feature: Add register dump support for Solarflare SFC9100 family + (-d option) + +Version 3.11 - September 12, 2013 + + * Feature: Update Realtek chip list for register dump to match + r8169 driver in Linux 3.11 (-d option) + * Feature: Add ixgbevf support for register dump (-d option) + * Feature: Filter ixgbe register dump according to the specific chip + (-d option) + +Version 3.10 - July 1, 2013 + + * Feature: Beautify private flags print (--show-priv-flags option) + +Version 3.9 - April 30, 2013 + + * Feature: Display support for 10000BASE-KR link mode (no options) + * Feature: Add support for new versions of ixgbe register dump + (-d dump) + +Version 3.8 - February 28, 2013 + + * Feature: Allow setting destination MAC address in L3/L4 flow spec + rules (-N/-U option) + * Fix: Show full 64 bits of user-data (-n/-u option) + * Fix: Add version check for et131x regs (-d option) + * Doc: Improve description of -f, -t, -s, -N/-U, -W options in man page + * Fix: Restore 20000baseKR2 cap display (no options) + +Version 3.7 - December 13, 2012 + + * Fix: Gracefully handle failure of register pretty-printer (-d option) + * Feature: Add support for et131x registers (-d option) + * Feature: Basic optical diagnostics for SFF-8472 modules (-m option) + +Version 3.6 - October 5, 2012 + + * Feature: Allow setting MDI-X state (-s option) + * Fix: Preserve pause advertising bits when setting speed and + duplex with autoneg on (-s option) + * Fix: Don't call ioctl to set EEE parameters if they are the same + as the current parameters (--set-eee option) + +Version 3.5 - August 2, 2012 + + * Feature: Display support for 1000BASE-KX and 10GBASE-KX4 link modes + * Feature: Energy-Efficient Ethernet (EEE) configuration + (--show-eee and --set-eee options) + * Fix: Don't trust drivers to null-terminate strings + * Feature: Display support for 40G link modes + * Package: Update RPM summary, description and URL + * Package: Exclude redundant documentation from RPM + +Version 3.4.2 - July 16, 2012 + + * Fix: Fix regression in RX NFC rule insertion for drivers that do + not select rule locations (-N/-U option) + * Fix: Remove bogus error message when changing offload settings + on Linux < 2.6.39 (-K option) + * Fix: Use alternate method to check for VLAN tag offload on Linux + < 2.6.37 (-k option) + +Version 3.4.1 - June 13, 2012 + + * Fix: Work around failure of ETHTOOL_GSSET_INFO for unprivileged + users (-k option) + * Fix: Report any unexpected error code from ETHTOOL_GSSET_INFO + (-k and -K options) + * Doc: Fix the date of the man page to match the last update + +Version 3.4 - June 8, 2012 + + * Cleanup: Merge RX NFC options + * Doc: Improve description of RX NFC options + * Doc: Add ntuple to the -K option in the man page + * Feature: Show time stamping capabilities (-T option) + * Feature: Dump plug-in module EEPROM (-m option) + * Feature: Show and change all generic net device features + (-k and -K options) + +Version 3.2 - January 12, 2012 + + * Feature: Add support for querying and setting private flags + (--show-priv-flags, --set-priv-flags options) + * Feature: Omit zero values in Solarflare register tables (-d option) + * Feature: Allow driver to select RX NFC rule location (-U option) + * Fix: Correct register dump offsets for Intel 82575 chipsets + (-d option) + +Version 3.1 - November 16, 2011 + + * Fix: Show all non-zero registers for tg3 (-d option) + * Feature: Add support for external loopback test (-t option) + * Fix: Show correct flow control registers for Intel 82599 (-d option) + * Feature: Add support for reporting and configuring numbers of + channels/queues (-l and -L options) + * Feature: Report pause frame autonegotiation result (-a option) + * Doc: Change device name metavariable from 'ethX' to 'devname' + * Doc: Fix various layout problems + * Cleanup: Reorganise and add test cases for argument parsing + * Fix: Strictly check for extraneous or missing arguments; in + particular, fail if the device name is missing + +Version 3.0 - August 4, 2011 + + * Feature: Report supported pause frame modes + * Feature: Support firmware dump (-w and -W options) + * Feature: Report advertised and supported 20G link modes + * Feature: Add an 'l4data' option for ip4 filters (-U option) + * Fix: Correct swapped h_source and h_dest fields for ether filters + (-U option) + * Fix: Set ip_ver field correctly for ip4 filters (-U option) + * Fix: Correct parameter validation for -e and -E options; in + particular, treat the 'magic' value as unsigned + +Version 2.6.39 - June 1, 2011 + + * Feature: Report some driver features (-i option) + * Doc: Remove misleading 'Auto' advertising mask from manual page + * Doc: Improve table formatting on manual page, using tbl + * Doc: Remove initial blank page in printed manual page + * Doc: Fix line-wrapping of options + * Feature: Add support for ESP as a separate protocol from AH + (-n, -N, -u and -U options) + * Cleanup: Remove support for showing RX n-tuple settings + (-u option), which was never implemented correctly in the kernel + * Feature: Add support for RX network flow classifier (NFC) + (-u and -U options) + * Feature: Add support for e1000 M88 PHY registers (-d option) + * Cleanup: Change bug-address to netdev + +Version 2.6.38 - March 15, 2011 + + * Doc: Fix spelling and spacing in online help + * Doc: Update date, version and web site reference in manual page + * Doc: Fix spelling, capitalisation, consistency and style in + manual page + * Doc: Generalise some references to network devices rather than + Ethernet devices + * Fix: Don't silently ignore speed/duplex when autoneg is on + * Fix: Report an error (rather than full usage information) if + given an unrecognised option + * Feature: Add --version option + +Version 2.6.37 - January 5, 2011 + + * Fix: Build fix for distributions with kernel headers from + Linux 2.6.9 or earlier + +Version 2.6.36 - November 16, 2010 + + * Fix: RX n-tuple masks and documentation + * Feature: Ethernet-level RX n-tuple filtering and 'clear' action + * Feature: stmmac register dump support + * Feature: get permanent address (-P) option + * Feature: VLAN acceleration control + +Version 2.6.35 - August 10, 2010 + + * Feature: sfc register dump support + * Feature: improve cmd line parsing of ints, IPv4 addresses + * Feature: support ethtool named flags, messaging types + * Feature: minor man page fixes + * Feature: control RX flow hash indirection + +Version 2.6.34 - May 26, 2010 + + * Feature: Support n-tuple filter programming + * Feature: Support rx hashing, v2 (targetted for 2.6.35) + * Feature: Add names of newer Marvell chips + +Version 2.6.33 - February 24, 2010 + + This version introduces a new release numbering scheme, based + on the latest upstream kernel interface supported. + + * Fix: several man page corrections + * Feature: rx flow hash configuration + * Feature: report 10000baseT support, where available + * Feature: report MDI-X status, pause auto-neg, link partner adverts + * Feature: support additional port types + * Feature: support arbitrary speeds, faster than 65535 Mb + * Feature: large and generic receive offload (LRO, GRO) support + * Feature: option to flash firmware image from specified file + * Feature: support for block writing of EEPROMs + * Feature: marvell register dump update + * Feature: at76c50x-usb, e1000e, igb, ixgbe, r8169 register dump support + * Cleanup: remove support for RX hashing by port (was removed in + kernel by 59089d8d162ddcb5c434672e915331964d38a754) + * Doc: Explicitly ship GPLv2 license, rather than relying + on autotools to supply it for us (autotools started auto-installing + GPLv3 recently) + +Version 6 - July 26, 2007 + + * Fix/security: Fix handling of statistics where the label + is exactly 32 bytes (ETH_GSTRING_LEN). + * Feature: Add ability to change the advertised speed/duplex + to a different range of values, rather than all-or-one. + * Feature: ixgb register dump support + * Feature: sky2 register dump support + * Feature: Fabric7 VIOC register dump support + * Feature: Decode raw register dump stored in a file + * Feature: Add ability to force hex register dump, if desired + * Feature: update e1000 register dump + * Feature: Additional 10Gbps support + * Feature: Add 2.5G support + * Feature: Update r8169 register dump + * Feature: SMSC LAN911x/LAN921x register dump support + * Cleanup: Update internal ethtool.h copy to match upstream + kernel 2.6.23-rc1 version of ethtool.h. + +Version 5 - September 1, 2006 + + * Security: Avoid potential buffer overflow + * Feature: GSO support + * Feature: skge register dump + +Version 4 - July 18, 2006 + + * Feature: UFO support + * Feature: support long options + * Features: e1000, pcnet32, tg3 updates + * Feature: added PPC4xx EMAC support + * Feature: Use hexdump instead of single values for register dump + +Version 3 - January 27, 2005 + + * Feature: r8159 register dump support + * Feature / bug fix: Support advertising gigabit ethernet + * Bug fix: make sure to advertise 10baseT-HD + * Other minor bug fixes. + +Version 2 - August 17, 2004 + + * Feature: ethtool register dump raw mode + * Feature: return results of self-test back to OS via exit(2) + * Feature: add verbose register dump for pcnet32, fec_8xx + * Maintenance: update to more recent autoconf + * Maintenance: minor updates to e1000-specific module + * Bug fix: Remove silly restriction on ethernet interface naming + +Version 1.8 - July 19, 2003 + + * Feature: Support amd8111e register dumps + * Feature: Support TSO enable/disable + * Feature: Support 10 gigabit ethernet + * Feature: Support writing EEPROM data + * Feature: Output e100 MDI/MDI-x status in register dump + * Feature: Clean up RealTek (RTL) chip output, support new chips. + * Feature: More supported e1000 devices. + * Bug fix: Properly set ecmd.advertising + * Bug fix: Fix leaks, handle some error conditions better. + +Version 1.7 - October 21, 2002 + + * Feature: Support e100 register dumps + * Feature: Support tg3 eeprom dumps + * Feature: Support partial eeprom dumps (with non-zero offsets) + * Feature: Support decimal/octal/hex numbers transparently, + at the user's discretion. + +Version 1.6 - June 20, 2002 + + * Feature: Support e1000 register dumps + * Feature: Support RealTek RTL-8139C+ and RTL-8169 register dumps + * Feature: Support coalescing config (ETHTOOL_[GS]COALESCE) + * Feature: Support ring param config (ETHTOOL_[GS]RINGPARAM) + * Feature: Support pause param config (ETHTOOL_[GS]PAUSEPARAM) + * Feature: Support physical NIC identification (ETHTOOL_PHYS_ID) + * Feature: Support NIC self-testing (ETHTOOL_TEST) + * Feature: Support NIC checksum/scatter-gather configuration + (ETHTOOL_[GS]RXCSUM, ETHTOOL_[GS]TXCSUM, ETHTOOL_[GS]SG) + +Version 1.5 - Mar 4, 2002 + + * Fix: support usb network interfaces + * Fix: include redhat spec file in autoconf build system + * Fix: minor fixes to natsemi register dump + * Feature: report advertised as well as supported media, + when printing device settings. + +Version 1.4 - Nov 19, 2001 + + * Support builds on configurations missing SIOCETHTOOL constant. + * Import ethtool.h from kernel 2.4.15-pre6. + * Support retrieval/setting of per-driver debug levels + (ETHTOOL G/SMSGLVL) + * Support pretty-printing register dumps on natsemi, de2104x + (ETHTOOL GREGS) + * Support restarting autonegotiation (ETHTOOL NWAY_RST) + * Support obtaining link status (ETHTOOL GLINK) + +Version 1.3 - Aug 02, 2001 + + * Support Wake-on-LAN (ETHTOOL GWOL and ETHTOOL SWOL ioctl). + +Version 1.2 - May 17, 2001 + + * Support ETHTOOL_GDRVINFO ioctl, which obtains + information from the ethernet driver associated + with the specified interface. + diff --git a/README b/README new file mode 100644 index 0000000..9e03205 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +ethtool is a small utility for examining and tuning your ethernet-based +network interface. See the man page for more details. diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..ec17a0b --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1464 @@ +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.2]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR + +# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/amd8111e.c b/amd8111e.c new file mode 100644 index 0000000..175516b --- /dev/null +++ b/amd8111e.c @@ -0,0 +1,306 @@ + +/* Copyright (C) 2003 Advanced Micro Devices Inc. */ +#include +#include "internal.h" + +typedef enum { + /* VAL2 */ + RDMD0 = (1 << 16), + /* VAL1 */ + TDMD3 = (1 << 11), + TDMD2 = (1 << 10), + TDMD1 = (1 << 9), + TDMD0 = (1 << 8), + /* VAL0 */ + UINTCMD = (1 << 6), + RX_FAST_SPND = (1 << 5), + TX_FAST_SPND = (1 << 4), + RX_SPND = (1 << 3), + TX_SPND = (1 << 2), + INTREN = (1 << 1), + RUN = (1 << 0), + + CMD0_CLEAR = 0x000F0F7F, /* Command style register */ + +}CMD0_BITS; +typedef enum { + + /* VAL3 */ + CONDUIT_MODE = (1 << 29), + /* VAL2 */ + RPA = (1 << 19), + DRCVPA = (1 << 18), + DRCVBC = (1 << 17), + PROM = (1 << 16), + /* VAL1 */ + ASTRP_RCV = (1 << 13), + RCV_DROP0 = (1 << 12), + EMBA = (1 << 11), + DXMT2PD = (1 << 10), + LTINTEN = (1 << 9), + DXMTFCS = (1 << 8), + /* VAL0 */ + APAD_XMT = (1 << 6), + DRTY = (1 << 5), + INLOOP = (1 << 4), + EXLOOP = (1 << 3), + REX_RTRY = (1 << 2), + REX_UFLO = (1 << 1), + REX_LCOL = (1 << 0), + + CMD2_CLEAR = 0x3F7F3F7F, /* Command style register */ + +}CMD2_BITS; +typedef enum { + + /* VAL3 */ + ASF_INIT_DONE_ALIAS = (1 << 29), + /* VAL2 */ + JUMBO = (1 << 21), + VSIZE = (1 << 20), + VLONLY = (1 << 19), + VL_TAG_DEL = (1 << 18), + /* VAL1 */ + EN_PMGR = (1 << 14), + INTLEVEL = (1 << 13), + FORCE_FULL_DUPLEX = (1 << 12), + FORCE_LINK_STATUS = (1 << 11), + APEP = (1 << 10), + MPPLBA = (1 << 9), + /* VAL0 */ + RESET_PHY_PULSE = (1 << 2), + RESET_PHY = (1 << 1), + PHY_RST_POL = (1 << 0), + +}CMD3_BITS; +typedef enum { + + INTR = (1 << 31), + PCSINT = (1 << 28), + LCINT = (1 << 27), + APINT5 = (1 << 26), + APINT4 = (1 << 25), + APINT3 = (1 << 24), + TINT_SUM = (1 << 23), + APINT2 = (1 << 22), + APINT1 = (1 << 21), + APINT0 = (1 << 20), + MIIPDTINT = (1 << 19), + MCCINT = (1 << 17), + MREINT = (1 << 16), + RINT_SUM = (1 << 15), + SPNDINT = (1 << 14), + MPINT = (1 << 13), + SINT = (1 << 12), + TINT3 = (1 << 11), + TINT2 = (1 << 10), + TINT1 = (1 << 9), + TINT0 = (1 << 8), + UINT = (1 << 7), + STINT = (1 << 4), + RINT0 = (1 << 0), + +}INT0_BITS; +typedef enum { + + /* VAL3 */ + LCINTEN = (1 << 27), + APINT5EN = (1 << 26), + APINT4EN = (1 << 25), + APINT3EN = (1 << 24), + /* VAL2 */ + APINT2EN = (1 << 22), + APINT1EN = (1 << 21), + APINT0EN = (1 << 20), + MIIPDTINTEN = (1 << 19), + MCCIINTEN = (1 << 18), + MCCINTEN = (1 << 17), + MREINTEN = (1 << 16), + /* VAL1 */ + SPNDINTEN = (1 << 14), + MPINTEN = (1 << 13), + TINTEN3 = (1 << 11), + SINTEN = (1 << 12), + TINTEN2 = (1 << 10), + TINTEN1 = (1 << 9), + TINTEN0 = (1 << 8), + /* VAL0 */ + STINTEN = (1 << 4), + RINTEN0 = (1 << 0), + + INTEN0_CLEAR = 0x1F7F7F1F, /* Command style register */ + +}INTEN0_BITS; + +typedef enum { + + PMAT_DET = (1 << 12), + MP_DET = (1 << 11), + LC_DET = (1 << 10), + SPEED_MASK = (1 << 9)|(1 << 8)|(1 << 7), + FULL_DPLX = (1 << 6), + LINK_STATS = (1 << 5), + AUTONEG_COMPLETE = (1 << 4), + MIIPD = (1 << 3), + RX_SUSPENDED = (1 << 2), + TX_SUSPENDED = (1 << 1), + RUNNING = (1 << 0), + +}STAT0_BITS; + +#define PHY_SPEED_10 0x2 +#define PHY_SPEED_100 0x3 + + +int amd8111e_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + + u32 *reg_buff = (u32 *)regs->data; + u32 reg; + + fprintf(stdout, "Descriptor Registers\n"); + fprintf(stdout, "---------------------\n"); + + /* Transmit descriptor base address register */ + reg = reg_buff[0]; + fprintf(stdout, + "0x00100: Transmit descriptor base address register %08X\n",reg); + + /* Transmit descriptor length register */ + reg = reg_buff[1]; + fprintf(stdout, + "0x00140: Transmit descriptor length register 0x%08X\n",reg); + + /* Receive descriptor base address register */ + reg = reg_buff[2]; + fprintf(stdout, + "0x00120: Receive descriptor base address register %08X\n",reg); + + /* Receive descriptor length register */ + reg = reg_buff[3]; + fprintf(stdout, + "0x00150: Receive descriptor length register 0x%08X\n",reg); + + fprintf(stdout, "\n"); + + + fprintf(stdout, "Command Registers\n"); + fprintf(stdout, "-------------------\n"); + + /* Command 0 Register */ + reg = reg_buff[4]; + fprintf(stdout, + "0x00048: Command 0 register 0x%08X\n" + " Interrupts: %s\n" + " Device: %s\n", + reg, + reg & INTREN ? "Enabled" : "Disabled", + reg & RUN ? "Running" : "Stopped"); + + /* Command 2 Register */ + reg = reg_buff[5]; + fprintf(stdout, + "0x00050: Command 2 register 0x%08X\n" + " Promiscuous mode: %s\n" + " Retransmit on underflow: %s\n", + reg, + reg & PROM ? "Enabled" : "Disabled", + reg & REX_UFLO ? "Enabled" : "Disabled"); + /* Command 3 Register */ + reg = reg_buff[6]; + fprintf(stdout, + "0x00054: Command 3 register 0x%08X\n" + " Jumbo frame: %s\n" + " Admit only VLAN frame: %s\n" + " Delete VLAN tag: %s\n", + reg, + reg & JUMBO ? "Enabled" : "Disabled", + reg & VLONLY ? "Yes" : "No", + reg & VL_TAG_DEL ? "Yes" : "No"); + + /* Command 7 Register */ + reg = reg_buff[7]; + fprintf(stdout, + "0x00064: Command 7 register 0x%08X\n", + reg); + + fprintf(stdout, "\n"); + fprintf(stdout, "Interrupt Registers\n"); + fprintf(stdout, "-------------------\n"); + + /* Interrupt 0 Register */ + reg = reg_buff[8]; + fprintf(stdout, + "0x00038: Interrupt register 0x%08X\n" + " Any interrupt is set: %s\n" + " Link change interrupt: %s\n" + " Register 0 auto-poll interrupt: %s\n" + " Transmit interrupt: %s\n" + " Software timer interrupt: %s\n" + " Receive interrupt: %s\n", + reg, + reg & INTR ? "Yes" : "No", + reg & LCINT ? "Yes" : "No", + reg & APINT0 ? "Yes" : "No", + reg & TINT0 ? "Yes" : "No", + reg & STINT ? "Yes" : "No", + reg & RINT0 ? "Yes" : "No" + ); + /* Interrupt 0 enable Register */ + reg = reg_buff[9]; + fprintf(stdout, + "0x00040: Interrupt enable register 0x%08X\n" + " Link change interrupt: %s\n" + " Register 0 auto-poll interrupt: %s\n" + " Transmit interrupt: %s\n" + " Software timer interrupt: %s\n" + " Receive interrupt: %s\n", + reg, + reg & LCINTEN ? "Enabled" : "Disabled", + reg & APINT0EN ? "Enabled" : "Disabled", + reg & TINTEN0 ? "Enabled" : "Disabled", + reg & STINTEN ? "Enabled" : "Disabled", + reg & RINTEN0 ? "Enabled" : "Disabled" + ); + + fprintf(stdout, "\n"); + fprintf(stdout, "Logical Address Filter Register\n"); + fprintf(stdout, "-------------------\n"); + + /* Logical Address Filter Register */ + fprintf(stdout, + "0x00168: Logical address filter register 0x%08X%08X\n", + reg_buff[11],reg_buff[10]); + + fprintf(stdout, "\n"); + fprintf(stdout, "Link status Register\n"); + fprintf(stdout, "-------------------\n"); + + /* Status 0 Register */ + reg = reg_buff[12]; + if(reg & LINK_STATS){ + fprintf(stdout, + "0x00030: Link status register 0x%08X\n" + " Link status: %s\n" + " Auto negotiation complete %s\n" + " Duplex %s\n" + " Speed %s\n", + reg, + reg & LINK_STATS ? "Valid" : "Invalid", + reg & AUTONEG_COMPLETE ? "Yes" : "No", + reg & FULL_DPLX ? "Full" : "Half", + ((reg & SPEED_MASK) >> 7 == PHY_SPEED_10) ? "10Mbits/ Sec": + "100Mbits/Sec"); + + } + else{ + fprintf(stdout, + "0x00030: Link status register 0x%08X\n" + " Link status: %s\n", + reg, + reg & LINK_STATS ? "Valid" : "Invalid"); + } + return 0; + +} diff --git a/at76c50x-usb.c b/at76c50x-usb.c new file mode 100644 index 0000000..fad41bf --- /dev/null +++ b/at76c50x-usb.c @@ -0,0 +1,32 @@ +#include +#include "internal.h" + +static char *hw_versions[] = { + "503_ISL3861", + "503_ISL3863", + " 503", + " 503_ACC", + " 505", + " 505_2958", + " 505A", + " 505AMX", +}; + +int at76c50x_usb_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u8 version = (u8)(regs->version >> 24); + u8 rev_id = (u8)(regs->version); + char *ver_string; + + if (version != 0) + return -1; + + ver_string = hw_versions[rev_id]; + fprintf(stdout, + "Hardware Version %s\n", + ver_string); + + return 0; +} + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..9f98ef8 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# You need autoconf 2.5x, preferably 2.57 or later +# You need automake 1.7 or later. 1.6 might work. + +set -e + +aclocal +autoheader +automake --gnu --add-missing --copy +autoconf diff --git a/bnxt.c b/bnxt.c new file mode 100644 index 0000000..2b0ac76 --- /dev/null +++ b/bnxt.c @@ -0,0 +1,97 @@ +/* Code to dump registers for NetXtreme-E/NetXtreme-C Broadcom devices. + * + * Copyright (c) 2020 Broadcom Inc. + */ +#include +#include "internal.h" + +#define BNXT_PXP_REG_LEN 0x3110 +#define BNXT_PCIE_STATS_LEN (12 * sizeof(u64)) + +struct bnxt_pcie_stat { + const char *name; + u16 offset; + u8 size; + const char *format; +}; + +static const struct bnxt_pcie_stat bnxt_pcie_stats[] = { + { .name = "PL Signal integrity errors", .offset = 0, .size = 4, .format = "%llu" }, + { .name = "DL Signal integrity errors", .offset = 4, .size = 4, .format = "%llu" }, + { .name = "TLP Signal integrity errors", .offset = 8, .size = 4, .format = "%llu" }, + { .name = "Link integrity", .offset = 12, .size = 4, .format = "%llu" }, + { .name = "TX TLP traffic rate", .offset = 16, .size = 4, .format = "%llu" }, + { .name = "RX TLP traffic rate", .offset = 20, .size = 4, .format = "%llu" }, + { .name = "TX DLLP traffic rate", .offset = 24, .size = 4, .format = "%llu" }, + { .name = "RX DLLP traffic rate", .offset = 28, .size = 4, .format = "%llu" }, + { .name = "Equalization Phase 0 time(ms)", .offset = 33, .size = 1, .format = "0x%x" }, + { .name = "Equalization Phase 1 time(ms)", .offset = 32, .size = 1, .format = "0x%x" }, + { .name = "Equalization Phase 2 time(ms)", .offset = 35, .size = 1, .format = "0x%x" }, + { .name = "Equalization Phase 3 time(ms)", .offset = 34, .size = 1, .format = "0x%x" }, + { .name = "PHY LTSSM Histogram 0", .offset = 36, .size = 2, .format = "0x%x"}, + { .name = "PHY LTSSM Histogram 1", .offset = 38, .size = 2, .format = "0x%x"}, + { .name = "PHY LTSSM Histogram 2", .offset = 40, .size = 2, .format = "0x%x"}, + { .name = "PHY LTSSM Histogram 3", .offset = 42, .size = 2, .format = "0x%x"}, + { .name = "Recovery Histogram 0", .offset = 44, .size = 2, .format = "0x%x"}, + { .name = "Recovery Histogram 1", .offset = 46, .size = 2, .format = "0x%x"}, +}; + +int bnxt_dump_regs(struct ethtool_drvinfo *info __maybe_unused, struct ethtool_regs *regs) +{ + const struct bnxt_pcie_stat *stats = bnxt_pcie_stats; + u16 *pcie_stats, pcie_stat16; + u32 reg, i, pcie_stat32; + u64 pcie_stat64; + + if (regs->len < BNXT_PXP_REG_LEN) { + fprintf(stdout, "Length too short, expected at least 0x%x\n", + BNXT_PXP_REG_LEN); + return -1; + } + + fprintf(stdout, "PXP Registers\n"); + fprintf(stdout, "Offset\tValue\n"); + fprintf(stdout, "------\t-------\n"); + for (i = 0; i < BNXT_PXP_REG_LEN; i += sizeof(reg)) { + memcpy(®, ®s->data[i], sizeof(reg)); + if (reg) + fprintf(stdout, "0x%04x\t0x%08x\n", i, reg); + } + fprintf(stdout, "\n"); + + if (!regs->version) + return 0; + + if (regs->len < (BNXT_PXP_REG_LEN + BNXT_PCIE_STATS_LEN)) { + fprintf(stdout, "Length is too short, expected 0x%zx\n", + BNXT_PXP_REG_LEN + BNXT_PCIE_STATS_LEN); + return -1; + } + + pcie_stats = (u16 *)(regs->data + BNXT_PXP_REG_LEN); + fprintf(stdout, "PCIe statistics:\n"); + fprintf(stdout, "----------------\n"); + for (i = 0; i < ARRAY_SIZE(bnxt_pcie_stats); i++) { + fprintf(stdout, "%-30s : ", stats[i].name); + switch (stats[i].size) { + case 1: + pcie_stat16 = 0; + memcpy(&pcie_stat16, &pcie_stats[stats[i].offset], sizeof(u16)); + fprintf(stdout, stats[i].format, pcie_stat16); + break; + case 2: + pcie_stat32 = 0; + memcpy(&pcie_stat32, &pcie_stats[stats[i].offset], sizeof(u32)); + fprintf(stdout, stats[i].format, pcie_stat32); + break; + case 4: + pcie_stat64 = 0; + memcpy(&pcie_stat64, &pcie_stats[stats[i].offset], sizeof(u64)); + fprintf(stdout, stats[i].format, pcie_stat64); + break; + } + fprintf(stdout, "\n"); + } + + return 0; +} diff --git a/cmis.c b/cmis.c new file mode 100644 index 0000000..d0b6272 --- /dev/null +++ b/cmis.c @@ -0,0 +1,1002 @@ +/** + * Description: + * + * This module adds CMIS support to ethtool. The changes are similar to + * the ones already existing in qsfp.c, but customized to use the memory + * addresses and logic as defined in the specification's document. + * + */ + +#include +#include +#include +#include "internal.h" +#include "sff-common.h" +#include "cmis.h" +#include "netlink/extapi.h" + +/* The maximum number of supported Banks. Relevant documents: + * [1] CMIS Rev. 5, page. 128, section 8.4.4, Table 8-40 + */ +#define CMIS_MAX_BANKS 4 +#define CMIS_CHANNELS_PER_BANK 8 +#define CMIS_MAX_CHANNEL_NUM (CMIS_MAX_BANKS * CMIS_CHANNELS_PER_BANK) + +/* We are not parsing further than Page 11h. */ +#define CMIS_MAX_PAGES 18 + +struct cmis_memory_map { + const __u8 *lower_memory; + const __u8 *upper_memory[CMIS_MAX_BANKS][CMIS_MAX_PAGES]; +#define page_00h upper_memory[0x0][0x0] +#define page_01h upper_memory[0x0][0x1] +#define page_02h upper_memory[0x0][0x2] +}; + +#define CMIS_PAGE_SIZE 0x80 +#define CMIS_I2C_ADDRESS 0x50 + +static struct { + const char *str; + int offset; + __u8 value; /* Alarm is on if (offset & value) != 0. */ +} cmis_aw_mod_flags[] = { + { "Module temperature high alarm", + CMIS_TEMP_AW_OFFSET, CMIS_TEMP_HALARM_STATUS }, + { "Module temperature low alarm", + CMIS_TEMP_AW_OFFSET, CMIS_TEMP_LALARM_STATUS }, + { "Module temperature high warning", + CMIS_TEMP_AW_OFFSET, CMIS_TEMP_HWARN_STATUS }, + { "Module temperature low warning", + CMIS_TEMP_AW_OFFSET, CMIS_TEMP_LWARN_STATUS }, + + { "Module voltage high alarm", + CMIS_VCC_AW_OFFSET, CMIS_VCC_HALARM_STATUS }, + { "Module voltage low alarm", + CMIS_VCC_AW_OFFSET, CMIS_VCC_LALARM_STATUS }, + { "Module voltage high warning", + CMIS_VCC_AW_OFFSET, CMIS_VCC_HWARN_STATUS }, + { "Module voltage low warning", + CMIS_VCC_AW_OFFSET, CMIS_VCC_LWARN_STATUS }, + + { NULL, 0, 0 }, +}; + +static struct { + const char *fmt_str; + int offset; + int adver_offset; /* In Page 01h. */ + __u8 adver_value; /* Supported if (offset & value) != 0. */ +} cmis_aw_chan_flags[] = { + { "Laser bias current high alarm (Chan %d)", + CMIS_TX_BIAS_AW_HALARM_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK }, + { "Laser bias current low alarm (Chan %d)", + CMIS_TX_BIAS_AW_LALARM_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK }, + { "Laser bias current high warning (Chan %d)", + CMIS_TX_BIAS_AW_HWARN_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK }, + { "Laser bias current low warning (Chan %d)", + CMIS_TX_BIAS_AW_LWARN_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK }, + + { "Laser tx power high alarm (Channel %d)", + CMIS_TX_PWR_AW_HALARM_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK }, + { "Laser tx power low alarm (Channel %d)", + CMIS_TX_PWR_AW_LALARM_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK }, + { "Laser tx power high warning (Channel %d)", + CMIS_TX_PWR_AW_HWARN_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK }, + { "Laser tx power low warning (Channel %d)", + CMIS_TX_PWR_AW_LWARN_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK }, + + { "Laser rx power high alarm (Channel %d)", + CMIS_RX_PWR_AW_HALARM_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK }, + { "Laser rx power low alarm (Channel %d)", + CMIS_RX_PWR_AW_LALARM_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK }, + { "Laser rx power high warning (Channel %d)", + CMIS_RX_PWR_AW_HWARN_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK }, + { "Laser rx power low warning (Channel %d)", + CMIS_RX_PWR_AW_LWARN_OFFSET, + CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK }, + + { NULL, 0, 0, 0 }, +}; + +static void cmis_show_identifier(const struct cmis_memory_map *map) +{ + sff8024_show_identifier(map->lower_memory, CMIS_ID_OFFSET); +} + +static void cmis_show_connector(const struct cmis_memory_map *map) +{ + sff8024_show_connector(map->page_00h, CMIS_CTOR_OFFSET); +} + +static void cmis_show_oui(const struct cmis_memory_map *map) +{ + sff8024_show_oui(map->page_00h, CMIS_VENDOR_OUI_OFFSET); +} + +/** + * Print the revision compliance. Relevant documents: + * [1] CMIS Rev. 3, pag. 45, section 1.7.2.1, Table 18 + * [2] CMIS Rev. 4, pag. 81, section 8.2.1, Table 8-2 + */ +static void cmis_show_rev_compliance(const struct cmis_memory_map *map) +{ + __u8 rev = map->lower_memory[CMIS_REV_COMPLIANCE_OFFSET]; + int major = (rev >> 4) & 0x0F; + int minor = rev & 0x0F; + + printf("\t%-41s : Rev. %d.%d\n", "Revision compliance", major, minor); +} + +/** + * Print information about the device's power consumption. + * Relevant documents: + * [1] CMIS Rev. 3, pag. 59, section 1.7.3.9, Table 30 + * [2] CMIS Rev. 4, pag. 94, section 8.3.9, Table 8-18 + * [3] QSFP-DD Hardware Rev 5.0, pag. 22, section 4.2.1 + */ +static void cmis_show_power_info(const struct cmis_memory_map *map) +{ + float max_power = 0.0f; + __u8 base_power = 0; + __u8 power_class; + + /* Get the power class (first 3 most significat bytes) */ + power_class = (map->page_00h[CMIS_PWR_CLASS_OFFSET] >> 5) & 0x07; + + /* Get the base power in multiples of 0.25W */ + base_power = map->page_00h[CMIS_PWR_MAX_POWER_OFFSET]; + max_power = base_power * 0.25f; + + printf("\t%-41s : %d\n", "Power class", power_class + 1); + printf("\t%-41s : %.02fW\n", "Max power", max_power); +} + +/** + * Print the cable assembly length, for both passive copper and active + * optical or electrical cables. The base length (bits 5-0) must be + * multiplied with the SMF length multiplier (bits 7-6) to obtain the + * correct value. Relevant documents: + * [1] CMIS Rev. 3, pag. 59, section 1.7.3.10, Table 31 + * [2] CMIS Rev. 4, pag. 94, section 8.3.10, Table 8-19 + */ +static void cmis_show_cbl_asm_len(const struct cmis_memory_map *map) +{ + static const char *fn = "Cable assembly length"; + float mul = 1.0f; + float val = 0.0f; + + /* Check if max length */ + if (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] == CMIS_6300M_MAX_LEN) { + printf("\t%-41s : > 6.3km\n", fn); + return; + } + + /* Get the multiplier from the first two bits */ + switch (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_MUL_MASK) { + case CMIS_MULTIPLIER_00: + mul = 0.1f; + break; + case CMIS_MULTIPLIER_01: + mul = 1.0f; + break; + case CMIS_MULTIPLIER_10: + mul = 10.0f; + break; + case CMIS_MULTIPLIER_11: + mul = 100.0f; + break; + default: + break; + } + + /* Get base value from first 6 bits and multiply by mul */ + val = (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_VAL_MASK); + val = (float)val * mul; + printf("\t%-41s : %0.2fm\n", fn, val); +} + +/** + * Print the length for SMF fiber. The base length (bits 5-0) must be + * multiplied with the SMF length multiplier (bits 7-6) to obtain the + * correct value. Relevant documents: + * [1] CMIS Rev. 3, pag. 63, section 1.7.4.2, Table 39 + * [2] CMIS Rev. 4, pag. 99, section 8.4.2, Table 8-27 + */ +static void cmis_print_smf_cbl_len(const struct cmis_memory_map *map) +{ + static const char *fn = "Length (SMF)"; + float mul = 1.0f; + float val = 0.0f; + + if (!map->page_01h) + return; + + /* Get the multiplier from the first two bits */ + switch (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_MUL_MASK) { + case CMIS_MULTIPLIER_00: + mul = 0.1f; + break; + case CMIS_MULTIPLIER_01: + mul = 1.0f; + break; + default: + break; + } + + /* Get base value from first 6 bits and multiply by mul */ + val = (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_VAL_MASK); + val = (float)val * mul; + printf("\t%-41s : %0.2fkm\n", fn, val); +} + +/** + * Print relevant signal integrity control properties. Relevant documents: + * [1] CMIS Rev. 3, pag. 71, section 1.7.4.10, Table 46 + * [2] CMIS Rev. 4, pag. 105, section 8.4.10, Table 8-34 + */ +static void cmis_show_sig_integrity(const struct cmis_memory_map *map) +{ + if (!map->page_01h) + return; + + /* CDR Bypass control: 2nd bit from each byte */ + printf("\t%-41s : ", "Tx CDR bypass control"); + printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x02)); + + printf("\t%-41s : ", "Rx CDR bypass control"); + printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x02)); + + /* CDR Implementation: 1st bit from each byte */ + printf("\t%-41s : ", "Tx CDR"); + printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x01)); + + printf("\t%-41s : ", "Rx CDR"); + printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x01)); +} + +/** + * Print relevant media interface technology info. Relevant documents: + * [1] CMIS Rev. 3 + * --> pag. 61, section 1.7.3.14, Table 36 + * --> pag. 64, section 1.7.4.3, 1.7.4.4 + * [2] CMIS Rev. 4 + * --> pag. 97, section 8.3.14, Table 8-24 + * --> pag. 98, section 8.4, Table 8-25 + * --> page 100, section 8.4.3, 8.4.4 + */ +static void cmis_show_mit_compliance(const struct cmis_memory_map *map) +{ + static const char *cc = " (Copper cable,"; + + printf("\t%-41s : 0x%02x", "Transmitter technology", + map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]); + + switch (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]) { + case CMIS_850_VCSEL: + printf(" (850 nm VCSEL)\n"); + break; + case CMIS_1310_VCSEL: + printf(" (1310 nm VCSEL)\n"); + break; + case CMIS_1550_VCSEL: + printf(" (1550 nm VCSEL)\n"); + break; + case CMIS_1310_FP: + printf(" (1310 nm FP)\n"); + break; + case CMIS_1310_DFB: + printf(" (1310 nm DFB)\n"); + break; + case CMIS_1550_DFB: + printf(" (1550 nm DFB)\n"); + break; + case CMIS_1310_EML: + printf(" (1310 nm EML)\n"); + break; + case CMIS_1550_EML: + printf(" (1550 nm EML)\n"); + break; + case CMIS_OTHERS: + printf(" (Others/Undefined)\n"); + break; + case CMIS_1490_DFB: + printf(" (1490 nm DFB)\n"); + break; + case CMIS_COPPER_UNEQUAL: + printf("%s unequalized)\n", cc); + break; + case CMIS_COPPER_PASS_EQUAL: + printf("%s passive equalized)\n", cc); + break; + case CMIS_COPPER_NF_EQUAL: + printf("%s near and far end limiting active equalizers)\n", cc); + break; + case CMIS_COPPER_F_EQUAL: + printf("%s far end limiting active equalizers)\n", cc); + break; + case CMIS_COPPER_N_EQUAL: + printf("%s near end limiting active equalizers)\n", cc); + break; + case CMIS_COPPER_LINEAR_EQUAL: + printf("%s linear active equalizers)\n", cc); + break; + } + + if (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET] >= CMIS_COPPER_UNEQUAL) { + printf("\t%-41s : %udb\n", "Attenuation at 5GHz", + map->page_00h[CMIS_COPPER_ATT_5GHZ]); + printf("\t%-41s : %udb\n", "Attenuation at 7GHz", + map->page_00h[CMIS_COPPER_ATT_7GHZ]); + printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz", + map->page_00h[CMIS_COPPER_ATT_12P9GHZ]); + printf("\t%-41s : %udb\n", "Attenuation at 25.8GHz", + map->page_00h[CMIS_COPPER_ATT_25P8GHZ]); + } else if (map->page_01h) { + printf("\t%-41s : %.3lfnm\n", "Laser wavelength", + (((map->page_01h[CMIS_NOM_WAVELENGTH_MSB] << 8) | + map->page_01h[CMIS_NOM_WAVELENGTH_LSB]) * 0.05)); + printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance", + (((map->page_01h[CMIS_WAVELENGTH_TOL_MSB] << 8) | + map->page_01h[CMIS_WAVELENGTH_TOL_LSB]) * 0.005)); + } +} + +/** + * Print relevant info about the maximum supported fiber media length + * for each type of fiber media at the maximum module-supported bit rate. + * Relevant documents: + * [1] CMIS Rev. 3, page 64, section 1.7.4.2, Table 39 + * [2] CMIS Rev. 4, page 99, section 8.4.2, Table 8-27 + */ +static void cmis_show_link_len(const struct cmis_memory_map *map) +{ + cmis_print_smf_cbl_len(map); + if (!map->page_01h) + return; + sff_show_value_with_unit(map->page_01h, CMIS_OM5_LEN_OFFSET, + "Length (OM5)", 2, "m"); + sff_show_value_with_unit(map->page_01h, CMIS_OM4_LEN_OFFSET, + "Length (OM4)", 2, "m"); + sff_show_value_with_unit(map->page_01h, CMIS_OM3_LEN_OFFSET, + "Length (OM3 50/125um)", 2, "m"); + sff_show_value_with_unit(map->page_01h, CMIS_OM2_LEN_OFFSET, + "Length (OM2 50/125um)", 1, "m"); +} + +/** + * Show relevant information about the vendor. Relevant documents: + * [1] CMIS Rev. 3, page 56, section 1.7.3, Table 27 + * [2] CMIS Rev. 4, page 91, section 8.2, Table 8-15 + */ +static void cmis_show_vendor_info(const struct cmis_memory_map *map) +{ + const char *clei; + + sff_show_ascii(map->page_00h, CMIS_VENDOR_NAME_START_OFFSET, + CMIS_VENDOR_NAME_END_OFFSET, "Vendor name"); + cmis_show_oui(map); + sff_show_ascii(map->page_00h, CMIS_VENDOR_PN_START_OFFSET, + CMIS_VENDOR_PN_END_OFFSET, "Vendor PN"); + sff_show_ascii(map->page_00h, CMIS_VENDOR_REV_START_OFFSET, + CMIS_VENDOR_REV_END_OFFSET, "Vendor rev"); + sff_show_ascii(map->page_00h, CMIS_VENDOR_SN_START_OFFSET, + CMIS_VENDOR_SN_END_OFFSET, "Vendor SN"); + sff_show_ascii(map->page_00h, CMIS_DATE_YEAR_OFFSET, + CMIS_DATE_VENDOR_LOT_OFFSET + 1, "Date code"); + + clei = (const char *)(map->page_00h + CMIS_CLEI_START_OFFSET); + if (*clei && strncmp(clei, CMIS_CLEI_BLANK, CMIS_CLEI_LEN)) + sff_show_ascii(map->page_00h, CMIS_CLEI_START_OFFSET, + CMIS_CLEI_END_OFFSET, "CLEI code"); +} + +/* Print the current Module State. Relevant documents: + * [1] CMIS Rev. 5, pag. 57, section 6.3.2.2, Figure 6-3 + * [2] CMIS Rev. 5, pag. 60, section 6.3.2.3, Figure 6-4 + * [3] CMIS Rev. 5, pag. 107, section 8.2.2, Table 8-6 + */ +static void cmis_show_mod_state(const struct cmis_memory_map *map) +{ + __u8 mod_state; + + mod_state = (map->lower_memory[CMIS_MODULE_STATE_OFFSET] & + CMIS_MODULE_STATE_MASK) >> 1; + printf("\t%-41s : 0x%02x", "Module State", mod_state); + switch (mod_state) { + case CMIS_MODULE_STATE_MODULE_LOW_PWR: + printf(" (ModuleLowPwr)\n"); + break; + case CMIS_MODULE_STATE_MODULE_PWR_UP: + printf(" (ModulePwrUp)\n"); + break; + case CMIS_MODULE_STATE_MODULE_READY: + printf(" (ModuleReady)\n"); + break; + case CMIS_MODULE_STATE_MODULE_PWR_DN: + printf(" (ModulePwrDn)\n"); + break; + case CMIS_MODULE_STATE_MODULE_FAULT: + printf(" (ModuleFault)\n"); + break; + default: + printf(" (reserved or unknown)\n"); + break; + } +} + +/* Print the Module Fault Information. Relevant documents: + * [1] CMIS Rev. 5, pag. 64, section 6.3.2.12 + * [2] CMIS Rev. 5, pag. 115, section 8.2.10, Table 8-15 + */ +static void cmis_show_mod_fault_cause(const struct cmis_memory_map *map) +{ + __u8 mod_state, fault_cause; + + mod_state = (map->lower_memory[CMIS_MODULE_STATE_OFFSET] & + CMIS_MODULE_STATE_MASK) >> 1; + if (mod_state != CMIS_MODULE_STATE_MODULE_FAULT) + return; + + fault_cause = map->lower_memory[CMIS_MODULE_FAULT_OFFSET]; + printf("\t%-41s : 0x%02x", "Module Fault Cause", fault_cause); + switch (fault_cause) { + case CMIS_MODULE_FAULT_NO_FAULT: + printf(" (No fault detected / not supported)\n"); + break; + case CMIS_MODULE_FAULT_TEC_RUNAWAY: + printf(" (TEC runaway)\n"); + break; + case CMIS_MODULE_FAULT_DATA_MEM_CORRUPTED: + printf(" (Data memory corrupted)\n"); + break; + case CMIS_MODULE_FAULT_PROG_MEM_CORRUPTED: + printf(" (Program memory corrupted)\n"); + break; + default: + printf(" (reserved or unknown)\n"); + break; + } +} + +/* Print the current Module-Level Controls. Relevant documents: + * [1] CMIS Rev. 5, pag. 58, section 6.3.2.2, Table 6-12 + * [2] CMIS Rev. 5, pag. 111, section 8.2.6, Table 8-10 + */ +static void cmis_show_mod_lvl_controls(const struct cmis_memory_map *map) +{ + printf("\t%-41s : ", "LowPwrAllowRequestHW"); + printf("%s\n", ONOFF(map->lower_memory[CMIS_MODULE_CONTROL_OFFSET] & + CMIS_LOW_PWR_ALLOW_REQUEST_HW_MASK)); + printf("\t%-41s : ", "LowPwrRequestSW"); + printf("%s\n", ONOFF(map->lower_memory[CMIS_MODULE_CONTROL_OFFSET] & + CMIS_LOW_PWR_REQUEST_SW_MASK)); +} + +static void cmis_parse_dom_power_type(const struct cmis_memory_map *map, + struct sff_diags *sd) +{ + sd->rx_power_type = map->page_01h[CMIS_DIAG_TYPE_OFFSET] & + CMIS_RX_PWR_TYPE_MASK; + sd->tx_power_type = map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] & + CMIS_TX_PWR_MON_MASK; +} + +static void cmis_parse_dom_mod_lvl_monitors(const struct cmis_memory_map *map, + struct sff_diags *sd) +{ + sd->sfp_voltage[MCURR] = OFFSET_TO_U16_PTR(map->lower_memory, + CMIS_CURR_VCC_OFFSET); + sd->sfp_temp[MCURR] = (__s16)OFFSET_TO_U16_PTR(map->lower_memory, + CMIS_CURR_TEMP_OFFSET); +} + +static void cmis_parse_dom_mod_lvl_thresh(const struct cmis_memory_map *map, + struct sff_diags *sd) +{ + /* Page is not present in IOCTL path. */ + if (!map->page_02h) + return; + sd->supports_alarms = 1; + + sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_VCC_HALRM_OFFSET); + sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_VCC_LALRM_OFFSET); + sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_VCC_HWARN_OFFSET); + sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_VCC_LWARN_OFFSET); + + sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TEMP_HALRM_OFFSET); + sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TEMP_LALRM_OFFSET); + sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TEMP_HWARN_OFFSET); + sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TEMP_LWARN_OFFSET); +} + +static __u8 cmis_tx_bias_mul(const struct cmis_memory_map *map) +{ + switch (map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] & + CMIS_TX_BIAS_MUL_MASK) { + case CMIS_TX_BIAS_MUL_1: + return 0; + case CMIS_TX_BIAS_MUL_2: + return 1; + case CMIS_TX_BIAS_MUL_4: + return 2; + } + + return 0; +} + +static void +cmis_parse_dom_chan_lvl_monitors_bank(const struct cmis_memory_map *map, + struct sff_diags *sd, int bank) +{ + const __u8 *page_11h = map->upper_memory[bank][0x11]; + int i; + + if (!page_11h) + return; + + for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) { + __u8 tx_bias_offset, rx_power_offset, tx_power_offset; + int chan = bank * CMIS_CHANNELS_PER_BANK + i; + __u8 bias_mul = cmis_tx_bias_mul(map); + + tx_bias_offset = CMIS_TX_BIAS_OFFSET + i * sizeof(__u16); + rx_power_offset = CMIS_RX_PWR_OFFSET + i * sizeof(__u16); + tx_power_offset = CMIS_TX_PWR_OFFSET + i * sizeof(__u16); + + sd->scd[chan].bias_cur = OFFSET_TO_U16_PTR(page_11h, + tx_bias_offset); + sd->scd[chan].bias_cur >>= bias_mul; + sd->scd[chan].rx_power = OFFSET_TO_U16_PTR(page_11h, + rx_power_offset); + sd->scd[chan].tx_power = OFFSET_TO_U16_PTR(page_11h, + tx_power_offset); + } +} + +static void cmis_parse_dom_chan_lvl_monitors(const struct cmis_memory_map *map, + struct sff_diags *sd) +{ + int i; + + for (i = 0; i < CMIS_MAX_BANKS; i++) + cmis_parse_dom_chan_lvl_monitors_bank(map, sd, i); +} + +static void cmis_parse_dom_chan_lvl_thresh(const struct cmis_memory_map *map, + struct sff_diags *sd) +{ + __u8 bias_mul = cmis_tx_bias_mul(map); + + if (!map->page_02h) + return; + + sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TX_BIAS_HALRM_OFFSET); + sd->bias_cur[HALRM] >>= bias_mul; + sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TX_BIAS_LALRM_OFFSET); + sd->bias_cur[LALRM] >>= bias_mul; + sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TX_BIAS_HWARN_OFFSET); + sd->bias_cur[HWARN] >>= bias_mul; + sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TX_BIAS_LWARN_OFFSET); + sd->bias_cur[LWARN] >>= bias_mul; + + sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TX_PWR_HALRM_OFFSET); + sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TX_PWR_LALRM_OFFSET); + sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TX_PWR_HWARN_OFFSET); + sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_TX_PWR_LWARN_OFFSET); + + sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_RX_PWR_HALRM_OFFSET); + sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_RX_PWR_LALRM_OFFSET); + sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_RX_PWR_HWARN_OFFSET); + sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_02h, + CMIS_RX_PWR_LWARN_OFFSET); +} + +static void cmis_parse_dom(const struct cmis_memory_map *map, + struct sff_diags *sd) +{ + cmis_parse_dom_power_type(map, sd); + cmis_parse_dom_mod_lvl_monitors(map, sd); + cmis_parse_dom_mod_lvl_thresh(map, sd); + cmis_parse_dom_chan_lvl_monitors(map, sd); + cmis_parse_dom_chan_lvl_thresh(map, sd); +} + +/* Print module-level monitoring values. Relevant documents: + * [1] CMIS Rev. 5, page 110, section 8.2.5, Table 8-9 + */ +static void cmis_show_dom_mod_lvl_monitors(const struct sff_diags *sd) +{ + PRINT_TEMP("Module temperature", sd->sfp_temp[MCURR]); + PRINT_VCC("Module voltage", sd->sfp_voltage[MCURR]); +} + +/* Print channel Tx laser bias current. Relevant documents: + * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79 + */ +static void +cmis_show_dom_chan_lvl_tx_bias_bank(const struct cmis_memory_map *map, + const struct sff_diags *sd, int bank) +{ + const __u8 *page_11h = map->upper_memory[bank][0x11]; + int i; + + if (!page_11h) + return; + + for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) { + int chan = bank * CMIS_CHANNELS_PER_BANK + i; + char fmt_str[80]; + + snprintf(fmt_str, 80, "%s (Channel %d)", + "Laser tx bias current", chan + 1); + PRINT_BIAS(fmt_str, sd->scd[chan].bias_cur); + } +} + +static void cmis_show_dom_chan_lvl_tx_bias(const struct cmis_memory_map *map, + const struct sff_diags *sd) +{ + int i; + + if(!(map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] & + CMIS_TX_BIAS_MON_MASK)) + return; + + for (i = 0; i < CMIS_MAX_BANKS; i++) + cmis_show_dom_chan_lvl_tx_bias_bank(map, sd, i); +} + +/* Print channel Tx average optical power. Relevant documents: + * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79 + */ +static void +cmis_show_dom_chan_lvl_tx_power_bank(const struct cmis_memory_map *map, + const struct sff_diags *sd, int bank) +{ + const __u8 *page_11h = map->upper_memory[bank][0x11]; + int i; + + if (!page_11h) + return; + + for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) { + int chan = bank * CMIS_CHANNELS_PER_BANK + i; + char fmt_str[80]; + + snprintf(fmt_str, 80, "%s (Channel %d)", + "Transmit avg optical power", chan + 1); + PRINT_xX_PWR(fmt_str, sd->scd[chan].tx_power); + } +} + +static void cmis_show_dom_chan_lvl_tx_power(const struct cmis_memory_map *map, + const struct sff_diags *sd) +{ + int i; + + if (!sd->tx_power_type) + return; + + for (i = 0; i < CMIS_MAX_BANKS; i++) + cmis_show_dom_chan_lvl_tx_power_bank(map, sd, i); +} + +/* Print channel Rx input optical power. Relevant documents: + * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79 + */ +static void +cmis_show_dom_chan_lvl_rx_power_bank(const struct cmis_memory_map *map, + const struct sff_diags *sd, int bank) +{ + const __u8 *page_11h = map->upper_memory[bank][0x11]; + int i; + + if (!page_11h) + return; + + for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) { + int chan = bank * CMIS_CHANNELS_PER_BANK + i; + char *rx_power_str; + char fmt_str[80]; + + if (!sd->rx_power_type) + rx_power_str = "Receiver signal OMA"; + else + rx_power_str = "Rcvr signal avg optical power"; + + snprintf(fmt_str, 80, "%s (Channel %d)", rx_power_str, + chan + 1); + PRINT_xX_PWR(fmt_str, sd->scd[chan].rx_power); + } +} + +static void cmis_show_dom_chan_lvl_rx_power(const struct cmis_memory_map *map, + const struct sff_diags *sd) +{ + int i; + + if(!(map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] & CMIS_RX_PWR_MON_MASK)) + return; + + for (i = 0; i < CMIS_MAX_BANKS; i++) + cmis_show_dom_chan_lvl_rx_power_bank(map, sd, i); +} + +static void cmis_show_dom_chan_lvl_monitors(const struct cmis_memory_map *map, + const struct sff_diags *sd) +{ + cmis_show_dom_chan_lvl_tx_bias(map, sd); + cmis_show_dom_chan_lvl_tx_power(map, sd); + cmis_show_dom_chan_lvl_rx_power(map, sd); +} + +/* Print module-level flags. Relevant documents: + * [1] CMIS Rev. 5, page 109, section 8.2.4, Table 8-8 + */ +static void cmis_show_dom_mod_lvl_flags(const struct cmis_memory_map *map) +{ + int i; + + for (i = 0; cmis_aw_mod_flags[i].str; i++) { + printf("\t%-41s : %s\n", cmis_aw_mod_flags[i].str, + map->lower_memory[cmis_aw_mod_flags[i].offset] & + cmis_aw_mod_flags[i].value ? "On" : "Off"); + } +} + +/* Print channel-level flags. Relevant documents: + * [1] CMIS Rev. 5, page 162, section 8.9.3, Table 8-77 + * [1] CMIS Rev. 5, page 164, section 8.9.3, Table 8-78 + */ +static void cmis_show_dom_chan_lvl_flags_chan(const struct cmis_memory_map *map, + int bank, int chan) +{ + const __u8 *page_11h = map->upper_memory[bank][0x11]; + int i; + + for (i = 0; cmis_aw_chan_flags[i].fmt_str; i++) { + char str[80]; + + if (!(map->page_01h[cmis_aw_chan_flags[i].adver_offset] & + cmis_aw_chan_flags[i].adver_value)) + continue; + + snprintf(str, 80, cmis_aw_chan_flags[i].fmt_str, chan + 1); + printf("\t%-41s : %s\n", str, + page_11h[cmis_aw_chan_flags[i].offset] & chan ? + "On" : "Off"); + } +} + +static void +cmis_show_dom_chan_lvl_flags_bank(const struct cmis_memory_map *map, + int bank) +{ + const __u8 *page_11h = map->upper_memory[bank][0x11]; + int i; + + if (!page_11h) + return; + + for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) { + int chan = bank * CMIS_CHANNELS_PER_BANK + i; + + cmis_show_dom_chan_lvl_flags_chan(map, bank, chan); + } +} + +static void cmis_show_dom_chan_lvl_flags(const struct cmis_memory_map *map) +{ + int i; + + for (i = 0; i < CMIS_MAX_BANKS; i++) + cmis_show_dom_chan_lvl_flags_bank(map, i); +} + + +static void cmis_show_dom(const struct cmis_memory_map *map) +{ + struct sff_diags sd = {}; + + /* Diagnostic information is only relevant when the module memory + * model is paged and not flat. + */ + if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] & + CMIS_MEMORY_MODEL_MASK) + return; + + cmis_parse_dom(map, &sd); + + cmis_show_dom_mod_lvl_monitors(&sd); + cmis_show_dom_chan_lvl_monitors(map, &sd); + cmis_show_dom_mod_lvl_flags(map); + cmis_show_dom_chan_lvl_flags(map); + if (sd.supports_alarms) + sff_show_thresholds(sd); +} + +static void cmis_show_all_common(const struct cmis_memory_map *map) +{ + cmis_show_identifier(map); + cmis_show_power_info(map); + cmis_show_connector(map); + cmis_show_cbl_asm_len(map); + cmis_show_sig_integrity(map); + cmis_show_mit_compliance(map); + cmis_show_link_len(map); + cmis_show_vendor_info(map); + cmis_show_rev_compliance(map); + cmis_show_mod_state(map); + cmis_show_mod_fault_cause(map); + cmis_show_mod_lvl_controls(map); + cmis_show_dom(map); +} + +static void cmis_memory_map_init_buf(struct cmis_memory_map *map, + const __u8 *id) +{ + /* Lower Memory and Page 00h are always present. + * + * Offset into Upper Memory is between page size and twice the page + * size. Therefore, set the base address of each page to base address + * plus page size multiplied by the page number. + */ + map->lower_memory = id; + map->page_00h = id; + + /* Page 01h is only present when the module memory model is paged and + * not flat. + */ + if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] & + CMIS_MEMORY_MODEL_MASK) + return; + + map->page_01h = id + CMIS_PAGE_SIZE; +} + +void cmis_show_all_ioctl(const __u8 *id) +{ + struct cmis_memory_map map = {}; + + cmis_memory_map_init_buf(&map, id); + cmis_show_all_common(&map); +} + +static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank, + u8 page, u32 offset) +{ + request->offset = offset; + request->length = CMIS_PAGE_SIZE; + request->page = page; + request->bank = bank; + request->i2c_address = CMIS_I2C_ADDRESS; + request->data = NULL; +} + +static int cmis_num_banks_get(const struct cmis_memory_map *map, + int *p_num_banks) +{ + switch (map->page_01h[CMIS_PAGES_ADVER_OFFSET] & + CMIS_BANKS_SUPPORTED_MASK) { + case CMIS_BANK_0_SUPPORTED: + *p_num_banks = 1; + break; + case CMIS_BANK_0_1_SUPPORTED: + *p_num_banks = 2; + break; + case CMIS_BANK_0_3_SUPPORTED: + *p_num_banks = 4; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int +cmis_memory_map_init_pages(struct cmd_context *ctx, + struct cmis_memory_map *map) +{ + struct ethtool_module_eeprom request; + int num_banks, i, ret; + + /* Lower Memory and Page 00h are always present. + * + * Offset into Upper Memory is between page size and twice the page + * size. Therefore, set the base address of each page to its base + * address minus page size. + */ + cmis_request_init(&request, 0, 0x0, 0); + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + map->lower_memory = request.data; + + cmis_request_init(&request, 0, 0x0, CMIS_PAGE_SIZE); + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + map->page_00h = request.data - CMIS_PAGE_SIZE; + + /* Pages 01h and 02h are only present when the module memory model is + * paged and not flat. + */ + if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] & + CMIS_MEMORY_MODEL_MASK) + return 0; + + cmis_request_init(&request, 0, 0x1, CMIS_PAGE_SIZE); + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + map->page_01h = request.data - CMIS_PAGE_SIZE; + + cmis_request_init(&request, 0, 0x2, CMIS_PAGE_SIZE); + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + map->page_02h = request.data - CMIS_PAGE_SIZE; + + /* Bank 0 of Page 11h provides lane-specific registers for the first 8 + * lanes, and each additional Banks provides support for an additional + * 8 lanes. Only initialize supported Banks. + */ + ret = cmis_num_banks_get(map, &num_banks); + if (ret < 0) + return ret; + + for (i = 0; i < num_banks; i++) { + cmis_request_init(&request, i, 0x11, CMIS_PAGE_SIZE); + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + map->upper_memory[i][0x11] = request.data - CMIS_PAGE_SIZE; + } + + return 0; +} + +int cmis_show_all_nl(struct cmd_context *ctx) +{ + struct cmis_memory_map map = {}; + int ret; + + ret = cmis_memory_map_init_pages(ctx, &map); + if (ret < 0) + return ret; + cmis_show_all_common(&map); + + return 0; +} diff --git a/cmis.h b/cmis.h new file mode 100644 index 0000000..4679708 --- /dev/null +++ b/cmis.h @@ -0,0 +1,235 @@ +#ifndef CMIS_H__ +#define CMIS_H__ + +/* Identifier and revision compliance (Page 0) */ +#define CMIS_ID_OFFSET 0x00 +#define CMIS_REV_COMPLIANCE_OFFSET 0x01 +#define CMIS_MEMORY_MODEL_OFFSET 0x02 +#define CMIS_MEMORY_MODEL_MASK 0x80 + +/* Global Status Information (Page 0) */ +#define CMIS_MODULE_STATE_OFFSET 0x03 +#define CMIS_MODULE_STATE_MASK 0x0E +#define CMIS_MODULE_STATE_MODULE_LOW_PWR 0x01 +#define CMIS_MODULE_STATE_MODULE_PWR_UP 0x02 +#define CMIS_MODULE_STATE_MODULE_READY 0x03 +#define CMIS_MODULE_STATE_MODULE_PWR_DN 0x04 +#define CMIS_MODULE_STATE_MODULE_FAULT 0x05 + +/* Module Flags (Page 0) */ +#define CMIS_VCC_AW_OFFSET 0x09 +#define CMIS_VCC_LWARN_STATUS 0x80 +#define CMIS_VCC_HWARN_STATUS 0x40 +#define CMIS_VCC_LALARM_STATUS 0x20 +#define CMIS_VCC_HALARM_STATUS 0x10 +#define CMIS_TEMP_AW_OFFSET 0x09 +#define CMIS_TEMP_LWARN_STATUS 0x08 +#define CMIS_TEMP_HWARN_STATUS 0x04 +#define CMIS_TEMP_LALARM_STATUS 0x02 +#define CMIS_TEMP_HALARM_STATUS 0x01 + +#define CMIS_MODULE_TYPE_OFFSET 0x55 +#define CMIS_MT_MMF 0x01 +#define CMIS_MT_SMF 0x02 + +/* Module-Level Monitors (Page 0) */ +#define CMIS_CURR_TEMP_OFFSET 0x0E +#define CMIS_CURR_VCC_OFFSET 0x10 + +/* Module Global Controls (Page 0) */ +#define CMIS_MODULE_CONTROL_OFFSET 0x1A +#define CMIS_LOW_PWR_ALLOW_REQUEST_HW_MASK 0x40 +#define CMIS_LOW_PWR_REQUEST_SW_MASK 0x10 + +/* Module Fault Information (Page 0) */ +#define CMIS_MODULE_FAULT_OFFSET 0x29 +#define CMIS_MODULE_FAULT_NO_FAULT 0x00 +#define CMIS_MODULE_FAULT_TEC_RUNAWAY 0x01 +#define CMIS_MODULE_FAULT_DATA_MEM_CORRUPTED 0x02 +#define CMIS_MODULE_FAULT_PROG_MEM_CORRUPTED 0x03 + +#define CMIS_CTOR_OFFSET 0xCB + +/* Vendor related information (Page 0) */ +#define CMIS_VENDOR_NAME_START_OFFSET 0x81 +#define CMIS_VENDOR_NAME_END_OFFSET 0x90 + +#define CMIS_VENDOR_OUI_OFFSET 0x91 + +#define CMIS_VENDOR_PN_START_OFFSET 0x94 +#define CMIS_VENDOR_PN_END_OFFSET 0xA3 + +#define CMIS_VENDOR_REV_START_OFFSET 0xA4 +#define CMIS_VENDOR_REV_END_OFFSET 0xA5 + +#define CMIS_VENDOR_SN_START_OFFSET 0xA6 +#define CMIS_VENDOR_SN_END_OFFSET 0xB5 + +#define CMIS_DATE_YEAR_OFFSET 0xB6 +#define CMIS_DATE_VENDOR_LOT_OFFSET 0xBC + +/* CLEI Code (Page 0) */ +#define CMIS_CLEI_START_OFFSET 0xBE +#define CMIS_CLEI_END_OFFSET 0xC7 +#define CMIS_CLEI_BLANK " " +#define CMIS_CLEI_LEN 0x0A + +/* Cable assembly length */ +#define CMIS_CBL_ASM_LEN_OFFSET 0xCA +#define CMIS_6300M_MAX_LEN 0xFF + +/* Cable length with multiplier */ +#define CMIS_MULTIPLIER_00 0x00 +#define CMIS_MULTIPLIER_01 0x40 +#define CMIS_MULTIPLIER_10 0x80 +#define CMIS_MULTIPLIER_11 0xC0 +#define CMIS_LEN_MUL_MASK 0xC0 +#define CMIS_LEN_VAL_MASK 0x3F + +/* Module power characteristics */ +#define CMIS_PWR_CLASS_OFFSET 0xC8 +#define CMIS_PWR_MAX_POWER_OFFSET 0xC9 +#define CMIS_PWR_CLASS_MASK 0xE0 +#define CMIS_PWR_CLASS_1 0x00 +#define CMIS_PWR_CLASS_2 0x01 +#define CMIS_PWR_CLASS_3 0x02 +#define CMIS_PWR_CLASS_4 0x03 +#define CMIS_PWR_CLASS_5 0x04 +#define CMIS_PWR_CLASS_6 0x05 +#define CMIS_PWR_CLASS_7 0x06 +#define CMIS_PWR_CLASS_8 0x07 + +/* Copper cable attenuation */ +#define CMIS_COPPER_ATT_5GHZ 0xCC +#define CMIS_COPPER_ATT_7GHZ 0xCD +#define CMIS_COPPER_ATT_12P9GHZ 0xCE +#define CMIS_COPPER_ATT_25P8GHZ 0xCF + +/* Cable assembly lane */ +#define CMIS_CABLE_ASM_NEAR_END_OFFSET 0xD2 +#define CMIS_CABLE_ASM_FAR_END_OFFSET 0xD3 + +/* Media interface technology */ +#define CMIS_MEDIA_INTF_TECH_OFFSET 0xD4 +#define CMIS_850_VCSEL 0x00 +#define CMIS_1310_VCSEL 0x01 +#define CMIS_1550_VCSEL 0x02 +#define CMIS_1310_FP 0x03 +#define CMIS_1310_DFB 0x04 +#define CMIS_1550_DFB 0x05 +#define CMIS_1310_EML 0x06 +#define CMIS_1550_EML 0x07 +#define CMIS_OTHERS 0x08 +#define CMIS_1490_DFB 0x09 +#define CMIS_COPPER_UNEQUAL 0x0A +#define CMIS_COPPER_PASS_EQUAL 0x0B +#define CMIS_COPPER_NF_EQUAL 0x0C +#define CMIS_COPPER_F_EQUAL 0x0D +#define CMIS_COPPER_N_EQUAL 0x0E +#define CMIS_COPPER_LINEAR_EQUAL 0x0F + +/*----------------------------------------------------------------------- + * Upper Memory Page 0x01: contains advertising fields that define properties + * that are unique to active modules and cable assemblies. + * GlobalOffset = 2 * 0x80 + LocalOffset + */ + +/* Supported Link Length (Page 1) */ +#define CMIS_SMF_LEN_OFFSET 0x84 +#define CMIS_OM5_LEN_OFFSET 0x85 +#define CMIS_OM4_LEN_OFFSET 0x86 +#define CMIS_OM3_LEN_OFFSET 0x87 +#define CMIS_OM2_LEN_OFFSET 0x88 + +/* Wavelength (Page 1) */ +#define CMIS_NOM_WAVELENGTH_MSB 0x8A +#define CMIS_NOM_WAVELENGTH_LSB 0x8B +#define CMIS_WAVELENGTH_TOL_MSB 0x8C +#define CMIS_WAVELENGTH_TOL_LSB 0x8D + +/* Supported Pages Advertising (Page 1) */ +#define CMIS_PAGES_ADVER_OFFSET 0x8E +#define CMIS_BANKS_SUPPORTED_MASK 0x03 +#define CMIS_BANK_0_SUPPORTED 0x00 +#define CMIS_BANK_0_1_SUPPORTED 0x01 +#define CMIS_BANK_0_3_SUPPORTED 0x02 + +/* Module Characteristics Advertising (Page 1) */ +#define CMIS_DIAG_TYPE_OFFSET 0x97 +#define CMIS_RX_PWR_TYPE_MASK 0x10 + +/* Supported Monitors Advertisement (Page 1) */ +#define CMIS_DIAG_CHAN_ADVER_OFFSET 0xA0 +#define CMIS_TX_BIAS_MON_MASK 0x01 +#define CMIS_TX_PWR_MON_MASK 0x02 +#define CMIS_RX_PWR_MON_MASK 0x04 +#define CMIS_TX_BIAS_MUL_MASK 0x18 +#define CMIS_TX_BIAS_MUL_1 0x00 +#define CMIS_TX_BIAS_MUL_2 0x08 +#define CMIS_TX_BIAS_MUL_4 0x10 + +/* Signal integrity controls */ +#define CMIS_SIG_INTEG_TX_OFFSET 0xA1 +#define CMIS_SIG_INTEG_RX_OFFSET 0xA2 + +/*----------------------------------------------------------------------- + * Upper Memory Page 0x02: Optional Page that informs about module-defined + * thresholds for module-level and lane-specific threshold crossing monitors. + */ + +/* Module-Level Monitor Thresholds (Page 2) */ +#define CMIS_TEMP_HALRM_OFFSET 0x80 +#define CMIS_TEMP_LALRM_OFFSET 0x82 +#define CMIS_TEMP_HWARN_OFFSET 0x84 +#define CMIS_TEMP_LWARN_OFFSET 0x86 +#define CMIS_VCC_HALRM_OFFSET 0x88 +#define CMIS_VCC_LALRM_OFFSET 0x8A +#define CMIS_VCC_HWARN_OFFSET 0x8C +#define CMIS_VCC_LWARN_OFFSET 0x8E + +/* Lane-Related Monitor Thresholds (Page 2) */ +#define CMIS_TX_PWR_HALRM_OFFSET 0xB0 +#define CMIS_TX_PWR_LALRM_OFFSET 0xB2 +#define CMIS_TX_PWR_HWARN_OFFSET 0xB4 +#define CMIS_TX_PWR_LWARN_OFFSET 0xB6 +#define CMIS_TX_BIAS_HALRM_OFFSET 0xB8 +#define CMIS_TX_BIAS_LALRM_OFFSET 0xBA +#define CMIS_TX_BIAS_HWARN_OFFSET 0xBC +#define CMIS_TX_BIAS_LWARN_OFFSET 0xBE +#define CMIS_RX_PWR_HALRM_OFFSET 0xC0 +#define CMIS_RX_PWR_LALRM_OFFSET 0xC2 +#define CMIS_RX_PWR_HWARN_OFFSET 0xC4 +#define CMIS_RX_PWR_LWARN_OFFSET 0xC6 + +/*----------------------------------------------------------------------- + * Upper Memory Page 0x11: Optional Page that contains lane dynamic status + * bytes. + */ + +/* Media Lane-Specific Flags (Page 0x11) */ +#define CMIS_TX_PWR_AW_HALARM_OFFSET 0x8B +#define CMIS_TX_PWR_AW_LALARM_OFFSET 0x8C +#define CMIS_TX_PWR_AW_HWARN_OFFSET 0x8D +#define CMIS_TX_PWR_AW_LWARN_OFFSET 0x8E +#define CMIS_TX_BIAS_AW_HALARM_OFFSET 0x8F +#define CMIS_TX_BIAS_AW_LALARM_OFFSET 0x90 +#define CMIS_TX_BIAS_AW_HWARN_OFFSET 0x91 +#define CMIS_TX_BIAS_AW_LWARN_OFFSET 0x92 +#define CMIS_RX_PWR_AW_HALARM_OFFSET 0x95 +#define CMIS_RX_PWR_AW_LALARM_OFFSET 0x96 +#define CMIS_RX_PWR_AW_HWARN_OFFSET 0x97 +#define CMIS_RX_PWR_AW_LWARN_OFFSET 0x98 + +/* Media Lane-Specific Monitors (Page 0x11) */ +#define CMIS_TX_PWR_OFFSET 0x9A +#define CMIS_TX_BIAS_OFFSET 0xAA +#define CMIS_RX_PWR_OFFSET 0xBA + +#define YESNO(x) (((x) != 0) ? "Yes" : "No") +#define ONOFF(x) (((x) != 0) ? "On" : "Off") + +void cmis_show_all_ioctl(const __u8 *id); + +int cmis_show_all_nl(struct cmd_context *ctx); + +#endif /* CMIS_H__ */ diff --git a/common.c b/common.c new file mode 100644 index 0000000..2630e73 --- /dev/null +++ b/common.c @@ -0,0 +1,175 @@ +/* + * common.h - common code header + * + * Data and functions shared by ioctl and netlink implementation. + */ + +#include "internal.h" +#include "common.h" + +#ifndef HAVE_NETIF_MSG +enum { + NETIF_MSG_DRV = 0x0001, + NETIF_MSG_PROBE = 0x0002, + NETIF_MSG_LINK = 0x0004, + NETIF_MSG_TIMER = 0x0008, + NETIF_MSG_IFDOWN = 0x0010, + NETIF_MSG_IFUP = 0x0020, + NETIF_MSG_RX_ERR = 0x0040, + NETIF_MSG_TX_ERR = 0x0080, + NETIF_MSG_TX_QUEUED = 0x0100, + NETIF_MSG_INTR = 0x0200, + NETIF_MSG_TX_DONE = 0x0400, + NETIF_MSG_RX_STATUS = 0x0800, + NETIF_MSG_PKTDATA = 0x1000, + NETIF_MSG_HW = 0x2000, + NETIF_MSG_WOL = 0x4000, +}; +#endif + +const struct flag_info flags_msglvl[] = { + { "drv", NETIF_MSG_DRV }, + { "probe", NETIF_MSG_PROBE }, + { "link", NETIF_MSG_LINK }, + { "timer", NETIF_MSG_TIMER }, + { "ifdown", NETIF_MSG_IFDOWN }, + { "ifup", NETIF_MSG_IFUP }, + { "rx_err", NETIF_MSG_RX_ERR }, + { "tx_err", NETIF_MSG_TX_ERR }, + { "tx_queued", NETIF_MSG_TX_QUEUED }, + { "intr", NETIF_MSG_INTR }, + { "tx_done", NETIF_MSG_TX_DONE }, + { "rx_status", NETIF_MSG_RX_STATUS }, + { "pktdata", NETIF_MSG_PKTDATA }, + { "hw", NETIF_MSG_HW }, + { "wol", NETIF_MSG_WOL }, + {} +}; +const unsigned int n_flags_msglvl = ARRAY_SIZE(flags_msglvl) - 1; + +const struct off_flag_def off_flag_def[] = { + { "rx", "rx-checksumming", "rx-checksum", + ETHTOOL_GRXCSUM, ETHTOOL_SRXCSUM, ETH_FLAG_RXCSUM, 0 }, + { "tx", "tx-checksumming", "tx-checksum-*", + ETHTOOL_GTXCSUM, ETHTOOL_STXCSUM, ETH_FLAG_TXCSUM, 0 }, + { "sg", "scatter-gather", "tx-scatter-gather*", + ETHTOOL_GSG, ETHTOOL_SSG, ETH_FLAG_SG, 0 }, + { "tso", "tcp-segmentation-offload", "tx-tcp*-segmentation", + ETHTOOL_GTSO, ETHTOOL_STSO, ETH_FLAG_TSO, 0 }, + { "ufo", "udp-fragmentation-offload", "tx-udp-fragmentation", + ETHTOOL_GUFO, ETHTOOL_SUFO, ETH_FLAG_UFO, 0 }, + { "gso", "generic-segmentation-offload", "tx-generic-segmentation", + ETHTOOL_GGSO, ETHTOOL_SGSO, ETH_FLAG_GSO, 0 }, + { "gro", "generic-receive-offload", "rx-gro", + ETHTOOL_GGRO, ETHTOOL_SGRO, ETH_FLAG_GRO, 0 }, + { "lro", "large-receive-offload", "rx-lro", + 0, 0, ETH_FLAG_LRO, + KERNEL_VERSION(2,6,24) }, + { "rxvlan", "rx-vlan-offload", "rx-vlan-hw-parse", + 0, 0, ETH_FLAG_RXVLAN, + KERNEL_VERSION(2,6,37) }, + { "txvlan", "tx-vlan-offload", "tx-vlan-hw-insert", + 0, 0, ETH_FLAG_TXVLAN, + KERNEL_VERSION(2,6,37) }, + { "ntuple", "ntuple-filters", "rx-ntuple-filter", + 0, 0, ETH_FLAG_NTUPLE, 0 }, + { "rxhash", "receive-hashing", "rx-hashing", + 0, 0, ETH_FLAG_RXHASH, 0 }, +}; + +void print_flags(const struct flag_info *info, unsigned int n_info, u32 value) +{ + const char *sep = ""; + + while (n_info) { + if (value & info->value) { + printf("%s%s", sep, info->name); + sep = " "; + value &= ~info->value; + } + ++info; + --n_info; + } + + /* Print any unrecognised flags in hex */ + if (value) + printf("%s%#x", sep, value); +} + +static char *unparse_wolopts(int wolopts) +{ + static char buf[16]; + char *p = buf; + + memset(buf, 0, sizeof(buf)); + + if (wolopts) { + if (wolopts & WAKE_PHY) + *p++ = 'p'; + if (wolopts & WAKE_UCAST) + *p++ = 'u'; + if (wolopts & WAKE_MCAST) + *p++ = 'm'; + if (wolopts & WAKE_BCAST) + *p++ = 'b'; + if (wolopts & WAKE_ARP) + *p++ = 'a'; + if (wolopts & WAKE_MAGIC) + *p++ = 'g'; + if (wolopts & WAKE_MAGICSECURE) + *p++ = 's'; + if (wolopts & WAKE_FILTER) + *p++ = 'f'; + } else { + *p = 'd'; + } + + return buf; +} + +int dump_wol(struct ethtool_wolinfo *wol) +{ + fprintf(stdout, " Supports Wake-on: %s\n", + unparse_wolopts(wol->supported)); + fprintf(stdout, " Wake-on: %s\n", + unparse_wolopts(wol->wolopts)); + if (wol->supported & WAKE_MAGICSECURE) { + int i; + int delim = 0; + + fprintf(stdout, " SecureOn password: "); + for (i = 0; i < SOPASS_MAX; i++) { + fprintf(stdout, "%s%02x", delim ? ":" : "", + wol->sopass[i]); + delim = 1; + } + fprintf(stdout, "\n"); + } + + return 0; +} + +void dump_mdix(u8 mdix, u8 mdix_ctrl) +{ + fprintf(stdout, " MDI-X: "); + if (mdix_ctrl == ETH_TP_MDI) { + fprintf(stdout, "off (forced)\n"); + } else if (mdix_ctrl == ETH_TP_MDI_X) { + fprintf(stdout, "on (forced)\n"); + } else { + switch (mdix) { + case ETH_TP_MDI: + fprintf(stdout, "off"); + break; + case ETH_TP_MDI_X: + fprintf(stdout, "on"); + break; + default: + fprintf(stdout, "Unknown"); + break; + } + if (mdix_ctrl == ETH_TP_MDI_AUTO) + fprintf(stdout, " (auto)"); + fprintf(stdout, "\n"); + } +} diff --git a/common.h b/common.h new file mode 100644 index 0000000..b74fdfa --- /dev/null +++ b/common.h @@ -0,0 +1,45 @@ +/* + * common.h - common code header + * + * Declarations for data and functions shared by ioctl and netlink code. + */ + +#ifndef ETHTOOL_COMMON_H__ +#define ETHTOOL_COMMON_H__ + +#include "internal.h" + +#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) + +struct flag_info { + const char *name; + u32 value; +}; + +extern const struct flag_info flags_msglvl[]; +extern const unsigned int n_flags_msglvl; + +struct off_flag_def { + const char *short_name; + const char *long_name; + const char *kernel_name; + u32 get_cmd, set_cmd; + u32 value; + /* For features exposed through ETHTOOL_GFLAGS, the oldest + * kernel version for which we can trust the result. Where + * the flag was added at the same time the kernel started + * supporting the feature, this is 0 (to allow for backports). + * Where the feature was supported before the flag was added, + * it is the version that introduced the flag. + */ + u32 min_kernel_ver; +}; + +#define OFF_FLAG_DEF_SIZE 12 +extern const struct off_flag_def off_flag_def[OFF_FLAG_DEF_SIZE]; + +void print_flags(const struct flag_info *info, unsigned int n_info, u32 value); +int dump_wol(struct ethtool_wolinfo *wol); +void dump_mdix(u8 mdix, u8 mdix_ctrl); + +#endif /* ETHTOOL_COMMON_H__ */ diff --git a/compile b/compile new file mode 100755 index 0000000..2ab71e4 --- /dev/null +++ b/compile @@ -0,0 +1,348 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2016-01-11.22; # UTC + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..5377ae2 --- /dev/null +++ b/configure @@ -0,0 +1,6050 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for ethtool 6.1. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: netdev@vger.kernel.org about your system, including any +$0: error possibly output before this message. Then install +$0: a modern shell, or manually run the script under such a +$0: shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='ethtool' +PACKAGE_TARNAME='ethtool' +PACKAGE_VERSION='6.1' +PACKAGE_STRING='ethtool 6.1' +PACKAGE_BUGREPORT='netdev@vger.kernel.org' +PACKAGE_URL='' + +ac_unique_file="ethtool.c" +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +ETHTOOL_ENABLE_NETLINK_FALSE +ETHTOOL_ENABLE_NETLINK_TRUE +MNL_LIBS +MNL_CFLAGS +ENABLE_BASH_COMPLETION_FALSE +ENABLE_BASH_COMPLETION_TRUE +BASH_COMPLETION_DIR +ETHTOOL_ENABLE_PRETTY_DUMP_FALSE +ETHTOOL_ENABLE_PRETTY_DUMP_TRUE +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_maintainer_mode +enable_dependency_tracking +enable_pretty_dump +with_bash_completion_dir +enable_netlink +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +MNL_CFLAGS +MNL_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures ethtool 6.1 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/ethtool] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ethtool 6.1:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-pretty-dump enable registers, EEPROM and SFP pretty dumps (enabled by default) + --enable-netlink enable netlink interface (enabled by default) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-bash-completion-dir=PATH + Install the bash-completion script in this + directory. [default=yes] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + MNL_CFLAGS C compiler flags for MNL, overriding pkg-config + MNL_LIBS linker flags for MNL, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +ethtool configure 6.1 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by ethtool $as_me 6.1, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +am__api_version='1.15' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='ethtool' + VERSION='6.1' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +ac_config_headers="$ac_config_headers ethtool-config.h" + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +if test $ac_cv_c_compiler_gnu = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 +$as_echo_n "checking whether $CC needs -traditional... " >&6; } +if ${ac_cv_prog_gcc_traditional+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_pattern="Autoconf.*'x'" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 +$as_echo "$ac_cv_prog_gcc_traditional" >&6; } + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + + + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether defines big-endian types" >&5 +$as_echo_n "checking whether defines big-endian types... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +__be16 foo;__be32 bar; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_BE_TYPES 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_func in socket strtol +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# Check whether --enable-pretty-dump was given. +if test "${enable_pretty_dump+set}" = set; then : + enableval=$enable_pretty_dump; +else + enable_pretty_dump=yes +fi + +if test x$enable_pretty_dump = xyes; then + +$as_echo "#define ETHTOOL_ENABLE_PRETTY_DUMP 1" >>confdefs.h + +fi + if test x$enable_pretty_dump = xyes; then + ETHTOOL_ENABLE_PRETTY_DUMP_TRUE= + ETHTOOL_ENABLE_PRETTY_DUMP_FALSE='#' +else + ETHTOOL_ENABLE_PRETTY_DUMP_TRUE='#' + ETHTOOL_ENABLE_PRETTY_DUMP_FALSE= +fi + + + +# Check whether --with-bash-completion-dir was given. +if test "${with_bash_completion_dir+set}" = set; then : + withval=$with_bash_completion_dir; +else + with_bash_completion_dir=yes +fi + +if test "x$with_bash_completion_dir" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bash-completion directory" >&5 +$as_echo_n "checking for bash-completion directory... " >&6; } + if test "x$PKG_CONFIG" != x \ + && bash_completion_prefix=`"$PKG_CONFIG" --print-errors --variable=prefix bash-completion 2>&5` \ + && bash_completion_dir=`"$PKG_CONFIG" --print-errors --variable=completionsdir bash-completion 2>&5`; then : + bash_completion_dir="${bash_completion_dir#"$bash_completion_prefix"}" + bash_completion_dir="${bash_completion_dir#/}" + BASH_COMPLETION_DIR='${prefix}'/"$bash_completion_dir" +else + BASH_COMPLETION_DIR='${datadir}/bash-completion/completions' +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BASH_COMPLETION_DIR" >&5 +$as_echo "$BASH_COMPLETION_DIR" >&6; } +else + BASH_COMPLETION_DIR="$with_bash_completion_dir" +fi + + if test "x$with_bash_completion_dir" != xno; then + ENABLE_BASH_COMPLETION_TRUE= + ENABLE_BASH_COMPLETION_FALSE='#' +else + ENABLE_BASH_COMPLETION_TRUE='#' + ENABLE_BASH_COMPLETION_FALSE= +fi + + +# Check whether --enable-netlink was given. +if test "${enable_netlink+set}" = set; then : + enableval=$enable_netlink; +else + enable_netlink=yes +fi + +if test x$enable_netlink = xyes; then + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5 +$as_echo_n "checking for libmnl... " >&6; } + +if test -n "$MNL_CFLAGS"; then + pkg_cv_MNL_CFLAGS="$MNL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmnl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmnl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_MNL_CFLAGS=`$PKG_CONFIG --cflags "libmnl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$MNL_LIBS"; then + pkg_cv_MNL_LIBS="$MNL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmnl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmnl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_MNL_LIBS=`$PKG_CONFIG --libs "libmnl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + MNL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmnl" 2>&1` + else + MNL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmnl" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$MNL_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libmnl) were not met: + +$MNL_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables MNL_CFLAGS +and MNL_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables MNL_CFLAGS +and MNL_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + MNL_CFLAGS=$pkg_cv_MNL_CFLAGS + MNL_LIBS=$pkg_cv_MNL_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +$as_echo "#define ETHTOOL_ENABLE_NETLINK 1" >>confdefs.h + +fi + if test x$enable_netlink = xyes; then + ETHTOOL_ENABLE_NETLINK_TRUE= + ETHTOOL_ENABLE_NETLINK_FALSE='#' +else + ETHTOOL_ENABLE_NETLINK_TRUE='#' + ETHTOOL_ENABLE_NETLINK_FALSE= +fi + + +ac_config_files="$ac_config_files Makefile ethtool.spec ethtool.8" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ETHTOOL_ENABLE_PRETTY_DUMP_TRUE}" && test -z "${ETHTOOL_ENABLE_PRETTY_DUMP_FALSE}"; then + as_fn_error $? "conditional \"ETHTOOL_ENABLE_PRETTY_DUMP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_BASH_COMPLETION_TRUE}" && test -z "${ENABLE_BASH_COMPLETION_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_BASH_COMPLETION\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ETHTOOL_ENABLE_NETLINK_TRUE}" && test -z "${ETHTOOL_ENABLE_NETLINK_FALSE}"; then + as_fn_error $? "conditional \"ETHTOOL_ENABLE_NETLINK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by ethtool $as_me 6.1, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +ethtool config.status 6.1 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "ethtool-config.h") CONFIG_HEADERS="$CONFIG_HEADERS ethtool-config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "ethtool.spec") CONFIG_FILES="$CONFIG_FILES ethtool.spec" ;; + "ethtool.8") CONFIG_FILES="$CONFIG_FILES ethtool.8" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..3eb4e7b --- /dev/null +++ b/configure.ac @@ -0,0 +1,82 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(ethtool, 6.1, netdev@vger.kernel.org) +AC_PREREQ(2.52) +AC_CONFIG_SRCDIR([ethtool.c]) +AM_INIT_AUTOMAKE([gnu subdir-objects]) +AC_CONFIG_HEADERS([ethtool-config.h]) + +AM_MAINTAINER_MODE + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_GCC_TRADITIONAL +AM_PROG_CC_C_O +PKG_PROG_PKG_CONFIG + +dnl Checks for libraries. + +dnl Checks for header files. + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_MSG_CHECKING([whether defines big-endian types]) +AC_TRY_COMPILE([#include ], + [__be16 foo;__be32 bar;], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_BE_TYPES], [1], + [Define to 1 if defines big-endian types])], + [AC_MSG_RESULT(no)]) + +dnl Checks for library functions. +AC_HEADER_STDC +AC_CHECK_FUNCS(socket strtol) + +dnl Check for options +AC_ARG_ENABLE(pretty-dump, + [ --enable-pretty-dump enable registers, EEPROM and SFP pretty dumps (enabled by default)], + , + enable_pretty_dump=yes) +if test x$enable_pretty_dump = xyes; then + AC_DEFINE(ETHTOOL_ENABLE_PRETTY_DUMP, 1, + [Define this to enable register, EEPROM and SFP pretty dumps.]) +fi +AM_CONDITIONAL([ETHTOOL_ENABLE_PRETTY_DUMP], [test x$enable_pretty_dump = xyes]) + +AC_ARG_WITH([bash-completion-dir], + AS_HELP_STRING([--with-bash-completion-dir[=PATH]], + [Install the bash-completion script in this directory. @<:@default=yes@:>@]), + [], + [with_bash_completion_dir=yes]) +AS_IF([test "x$with_bash_completion_dir" = xyes], + [AC_MSG_CHECKING([for bash-completion directory]) + dnl Attempt to use pkg-config completionsdir variable with given $prefix. + dnl This matches distcheck expectation that all files install to $prefix. + dnl It works with /usr and /usr/local (for default $XDG_DATA_DIRS) but + dnl may install to directory not used by bash-completion in other cases. + dnl See: https://lore.kernel.org/netdev/20190417025333.GA28674@kevinolos/ + AS_IF([test "x$PKG_CONFIG" != x \ + && bash_completion_prefix=`"$PKG_CONFIG" --print-errors --variable=prefix bash-completion 2>&AS_MESSAGE_LOG_FD` \ + && bash_completion_dir=`"$PKG_CONFIG" --print-errors --variable=completionsdir bash-completion 2>&AS_MESSAGE_LOG_FD`], + [bash_completion_dir="${bash_completion_dir#"$bash_completion_prefix"}" + bash_completion_dir="${bash_completion_dir#/}" + BASH_COMPLETION_DIR='${prefix}'/"$bash_completion_dir"], + [BASH_COMPLETION_DIR='${datadir}/bash-completion/completions']) + AC_MSG_RESULT([$BASH_COMPLETION_DIR])], + [BASH_COMPLETION_DIR="$with_bash_completion_dir"]) +AC_SUBST([BASH_COMPLETION_DIR]) +AM_CONDITIONAL([ENABLE_BASH_COMPLETION], + [test "x$with_bash_completion_dir" != xno]) + +AC_ARG_ENABLE(netlink, + [ --enable-netlink enable netlink interface (enabled by default)], + , + enable_netlink=yes) +if test x$enable_netlink = xyes; then + PKG_PROG_PKG_CONFIG + PKG_CHECK_MODULES([MNL], [libmnl]) + AC_DEFINE(ETHTOOL_ENABLE_NETLINK, 1, + Define this to support netlink interface to talk to kernel.) +fi +AM_CONDITIONAL([ETHTOOL_ENABLE_NETLINK], [test x$enable_netlink = xyes]) + +AC_CONFIG_FILES([Makefile ethtool.spec ethtool.8]) +AC_OUTPUT diff --git a/cpsw.c b/cpsw.c new file mode 100644 index 0000000..68dcfac --- /dev/null +++ b/cpsw.c @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Code to dump registers for TI CPSW switch devices. + * + * Copyright (c) 2022 Linutronix GmbH + * Author: Benedikt Spranger + */ + +#include +#include + +#include "internal.h" + +#define ALE_ENTRY_BITS 68 +#define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32) +#define ALE_ENTRY_BYTES (ALE_ENTRY_WORDS * 4) + +struct address_table_entry +{ + u8 port; + u8 reserved1; + u8 reserved2; + u8 reserved3; + u8 addr2; + u8 addr1; + u16 vlan; + u8 addr6; + u8 addr5; + u8 addr4; + u8 addr3; +} __attribute__((packed)); + +struct vlan_table_entry +{ + u8 reserved1; + u8 reserved2; + u8 reserved3; + u8 reserved4; + u8 reserved5; + u8 reserved6; + u16 vlan; + u8 member; + u8 mc_unreg; + u8 mc_reg; + u8 untag; +} __attribute__((packed)); + +union ale_entry { + struct address_table_entry addr; + struct vlan_table_entry vlan; + u32 val[3]; + u8 byte[12]; +}; + +enum entry_type { + FREE_ENTRY = 0, + ADDR_ENTRY, + VLAN_ENTRY, + VLAN_ADDR_ENTRY, + LAST_ENTRY +}; + +static char *fwd_state_name[] = { + "Forwarding", + "Blocking/Forwarding/Learning", + "Forwarding/Learning", + "Forwarding", +}; + +static char *type_name[] = { + "free entry", + "address entry", + "VLAN entry", + "VLAN address entry", + "invalid" +}; + +enum entry_type decode_type(union ale_entry *entry) +{ + /* Entry Type (61:60) */ + return (entry->byte[7] >> 4) & 0x3; +} + +static void print_addr(u8 *data) +{ + printf("%02x:%02x:%02x:%02x:%02x:%02x", + data[5], data[4], data[11], data[10], data[9], data[8]); +} + +static void decode_multi_addr(union ale_entry *entry, int vlan) +{ + printf(" MULTI: "); + print_addr(entry->byte); + printf(" %s", fwd_state_name[entry->addr.vlan >> 14]); + printf("%s", (entry->addr.port & 0x02) ? " Super" : ""); + printf(" Ports: 0x%x", (entry->addr.port >> 2) & 0x3); + if (vlan) + printf(" VLAN: %04d", entry->addr.vlan & 0x0fff); + printf("\n"); +} + +static void decode_uni_addr(union ale_entry *entry, int vlan) +{ + printf(" UNI : "); + print_addr(entry->byte); + printf("%s", (entry->addr.port & 0x01) ? " Secure" : ""); + printf("%s", (entry->addr.port & 0x02) ? " Block" : ""); + printf("%s", (entry->addr.port & 0x20) ? " DLR" : ""); + printf(" Ports: 0x%x", (entry->addr.port >> 2) & 0x3); + if (vlan) + printf(" VLAN: %04d", entry->addr.vlan & 0x0fff); + printf("\n"); +} + +static void decode_oui_addr(union ale_entry *entry) +{ + printf(" OUI : "); + print_addr(entry->byte); + printf("\n"); +} + +static void decode_vlan(union ale_entry *entry) +{ + printf(" VLAN "); + printf("%04d: ", entry->vlan.vlan & 0x0fff); + printf("member: 0x%x ", entry->vlan.member & 0x7); + printf("mc flood unreg: 0x%x ", entry->vlan.mc_unreg & 0x7); + printf("mc flood reg: 0x%x ", entry->vlan.mc_reg & 0x7); + printf("untag: 0x%x\n", entry->vlan.untag & 0x7); +} + +static enum entry_type decode_ale_entry(unsigned int idx, const u8 *data, + bool last_was_free) +{ + union ale_entry *entry = (union ale_entry *) data; + enum entry_type type; + + entry = entry + idx; + type = decode_type(entry); + + if (!last_was_free || type != FREE_ENTRY) + printf("%04d: %s\n", idx, type_name[type]); + + switch (type) + { + case FREE_ENTRY: + goto out; + break; + + case ADDR_ENTRY: + /* Multicast: OUI 01:00:5e:xx:xx:xx */ + if (entry->addr.addr1 == 0x01) + decode_multi_addr(entry, 0); + else + if ((entry->addr.vlan >> 14) == 0x2) + decode_oui_addr(entry); + else + decode_uni_addr(entry, 0); + break; + + case VLAN_ENTRY: + decode_vlan(entry); + break; + + case VLAN_ADDR_ENTRY: + /* Check for Individual/Group bit */ + if (entry->addr.addr1 & 0x01) + decode_multi_addr(entry, 1); + else + decode_uni_addr(entry, 1); + break; + + default: + printf("internal failure.\n"); + } + +out: + return type; +} + +int cpsw_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + unsigned int entries = regs->len/ALE_ENTRY_BYTES; + enum entry_type type = LAST_ENTRY; + unsigned int i; + + printf("ALE Entries (%d):\n", entries); + + for (i = 0; i < entries; i++) + type = decode_ale_entry(i, regs->data, (type == FREE_ENTRY)); + + return 0; +} diff --git a/de2104x.c b/de2104x.c new file mode 100644 index 0000000..190422f --- /dev/null +++ b/de2104x.c @@ -0,0 +1,783 @@ +/* Copyright 2001 Sun Microsystems (thockin@sun.com) */ +#include +#include "internal.h" + +static const char * const csr0_tap[4] = { + "No transmit automatic polling", + "Transmit automatic polling every 200 seconds", + "Transmit automatic polling every 800 seconds", + "Transmit automatic polling every 1.6 milliseconds", +}; + +static const char * const csr0_cache_al[4] = { + "not used", + "8-longword boundary alignment", + "16-longword boundary alignment", + "32-longword boundary alignment", +}; + +static const char * const csr5_buserr[8] = { + " Bus error: parity", + " Bus error: master abort", + " Bus error: target abort", + " Bus error: (unknown code, reserved)", + " Bus error: (unknown code, reserved)", + " Bus error: (unknown code, reserved)", + " Bus error: (unknown code, reserved)", + " Bus error: (unknown code, reserved)", +}; + +static const int csr6_tx_thresh[4] = { + 72, + 96, + 128, + 160, +}; + +static const char * const csr6_om[4] = { + "normal", + "internal loopback", + "external loopback", + "unknown (not used)", +}; + +static const char * const csr5_tx_state[8] = { + "stopped", + "running: fetch desc", + "running: wait xmit end", + "running: read buf", + "unknown (reserved)", + "running: setup packet", + "suspended", + "running: close desc", +}; + +static const char * const csr5_rx_state[8] = { + "stopped", + "running: fetch desc", + "running: chk pkt end", + "running: wait for pkt", + "suspended", + "running: close", + "running: flush", + "running: queue", +}; + +static const char * const csr12_nway_state[8] = { + "Autonegotiation disable", + "Transmit disable", + "Ability detect", + "Acknowledge detect", + "Complete acknowledge", + "FLP link good, nway complete", + "Link check", + "unknown (reserved)", +}; + +static const char * const csr14_tp_comp[4] = { + "Compensation Disabled Mode", + "Compensation Disabled Mode", + "High Power Mode", + "Normal Compensation Mode", +}; + +static void +print_ring_addresses(u32 csr3, u32 csr4) +{ + fprintf(stdout, + "0x18: CSR3 (Rx Ring Base Address) 0x%08x\n" + "0x20: CSR4 (Tx Ring Base Address) 0x%08x\n" + , + csr3, + csr4); +} + +static void +print_rx_missed(u32 csr8) +{ + fprintf(stdout, + "0x40: CSR8 (Missed Frames Counter) 0x%08x\n", csr8); + if (csr8 & (1 << 16)) + fprintf(stdout, + " Counter overflow\n"); + else { + unsigned int rx_missed = csr8 & 0xffff; + if (!rx_missed) + fprintf(stdout, + " No missed frames\n"); + else + fprintf(stdout, + " %u missed frames\n", rx_missed); + } +} + +static void de21040_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 tmp, v, *data = (u32 *)regs->data; + + fprintf(stdout, "21040 Registers\n"); + fprintf(stdout, "---------------\n"); + + /* + * CSR0 + */ + v = data[0]; + fprintf(stdout, + "0x00: CSR0 (Bus Mode) 0x%08x\n" + " %s\n" + " %s address space\n" + " Cache alignment: %s\n" + , + v, + csr0_tap[(v >> 17) & 3], + v & (1 << 16) ? "Diagnostic" : "Standard", + csr0_cache_al[(v >> 14) & 3]); + tmp = (v >> 8) & 0x3f; + if (tmp == 0) + fprintf(stdout, " Programmable burst length unlimited\n"); + else + fprintf(stdout, + " Programmable burst length %d longwords\n", + tmp); + fprintf(stdout, + " %s endian data buffers\n" + " Descriptor skip length %d longwords\n" + " %s bus arbitration scheme\n" + , + v & (1 << 7) ? "Big" : "Little", + (v >> 2) & 0x1f, + v & (1 << 1) ? "Round-robin" : "RX-has-priority"); + if (v & (1 << 0)) + fprintf(stdout, " Software reset asserted\n"); + + /* + * CSR3, 4 + */ + print_ring_addresses(data[3], data[4]); + + /* + * CSR5 + */ + v = data[5]; + fprintf(stdout, + "0x28: CSR5 (Status) 0x%08x\n" + "%s" + " Transmit process %s\n" + " Receive process %s\n" + " Link %s\n" + , + v, + v & (1 << 13) ? csr5_buserr[(v >> 23) & 0x7] : "", + csr5_tx_state[(v >> 20) & 0x7], + csr5_rx_state[(v >> 17) & 0x7], + v & (1 << 12) ? "fail" : "OK"); + if (v & (1 << 16)) + fprintf(stdout, + " Normal interrupts: %s%s%s\n" + , + v & (1 << 0) ? "TxOK " : "", + v & (1 << 2) ? "TxNoBufs " : "", + v & (1 << 6) ? "RxOK" : ""); + if (v & (1 << 15)) + fprintf(stdout, + " Abnormal intr: %s%s%s%s%s%s%s%s\n" + , + v & (1 << 1) ? "TxStop " : "", + v & (1 << 3) ? "TxJabber " : "", + v & (1 << 5) ? "TxUnder " : "", + v & (1 << 7) ? "RxNoBufs " : "", + v & (1 << 8) ? "RxStopped " : "", + v & (1 << 9) ? "RxTimeout " : "", + v & (1 << 10) ? "AUI_TP " : "", + v & (1 << 11) ? "FD_Short " : ""); + + /* + * CSR6 + */ + v = data[6]; + fprintf(stdout, + "0x30: CSR6 (Operating Mode) 0x%08x\n" + "%s" + "%s" + " Transmit threshold %d bytes\n" + " Transmit DMA %sabled\n" + "%s" + " Operating mode: %s\n" + " %s duplex\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + " Receive DMA %sabled\n" + " %s filtering mode\n" + , + v, + v & (1<<17) ? " Capture effect enabled\n" : "", + v & (1<<16) ? " Back pressure enabled\n" : "", + csr6_tx_thresh[(v >> 14) & 3], + v & (1<<13) ? "en" : "dis", + v & (1<<12) ? " Forcing collisions\n" : "", + csr6_om[(v >> 10) & 3], + v & (1<<9) ? "Full" : "Half", + v & (1<<8) ? " Flaky oscillator disable\n" : "", + v & (1<<7) ? " Pass All Multicast\n" : "", + v & (1<<6) ? " Promisc Mode\n" : "", + v & (1<<5) ? " Start/Stop Backoff Counter\n" : "", + v & (1<<4) ? " Inverse Filtering\n" : "", + v & (1<<3) ? " Pass Bad Frames\n" : "", + v & (1<<2) ? " Hash-only Filtering\n" : "", + v & (1<<1) ? "en" : "dis", + v & (1<<0) ? "Hash" : "Perfect"); + + /* + * CSR7 + */ + v = data[7]; + fprintf(stdout, + "0x38: CSR7 (Interrupt Mask) 0x%08x\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + , + v, + v & (1<<16) ? " Normal interrupt summary\n" : "", + v & (1<<15) ? " Abnormal interrupt summary\n" : "", + v & (1<<13) ? " System error\n" : "", + v & (1<<12) ? " Link fail\n" : "", + v & (1<<11) ? " Full duplex\n" : "", + v & (1<<10) ? " AUI_TP pin\n" : "", + v & (1<<9) ? " Receive watchdog timeout\n" : "", + v & (1<<8) ? " Receive stopped\n" : "", + v & (1<<7) ? " Receive buffer unavailable\n" : "", + v & (1<<6) ? " Receive interrupt\n" : "", + v & (1<<5) ? " Transmit underflow\n" : "", + v & (1<<3) ? " Transmit jabber timeout\n" : "", + v & (1<<2) ? " Transmit buffer unavailable\n" : "", + v & (1<<1) ? " Transmit stopped\n" : "", + v & (1<<0) ? " Transmit interrupt\n" : ""); + + /* + * CSR8 + */ + print_rx_missed(data[8]); + + /* + * CSR9 + */ + v = data[9]; + fprintf(stdout, + "0x48: CSR9 (Ethernet Address ROM) 0x%08x\n", v); + + /* + * CSR11 + */ + v = data[11]; + fprintf(stdout, + "0x58: CSR11 (Full Duplex Autoconfig) 0x%08x\n", v); + + /* + * CSR12 + */ + v = data[12]; + fprintf(stdout, + "0x60: CSR12 (SIA Status) 0x%08x\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + " AUI_TP pin: %s\n" + , + v, + v & (1<<7) ? " PLL sampler high\n" : "", + v & (1<<6) ? " PLL sampler low\n" : "", + v & (1<<5) ? " PLL self-test pass\n" : "", + v & (1<<4) ? " PLL self-test done\n" : "", + v & (1<<3) ? " Autopolarity state\n" : "", + v & (1<<2) ? " Link fail\n" : "", + v & (1<<1) ? " Network connection error\n" : "", + v & (1<<0) ? "AUI" : "TP"); + + /* + * CSR13 + */ + v = data[13]; + fprintf(stdout, + "0x68: CSR13 (SIA Connectivity) 0x%08x\n" + "%s" + "%s" + "%s" + "%s" + " External port output multiplexer select: %u%u%u%u\n" + "%s" + "%s" + "%s" + "%s" + " %s interface selected\n" + "%s" + "%s" + "%s" + , + v, + v & (1<<15) ? " Enable pins 5, 6, 7\n" : "", + v & (1<<14) ? " Enable pins 2, 4\n" : "", + v & (1<<13) ? " Enable pins 1, 3\n" : "", + v & (1<<12) ? " Input enable\n" : "", + v & (1<<11) ? 1 : 0, + v & (1<<10) ? 1 : 0, + v & (1<<9) ? 1 : 0, + v & (1<<8) ? 1 : 0, + v & (1<<7) ? " APLL start\n" : "", + v & (1<<6) ? " Serial interface input multiplexer\n" : "", + v & (1<<5) ? " Encoder input multiplexer\n" : "", + v & (1<<4) ? " SIA PLL external input enable\n" : "", + v & (1<<3) ? "AUI" : "10base-T", + v & (1<<2) ? " CSR autoconfiguration\n" : "", + v & (1<<1) ? " AUI_TP pin autoconfiguration\n" : "", + v & (1<<0) ? " SIA reset\n" : ""); + + /* + * CSR14 + */ + v = data[14]; + fprintf(stdout, + "0x70: CSR14 (SIA Transmit and Receive) 0x%08x\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + " %s\n" + "%s" + "%s" + "%s" + "%s" + , + v, + v & (1<<14) ? " Set polarity plus\n" : "", + v & (1<<13) ? " Autopolarity enable\n" : "", + v & (1<<12) ? " Link test enable\n" : "", + v & (1<<11) ? " Heartbeat enable\n" : "", + v & (1<<10) ? " Collision detect enable\n" : "", + v & (1<<9) ? " Collision squelch enable\n" : "", + v & (1<<8) ? " Receive squelch enable\n" : "", + csr14_tp_comp[(v >> 4) & 0x3], + v & (1<<3) ? " Link pulse send enable\n" : "", + v & (1<<2) ? " Driver enable\n" : "", + v & (1<<1) ? " Loopback enable\n" : "", + v & (1<<0) ? " Encoder enable\n" : ""); + + /* + * CSR15 + */ + v = data[15]; + fprintf(stdout, + "0x78: CSR15 (SIA General) 0x%08x\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + , + v, + v & (1<<13) ? " Force receiver low\n" : "", + v & (1<<12) ? " PLL self-test start\n" : "", + v & (1<<11) ? " Force link fail\n" : "", + v & (1<<9) ? " Force unsquelch\n" : "", + v & (1<<8) ? " Test clock\n" : "", + v & (1<<5) ? " Receive watchdog release\n" : "", + v & (1<<4) ? " Receive watchdog disable\n" : "", + v & (1<<2) ? " Jabber clock\n" : "", + v & (1<<1) ? " Host unjab\n" : "", + v & (1<<0) ? " Jabber disable\n" : ""); +} + +static void de21041_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 tmp, v, *data = (u32 *)regs->data; + + fprintf(stdout, "21041 Registers\n"); + fprintf(stdout, "---------------\n"); + + /* + * CSR0 + */ + v = data[0]; + fprintf(stdout, + "0x00: CSR0 (Bus Mode) 0x%08x\n" + " %s endian descriptors\n" + " %s\n" + " %s address space\n" + " Cache alignment: %s\n" + , + v, + v & (1 << 20) ? "Big" : "Little", + csr0_tap[(v >> 17) & 3], + v & (1 << 16) ? "Diagnostic" : "Standard", + csr0_cache_al[(v >> 14) & 3]); + tmp = (v >> 8) & 0x3f; + if (tmp == 0) + fprintf(stdout, " Programmable burst length unlimited\n"); + else + fprintf(stdout, + " Programmable burst length %d longwords\n", + tmp); + fprintf(stdout, + " %s endian data buffers\n" + " Descriptor skip length %d longwords\n" + " %s bus arbitration scheme\n" + , + v & (1 << 7) ? "Big" : "Little", + (v >> 2) & 0x1f, + v & (1 << 1) ? "Round-robin" : "RX-has-priority"); + if (v & (1 << 0)) + fprintf(stdout, " Software reset asserted\n"); + + /* + * CSR3, 4 + */ + print_ring_addresses(data[3], data[4]); + + /* + * CSR5 + */ + v = data[5]; + fprintf(stdout, + "0x28: CSR5 (Status) 0x%08x\n" + "%s" + " Transmit process %s\n" + " Receive process %s\n" + " Link %s\n" + , + v, + v & (1 << 13) ? csr5_buserr[(v >> 23) & 0x7] : "", + csr5_tx_state[(v >> 20) & 0x7], + csr5_rx_state[(v >> 17) & 0x7], + v & (1 << 12) ? "fail" : "OK"); + if (v & (1 << 16)) + fprintf(stdout, + " Normal interrupts: %s%s%s%s%s\n" + , + v & (1 << 0) ? "TxOK " : "", + v & (1 << 2) ? "TxNoBufs " : "", + v & (1 << 6) ? "RxOK" : "", + v & (1 << 11) ? "TimerExp " : "", + v & (1 << 14) ? "EarlyRx " : ""); + if (v & (1 << 15)) + fprintf(stdout, + " Abnormal intr: %s%s%s%s%s%s%s\n" + , + v & (1 << 1) ? "TxStop " : "", + v & (1 << 3) ? "TxJabber " : "", + v & (1 << 4) ? "ANC " : "", + v & (1 << 5) ? "TxUnder " : "", + v & (1 << 7) ? "RxNoBufs " : "", + v & (1 << 8) ? "RxStopped " : "", + v & (1 << 9) ? "RxTimeout " : ""); + + /* + * CSR6 + */ + v = data[6]; + fprintf(stdout, + "0x30: CSR6 (Operating Mode) 0x%08x\n" + "%s" + "%s" + " Transmit threshold %d bytes\n" + " Transmit DMA %sabled\n" + "%s" + " Operating mode: %s\n" + " %s duplex\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + " Receive DMA %sabled\n" + " %s filtering mode\n" + , + v, + v & (1<<31) ? " Special capture effect enabled\n" : "", + v & (1<<17) ? " Capture effect enabled\n" : "", + csr6_tx_thresh[(v >> 14) & 3], + v & (1<<13) ? "en" : "dis", + v & (1<<12) ? " Forcing collisions\n" : "", + csr6_om[(v >> 10) & 3], + v & (1<<9) ? "Full" : "Half", + v & (1<<8) ? " Flaky oscillator disable\n" : "", + v & (1<<7) ? " Pass All Multicast\n" : "", + v & (1<<6) ? " Promisc Mode\n" : "", + v & (1<<5) ? " Start/Stop Backoff Counter\n" : "", + v & (1<<4) ? " Inverse Filtering\n" : "", + v & (1<<3) ? " Pass Bad Frames\n" : "", + v & (1<<2) ? " Hash-only Filtering\n" : "", + v & (1<<1) ? "en" : "dis", + v & (1<<0) ? "Hash" : "Perfect"); + + /* + * CSR7 + */ + v = data[7]; + fprintf(stdout, + "0x38: CSR7 (Interrupt Mask) 0x%08x\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + , + v, + v & (1<<16) ? " Normal interrupt summary\n" : "", + v & (1<<15) ? " Abnormal interrupt summary\n" : "", + v & (1<<14) ? " Early receive interrupt\n" : "", + v & (1<<13) ? " System error\n" : "", + v & (1<<12) ? " Link fail\n" : "", + v & (1<<11) ? " Timer expired\n" : "", + v & (1<<9) ? " Receive watchdog timeout\n" : "", + v & (1<<8) ? " Receive stopped\n" : "", + v & (1<<7) ? " Receive buffer unavailable\n" : "", + v & (1<<6) ? " Receive interrupt\n" : "", + v & (1<<5) ? " Transmit underflow\n" : "", + v & (1<<4) ? " Link pass\n" : "", + v & (1<<3) ? " Transmit jabber timeout\n" : "", + v & (1<<2) ? " Transmit buffer unavailable\n" : "", + v & (1<<1) ? " Transmit stopped\n" : "", + v & (1<<0) ? " Transmit interrupt\n" : ""); + + /* + * CSR8 + */ + print_rx_missed(data[8]); + + /* + * CSR9 + */ + v = data[9]; + fprintf(stdout, + "0x48: CSR9 (Boot and Ethernet ROMs) 0x%08x\n" + " Select bits: %s%s%s%s%s%s\n" + " Data: %d%d%d%d%d%d%d%d\n" + , + v, + v & (1<<15) ? "Mode " : "", + v & (1<<14) ? "Read " : "", + v & (1<<13) ? "Write " : "", + v & (1<<12) ? "BootROM " : "", + v & (1<<11) ? "SROM " : "", + v & (1<<10) ? "ExtReg " : "", + v & (1<<7) ? 1 : 0, + v & (1<<6) ? 1 : 0, + v & (1<<5) ? 1 : 0, + v & (1<<4) ? 1 : 0, + v & (1<<3) ? 1 : 0, + v & (1<<2) ? 1 : 0, + v & (1<<1) ? 1 : 0, + v & (1<<0) ? 1 : 0); + + /* + * CSR10 + */ + v = data[10]; + fprintf(stdout, + "0x50: CSR10 (Boot ROM Address) 0x%08x\n", v); + + /* + * CSR11 + */ + v = data[11]; + fprintf(stdout, + "0x58: CSR11 (General Purpose Timer) 0x%08x\n" + "%s" + " Timer value: %u cycles\n" + , + v, + v & (1<<16) ? " Continuous mode\n" : "", + v & 0xffff); + + /* + * CSR12 + */ + v = data[12]; + fprintf(stdout, + "0x60: CSR12 (SIA Status) 0x%08x\n" + " Link partner code word 0x%04x\n" + "%s" + " NWay state: %s\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + , + v, + v >> 16, + v & (1<<15) ? " Link partner negotiable\n" : "", + csr12_nway_state[(v >> 12) & 0x7], + v & (1<<11) ? " Transmit remote fault\n" : "", + v & (1<<10) ? " Unstable NLP detected\n" : "", + v & (1<<9) ? " Non-selected port receive activity\n" : "", + v & (1<<8) ? " Selected port receive activity\n" : "", + v & (1<<7) ? " PLL sampler high\n" : "", + v & (1<<6) ? " PLL sampler low\n" : "", + v & (1<<5) ? " PLL self-test pass\n" : "", + v & (1<<4) ? " PLL self-test done\n" : "", + v & (1<<3) ? " Autopolarity state\n" : "", + v & (1<<2) ? " Link fail\n" : "", + v & (1<<1) ? " Network connection error\n" : ""); + + /* + * CSR13 + */ + v = data[13]; + fprintf(stdout, + "0x68: CSR13 (SIA Connectivity) 0x%08x\n" + " SIA Diagnostic Mode 0x%04x\n" + " %s\n" + "%s" + "%s" + , + v, + (v >> 4) & 0xfff, + v & (1<<3) ? "AUI/BNC port" : "10base-T port", + v & (1<<2) ? " CSR autoconfiguration enabled\n" : "", + v & (1<<0) ? " SIA register reset asserted\n" : ""); + + /* + * CSR14 + */ + v = data[14]; + fprintf(stdout, + "0x70: CSR14 (SIA Transmit and Receive) 0x%08x\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + " %s\n" + "%s" + "%s" + "%s" + "%s" + , + v, + v & (1<<15) ? " 10base-T/AUI autosensing\n" : "", + v & (1<<14) ? " Set polarity plus\n" : "", + v & (1<<13) ? " Autopolarity enable\n" : "", + v & (1<<12) ? " Link test enable\n" : "", + v & (1<<11) ? " Heartbeat enable\n" : "", + v & (1<<10) ? " Collision detect enable\n" : "", + v & (1<<9) ? " Collision squelch enable\n" : "", + v & (1<<8) ? " Receive squelch enable\n" : "", + v & (1<<7) ? " Autonegotiation enable\n" : "", + v & (1<<6) ? " Must Be One\n" : "", + csr14_tp_comp[(v >> 4) & 0x3], + v & (1<<3) ? " Link pulse send enable\n" : "", + v & (1<<2) ? " Driver enable\n" : "", + v & (1<<1) ? " Loopback enable\n" : "", + v & (1<<0) ? " Encoder enable\n" : ""); + + /* + * CSR15 + */ + v = data[15]; + fprintf(stdout, + "0x78: CSR15 (SIA General) 0x%08x\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + " %s port selected\n" + "%s" + "%s" + "%s" + , + v, + v & (1<<15) ? " GP LED2 on\n" : "", + v & (1<<14) ? " GP LED2 enable\n" : "", + v & (1<<13) ? " Force receiver low\n" : "", + v & (1<<12) ? " PLL self-test start\n" : "", + v & (1<<11) ? " LED stretch disable\n" : "", + v & (1<<10) ? " Force link fail\n" : "", + v & (1<<9) ? " Force unsquelch\n" : "", + v & (1<<8) ? " Test clock\n" : "", + v & (1<<7) ? " GP LED1 on\n" : "", + v & (1<<6) ? " GP LED1 enable\n" : "", + v & (1<<5) ? " Receive watchdog release\n" : "", + v & (1<<4) ? " Receive watchdog disable\n" : "", + v & (1<<3) ? "AUI" : "BNC", + v & (1<<2) ? " Jabber clock\n" : "", + v & (1<<1) ? " Host unjab\n" : "", + v & (1<<0) ? " Jabber disable\n" : ""); +} + +int +de2104x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs) +{ + unsigned int de21040 = regs->version & 1; + + if (de21040) + de21040_dump_regs(info, regs); + else + de21041_dump_regs(info, regs); + + return 0; +} + diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..b39f98f --- /dev/null +++ b/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2016-01-11.22; # UTC + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/dsa.c b/dsa.c new file mode 100644 index 0000000..33c1d39 --- /dev/null +++ b/dsa.c @@ -0,0 +1,882 @@ +#include +#include + +#include "internal.h" + +#define SERDES_OFFSET 32 + +/* Macros and dump functions for the 16-bit mv88e6xxx per-port registers */ + +#define REG(_reg, _name, _val) \ + printf("%.02u: %-38.38s 0x%.4x\n", _reg, _name, _val) + +#define FIELD(_name, _fmt, ...) \ + printf(" %-36.36s " _fmt "\n", _name, ##__VA_ARGS__) + +#define FIELD_BITMAP(_name, _val) \ + FIELD(_name, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", \ + ((_val) & 0x0001) ? "0 " : "", \ + ((_val) & 0x0002) ? "1 " : "", \ + ((_val) & 0x0004) ? "2 " : "", \ + ((_val) & 0x0008) ? "3 " : "", \ + ((_val) & 0x0010) ? "4 " : "", \ + ((_val) & 0x0020) ? "5 " : "", \ + ((_val) & 0x0040) ? "6 " : "", \ + ((_val) & 0x0080) ? "7 " : "", \ + ((_val) & 0x0100) ? "8 " : "", \ + ((_val) & 0x0200) ? "9 " : "", \ + ((_val) & 0x0400) ? "10 " : "", \ + ((_val) & 0x0800) ? "11 " : "", \ + ((_val) & 0x1000) ? "12 " : "", \ + ((_val) & 0x2000) ? "13 " : "", \ + ((_val) & 0x4000) ? "14 " : "", \ + ((_val) & 0x8000) ? "15 " : "") + +static void dsa_mv88e6161(int reg, u16 val) +{ + switch (reg) { + case 0: + REG(reg, "Port Status", val); + FIELD("Pause Enabled", "%u", !!(val & 0x8000)); + FIELD("My Pause", "%u", !!(val & 0x4000)); + FIELD("Half-duplex Flow Control", "%u", !!(val & 0x2000)); + FIELD("802.3 PHY Detected", "%u", !!(val & 0x1000)); + FIELD("Link Status", "%s", val & 0x0800 ? "Up" : "Down"); + FIELD("Duplex", "%s", val & 0x0400 ? "Full" : "Half"); + FIELD("Speed", "%s", + (val & 0x0300) == 0x0000 ? "10 Mbps" : + (val & 0x0300) == 0x0100 ? "100 Mbps" : + (val & 0x0300) == 0x0200 ? "1000 Mbps" : + (val & 0x0300) == 0x0300 ? "Reserved" : "?"); + FIELD("Auto-Media Detect Disable", "%u", !!(val & 0x0040)); + FIELD("Transmitter Paused", "%u", !!(val & 0x0020)); + FIELD("Flow Control", "%u", !!(val & 0x0010)); + FIELD("Config Duplex", "%s", val & 0x0008 ? "Full" : "Half"); + FIELD("Config Mode", "0x%x", val & 0x0007); + break; + case 1: + REG(reg, "PCS Control", val); + FIELD("Flow Control's Forced value", "%u", !!(val & 0x0080)); + FIELD("Force Flow Control", "%u", !!(val & 0x0040)); + FIELD("Link's Forced value", "%s", val & 0x0020 ? "Up" : "Down"); + FIELD("Force Link", "%u", !!(val & 0x0010)); + FIELD("Duplex's Forced value", "%s", val & 0x0008 ? "Full" : "Half"); + FIELD("Force Duplex", "%u", !!(val & 0x0004)); + FIELD("Force Speed", "%s", + (val & 0x0003) == 0x0000 ? "10 Mbps" : + (val & 0x0003) == 0x0001 ? "100 Mbps" : + (val & 0x0003) == 0x0002 ? "1000 Mbps" : + (val & 0x0003) == 0x0003 ? "Not forced" : "?"); + break; + case 2: + REG(reg, "Jamming Control", val); + break; + case 3: + REG(reg, "Switch Identifier", val); + break; + case 4: + REG(reg, "Port Control", val); + FIELD("Source Address Filtering controls", "%s", + (val & 0xc000) == 0x0000 ? "Disabled" : + (val & 0xc000) == 0x4000 ? "Drop On Lock" : + (val & 0xc000) == 0x8000 ? "Drop On Unlock" : + (val & 0xc000) == 0xc000 ? "Drop to CPU" : "?"); + FIELD("Egress Mode", "%s", + (val & 0x3000) == 0x0000 ? "Unmodified" : + (val & 0x3000) == 0x1000 ? "Untagged" : + (val & 0x3000) == 0x2000 ? "Tagged" : + (val & 0x3000) == 0x3000 ? "Reserved" : "?"); + FIELD("Ingress & Egress Header Mode", "%u", !!(val & 0x0800)); + FIELD("IGMP and MLD Snooping", "%u", !!(val & 0x0400)); + FIELD("Frame Mode", "%s", + (val & 0x0300) == 0x0000 ? "Normal" : + (val & 0x0300) == 0x0100 ? "DSA" : + (val & 0x0300) == 0x0200 ? "Provider" : + (val & 0x0300) == 0x0300 ? "Ether Type DSA" : "?"); + FIELD("VLAN Tunnel", "%u", !!(val & 0x0080)); + FIELD("TagIfBoth", "%u", !!(val & 0x0040)); + FIELD("Initial Priority assignment", "%s", + (val & 0x0030) == 0x0000 ? "Defaults" : + (val & 0x0030) == 0x0010 ? "Tag Priority" : + (val & 0x0030) == 0x0020 ? "IP Priority" : + (val & 0x0030) == 0x0030 ? "Tag & IP Priority" : "?"); + FIELD("Egress Flooding mode", "%s", + (val & 0x000c) == 0x0000 ? "No unknown DA" : + (val & 0x000c) == 0x0004 ? "No unknown multicast DA" : + (val & 0x000c) == 0x0008 ? "No unknown unicast DA" : + (val & 0x000c) == 0x000c ? "Allow unknown DA" : "?"); + FIELD("Port State", "%s", + (val & 0x0003) == 0x0000 ? "Disabled" : + (val & 0x0003) == 0x0001 ? "Blocking/Listening" : + (val & 0x0003) == 0x0002 ? "Learning" : + (val & 0x0003) == 0x0003 ? "Forwarding" : "?"); + break; + case 5: + REG(reg, "Port Control 1", val); + FIELD("Message Port", "%u", !!(val & 0x8000)); + FIELD("Trunk Port", "%u", !!(val & 0x4000)); + FIELD("Trunk ID", "%u", (val & 0x0f00) >> 8); + FIELD("FID[5:4]", "0x%.2x", (val & 0x0003) << 4); + break; + case 6: + REG(reg, "Port Base VLAN Map (Header)", val); + FIELD("FID[3:0]", "0x%.2x", (val & 0xf000) >> 12); + FIELD_BITMAP("VLANTable", val & 0x003f); + break; + case 7: + REG(reg, "Default VLAN ID & Priority", val); + FIELD("Default Priority", "0x%x", (val & 0xe000) >> 13); + FIELD("Force to use Default VID", "%u", !!(val & 0x1000)); + FIELD("Default VLAN Identifier", "%u", val & 0x0fff); + break; + case 8: + REG(reg, "Port Control 2", val); + FIELD("Force good FCS in the frame", "%u", !!(val & 0x8000)); + FIELD("Jumbo Mode", "%s", + (val & 0x3000) == 0x0000 ? "1522" : + (val & 0x3000) == 0x1000 ? "2048" : + (val & 0x3000) == 0x2000 ? "10240" : + (val & 0x3000) == 0x3000 ? "Reserved" : "?"); + FIELD("802.1QMode", "%s", + (val & 0x0c00) == 0x0000 ? "Disabled" : + (val & 0x0c00) == 0x0400 ? "Fallback" : + (val & 0x0c00) == 0x0800 ? "Check" : + (val & 0x0c00) == 0x0c00 ? "Secure" : "?"); + FIELD("Discard Tagged Frames", "%u", !!(val & 0x0200)); + FIELD("Discard Untagged Frames", "%u", !!(val & 0x0100)); + FIELD("Map using DA hits", "%u", !!(val & 0x0080)); + FIELD("ARP Mirror enable", "%u", !!(val & 0x0040)); + FIELD("Egress Monitor Source Port", "%u", !!(val & 0x0020)); + FIELD("Ingress Monitor Source Port", "%u", !!(val & 0x0010)); + break; + case 9: + REG(reg, "Egress Rate Control", val); + break; + case 10: + REG(reg, "Egress Rate Control 2", val); + break; + case 11: + REG(reg, "Port Association Vector", val); + break; + case 12: + REG(reg, "Port ATU Control", val); + break; + case 13: + REG(reg, "Priority Override", val); + break; + case 15: + REG(reg, "PortEType", val); + break; + case 16: + REG(reg, "InDiscardsLo Frame Counter", val); + break; + case 17: + REG(reg, "InDiscardsHi Frame Counter", val); + break; + case 18: + REG(reg, "InFiltered Frame Counter", val); + break; + case 19: + REG(reg, "OutFiltered Frame Counter", val); + break; + case 24: + REG(reg, "Tag Remap 0-3", val); + break; + case 25: + REG(reg, "Tag Remap 4-7", val); + break; + case 27: + REG(reg, "Queue Counters", val); + break; + default: + REG(reg, "Reserved", val); + break; + } +} + +static void dsa_mv88e6185(int reg, u16 val) +{ + switch (reg) { + case 0: + REG(reg, "Port Status", val); + break; + case 1: + REG(reg, "PCS Control", val); + break; + case 3: + REG(reg, "Switch Identifier", val); + break; + case 4: + REG(reg, "Port Control", val); + break; + case 5: + REG(reg, "Port Control 1", val); + break; + case 6: + REG(reg, "Port Base VLAN Map (Header)", val); + break; + case 7: + REG(reg, "Default VLAN ID & Priority", val); + break; + case 8: + REG(reg, "Port Control 2", val); + break; + case 9: + REG(reg, "Rate Control", val); + break; + case 10: + REG(reg, "Rate Control 2", val); + break; + case 11: + REG(reg, "Port Association Vector", val); + break; + case 16: + REG(reg, "InDiscardsLo Frame Counter", val); + break; + case 17: + REG(reg, "InDiscardsHi Frame Counter", val); + break; + case 18: + REG(reg, "InFiltered Frame Counter", val); + break; + case 19: + REG(reg, "OutFiltered Frame Counter", val); + break; + case 24: + REG(reg, "Tag Remap 0-3", val); + break; + case 25: + REG(reg, "Tag Remap 4-7", val); + break; + default: + REG(reg, "Reserved", val); + break; + } +}; + +static void dsa_mv88e6352(int reg, u16 val) +{ + switch (reg) { + case 0: + REG(reg, "Port Status", val); + FIELD("Pause Enabled", "%u", !!(val & 0x8000)); + FIELD("My Pause", "%u", !!(val & 0x4000)); + FIELD("802.3 PHY Detected", "%u", !!(val & 0x1000)); + FIELD("Link Status", "%s", val & 0x0800 ? "Up" : "Down"); + FIELD("Duplex", "%s", val & 0x0400 ? "Full" : "Half"); + FIELD("Speed", "%s", + (val & 0x0300) == 0x0000 ? "10 Mbps" : + (val & 0x0300) == 0x0100 ? "100 or 200 Mbps" : + (val & 0x0300) == 0x0200 ? "1000 Mbps" : + (val & 0x0300) == 0x0300 ? "Reserved" : "?"); + FIELD("EEE Enabled", "%u", !!(val & 0x0040)); + FIELD("Transmitter Paused", "%u", !!(val & 0x0020)); + FIELD("Flow Control", "%u", !!(val & 0x0010)); + FIELD("Config Mode", "0x%x", val & 0x000f); + break; + case 1: + REG(reg, "Physical Control", val); + FIELD("RGMII Receive Timing Control", "%s", val & 0x8000 ? "Delay" : "Default"); + FIELD("RGMII Transmit Timing Control", "%s", val & 0x4000 ? "Delay" : "Default"); + FIELD("200 BASE Mode", "%s", val & 0x1000 ? "200" : "100"); + FIELD("Flow Control's Forced value", "%u", !!(val & 0x0080)); + FIELD("Force Flow Control", "%u", !!(val & 0x0040)); + FIELD("Link's Forced value", "%s", val & 0x0020 ? "Up" : "Down"); + FIELD("Force Link", "%u", !!(val & 0x0010)); + FIELD("Duplex's Forced value", "%s", val & 0x0008 ? "Full" : "Half"); + FIELD("Force Duplex", "%u", !!(val & 0x0004)); + FIELD("Force Speed", "%s", + (val & 0x0003) == 0x0000 ? "10 Mbps" : + (val & 0x0003) == 0x0001 ? "100 or 200 Mbps" : + (val & 0x0003) == 0x0002 ? "1000 Mbps" : + (val & 0x0003) == 0x0003 ? "Not forced" : "?"); + break; + case 2: + REG(reg, "Jamming Control", val); + break; + case 3: + REG(reg, "Switch Identifier", val); + break; + case 4: + REG(reg, "Port Control", val); + FIELD("Source Address Filtering controls", "%s", + (val & 0xc000) == 0x0000 ? "Disabled" : + (val & 0xc000) == 0x4000 ? "Drop On Lock" : + (val & 0xc000) == 0x8000 ? "Drop On Unlock" : + (val & 0xc000) == 0xc000 ? "Drop to CPU" : "?"); + FIELD("Egress Mode", "%s", + (val & 0x3000) == 0x0000 ? "Unmodified" : + (val & 0x3000) == 0x1000 ? "Untagged" : + (val & 0x3000) == 0x2000 ? "Tagged" : + (val & 0x3000) == 0x3000 ? "Reserved" : "?"); + FIELD("Ingress & Egress Header Mode", "%u", !!(val & 0x0800)); + FIELD("IGMP and MLD Snooping", "%u", !!(val & 0x0400)); + FIELD("Frame Mode", "%s", + (val & 0x0300) == 0x0000 ? "Normal" : + (val & 0x0300) == 0x0100 ? "DSA" : + (val & 0x0300) == 0x0200 ? "Provider" : + (val & 0x0300) == 0x0300 ? "Ether Type DSA" : "?"); + FIELD("VLAN Tunnel", "%u", !!(val & 0x0080)); + FIELD("TagIfBoth", "%u", !!(val & 0x0040)); + FIELD("Initial Priority assignment", "%s", + (val & 0x0030) == 0x0000 ? "Defaults" : + (val & 0x0030) == 0x0010 ? "Tag Priority" : + (val & 0x0030) == 0x0020 ? "IP Priority" : + (val & 0x0030) == 0x0030 ? "Tag & IP Priority" : "?"); + FIELD("Egress Flooding mode", "%s", + (val & 0x000c) == 0x0000 ? "No unknown DA" : + (val & 0x000c) == 0x0004 ? "No unknown multicast DA" : + (val & 0x000c) == 0x0008 ? "No unknown unicast DA" : + (val & 0x000c) == 0x000c ? "Allow unknown DA" : "?"); + FIELD("Port State", "%s", + (val & 0x0003) == 0x0000 ? "Disabled" : + (val & 0x0003) == 0x0001 ? "Blocking/Listening" : + (val & 0x0003) == 0x0002 ? "Learning" : + (val & 0x0003) == 0x0003 ? "Forwarding" : "?"); + break; + case 5: + REG(reg, "Port Control 1", val); + FIELD("Message Port", "%u", !!(val & 0x8000)); + FIELD("Trunk Port", "%u", !!(val & 0x4000)); + FIELD("Trunk ID", "%u", (val & 0x0f00) >> 8); + FIELD("FID[11:4]", "0x%.3x", (val & 0x00ff) << 4); + break; + case 6: + REG(reg, "Port Base VLAN Map (Header)", val); + FIELD("FID[3:0]", "0x%.3x", (val & 0xf000) >> 12); + FIELD_BITMAP("VLANTable", val & 0x007f); + break; + case 7: + REG(reg, "Default VLAN ID & Priority", val); + FIELD("Default Priority", "0x%x", (val & 0xe000) >> 13); + FIELD("Force to use Default VID", "%u", !!(val & 0x1000)); + FIELD("Default VLAN Identifier", "%u", val & 0x0fff); + break; + case 8: + REG(reg, "Port Control 2", val); + FIELD("Force good FCS in the frame", "%u", !!(val & 0x8000)); + FIELD("Jumbo Mode", "%s", + (val & 0x3000) == 0x0000 ? "1522" : + (val & 0x3000) == 0x1000 ? "2048" : + (val & 0x3000) == 0x2000 ? "10240" : + (val & 0x3000) == 0x3000 ? "Reserved" : "?"); + FIELD("802.1QMode", "%s", + (val & 0x0c00) == 0x0000 ? "Disabled" : + (val & 0x0c00) == 0x0400 ? "Fallback" : + (val & 0x0c00) == 0x0800 ? "Check" : + (val & 0x0c00) == 0x0c00 ? "Secure" : "?"); + FIELD("Discard Tagged Frames", "%u", !!(val & 0x0200)); + FIELD("Discard Untagged Frames", "%u", !!(val & 0x0100)); + FIELD("Map using DA hits", "%u", !!(val & 0x0080)); + FIELD("ARP Mirror enable", "%u", !!(val & 0x0040)); + FIELD("Egress Monitor Source Port", "%u", !!(val & 0x0020)); + FIELD("Ingress Monitor Source Port", "%u", !!(val & 0x0010)); + FIELD("Use Default Queue Priority", "%u", !!(val & 0x0008)); + FIELD("Default Queue Priority", "0x%x", (val & 0x0006) >> 1); + break; + case 9: + REG(reg, "Egress Rate Control", val); + break; + case 10: + REG(reg, "Egress Rate Control 2", val); + break; + case 11: + REG(reg, "Port Association Vector", val); + break; + case 12: + REG(reg, "Port ATU Control", val); + break; + case 13: + REG(reg, "Override", val); + break; + case 14: + REG(reg, "Policy Control", val); + break; + case 15: + REG(reg, "Port Ether Type", val); + break; + case 16: + REG(reg, "InDiscardsLo Frame Counter", val); + break; + case 17: + REG(reg, "InDiscardsHi Frame Counter", val); + break; + case 18: + REG(reg, "InFiltered/TcamCtr Frame Counter", val); + break; + case 19: + REG(reg, "Rx Frame Counter", val); + break; + case 20 ... 21: + REG(reg, "Reserved", val); + break; + case 22: + REG(reg, "LED Control", val); + break; + case 23: + REG(reg, "Reserved", val); + break; + case 24: + REG(reg, "Tag Remap 0-3", val); + break; + case 25: + REG(reg, "Tag Remap 4-7", val); + break; + case 26: + REG(reg, "Reserved", val); + break; + case 27: + REG(reg, "Queue Counters", val); + break; + case 28 ... 31: + REG(reg, "Reserved", val); + break; + case SERDES_OFFSET + 0: + REG(reg - SERDES_OFFSET, "Fiber Control", val); + FIELD("Fiber Reset", "%u", !!(val & 0x8000)); + FIELD("Loopback", "%u", !!(val & 0x4000)); + FIELD("Speed", "%s", + (val & (0x2000 | 0x0040)) == 0x0000 ? "10 Mbps" : + (val & (0x2000 | 0x0040)) == 0x2000 ? "100 Mbps" : + (val & (0x2000 | 0x0040)) == 0x0040 ? "1000 Mbps" : + (val & (0x2000 | 0x0040)) == (0x2000 | 0x0040) ? + "Reserved" : "?"); + FIELD("Autoneg Enable", "%u", !!(val & 0x1000)); + FIELD("Power down", "%u", !!(val & 0x0800)); + FIELD("Isolate", "%u", !!(val & 0x0400)); + FIELD("Restart Autoneg", "%u", !!(val & 0x0200)); + FIELD("Duplex", "%s", val & 0x0100 ? "Full" : "Half"); + break; + case SERDES_OFFSET + 1: + REG(reg - SERDES_OFFSET, "Fiber Status", val); + FIELD("100Base-X FD", "%u", !!(val & 0x4000)); + FIELD("100Base-X HD", "%u", !!(val & 0x2000)); + FIELD("Autoneg Complete", "%u", !!(val & 0x0020)); + FIELD("Remote Fault", "%u", !!(val & 0x0010)); + FIELD("Autoneg Ability", "%u", !!(val & 0x0008)); + FIELD("Link Status", "%s", val & 0x0004 ? "Up" : "Down"); + break; + case SERDES_OFFSET + 2: + REG(reg - SERDES_OFFSET, "PHY ID 1", val); + break; + case SERDES_OFFSET + 3: + REG(reg - SERDES_OFFSET, "PHY ID 2", val); + break; + case SERDES_OFFSET + 4: + REG(reg - SERDES_OFFSET, "Fiber Autoneg Advertisement", val); + FIELD("Remote Fault", "%s", + (val & 0x3000) == 0x0000 ? "No error, link OK" : + (val & 0x3000) == 0x1000 ? "Link failure" : + (val & 0x3000) == 0x2000 ? "Offline" : + (val & 0x3000) == 0x3000 ? "Autoneg Error" : "?"); + FIELD("Pause", "%s", + (val & 0x0180) == 0x0000 ? "No Pause" : + (val & 0x0180) == 0x0080 ? "Symmetric Pause" : + (val & 0x0180) == 0x0100 ? "Asymmetric Pause" : + (val & 0x0180) == 0x0180 ? "Symmetric & Asymmetric Pause" : + "?"); + FIELD("1000BaseX HD", "%u", !!(val & 0x0040)); + FIELD("1000BaseX FD", "%u", !!(val & 0x0020)); + break; + case SERDES_OFFSET + 5: + REG(reg - SERDES_OFFSET, "Fiber Link Autoneg Ability", val); + FIELD("Acknowledge", "%u", !!(val & 0x4000)); + FIELD("Remote Fault", "%s", + (val & 0x3000) == 0x0000 ? "No error, link OK" : + (val & 0x3000) == 0x1000 ? "Link failure" : + (val & 0x3000) == 0x2000 ? "Offline" : + (val & 0x3000) == 0x3000 ? "Autoneg Error" : "?"); + FIELD("Pause", "%s", + (val & 0x0180) == 0x0000 ? "No Pause" : + (val & 0x0180) == 0x0080 ? "Symmetric Pause" : + (val & 0x0180) == 0x0100 ? "Asymmetric Pause" : + (val & 0x0180) == 0x0180 ? "Symmetric & Asymmetric Pause" : + "?"); + FIELD("1000BaseX HD", "%u", !!(val & 0x0040)); + FIELD("1000BaseX FD", "%u", !!(val & 0x0020)); + break; + case SERDES_OFFSET + 6: + REG(reg - SERDES_OFFSET, "Fiber Autoneg Expansion", val); + FIELD("Link Partner Next Page Ability", "%u", !!(val & 0x0008)); + FIELD("Page Received", "%u", !!(val & 0x0002)); + FIELD("Link Partner Autoneg Ability", "%u", !!(val & 0x0001)); + break; + case SERDES_OFFSET + 7: + REG(reg - SERDES_OFFSET, "Fiber Next Page Transmit", val); + break; + case SERDES_OFFSET + 8: + REG(reg - SERDES_OFFSET, "Fiber Link Partner Next Page", val); + break; + case SERDES_OFFSET + 9 ... SERDES_OFFSET + 14: + REG(reg - SERDES_OFFSET, "Reserved", val); + break; + case SERDES_OFFSET + 15: + REG(reg - SERDES_OFFSET, "Extended Status", val); + break; + case SERDES_OFFSET + 16: + REG(reg - SERDES_OFFSET, "Fiber Specific Control", val); + FIELD("Fiber Transmit FIFO Depth", "%s", + (val & 0xc000) == 0x0000 ? "16 Bits" : + (val & 0xc000) == 0x4000 ? "24 Bits" : + (val & 0xc000) == 0x8000 ? "32 Bits" : + (val & 0xc000) == 0xc000 ? "40 Bits" : "?"); + FIELD("SERDES Loopback", "%u", !!(val & 0x1000)); + FIELD("Force Link Good", "%u", !!(val & 0x0400)); + FIELD("MAC Interface Power Down", "%u", !!(val & 0x0008)); + FIELD("Mode", "%s", + (val & 0x0003) == 0x0000 ? "100BaseFX" : + (val & 0x0003) == 0x0001 ? "1000BaseX" : + (val & 0x0003) == 0x0002 ? "SGMII System" : + (val & 0x0003) == 0x0003 ? "SGMII Media" : "?"); + break; + case SERDES_OFFSET + 17: + REG(reg - SERDES_OFFSET, "Fiber Specific Status", val); + FIELD("Speed", "%s", + (val & 0xc000) == 0x0000 ? "10 Mbps" : + (val & 0xc000) == 0x4000 ? "100 Mbps" : + (val & 0xc000) == 0x8000 ? "1000 Mbps" : + (val & 0xc000) == 0xc000 ? "Reserved" : "?"); + FIELD("Duplex", "%s", val & 0x2000 ? "Full" : "Half"); + FIELD("Page Received", "%u", !!(val & 0x1000)); + FIELD("Speed/Duplex Resolved", "%u", !!(val & 0x0800)); + FIELD("Link", "%s", val & 0x0400 ? "Up" : "Down"); + FIELD("Sync", "%u", !!(val & 0x0020)); + FIELD("Energy Detect", "%s", val & 0x010 ? "False" : "True"); + FIELD("Transmit Pause", "%u", !!(val & 0x0008)); + FIELD("Receive Pause", "%u", !!(val & 0x00004)); + break; + case SERDES_OFFSET + 18: + REG(reg - SERDES_OFFSET, "Fiber Interrupt Enable", val); + FIELD("Speed Changed", "%u", !!(val & 0x4000)); + FIELD("Duplex Changed", "%u", !!(val & 0x2000)); + FIELD("Page Received", "%u", !!(val & 0x1000)); + FIELD("Autoneg Complete", "%u", !!(val & 0x0800)); + FIELD("Link Status Change", "%u", !!(val & 0x0400)); + FIELD("Symbol Error", "%u", !!(val & 0x0200)); + FIELD("False Carrier", "%u", !!(val & 0x0100)); + FIELD("Energy Detect", "%u", !!(val & 0x0010)); + break; + case SERDES_OFFSET + 19: + REG(reg - SERDES_OFFSET, "Fiber Interrupt Status", val); + FIELD("Speed Changed", "%u", !!(val & 0x4000)); + FIELD("Duplex Changed", "%u", !!(val & 0x2000)); + FIELD("Page Received", "%u", !!(val & 0x1000)); + FIELD("Autoneg Complete", "%u", !!(val & 0x0800)); + FIELD("Link Status Change", "%u", !!(val & 0x0400)); + FIELD("Symbol Error", "%u", !!(val & 0x0200)); + FIELD("False Carrier", "%u", !!(val & 0x0100)); + FIELD("Energy Detect", "%u", !!(val & 0x0010)); + break; + case SERDES_OFFSET + 20: + REG(reg - SERDES_OFFSET, "Reserved", val); + break; + case SERDES_OFFSET + 21: + REG(reg - SERDES_OFFSET, "Fiber Receive Error Counter", val); + break; + case SERDES_OFFSET + 22: + REG(reg - SERDES_OFFSET, "Reserved", val); + break; + case SERDES_OFFSET + 23: + REG(reg - SERDES_OFFSET, "PRBS Control", val); + break; + case SERDES_OFFSET + 24: + REG(reg - SERDES_OFFSET, "PRBS Error Counter LSB", val); + break; + case SERDES_OFFSET + 25: + REG(reg - SERDES_OFFSET, "PRBS Error Counter MSB", val); + break; + case SERDES_OFFSET + 26: + REG(reg - SERDES_OFFSET, "Fiber Specific Control 2", val); + FIELD("1000BaseX Noise Filtering", "%u", !!(val & 0x4000)); + FIELD("1000BaseFX Noise Filtering", "%u", !!(val & 0x2000)); + FIELD("SERDES Autoneg Bypass Enable", "%u", !!(val & 0x0040)); + FIELD("SERDES Autoneg Bypass Status", "%u", !!(val & 0x0020)); + FIELD("Fiber Transmitter Disable", "%u", !!(val & 0x0008)); + FIELD("SGMII/Fiber Output Amplitude", "%s", + (val & 0x0007) == 0x0000 ? "14mV" : + (val & 0x0007) == 0x0001 ? "112mV" : + (val & 0x0007) == 0x0002 ? "210mV" : + (val & 0x0007) == 0x0003 ? "308mV" : + (val & 0x0007) == 0x0004 ? "406mV" : + (val & 0x0007) == 0x0005 ? "504mV" : + (val & 0x0007) == 0x0006 ? "602mV" : + (val & 0x0007) == 0x0007 ? "700mV" : "?"); + break; + default: + REG(reg - SERDES_OFFSET, "Reserved", val); + break; + } +}; + +static void dsa_mv88e6390(int reg, u16 val) +{ + switch (reg) { + case 0: + REG(reg, "Port Status", val); + FIELD("Transmit Pause Enable bit", "%u", !!(val & 0x8000)); + FIELD("Receive Pause Enable bit", "%u", !!(val & 0x4000)); + FIELD("802.3 PHY Detected", "%u", !!(val & 0x1000)); + FIELD("Link Status", "%s", val & 0x0800 ? "Up" : "Down"); + FIELD("Duplex", "%s", val & 0x0400 ? "Full" : "Half"); + FIELD("Speed", "%s", + (val & 0x0300) == 0x0000 ? "10 Mbps" : + (val & 0x0300) == 0x0100 ? "100 or 200 Mbps" : + (val & 0x0300) == 0x0200 ? "1000 Mbps" : + (val & 0x0300) == 0x0300 ? "10 Gb or 2500 Mbps" : "?"); + FIELD("Duplex Fixed", "%u", !!(val & 0x0080)); + FIELD("EEE Enabled", "%u", !!(val & 0x0040)); + FIELD("Transmitter Paused", "%u", !!(val & 0x0020)); + FIELD("Flow Control", "%u", !!(val & 0x0010)); + FIELD("Config Mode", "0x%x", val & 0x000f); + break; + case 1: + REG(reg, "Physical Control", val); + FIELD("RGMII Receive Timing Control", "%s", val & 0x8000 ? "Delay" : "Default"); + FIELD("RGMII Transmit Timing Control", "%s", val & 0x4000 ? "Delay" : "Default"); + FIELD("Force Speed", "%u", !!(val & 0x2000)); + FIELD("Alternate Speed Mode", "%s", val & 0x1000 ? "Alternate" : "Normal"); + FIELD("MII PHY Mode", "%s", val & 0x0800 ? "PHY" : "MAC"); + FIELD("EEE force value", "%u", !!(val & 0x0200)); + FIELD("Force EEE", "%u", !!(val & 0x0100)); + FIELD("Link's Forced value", "%s", val & 0x0020 ? "Up" : "Down"); + FIELD("Force Link", "%u", !!(val & 0x0010)); + FIELD("Duplex's Forced value", "%s", val & 0x0008 ? "Full" : "Half"); + FIELD("Force Duplex", "%u", !!(val & 0x0004)); + FIELD("Force Speed", "%s", + (val & 0x0003) == 0x0000 ? "10 Mbps" : + (val & 0x0003) == 0x0001 ? "100 or 200 Mbps" : + (val & 0x0003) == 0x0002 ? "1000 Mbps" : + (val & 0x0003) == 0x0003 ? "10 Gb or 2500 Mbps" : "?"); + break; + case 2: + REG(reg, "Flow Control", val); + break; + case 3: + REG(reg, "Switch Identifier", val); + break; + case 4: + REG(reg, "Port Control", val); + FIELD("Source Address Filtering controls", "%s", + (val & 0xc000) == 0x0000 ? "Disabled" : + (val & 0xc000) == 0x4000 ? "Drop On Lock" : + (val & 0xc000) == 0x8000 ? "Drop On Unlock" : + (val & 0xc000) == 0xc000 ? "Drop to CPU" : "?"); + FIELD("Egress Mode", "%s", + (val & 0x3000) == 0x0000 ? "Unmodified" : + (val & 0x3000) == 0x1000 ? "Untagged" : + (val & 0x3000) == 0x2000 ? "Tagged" : + (val & 0x3000) == 0x3000 ? "Reserved" : "?"); + FIELD("Ingress & Egress Header Mode", "%u", !!(val & 0x0800)); + FIELD("IGMP and MLD Snooping", "%u", !!(val & 0x0400)); + FIELD("Frame Mode", "%s", + (val & 0x0300) == 0x0000 ? "Normal" : + (val & 0x0300) == 0x0100 ? "DSA" : + (val & 0x0300) == 0x0200 ? "Provider" : + (val & 0x0300) == 0x0300 ? "Ether Type DSA" : "?"); + FIELD("VLAN Tunnel", "%u", !!(val & 0x0080)); + FIELD("TagIfBoth", "%u", !!(val & 0x0040)); + FIELD("Initial Priority assignment", "%s", + (val & 0x0030) == 0x0000 ? "Defaults" : + (val & 0x0030) == 0x0010 ? "Tag Priority" : + (val & 0x0030) == 0x0020 ? "IP Priority" : + (val & 0x0030) == 0x0030 ? "Tag & IP Priority" : "?"); + FIELD("Egress Flooding mode", "%s", + (val & 0x000c) == 0x0000 ? "No unknown DA" : + (val & 0x000c) == 0x0004 ? "No unknown multicast DA" : + (val & 0x000c) == 0x0008 ? "No unknown unicast DA" : + (val & 0x000c) == 0x000c ? "Allow unknown DA" : "?"); + FIELD("Port State", "%s", + (val & 0x0003) == 0x0000 ? "Disabled" : + (val & 0x0003) == 0x0001 ? "Blocking/Listening" : + (val & 0x0003) == 0x0002 ? "Learning" : + (val & 0x0003) == 0x0003 ? "Forwarding" : "?"); + break; + case 5: + REG(reg, "Port Control 1", val); + FIELD("Message Port", "%u", !!(val & 0x8000)); + FIELD("LAG Port", "%u", !!(val & 0x4000)); + FIELD("VTU Page", "%u", !!(val & 0x2000)); + FIELD("LAG ID", "%u", (val & 0x0f00) >> 8); + FIELD("FID[11:4]", "0x%.3x", (val & 0x00ff) << 4); + break; + case 6: + REG(reg, "Port Base VLAN Map (Header)", val); + FIELD("FID[3:0]", "0x%.3x", (val & 0xf000) >> 12); + FIELD("Force Mapping", "%u", !!(val & 0x0800)); + FIELD_BITMAP("VLANTable", val & 0x007ff); + break; + case 7: + REG(reg, "Default VLAN ID & Priority", val); + FIELD("Default Priority", "0x%x", (val & 0xe000) >> 13); + FIELD("Force to use Default VID", "%u", !!(val & 0x1000)); + FIELD("Default VLAN Identifier", "%u", val & 0x0fff); + break; + case 8: + REG(reg, "Port Control 2", val); + FIELD("Force good FCS in the frame", "%u", !!(val & 0x8000)); + FIELD("Allow bad FCS", "%u", !!(val & 0x4000)); + FIELD("Jumbo Mode", "%s", + (val & 0x3000) == 0x0000 ? "1522" : + (val & 0x3000) == 0x1000 ? "2048" : + (val & 0x3000) == 0x2000 ? "10240" : + (val & 0x3000) == 0x3000 ? "Reserved" : "?"); + FIELD("802.1QMode", "%s", + (val & 0x0c00) == 0x0000 ? "Disabled" : + (val & 0x0c00) == 0x0400 ? "Fallback" : + (val & 0x0c00) == 0x0800 ? "Check" : + (val & 0x0c00) == 0x0c00 ? "Secure" : "?"); + FIELD("Discard Tagged Frames", "%u", !!(val & 0x0200)); + FIELD("Discard Untagged Frames", "%u", !!(val & 0x0100)); + FIELD("Map using DA hits", "%u", !!(val & 0x0080)); + FIELD("ARP Mirror enable", "%u", !!(val & 0x0040)); + FIELD("Egress Monitor Source Port", "%u", !!(val & 0x0020)); + FIELD("Ingress Monitor Source Port", "%u", !!(val & 0x0010)); + FIELD("Allow VID of Zero", "%u", !!(val & 0x0008)); + FIELD("Default Queue Priority", "0x%x", val & 0x0007); + break; + case 9: + REG(reg, "Egress Rate Control", val); + break; + case 10: + REG(reg, "Egress Rate Control 2", val); + break; + case 11: + REG(reg, "Port Association Vector", val); + break; + case 12: + REG(reg, "Port ATU Control", val); + break; + case 13: + REG(reg, "Override", val); + break; + case 14: + REG(reg, "Policy Control", val); + break; + case 15: + REG(reg, "Port Ether Type", val); + break; + case 22: + REG(reg, "LED Control", val); + break; + case 23: + REG(reg, "IP Priority Mapping Table", val); + break; + case 24: + REG(reg, "IEEE Priority Mapping Table", val); + break; + case 25: + REG(reg, "Port Control 3", val); + break; + case 27: + REG(reg, "Queue Counters", val); + break; + case 28: + REG(reg, "Queue Control", val); + break; + case 30: + REG(reg, "Cut Through Control", val); + break; + case 31: + REG(reg, "Debug Counters", val); + break; + default: + REG(reg, "Reserved", val); + break; + } +}; + +struct dsa_mv88e6xxx_switch { + void (*dump)(int reg, u16 val); + const char *name; + u16 id; +}; + +static const struct dsa_mv88e6xxx_switch dsa_mv88e6xxx_switches[] = { + { .id = 0x04a0, .name = "88E6085 ", .dump = NULL }, + { .id = 0x0950, .name = "88E6095 ", .dump = NULL }, + { .id = 0x0990, .name = "88E6097 ", .dump = NULL }, + { .id = 0x0a00, .name = "88E6190X", .dump = dsa_mv88e6390 }, + { .id = 0x0a10, .name = "88E6390X", .dump = dsa_mv88e6390 }, + { .id = 0x1060, .name = "88E6131 ", .dump = NULL }, + { .id = 0x1150, .name = "88E6320 ", .dump = NULL }, + { .id = 0x1210, .name = "88E6123 ", .dump = dsa_mv88e6161 }, + { .id = 0x1610, .name = "88E6161 ", .dump = dsa_mv88e6161 }, + { .id = 0x1650, .name = "88E6165 ", .dump = NULL }, + { .id = 0x1710, .name = "88E6171 ", .dump = NULL }, + { .id = 0x1720, .name = "88E6172 ", .dump = dsa_mv88e6352 }, + { .id = 0x1750, .name = "88E6175 ", .dump = NULL }, + { .id = 0x1760, .name = "88E6176 ", .dump = dsa_mv88e6352 }, + { .id = 0x1900, .name = "88E6190 ", .dump = dsa_mv88e6390 }, + { .id = 0x1910, .name = "88E6191 ", .dump = NULL }, + { .id = 0x1a70, .name = "88E6185 ", .dump = dsa_mv88e6185 }, + { .id = 0x2400, .name = "88E6240 ", .dump = dsa_mv88e6352 }, + { .id = 0x2900, .name = "88E6290 ", .dump = dsa_mv88e6390 }, + { .id = 0x3100, .name = "88E6321 ", .dump = NULL }, + { .id = 0x3400, .name = "88E6141 ", .dump = NULL }, + { .id = 0x3410, .name = "88E6341 ", .dump = NULL }, + { .id = 0x3520, .name = "88E6352 ", .dump = dsa_mv88e6352 }, + { .id = 0x3710, .name = "88E6350 ", .dump = NULL }, + { .id = 0x3750, .name = "88E6351 ", .dump = NULL }, + { .id = 0x3900, .name = "88E6390 ", .dump = dsa_mv88e6390 }, +}; + +static int dsa_mv88e6xxx_dump_regs(struct ethtool_regs *regs) +{ + const struct dsa_mv88e6xxx_switch *sw = NULL; + const u16 *data = (u16 *)regs->data; + unsigned int i; + u16 id; + + /* Marvell chips have 32 per-port 16-bit registers */ + if (regs->len < 32 * sizeof(u16)) + return 1; + + id = regs->version & 0xfff0; + + for (i = 0; i < ARRAY_SIZE(dsa_mv88e6xxx_switches); i++) { + if (id == dsa_mv88e6xxx_switches[i].id) { + sw = &dsa_mv88e6xxx_switches[i]; + break; + } + } + + if (!sw) + return 1; + + printf("%s Switch Port Registers\n", sw->name); + printf("------------------------------\n"); + + for (i = 0; i < 32; i++) + if (sw->dump) + sw->dump(i, data[i]); + else + REG(i, "", data[i]); + + /* Dump the SERDES registers, if provided */ + if (regs->len > SERDES_OFFSET * sizeof(u16)) { + printf("\n%s Switch Port SERDES Registers\n", sw->name); + printf("-------------------------------------\n"); + for (i = SERDES_OFFSET; i < regs->len / 2; i++) + if (sw->dump) + sw->dump(i, data[i]); + else + REG(i - SERDES_OFFSET, "", data[i]); + } + + return 0; +} + +#undef FIELD_BITMAP +#undef FIELD +#undef REG + +int dsa_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + /* DSA per-driver register dump */ + if (!dsa_mv88e6xxx_dump_regs(regs)) + return 0; + + /* Fallback to hexdump */ + return 1; +} diff --git a/e100.c b/e100.c new file mode 100644 index 0000000..fd4bd03 --- /dev/null +++ b/e100.c @@ -0,0 +1,238 @@ +/* Copyright (c) 2002 Intel Corporation */ +#include +#include "internal.h" + +#define D102_REV_ID 12 + +#define MDI_MDIX_CONFIG_IS_OK 0x0010 +#define MDI_MDIX_STATUS 0x0020 + +#define SOFT_INT 0x0200 /* Generate a S/W interrupt */ + +/* Interrupt masks */ +#define ALL_INT_MASK 0x0100 /* Mask interrupts */ +#define FCP_INT_MASK 0x0400 /* Flow Control Pause */ +#define ER_INT_MASK 0x0800 /* Early Receive */ +#define RNR_INT_MASK 0x1000 /* RU Not Ready */ +#define CNA_INT_MASK 0x2000 /* CU Not Active */ +#define FR_INT_MASK 0x4000 /* Frame Received */ +#define CX_INT_MASK 0x8000 /* CU eXecution w/ I-bit done */ + +/* Interrupts pending */ +#define FCP_INT_PENDING 0x0100 /* Flow Control Pause */ +#define ER_INT_PENDING 0x0200 /* Early Receive */ +#define SWI_INT_PENDING 0x0400 /* S/W generated interrupt */ +#define MDI_INT_PENDING 0x0800 /* MDI read or write done */ +#define RNR_INT_PENDING 0x1000 /* RU Became Not Ready */ +#define CNA_INT_PENDING 0x2000 /* CU Became Inactive (IDLE) */ +#define FR_INT_PENDING 0x4000 /* RU Received A Frame */ +#define CX_INT_PENDING 0x8000 /* CU Completed Action Cmd */ + +/* Status */ +#define CU_STATUS 0x00C0 +#define RU_STATUS 0x003C + +/* Commands */ +#define CU_CMD 0x00F0 +#define RU_CMD 0x0007 + +int e100_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *regs_buff = (u32 *)regs->data; + u8 version = (u8)(regs->version >> 24); + u8 rev_id = (u8)(regs->version); + u8 regs_len = regs->len / sizeof(u32); + u32 reg; + u16 scb_status, scb_cmd; + + if (version != 1) + return -1; + + reg = regs_buff[0]; + scb_status = reg & 0x0000ffff; + scb_cmd = reg >> 16; + fprintf(stdout, + "SCB Status Word (Lower Word) 0x%04X\n", + scb_status); + + switch ((scb_status & RU_STATUS) >> 2) { + case 0: + fprintf(stdout, + " RU Status: Idle\n"); + break; + case 1: + fprintf(stdout, + " RU Status: Suspended\n"); + break; + case 2: + fprintf(stdout, + " RU Status: No Resources\n"); + break; + case 4: + fprintf(stdout, + " RU Status: Ready\n"); + break; + case 9: + fprintf(stdout, + " RU Status: Suspended with no more RBDs\n"); + break; + case 10: + fprintf(stdout, + " RU Status: No Resources due to no more RBDs\n"); + break; + case 12: + fprintf(stdout, + " RU Status: Ready with no RBDs present\n"); + break; + default: + fprintf(stdout, + " RU Status: Unknown State\n"); + break; + } + + switch ((scb_status & CU_STATUS) >> 6) { + case 0: + fprintf(stdout, + " CU Status: Idle\n"); + break; + case 1: + fprintf(stdout, + " CU Status: Suspended\n"); + break; + case 2: + fprintf(stdout, + " CU Status: Active\n"); + break; + default: + fprintf(stdout, + " CU Status: Unknown State\n"); + break; + } + + fprintf(stdout, + " ---- Interrupts Pending ----\n" + " Flow Control Pause: %s\n" + " Early Receive: %s\n" + " Software Generated Interrupt: %s\n" + " MDI Done: %s\n" + " RU Not In Ready State: %s\n" + " CU Not in Active State: %s\n" + " RU Received Frame: %s\n" + " CU Completed Command: %s\n", + scb_status & FCP_INT_PENDING ? "yes" : "no", + scb_status & ER_INT_PENDING ? "yes" : "no", + scb_status & SWI_INT_PENDING ? "yes" : "no", + scb_status & MDI_INT_PENDING ? "yes" : "no", + scb_status & RNR_INT_PENDING ? "yes" : "no", + scb_status & CNA_INT_PENDING ? "yes" : "no", + scb_status & FR_INT_PENDING ? "yes" : "no", + scb_status & CX_INT_PENDING ? "yes" : "no"); + + fprintf(stdout, + "SCB Command Word (Upper Word) 0x%04X\n", + scb_cmd); + + switch (scb_cmd & RU_CMD) { + case 0: + fprintf(stdout, + " RU Command: No Command\n"); + break; + case 1: + fprintf(stdout, + " RU Command: RU Start\n"); + break; + case 2: + fprintf(stdout, + " RU Command: RU Resume\n"); + break; + case 4: + fprintf(stdout, + " RU Command: RU Abort\n"); + break; + case 6: + fprintf(stdout, + " RU Command: Load RU Base\n"); + break; + default: + fprintf(stdout, + " RU Command: Unknown\n"); + break; + } + + switch ((scb_cmd & CU_CMD) >> 4) { + case 0: + fprintf(stdout, + " CU Command: No Command\n"); + break; + case 1: + fprintf(stdout, + " CU Command: CU Start\n"); + break; + case 2: + fprintf(stdout, + " CU Command: CU Resume\n"); + break; + case 4: + fprintf(stdout, + " CU Command: Load Dump Counters Address\n"); + break; + case 5: + fprintf(stdout, + " CU Command: Dump Counters\n"); + break; + case 6: + fprintf(stdout, + " CU Command: Load CU Base\n"); + break; + case 7: + fprintf(stdout, + " CU Command: Dump & Reset Counters\n"); + break; + default: + fprintf(stdout, + " CU Command: Unknown\n"); + break; + } + + fprintf(stdout, + " Software Generated Interrupt: %s\n", + scb_cmd & SOFT_INT ? "yes" : "no"); + + fprintf(stdout, + " ---- Interrupts Masked ----\n" + " ALL Interrupts: %s\n" + " Flow Control Pause: %s\n" + " Early Receive: %s\n" + " RU Not In Ready State: %s\n" + " CU Not in Active State: %s\n" + " RU Received Frame: %s\n" + " CU Completed Command: %s\n", + scb_cmd & ALL_INT_MASK ? "yes" : "no", + scb_cmd & FCP_INT_MASK ? "yes" : "no", + scb_cmd & ER_INT_MASK ? "yes" : "no", + scb_cmd & RNR_INT_MASK ? "yes" : "no", + scb_cmd & CNA_INT_MASK ? "yes" : "no", + scb_cmd & FR_INT_MASK ? "yes" : "no", + scb_cmd & CX_INT_MASK ? "yes" : "no"); + + if(regs_len > 1) { + fprintf(stdout, "MDI/MDI-X Status: "); + if(rev_id < D102_REV_ID) + fprintf(stdout, "MDI\n"); + else { + u16 ctrl_reg = regs_buff[1]; + + if(ctrl_reg & MDI_MDIX_CONFIG_IS_OK) { + if(ctrl_reg & MDI_MDIX_STATUS) + fprintf(stdout, "MDI-X\n"); + else + fprintf(stdout, "MDI\n"); + } else + fprintf(stdout, "Unknown\n"); + } + } + + return 0; +} + diff --git a/e1000.c b/e1000.c new file mode 100644 index 0000000..dbd6eb5 --- /dev/null +++ b/e1000.c @@ -0,0 +1,640 @@ +/* Copyright (c) 2002 Intel Corporation */ +#include +#include "internal.h" + +/* Register Bit Masks */ +/* Device Control */ +#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ +#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */ +#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */ +#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */ +#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */ +#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */ +#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */ +#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ +#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ +#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ +#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ +#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ +#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ +#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ +#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ +#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ +#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ +#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ +#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ +#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */ +#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ +#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */ +#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */ +#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */ +#define E1000_CTRL_RST 0x04000000 /* Global reset */ +#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ +#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ +#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */ +#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */ +#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ + +/* Device Status */ +#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */ +#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ +#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */ +#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ +#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */ +#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ +#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */ +#define E1000_STATUS_SPEED_MASK 0x000000C0 +#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */ +#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ +#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ +#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ +#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */ +#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */ +#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ +#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */ +#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */ + +/* Constants used to intrepret the masked PCI-X bus speed. */ +#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */ +#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */ +#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */ + +/* Receive Control */ +#define E1000_RCTL_RST 0x00000001 /* Software reset */ +#define E1000_RCTL_EN 0x00000002 /* enable */ +#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ +#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */ +#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */ +#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ +#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ +#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ +#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ +#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ +#define E1000_RCTL_RDMTS 0x00000300 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */ +#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ +#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ +#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ +#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ +#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ +#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ +#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ +#define E1000_RCTL_SZ 0x00030000 /* rx buffer size */ +/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ +#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */ +#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */ +#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */ +#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ +/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */ +#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */ +#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */ +#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */ +#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ +#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ +#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ +#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ +#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ +#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ + +/* Transmit Control */ +#define E1000_TCTL_RST 0x00000001 /* software reset */ +#define E1000_TCTL_EN 0x00000002 /* enable tx */ +#define E1000_TCTL_BCE 0x00000004 /* busy check enable */ +#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ +#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ +#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ +#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */ +#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ +#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ +#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ + +/* M88E1000 PHY Specific Status Register */ +#define M88_PSSR_JABBER 0x0001 /* 1=Jabber */ +#define M88_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */ +#define M88_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */ +#define M88_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */ +#define M88_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M; + * 3=110-140M;4=>140M */ +#define M88_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */ +#define M88_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ +#define M88_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */ +#define M88_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ +#define M88_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ +#define M88_PSSR_10MBS 0x0000 /* 00=10Mbs */ +#define M88_PSSR_100MBS 0x4000 /* 01=100Mbs */ +#define M88_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ + +#define M88_PSSR_CL_0_50 (0<<7) +#define M88_PSSR_CL_50_80 (1<<7) +#define M88_PSSR_CL_80_110 (2<<7) +#define M88_PSSR_CL_110_140 (3<<7) +#define M88_PSSR_CL_140_PLUS (4<<7) + +/* M88E1000 PHY Specific Control Register */ +#define M88_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ +#define M88_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */ +#define M88_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */ +#define M88_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low, + * 0=CLK125 toggling + */ +#define M88_PSCR_MDI_MASK 0x0060 +#define M88_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */ + /* Manual MDI configuration */ +#define M88_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ +#define M88_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover, + * 100BASE-TX/10BASE-T: + * MDI Mode + */ +#define M88_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled + * all speeds. + */ +#define M88_PSCR_10BT_EXT_DIST_ENABLE 0x0080 + /* 1=Enable Extended 10BASE-T distance + * (Lower 10BASE-T RX Threshold) + * 0=Normal 10BASE-T RX Threshold */ +#define M88_PSCR_MII_5BIT_ENABLE 0x0100 + /* 1=5-Bit interface in 100BASE-TX + * 0=MII interface in 100BASE-TX */ +#define M88_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ +#define M88_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ +#define M88_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */ + +#define M88_PSCR_POLARITY_REVERSAL_SHIFT 1 +#define M88_PSCR_AUTO_X_MODE_SHIFT 5 +#define M88_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7 + +/* PCI Device IDs */ +#define E1000_DEV_ID_82542 0x1000 +#define E1000_DEV_ID_82543GC_FIBER 0x1001 +#define E1000_DEV_ID_82543GC_COPPER 0x1004 +#define E1000_DEV_ID_82544EI_COPPER 0x1008 +#define E1000_DEV_ID_82544EI_FIBER 0x1009 +#define E1000_DEV_ID_82544GC_COPPER 0x100C +#define E1000_DEV_ID_82544GC_LOM 0x100D +#define E1000_DEV_ID_82540EM 0x100E +#define E1000_DEV_ID_82540EM_LOM 0x1015 +#define E1000_DEV_ID_82540EP_LOM 0x1016 +#define E1000_DEV_ID_82540EP 0x1017 +#define E1000_DEV_ID_82540EP_LP 0x101E +#define E1000_DEV_ID_82545EM_COPPER 0x100F +#define E1000_DEV_ID_82545EM_FIBER 0x1011 +#define E1000_DEV_ID_82545GM_COPPER 0x1026 +#define E1000_DEV_ID_82545GM_FIBER 0x1027 +#define E1000_DEV_ID_82545GM_SERDES 0x1028 +#define E1000_DEV_ID_82546EB_COPPER 0x1010 +#define E1000_DEV_ID_82546EB_FIBER 0x1012 +#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D +#define E1000_DEV_ID_82546GB_COPPER 0x1079 +#define E1000_DEV_ID_82546GB_FIBER 0x107A +#define E1000_DEV_ID_82546GB_SERDES 0x107B +#define E1000_DEV_ID_82546GB_PCIE 0x108A +#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 +#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5 +#define E1000_DEV_ID_82541EI 0x1013 +#define E1000_DEV_ID_82541EI_MOBILE 0x1018 +#define E1000_DEV_ID_82541ER_LOM 0x1014 +#define E1000_DEV_ID_82541ER 0x1078 +#define E1000_DEV_ID_82541GI 0x1076 +#define E1000_DEV_ID_82541GI_LF 0x107C +#define E1000_DEV_ID_82541GI_MOBILE 0x1077 +#define E1000_DEV_ID_82547EI 0x1019 +#define E1000_DEV_ID_82547EI_MOBILE 0x101A +#define E1000_DEV_ID_82547GI 0x1075 +#define E1000_DEV_ID_82571EB_COPPER 0x105E +#define E1000_DEV_ID_82571EB_FIBER 0x105F +#define E1000_DEV_ID_82571EB_SERDES 0x1060 +#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 +#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 +#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC +#define E1000_DEV_ID_82572EI_COPPER 0x107D +#define E1000_DEV_ID_82572EI_FIBER 0x107E +#define E1000_DEV_ID_82572EI_SERDES 0x107F +#define E1000_DEV_ID_82572EI 0x10B9 +#define E1000_DEV_ID_82573E 0x108B +#define E1000_DEV_ID_82573E_IAMT 0x108C +#define E1000_DEV_ID_82573L 0x109A +#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 +#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 +#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA +#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB +#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 +#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A +#define E1000_DEV_ID_ICH8_IGP_C 0x104B +#define E1000_DEV_ID_ICH8_IFE 0x104C +#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4 +#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 +#define E1000_DEV_ID_ICH8_IGP_M 0x104D + +#define E1000_82542_2_0_REV_ID 2 +#define E1000_82542_2_1_REV_ID 3 + +/* Enumerated types specific to the e1000 hardware */ +/* Media Access Controlers */ +enum e1000_mac_type { + e1000_undefined = 0, + e1000_82542, + e1000_82543, + e1000_82544, + e1000_82540, + e1000_82545, + e1000_82545_rev_3, + e1000_82546, + e1000_82546_rev_3, + e1000_82541, + e1000_82541_rev_2, + e1000_82547, + e1000_82547_rev_2, + e1000_82571, + e1000_82572, + e1000_82573, + e1000_80003es2lan, + e1000_ich8lan, + e1000_num_macs +}; + +static enum e1000_mac_type e1000_get_mac_type(u16 device_id) +{ + enum e1000_mac_type mac_type = e1000_undefined; + + switch (device_id) { + case E1000_DEV_ID_82542: + mac_type = e1000_82542; + break; + case E1000_DEV_ID_82543GC_FIBER: + case E1000_DEV_ID_82543GC_COPPER: + mac_type = e1000_82543; + break; + case E1000_DEV_ID_82544EI_COPPER: + case E1000_DEV_ID_82544EI_FIBER: + case E1000_DEV_ID_82544GC_COPPER: + case E1000_DEV_ID_82544GC_LOM: + mac_type = e1000_82544; + break; + case E1000_DEV_ID_82540EM: + case E1000_DEV_ID_82540EM_LOM: + case E1000_DEV_ID_82540EP: + case E1000_DEV_ID_82540EP_LOM: + case E1000_DEV_ID_82540EP_LP: + mac_type = e1000_82540; + break; + case E1000_DEV_ID_82545EM_COPPER: + case E1000_DEV_ID_82545EM_FIBER: + mac_type = e1000_82545; + break; + case E1000_DEV_ID_82545GM_COPPER: + case E1000_DEV_ID_82545GM_FIBER: + case E1000_DEV_ID_82545GM_SERDES: + mac_type = e1000_82545_rev_3; + break; + case E1000_DEV_ID_82546EB_COPPER: + case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: + mac_type = e1000_82546; + break; + case E1000_DEV_ID_82546GB_COPPER: + case E1000_DEV_ID_82546GB_FIBER: + case E1000_DEV_ID_82546GB_SERDES: + case E1000_DEV_ID_82546GB_PCIE: + case E1000_DEV_ID_82546GB_QUAD_COPPER: + case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: + mac_type = e1000_82546_rev_3; + break; + case E1000_DEV_ID_82541EI: + case E1000_DEV_ID_82541EI_MOBILE: + case E1000_DEV_ID_82541ER_LOM: + mac_type = e1000_82541; + break; + case E1000_DEV_ID_82541ER: + case E1000_DEV_ID_82541GI: + case E1000_DEV_ID_82541GI_LF: + case E1000_DEV_ID_82541GI_MOBILE: + mac_type = e1000_82541_rev_2; + break; + case E1000_DEV_ID_82547EI: + case E1000_DEV_ID_82547EI_MOBILE: + mac_type = e1000_82547; + break; + case E1000_DEV_ID_82547GI: + mac_type = e1000_82547_rev_2; + break; + case E1000_DEV_ID_82571EB_COPPER: + case E1000_DEV_ID_82571EB_FIBER: + case E1000_DEV_ID_82571EB_SERDES: + case E1000_DEV_ID_82571EB_QUAD_COPPER: + case E1000_DEV_ID_82571EB_QUAD_FIBER: + case E1000_DEV_ID_82571EB_QUAD_COPPER_LP: + mac_type = e1000_82571; + break; + case E1000_DEV_ID_82572EI: + case E1000_DEV_ID_82572EI_COPPER: + case E1000_DEV_ID_82572EI_FIBER: + case E1000_DEV_ID_82572EI_SERDES: + mac_type = e1000_82572; + break; + case E1000_DEV_ID_82573E: + case E1000_DEV_ID_82573E_IAMT: + case E1000_DEV_ID_82573L: + mac_type = e1000_82573; + break; + case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: + case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: + case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: + case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: + mac_type = e1000_80003es2lan; + break; + case E1000_DEV_ID_ICH8_IFE: + case E1000_DEV_ID_ICH8_IFE_GT: + case E1000_DEV_ID_ICH8_IFE_G: + case E1000_DEV_ID_ICH8_IGP_M: + case E1000_DEV_ID_ICH8_IGP_M_AMT: + case E1000_DEV_ID_ICH8_IGP_AMT: + case E1000_DEV_ID_ICH8_IGP_C: + mac_type = e1000_ich8lan; + break; + default: + /* assume old nic and attempt so user can get limited + * functionality */ + mac_type = e1000_82543; + break; + } + + return mac_type; +} + +int e1000_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *regs_buff = (u32 *)regs->data; + u16 hw_device_id = (u16)regs->version; + /* u8 hw_revision_id = (u8)(regs->version >> 16); */ + u8 version = (u8)(regs->version >> 24); + enum e1000_mac_type mac_type; + u32 reg; + + if (version != 1) + return -1; + + mac_type = e1000_get_mac_type(hw_device_id); + + if(mac_type == e1000_undefined) + return -1; + + fprintf(stdout, "MAC Registers\n"); + fprintf(stdout, "-------------\n"); + + /* Device control register */ + reg = regs_buff[0]; + fprintf(stdout, + "0x00000: CTRL (Device control register) 0x%08X\n" + " Endian mode (buffers): %s\n" + " Link reset: %s\n" + " Set link up: %s\n" + " Invert Loss-Of-Signal: %s\n" + " Receive flow control: %s\n" + " Transmit flow control: %s\n" + " VLAN mode: %s\n", + reg, + reg & E1000_CTRL_BEM ? "big" : "little", + reg & E1000_CTRL_LRST ? "reset" : "normal", + reg & E1000_CTRL_SLU ? "1" : "0", + reg & E1000_CTRL_ILOS ? "yes" : "no", + reg & E1000_CTRL_RFCE ? "enabled" : "disabled", + reg & E1000_CTRL_TFCE ? "enabled" : "disabled", + reg & E1000_CTRL_VME ? "enabled" : "disabled"); + if(mac_type >= e1000_82543) { + fprintf(stdout, + " Auto speed detect: %s\n" + " Speed select: %s\n" + " Force speed: %s\n" + " Force duplex: %s\n", + reg & E1000_CTRL_ASDE ? "enabled" : "disabled", + (reg & E1000_CTRL_SPD_SEL) == E1000_CTRL_SPD_10 ? "10Mb/s" : + (reg & E1000_CTRL_SPD_SEL) == E1000_CTRL_SPD_100 ? "100Mb/s" : + (reg & E1000_CTRL_SPD_SEL) == E1000_CTRL_SPD_1000 ? "1000Mb/s" : + "not used", + reg & E1000_CTRL_FRCSPD ? "yes" : "no", + reg & E1000_CTRL_FRCDPX ? "yes" : "no"); + } + + /* Device status register */ + reg = regs_buff[1]; + fprintf(stdout, + "0x00008: STATUS (Device status register) 0x%08X\n" + " Duplex: %s\n" + " Link up: %s\n", + reg, + reg & E1000_STATUS_FD ? "full" : "half", + reg & E1000_STATUS_LU ? "link config" : "no link config"); + if (mac_type >= e1000_82571) { + fprintf(stdout, + " TBI mode: %s\n" + " Link speed: %s\n" + " Bus type: %s\n" + " Port number: %s\n", + reg & E1000_STATUS_TBIMODE ? "enabled" : "disabled", + (reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_10 ? + "10Mb/s" : + (reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_100 ? + "100Mb/s" : + (reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_1000 ? + "1000Mb/s" : "not used", + "PCI Express", + (reg & E1000_STATUS_FUNC_MASK) == 0 ? "0" : "1"); + } + else if (mac_type >= e1000_82543) { + fprintf(stdout, + " TBI mode: %s\n" + " Link speed: %s\n" + " Bus type: %s\n" + " Bus speed: %s\n" + " Bus width: %s\n", + reg & E1000_STATUS_TBIMODE ? "enabled" : "disabled", + (reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_10 ? + "10Mb/s" : + (reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_100 ? + "100Mb/s" : + (reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_1000 ? + "1000Mb/s" : "not used", + (reg & E1000_STATUS_PCIX_MODE) ? "PCI-X" : "PCI", + (reg & E1000_STATUS_PCIX_MODE) ? + ((reg & E1000_STATUS_PCIX_SPEED_133) ? "133MHz" : + (reg & E1000_STATUS_PCIX_SPEED_100) ? "100MHz" : + "66MHz") : + ((reg & E1000_STATUS_PCI66) ? "66MHz" : "33MHz"), + (reg & E1000_STATUS_BUS64) ? "64-bit" : "32-bit"); + } + + /* Receive control register */ + reg = regs_buff[2]; + fprintf(stdout, + "0x00100: RCTL (Receive control register) 0x%08X\n" + " Receiver: %s\n" + " Store bad packets: %s\n" + " Unicast promiscuous: %s\n" + " Multicast promiscuous: %s\n" + " Long packet: %s\n" + " Descriptor minimum threshold size: %s\n" + " Broadcast accept mode: %s\n" + " VLAN filter: %s\n" + " Canonical form indicator: %s\n" + " Discard pause frames: %s\n" + " Pass MAC control frames: %s\n", + reg, + reg & E1000_RCTL_EN ? "enabled" : "disabled", + reg & E1000_RCTL_SBP ? "enabled" : "disabled", + reg & E1000_RCTL_UPE ? "enabled" : "disabled", + reg & E1000_RCTL_MPE ? "enabled" : "disabled", + reg & E1000_RCTL_LPE ? "enabled" : "disabled", + (reg & E1000_RCTL_RDMTS) == E1000_RCTL_RDMTS_HALF ? "1/2" : + (reg & E1000_RCTL_RDMTS) == E1000_RCTL_RDMTS_QUAT ? "1/4" : + (reg & E1000_RCTL_RDMTS) == E1000_RCTL_RDMTS_EIGTH ? "1/8" : + "reserved", + reg & E1000_RCTL_BAM ? "accept" : "ignore", + reg & E1000_RCTL_VFE ? "enabled" : "disabled", + reg & E1000_RCTL_CFIEN ? "enabled" : "disabled", + reg & E1000_RCTL_DPF ? "ignored" : "filtered", + reg & E1000_RCTL_PMCF ? "pass" : "don't pass"); + if(mac_type >= e1000_82543) { + fprintf(stdout, + " Receive buffer size: %s\n", + reg & E1000_RCTL_BSEX ? + ((reg & E1000_RCTL_SZ)==E1000_RCTL_SZ_16384 ? "16384" : + (reg & E1000_RCTL_SZ)==E1000_RCTL_SZ_8192 ? "8192" : + (reg & E1000_RCTL_SZ)==E1000_RCTL_SZ_4096 ? "4096" : + "reserved") : + ((reg & E1000_RCTL_SZ)==E1000_RCTL_SZ_2048 ? "2048" : + (reg & E1000_RCTL_SZ)==E1000_RCTL_SZ_1024 ? "1024" : + (reg & E1000_RCTL_SZ)==E1000_RCTL_SZ_512 ? "512" : + "256")); + } else { + fprintf(stdout, + " Receive buffer size: %s\n", + (reg & E1000_RCTL_SZ) == E1000_RCTL_SZ_2048 ? "2048" : + (reg & E1000_RCTL_SZ) == E1000_RCTL_SZ_1024 ? "1024" : + (reg & E1000_RCTL_SZ) == E1000_RCTL_SZ_512 ? "512" : + "256"); + } + + /* Receive descriptor registers */ + fprintf(stdout, + "0x02808: RDLEN (Receive desc length) 0x%08X\n", + regs_buff[3]); + fprintf(stdout, + "0x02810: RDH (Receive desc head) 0x%08X\n", + regs_buff[4]); + fprintf(stdout, + "0x02818: RDT (Receive desc tail) 0x%08X\n", + regs_buff[5]); + fprintf(stdout, + "0x02820: RDTR (Receive delay timer) 0x%08X\n", + regs_buff[6]); + + /* Transmit control register */ + reg = regs_buff[7]; + fprintf(stdout, + "0x00400: TCTL (Transmit ctrl register) 0x%08X\n" + " Transmitter: %s\n" + " Pad short packets: %s\n" + " Software XOFF Transmission: %s\n", + reg, + reg & E1000_TCTL_EN ? "enabled" : "disabled", + reg & E1000_TCTL_PSP ? "enabled" : "disabled", + reg & E1000_TCTL_SWXOFF ? "enabled" : "disabled"); + if(mac_type >= e1000_82543) { + fprintf(stdout, + " Re-transmit on late collision: %s\n", + reg & E1000_TCTL_RTLC ? "enabled" : "disabled"); + } + + /* Transmit descriptor registers */ + fprintf(stdout, + "0x03808: TDLEN (Transmit desc length) 0x%08X\n", + regs_buff[8]); + fprintf(stdout, + "0x03810: TDH (Transmit desc head) 0x%08X\n", + regs_buff[9]); + fprintf(stdout, + "0x03818: TDT (Transmit desc tail) 0x%08X\n", + regs_buff[10]); + fprintf(stdout, + "0x03820: TIDV (Transmit delay timer) 0x%08X\n", + regs_buff[11]); + + /* PHY type */ + fprintf(stdout, + "PHY type: %s\n", + regs_buff[12] == 0 ? "M88" : + regs_buff[12] == 1 ? "IGP" : + regs_buff[12] == 2 ? "IGP2" : "unknown" ); + + if (0 == regs_buff[12]) { + reg = regs_buff[13]; + fprintf(stdout, + "M88 PHY STATUS REGISTER: 0x%08X\n" + " Jabber: %s\n" + " Polarity: %s\n" + " Downshifted: %s\n" + " MDI/MDIX: %s\n" + " Cable Length Estimate: %s meters\n" + " Link State: %s\n" + " Speed & Duplex Resolved: %s\n" + " Page Received: %s\n" + " Duplex: %s\n" + " Speed: %s mbps\n", + reg, + reg & M88_PSSR_JABBER ? "yes" : "no", + reg & M88_PSSR_REV_POLARITY ? "reverse" : "normal", + reg & M88_PSSR_DOWNSHIFT ? "yes" : "no", + reg & M88_PSSR_MDIX ? "MDIX" : "MDI", + ((reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_0_50 ? "0-50" + : (reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_50_80 ? "50-80" + : (reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_80_110 ? "80-110" + : (reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_110_140? "110-140" + : (reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_140_PLUS ? "140+" + : "unknown"), + reg & M88_PSSR_LINK ? "Up" : "Down", + reg & M88_PSSR_SPD_DPLX_RESOLVED ? "Yes" : "No", + reg & M88_PSSR_PAGE_RCVD ? "Yes" : "No", + reg & M88_PSSR_DPLX ? "Full" : "Half", + ((reg & M88_PSSR_SPEED)==M88_PSSR_10MBS ? "10" + : (reg & M88_PSSR_SPEED)==M88_PSSR_100MBS ? "100" + : (reg & M88_PSSR_SPEED)==M88_PSSR_1000MBS ? "1000" + : "unknown") + ); + + reg = regs_buff[17]; + fprintf(stdout, + "M88 PHY CONTROL REGISTER: 0x%08X\n" + " Jabber function: %s\n" + " Auto-polarity: %s\n" + " SQE Test: %s\n" + " CLK125: %s\n" + " Auto-MDIX: %s\n" + " Extended 10Base-T Distance: %s\n" + " 100Base-TX Interface: %s\n" + " Scrambler: %s\n" + " Force Link Good: %s\n" + " Assert CRS on Transmit: %s\n", + reg, + reg & M88_PSCR_JABBER_DISABLE ? "disabled" : "enabled", + reg & M88_PSCR_POLARITY_REVERSAL ? "enabled" : "disabled", + reg & M88_PSCR_SQE_TEST ? "enabled" : "disabled", + reg & M88_PSCR_CLK125_DISABLE ? "disabled" : "enabled", + ((reg & M88_PSCR_MDI_MASK)==M88_PSCR_MDI_MANUAL_MODE ? "force MDI" + : (reg & M88_PSCR_MDI_MASK)==M88_PSCR_MDIX_MANUAL_MODE ? "force MDIX" + : (reg & M88_PSCR_MDI_MASK)==M88_PSCR_AUTO_X_1000T ? "1000 auto, 10/100 MDI" + : (reg & M88_PSCR_MDI_MASK)==M88_PSCR_AUTO_X_MODE ? "auto" + : "wtf"), + reg & M88_PSCR_10BT_EXT_DIST_ENABLE ? "enabled" : "disabled", + reg & M88_PSCR_MII_5BIT_ENABLE ? "5-bit" : "MII", + reg & M88_PSCR_SCRAMBLER_DISABLE ? "disabled" : "enabled", + reg & M88_PSCR_FORCE_LINK_GOOD ? "forced" : "disabled", + reg & M88_PSCR_ASSERT_CRS_ON_TX ? "enabled" : "disabled" + ); + } + + return 0; +} + diff --git a/et131x.c b/et131x.c new file mode 100644 index 0000000..a23f7a2 --- /dev/null +++ b/et131x.c @@ -0,0 +1,124 @@ +#include +#include +#include "internal.h" + +int et131x_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u8 version = (u8)(regs->version >> 24); + u32 *reg = (u32 *)regs->data; + + if (version != 1) + return -1; + + fprintf(stdout, "PHY Registers\n"); + fprintf(stdout, "0x0, Basic Control Reg = 0x%04X\n", *reg++); + fprintf(stdout, "0x1, Basic Status Reg = 0x%04X\n", *reg++); + fprintf(stdout, "0x2, PHY identifier 1 = 0x%04X\n", *reg++); + fprintf(stdout, "0x3, PHY identifier 2 = 0x%04X\n", *reg++); + fprintf(stdout, "0x4, Auto Neg Advertisement = 0x%04X\n", *reg++); + fprintf(stdout, "0x5, Auto Neg L Partner Ability = 0x%04X\n", *reg++); + fprintf(stdout, "0x6, Auto Neg Expansion = 0x%04X\n", *reg++); + fprintf(stdout, "0x7, Reserved = 0x%04X\n", *reg++); + fprintf(stdout, "0x8, Reserved = 0x%04X\n", *reg++); + fprintf(stdout, "0x9, 1000T Control = 0x%04X\n", *reg++); + fprintf(stdout, "0xA, 1000T Status = 0x%04X\n", *reg++); + fprintf(stdout, "0xB, Reserved = 0x%04X\n", *reg++); + fprintf(stdout, "0xC, Reserved = 0x%04X\n", *reg++); + fprintf(stdout, "0xD, MMD Access Control = 0x%04X\n", *reg++); + fprintf(stdout, "0xE, MMD access Data = 0x%04X\n", *reg++); + fprintf(stdout, "0xF, Extended Status = 0x%04X\n", *reg++); + fprintf(stdout, "0x10, Phy Index = 0x%04X\n", *reg++); + fprintf(stdout, "0x11, Phy Data = 0x%04X\n", *reg++); + fprintf(stdout, "0x12, MPhy Control = 0x%04X\n", *reg++); + fprintf(stdout, "0x13, Phy Loopback Control1 = 0x%04X\n", *reg++); + fprintf(stdout, "0x14, Phy Loopback Control2 = 0x%04X\n", *reg++); + fprintf(stdout, "0x15, Register Management = 0x%04X\n", *reg++); + fprintf(stdout, "0x16, Phy Config = 0x%04X\n", *reg++); + fprintf(stdout, "0x17, Phy Phy Control = 0x%04X\n", *reg++); + fprintf(stdout, "0x18, Phy Interrupt Mask = 0x%04X\n", *reg++); + fprintf(stdout, "0x19, Phy Interrupt Status = 0x%04X\n", *reg++); + fprintf(stdout, "0x1A, Phy Phy Status = 0x%04X\n", *reg++); + fprintf(stdout, "0x1B, Phy LED1 = 0x%04X\n", *reg++); + fprintf(stdout, "0x1C, Phy LED2 = 0x%04X\n", *reg++); + fprintf(stdout, "\n"); + + fprintf(stdout, "JAGCore Global Registers\n"); + fprintf(stdout, "0x0, TXQ Start Address = 0x%04X\n", *reg++); + fprintf(stdout, "0x1, TXQ End Address = 0x%04X\n", *reg++); + fprintf(stdout, "0x2, RXQ Start Address = 0x%04X\n", *reg++); + fprintf(stdout, "0x3, RXQ End Address = 0x%04X\n", *reg++); + fprintf(stdout, "0x4, Power Management Status = 0x%04X\n", *reg++); + fprintf(stdout, "0x5, Interrupt Status = 0x%04X\n", *reg++); + fprintf(stdout, "0x6, Interrupt Mask = 0x%04X\n", *reg++); + fprintf(stdout, "0x7, Int Alias Clear Mask = 0x%04X\n", *reg++); + fprintf(stdout, "0x8, Int Status Alias = 0x%04X\n", *reg++); + fprintf(stdout, "0x9, Software Reset = 0x%04X\n", *reg++); + fprintf(stdout, "0xA, SLV Timer = 0x%04X\n", *reg++); + fprintf(stdout, "0xB, MSI Config = 0x%04X\n", *reg++); + fprintf(stdout, "0xC, Loopback = 0x%04X\n", *reg++); + fprintf(stdout, "0xD, Watchdog Timer = 0x%04X\n", *reg++); + fprintf(stdout, "\n"); + + fprintf(stdout, "TXDMA Registers\n"); + fprintf(stdout, "0x0, Control Status = 0x%04X\n", *reg++); + fprintf(stdout, "0x1, Packet Ring Base Addr (Hi) = 0x%04X\n", *reg++); + fprintf(stdout, "0x2, Packet Ring Base Addr (Lo) = 0x%04X\n", *reg++); + fprintf(stdout, "0x3, Packet Ring Num Descrs = 0x%04X\n", *reg++); + fprintf(stdout, "0x4, TX Queue Write Address = 0x%04X\n", *reg++); + fprintf(stdout, "0x5, TX Queue Write Address Ext = 0x%04X\n", *reg++); + fprintf(stdout, "0x6, TX Queue Read Address = 0x%04X\n", *reg++); + fprintf(stdout, "0x7, Status Writeback Addr (Hi) = 0x%04X\n", *reg++); + fprintf(stdout, "0x8, Status Writeback Addr (Lo) = 0x%04X\n", *reg++); + fprintf(stdout, "0x9, Service Request = 0x%04X\n", *reg++); + fprintf(stdout, "0xA, Service Complete = 0x%04X\n", *reg++); + fprintf(stdout, "0xB, Cache Read Index = 0x%04X\n", *reg++); + fprintf(stdout, "0xC, Cache Write Index = 0x%04X\n", *reg++); + fprintf(stdout, "0xD, TXDMA Error = 0x%04X\n", *reg++); + fprintf(stdout, "0xE, Descriptor Abort Count = 0x%04X\n", *reg++); + fprintf(stdout, "0xF, Payload Abort Count = 0x%04X\n", *reg++); + fprintf(stdout, "0x10, Writeback Abort Count = 0x%04X\n", *reg++); + fprintf(stdout, "0x11, Descriptor Timeout Count = 0x%04X\n", *reg++); + fprintf(stdout, "0x12, Payload Timeout Count = 0x%04X\n", *reg++); + fprintf(stdout, "0x13, Writeback Timeout Count = 0x%04X\n", *reg++); + fprintf(stdout, "0x14, Descriptor Error Count = 0x%04X\n", *reg++); + fprintf(stdout, "0x15, Payload Error Count = 0x%04X\n", *reg++); + fprintf(stdout, "0x16, Writeback Error Count = 0x%04X\n", *reg++); + fprintf(stdout, "0x17, Dropped TLP Count = 0x%04X\n", *reg++); + fprintf(stdout, "0x18, New service Complete = 0x%04X\n", *reg++); + fprintf(stdout, "0x1A, Ethernet Packet Count = 0x%04X\n", *reg++); + fprintf(stdout, "\n"); + + fprintf(stdout, "RXDMA Registers\n"); + fprintf(stdout, "0x0, Control Status = 0x%04X\n", *reg++); + fprintf(stdout, "0x1, Writeback Addr (Hi) = 0x%04X\n", *reg++); + fprintf(stdout, "0x2, Writeback Addr (Lo) = 0x%04X\n", *reg++); + fprintf(stdout, "0x3, Num Packets Done = 0x%04X\n", *reg++); + fprintf(stdout, "0x4, Max Packet Time = 0x%04X\n", *reg++); + fprintf(stdout, "0x5, RX Queue Read Addr = 0x%04X\n", *reg++); + fprintf(stdout, "0x6, RX Queue Read Address Ext = 0x%04X\n", *reg++); + fprintf(stdout, "0x7, RX Queue Write Addr = 0x%04X\n", *reg++); + fprintf(stdout, "0x8, Packet Ring Base Addr (Hi) = 0x%04X\n", *reg++); + fprintf(stdout, "0x9, Packet Ring Base Addr (Lo) = 0x%04X\n", *reg++); + fprintf(stdout, "0xA, Packet Ring Num Descrs = 0x%04X\n", *reg++); + fprintf(stdout, "0xE, Packet Ring Avail Offset = 0x%04X\n", *reg++); + fprintf(stdout, "0xF, Packet Ring Full Offset = 0x%04X\n", *reg++); + fprintf(stdout, "0x10, Packet Ring Access Index = 0x%04X\n", *reg++); + fprintf(stdout, "0x11, Packet Ring Min Descrip = 0x%04X\n", *reg++); + fprintf(stdout, "0x12, FBR0 Address (Lo) = 0x%04X\n", *reg++); + fprintf(stdout, "0x13, FBR0 Address (Hi) = 0x%04X\n", *reg++); + fprintf(stdout, "0x14, FBR0 Num Descriptors = 0x%04X\n", *reg++); + fprintf(stdout, "0x15, FBR0 Available Offset = 0x%04X\n", *reg++); + fprintf(stdout, "0x16, FBR0 Full Offset = 0x%04X\n", *reg++); + fprintf(stdout, "0x17, FBR0 Read Index = 0x%04X\n", *reg++); + fprintf(stdout, "0x18, FBR0 Minimum Descriptors = 0x%04X\n", *reg++); + fprintf(stdout, "0x19, FBR1 Address (Lo) = 0x%04X\n", *reg++); + fprintf(stdout, "0x1A, FBR1 Address (Hi) = 0x%04X\n", *reg++); + fprintf(stdout, "0x1B, FBR1 Num Descriptors = 0x%04X\n", *reg++); + fprintf(stdout, "0x1C, FBR1 Available Offset = 0x%04X\n", *reg++); + fprintf(stdout, "0x1D, FBR1 Full Offset = 0x%04X\n", *reg++); + fprintf(stdout, "0x1E, FBR1 Read Index = 0x%04X\n", *reg++); + fprintf(stdout, "0x1F, FBR1 Minimum Descriptors = 0x%04X\n", *reg++); + fprintf(stdout, "\n"); + return 0; +} diff --git a/ethtool-config.h.in b/ethtool-config.h.in new file mode 100644 index 0000000..9bbf281 --- /dev/null +++ b/ethtool-config.h.in @@ -0,0 +1,43 @@ +/* ethtool-config.h.in. Generated from configure.ac by autoheader. */ + +/* Define this to support netlink interface to talk to kernel. */ +#undef ETHTOOL_ENABLE_NETLINK + +/* Define this to enable register, EEPROM and SFP pretty dumps. */ +#undef ETHTOOL_ENABLE_PRETTY_DUMP + +/* Define to 1 if defines big-endian types */ +#undef HAVE_BE_TYPES + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/ethtool.8 b/ethtool.8 new file mode 100644 index 0000000..26b3cfb --- /dev/null +++ b/ethtool.8 @@ -0,0 +1,1531 @@ +.\" -*- nroff -*- +.\" Copyright 1999 by David S. Miller. All Rights Reserved. +.\" Portions Copyright 2001 Sun Microsystems +.\" Portions Copyright 2007, 2009 Free Software Foundation, Inc. +.\" This file may be copied under the terms of the GNU Public License. +.\" +.\" There must be no text lines before .TH. Use '.' for vertical spacing. +.\" +.\" .An - list of n alternative values as in "flav vanilla|strawberry" +.\" +.de A1 +\\fB\\$1\\fP|\\fB\\$2\\fP +.. +.de A2 +\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP +.. +.de A3 +\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP|\\fB\\$4\\fP +.. +.de A4 +\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP|\\fB\\$4\\fP|\\fB\\$5\\fP +.. +.\" +.\" .Bn - same as above but framed by square brackets +.\" +.de B1 +[\\fB\\$1\\fP|\\fB\\$2\\fP] +.. +.de B2 +[\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP] +.. +.de B3 +[\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP|\\fB\\$4\\fP] +.. +.de B4 +[\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP|\\fB\\$4\\fP|\\fB\\$5\\fP] +.. +.\" +.\" .BN - value with a numeric input as in "[value N]" +.\" +.de BN +[\\fB\\$1\\fP\ \\fIN\\fP] +.. +.\" +.\" .BM - same as above but has a mask field for format "[value N [m N]]" +.\" +.de BM +[\\fB\\$1\\fP\ \\fIN\\fP\ [\\fBm\\fP\ \\fIN\\fP]] +.. +.\" +.\" \(*MA - mac address +.\" +.ds MA \fIxx\fP\fB:\fP\fIyy\fP\fB:\fP\fIzz\fP\fB:\fP\fIaa\fP\fB:\fP\fIbb\fP\fB:\fP\fIcc\fP +.\" +.\" \(*MS - master-slave property +.\" +.ds MS \fBpreferred-master\fP|\fBpreferred-slave\fP|\fBforced-master\fP|\fBforced-slave\fP +.\" +.\" \(*PA - IP address +.\" +.ds PA \fIip-address\fP +.\" +.\" \(*WO - wol flags +.\" +.ds WO \fBp\fP|\fBu\fP|\fBm\fP|\fBb\fP|\fBa\fP|\fBg\fP|\fBs\fP|\fBf|\fBd\fP... +.\" +.\" \(*FL - flow type values +.\" +.ds FL \fBtcp4\fP|\fBudp4\fP|\fBah4\fP|\fBesp4\fP|\fBsctp4\fP|\fBtcp6\fP|\fBudp6\fP|\fBah6\fP|\fBesp6\fP|\fBsctp6\fP +.\" +.\" \(*HO - hash options +.\" +.ds HO \fBm\fP|\fBv\fP|\fBt\fP|\fBs\fP|\fBd\fP|\fBf\fP|\fBn\fP|\fBr\fP... +.\" +.\" \(*SD - Self-diag test values +.\" +.ds SD \fBoffline\fP|\fBonline\fP|\fBexternal_lb\fP +.\" +.\" \(*NC - Network Classifier type values +.\" +.ds NC \fBether\fP|\fBip4\fP|\fBtcp4\fP|\fBudp4\fP|\fBsctp4\fP|\fBah4\fP|\fBesp4\fP|\fBip6\fP|\fBtcp6\fP|\fBudp6\fP|\fBah6\fP|\fBesp6\fP|\fBsctp6\fP +. +.\" +.\" Start URL. +.de UR +. ds m1 \\$1\" +. nh +. if \\n(mH \{\ +. \" Start diversion in a new environment. +. do ev URL-div +. do di URL-div +. \} +.. +.\" End URL. +.de UE +. ie \\n(mH \{\ +. br +. di +. ev +. +. \" Has there been one or more input lines for the link text? +. ie \\n(dn \{\ +. do HTML-NS "" +. \" Yes, strip off final newline of diversion and emit it. +. do chop URL-div +. do URL-div +\c +. do HTML-NS +. \} +. el \ +. do HTML-NS "\\*(m1" +\&\\$*\" +. \} +. el \ +\\*(la\\*(m1\\*(ra\\$*\" +. +. hy \\n(HY +.. +. +.TH ETHTOOL 8 "December 2022" "Ethtool version 6.1" +.SH NAME +ethtool \- query or control network driver and hardware settings +. +.SH SYNOPSIS +.\" Do not adjust lines (i.e. left justification) and do not hyphenate. +.na +.nh +.HP +.B ethtool +.I devname +.HP +.B ethtool \-h|\-\-help +.HP +.B ethtool \-\-version +.HP +.B ethtool +.BN --debug +.I args +.HP +.B ethtool [--json] +.I args +.HP +.B ethtool [-I | --include-statistics] +.I args +.HP +.B ethtool \-\-monitor +[ +.I command +] [ +.I devname +] +.HP +.B ethtool \-a|\-\-show\-pause +.I devname +.HP +.B ethtool \-A|\-\-pause +.I devname +.B2 autoneg on off +.B2 rx on off +.B2 tx on off +.HP +.B ethtool \-c|\-\-show\-coalesce +.I devname +.HP +.B ethtool \-C|\-\-coalesce +.I devname +.B2 adaptive\-rx on off +.B2 adaptive\-tx on off +.BN rx\-usecs +.BN rx\-frames +.BN rx\-usecs\-irq +.BN rx\-frames\-irq +.BN tx\-usecs +.BN tx\-frames +.BN tx\-usecs\-irq +.BN tx\-frames\-irq +.BN stats\-block\-usecs +.BN pkt\-rate\-low +.BN rx\-usecs\-low +.BN rx\-frames\-low +.BN tx\-usecs\-low +.BN tx\-frames\-low +.BN pkt\-rate\-high +.BN rx\-usecs\-high +.BN rx\-frames\-high +.BN tx\-usecs\-high +.BN tx\-frames\-high +.BN sample\-interval +.B2 cqe\-mode\-rx on off +.B2 cqe\-mode\-tx on off +.HP +.B ethtool \-g|\-\-show\-ring +.I devname +.HP +.B ethtool \-G|\-\-set\-ring +.I devname +.BN rx +.BN rx\-mini +.BN rx\-jumbo +.BN tx +.BN rx\-buf\-len +.BN cqe\-size +.BN tx\-push +.HP +.B ethtool \-i|\-\-driver +.I devname +.HP +.B ethtool \-d|\-\-register\-dump +.I devname +.B2 raw on off +.B2 hex on off +.RB [ file +.IR name ] +.HP +.B ethtool \-e|\-\-eeprom\-dump +.I devname +.B2 raw on off +.BN offset +.BN length +.HP +.B ethtool \-E|\-\-change\-eeprom +.I devname +.BN magic +.BN offset +.BN length +.BN value +.HP +.B ethtool \-k|\-\-show\-features|\-\-show\-offload +.I devname +.HP +.B ethtool \-K|\-\-features|\-\-offload +.I devname feature +.A1 on off +.RB ... +.HP +.B ethtool \-p|\-\-identify +.I devname +.RI [ N ] +.HP +.B ethtool \-P|\-\-show\-permaddr +.I devname +.HP +.B ethtool \-r|\-\-negotiate +.I devname +.HP +.B ethtool \-S|\-\-statistics +.I devname +.RB [\fB\-\-all\-groups\fP|\fB\-\-groups +.RB [\fBeth\-phy\fP] +.RB [\fBeth\-mac\fP] +.RB [\fBeth\-ctrl\fP] +.RB [\fBrmon\fP] +.RB ] +.HP +.B ethtool \-\-phy\-statistics +.I devname +.HP +.B ethtool \-t|\-\-test +.I devname +.RI [\*(SD] +.HP +.B ethtool \-s +.I devname +.BN speed +.BN lanes +.B2 duplex half full +.B4 port tp aui bnc mii fibre da +.B3 mdix auto on off +.B2 autoneg on off +.RB [ advertise \ \fIN\fP[\fB/\fP\fIM\fP] +| +.BI advertise \ mode +.A1 on off +.RB ...] +.BN phyad +.B2 xcvr internal external +.RB [ wol \ \fIN\fP[\fB/\fP\fIM\fP] +.RB | \ wol \ \*(WO] +.RB [ sopass \ \*(MA] +.RB [ master-slave \ \*(MS] +.RB [ msglvl +.IR N\fP[/\fIM\fP] \ | +.BI msglvl \ type +.A1 on off +.RB ...] +.HP +.B ethtool \-n|\-u|\-\-show\-nfc|\-\-show\-ntuple +.I devname +.RB [\ rx\-flow\-hash \ \*(FL \ | +.br +.BI rule \ N +.RB ] +.HP +.B ethtool \-N|\-U|\-\-config\-nfc|\-\-config\-ntuple +.I devname +.BR rx\-flow\-hash \ \*(FL \ \: \*(HO \ | +.br +.B flow\-type \*(NC +.RB [ src \ \*(MA\ [ m \ \*(MA]] +.RB [ dst \ \*(MA\ [ m \ \*(MA]] +.BM proto +.RB [ src\-ip \ \*(PA\ [ m \ \*(PA]] +.RB [ dst\-ip \ \*(PA\ [ m \ \*(PA]] +.BM tos +.BM tclass +.BM l4proto +.BM src\-port +.BM dst\-port +.BM spi +.BM l4data +.BM vlan\-etype +.BM vlan +.BM user\-def +.RB [ dst-mac \ \*(MA\ [ m \ \*(MA]] +.BN action +.BN context +.BN loc +.RB | +.br +.BI delete \ N +.HP +.B ethtool \-w|\-\-get\-dump +.I devname +.RB [ data +.IR filename ] +.HP +.B ethtool\ \-W|\-\-set\-dump +.I devname N +.HP +.B ethtool \-T|\-\-show\-time\-stamping +.I devname +.HP +.B ethtool \-x|\-\-show\-rxfh\-indir|\-\-show\-rxfh +.I devname +.HP +.B ethtool \-X|\-\-set\-rxfh\-indir|\-\-rxfh +.I devname +.RB [ hkey \ \*(MA:\...] +.RB [ start +.IR N ] +.RB [\ equal +.IR N \ | +.BI weight\ W0 +.IR W1 +.RB ...\ | \ default \ ] +.RB [ hfunc +.IR FUNC ] +.RB [ context +.I CTX +.RB |\ new ] +.RB [ delete ] +.HP +.B ethtool \-f|\-\-flash +.I devname file +.RI [ N ] +.HP +.B ethtool \-l|\-\-show\-channels +.I devname +.HP +.B ethtool \-L|\-\-set\-channels +.I devname +.BN rx +.BN tx +.BN other +.BN combined +.HP +.B ethtool \-m|\-\-dump\-module\-eeprom|\-\-module\-info +.I devname +.B2 raw on off +.B2 hex on off +.BN offset +.BN length +.BN page +.BN bank +.BN i2c +.HP +.B ethtool \-\-show\-priv\-flags +.I devname +.HP +.B ethtool \-\-set\-priv\-flags +.I devname flag +.A1 on off +.RB ... +.HP +.B ethtool \-\-show\-eee +.I devname +.HP +.B ethtool \-\-set\-eee +.I devname +.B2 eee on off +.B2 tx-lpi on off +.BN tx-timer +.BN advertise +.HP +.B ethtool \-\-set\-phy\-tunable +.I devname +.RB [ +.B downshift +.A1 on off +.BN count +.RB ] +.RB [ +.B fast\-link\-down +.A1 on off +.BN msecs +.RB ] +.RB [ +.B energy\-detect\-power\-down +.A1 on off +.BN msecs +.RB ] +.HP +.B ethtool \-\-get\-phy\-tunable +.I devname +.RB [ downshift ] +.RB [ fast-link-down ] +.RB [ energy-detect-power-down ] +.HP +.B ethtool \-\-get\-tunable +.I devname +.RB [ rx-copybreak ] +.RB [ tx-copybreak ] +.RB [ tx-buf-size ] +.RB [ pfc-prevention-tout ] +.HP +.B ethtool \-\-set\-tunable +.I devname +.BN rx\-copybreak +.BN tx\-copybreak +.BN tx\-buf\-size +.BN pfc\-prevention\-tout +.HP +.B ethtool \-\-reset +.I devname +.BN flags +.RB [ mgmt ] +.RB [ mgmt-shared ] +.RB [ irq ] +.RB [ irq-shared ] +.RB [ dma ] +.RB [ dma-shared ] +.RB [ filter ] +.RB [ filter-shared ] +.RB [ offload ] +.RB [ offload-shared ] +.RB [ mac ] +.RB [ mac-shared ] +.RB [ phy ] +.RB [ phy-shared ] +.RB [ ram ] +.RB [ ram-shared ] +.RB [ ap ] +.RB [ ap-shared ] +.RB [ dedicated ] +.RB [ all ] +.HP +.B ethtool \-\-show\-fec +.I devname +.HP +.B ethtool \-\-set\-fec +.I devname +.B encoding +.BR auto | off | rs | baser | llrs \ [...] +.HP +.B ethtool \-Q|\-\-per\-queue +.I devname +.RB [ queue_mask +.IR %x ] +.I sub_command +.RB ... + . +.HP +.B ethtool \-\-cable\-test +.I devname +.HP +.B ethtool \-\-cable\-test\-tdr +.I devname +.BN first N +.BN last N +.BN step N +.BN pair N +.HP +.B ethtool \-\-show\-tunnels +.I devname +.HP +.B ethtool \-\-show\-module +.I devname +.HP +.B ethtool \-\-set\-module +.I devname +.RB [ power\-mode\-policy +.BR high | auto ] +. +.\" Adjust lines (i.e. full justification) and hyphenate. +.ad +.hy + +.SH DESCRIPTION +.BI ethtool +is used to query and control network device driver and hardware +settings, particularly for wired Ethernet devices. + +.I devname +is the name of the network device on which ethtool should operate. + +.SH OPTIONS +.B ethtool +with a single argument specifying the device name prints current +settings of the specified device. +.TP +.B \-h \-\-help +Shows a short help message. +.TP +.B \-\-version +Shows the ethtool version number. +.TP +.BI \-\-debug \ N +Turns on debugging messages. Argument is interpreted as a mask: +.TS +nokeep; +lB l. +0x01 Parser information +.TE +.TP +.BI \-\-json +Output results in JavaScript Object Notation (JSON). Only a subset of +options support this. Those which do not will continue to output +plain text in the presence of this option. +.TP +.B \-I \-\-include\-statistics +Include command-related statistics in the output. This option allows +displaying relevant device statistics for selected get commands. +.TP +.B \-a \-\-show\-pause +Queries the specified Ethernet device for pause parameter information. +.TP +.B \-A \-\-pause +Changes the pause parameters of the specified Ethernet device. +.RS 4 +.TP +.A2 autoneg on off +Specifies whether pause autonegotiation should be enabled. +.TP +.A2 rx on off +Specifies whether RX pause should be enabled. +.TP +.A2 tx on off +Specifies whether TX pause should be enabled. +.RE +.TP +.B \-c \-\-show\-coalesce +Queries the specified network device for coalescing information. +.TP +.B \-C \-\-coalesce +Changes the coalescing settings of the specified network device. +.TP +.B \-g \-\-show\-ring +Queries the specified network device for rx/tx ring parameter information. +.TP +.B \-G \-\-set\-ring +Changes the rx/tx ring parameters of the specified network device. +.RS 4 +.TP +.BI rx \ N +Changes the number of ring entries for the Rx ring. +.TP +.BI rx\-mini \ N +Changes the number of ring entries for the Rx Mini ring. +.TP +.BI rx\-jumbo \ N +Changes the number of ring entries for the Rx Jumbo ring. +.TP +.BI tx \ N +Changes the number of ring entries for the Tx ring. +.TP +.BI rx\-buf\-len \ N +Changes the size of a buffer in the Rx ring. +.TP +.BI cqe\-size \ N +Changes the size of completion queue event. +.TP +.BI tx\-push \ on|off +Specifies whether TX push should be enabled. +.RE +.TP +.B \-i \-\-driver +Queries the specified network device for associated driver information. +.TP +.B \-d \-\-register\-dump +Retrieves and prints a register dump for the specified network device. +The register format for some devices is known and decoded others +are printed in hex. +When +.I raw +is enabled, then ethtool dumps the raw register data to stdout. +If +.I file +is specified, then use contents of previous raw register dump, rather +than reading from the device. +.TP +.B \-e \-\-eeprom\-dump +Retrieves and prints an EEPROM dump for the specified network device. +When raw is enabled, then it dumps the raw EEPROM data to stdout. The +length and offset parameters allow dumping certain portions of the EEPROM. +Default is to dump the entire EEPROM. +.RS 4 +.TP +.BI raw \ on|off +.TP +.BI offset \ N +.TP +.BI length \ N +.RE +.TP +.B \-E \-\-change\-eeprom +If value is specified, changes EEPROM byte for the specified network device. +offset and value specify which byte and it's new value. If value is not +specified, stdin is read and written to the EEPROM. The length and offset +parameters allow writing to certain portions of the EEPROM. +Because of the persistent nature of writing to the EEPROM, a device-specific +magic key must be specified to prevent the accidental writing to the EEPROM. +.TP +.B \-k \-\-show\-features \-\-show\-offload +Queries the specified network device for the state of protocol +offload and other features. +.TP +.B \-K \-\-features \-\-offload +Changes the offload parameters and other features of the specified +network device. The following feature names are built-in and others +may be defined by the kernel. +.RS 4 +.TP +.A2 rx on off +Specifies whether RX checksumming should be enabled. +.TP +.A2 tx on off +Specifies whether TX checksumming should be enabled. +.TP +.A2 sg on off +Specifies whether scatter-gather should be enabled. +.TP +.A2 tso on off +Specifies whether TCP segmentation offload should be enabled. +.TP +.A2 ufo on off +Specifies whether UDP fragmentation offload should be enabled +.TP +.A2 gso on off +Specifies whether generic segmentation offload should be enabled +.TP +.A2 gro on off +Specifies whether generic receive offload should be enabled +.TP +.A2 lro on off +Specifies whether large receive offload should be enabled +.TP +.A2 rxvlan on off +Specifies whether RX VLAN acceleration should be enabled +.TP +.A2 txvlan on off +Specifies whether TX VLAN acceleration should be enabled +.TP +.A2 ntuple on off +Specifies whether Rx ntuple filters and actions should be enabled +.TP +.A2 rxhash on off +Specifies whether receive hashing offload should be enabled +.RE +.TP +.B \-p \-\-identify +Initiates adapter-specific action intended to enable an operator to +easily identify the adapter by sight. Typically this involves +blinking one or more LEDs on the specific network port. +.RS 4 +.TP +.BN +Length of time to perform phys-id, in seconds. +.RE +.TP +.B \-P \-\-show\-permaddr +Queries the specified network device for permanent hardware address. +.TP +.B \-r \-\-negotiate +Restarts auto-negotiation on the specified Ethernet device, if +auto-negotiation is enabled. +.TP +.B \-S \-\-statistics +Queries the specified network device for standard (IEEE, IETF, etc.), or NIC- +and driver-specific statistics. NIC- and driver-specific statistics are +requested when no group of statistics is specified. + +NIC- and driver-specific statistics and standard statistics are independent, +devices may implement either, both or none. There is little commonality between +naming of NIC- and driver-specific statistics across vendors. +.RS 4 +.TP +.B \fB\-\-all\-groups +.TP +.B \fB\-\-groups [\fBeth\-phy\fP] [\fBeth\-mac\fP] [\fBeth\-ctrl\fP] [\fBrmon\fP] +Request groups of standard device statistics. +.RE +.TP +.B \-\-phy\-statistics +Queries the specified network device for PHY specific statistics. +.TP +.B \-t \-\-test +Executes adapter selftest on the specified network device. Possible test modes are: +.RS 4 +.TP +.B offline +Perform full set of tests, possibly interrupting normal operation +during the tests, +.TP +.B online +Perform limited set of tests, not interrupting normal operation, +.TP +.B external_lb +Perform full set of tests, as for \fBoffline\fR, and additionally an +external-loopback test. +.RE +.TP +.B \-s \-\-change +Allows changing some or all settings of the specified network device. +All following options only apply if +.B \-s +was specified. +.RS 4 +.TP +.BI speed \ N +Set speed in Mb/s. +.B ethtool +with just the device name as an argument will show you the supported device speeds. +.TP +.BI lanes \ N +Set number of lanes. +.TP +.A2 duplex half full +Sets full or half duplex mode. +.TP +.A4 port tp aui bnc mii fibre da +Selects device port. +.TP +.BR master-slave \ \*(MS +Configure MASTER/SLAVE role of the PHY. When the PHY is configured as MASTER, +the PMA Transmit function shall source TX_TCLK from a local clock source. When +configured as SLAVE, the PMA Transmit function shall source TX_TCLK from the +clock recovered from data stream provided by MASTER. Not all devices support this. +.TS +nokeep; +lB l. +preferred-master Prefer MASTER role on autonegotiation +preferred-slave Prefer SLAVE role on autonegotiation +forced-master Force the PHY in MASTER role. Can be used without autonegotiation +forced-slave Force the PHY in SLAVE role. Can be used without autonegotiation +.TE +.TP +.A3 mdix auto on off +Selects MDI-X mode for port. May be used to override the automatic +detection feature of most adapters. An argument of \fBauto\fR means +automatic detection of MDI status, \fBon\fR forces MDI-X (crossover) +mode, while \fBoff\fR means MDI (straight through) mode. The driver +should guarantee that this command takes effect immediately, and if +necessary may reset the link to cause the change to take effect. +.TP +.A2 autoneg on off +Specifies whether autonegotiation should be enabled. Autonegotiation +is enabled by default, but in some network devices may have trouble +with it, so you can disable it if really necessary. +.TP +.BI advertise \ N +Sets the speed and duplex advertised by autonegotiation. The argument is +a hexadecimal value using one or a combination of the following values: +.TS +nokeep; +lB l lB. +0x001 10baseT Half +0x002 10baseT Full +0x100000000000000000000000 10baseT1L Full +0x004 100baseT Half +0x008 100baseT Full +0x80000000000000000 100baseT1 Full +0x40000000000000000000000 100baseFX Half +0x80000000000000000000000 100baseFX Full +0x010 1000baseT Half (not supported by IEEE standards) +0x020 1000baseT Full +0x20000 1000baseKX Full +0x20000000000 1000baseX Full +0x100000000000000000 1000baseT1 Full +0x8000 2500baseX Full (not supported by IEEE standards) +0x800000000000 2500baseT Full +0x1000000000000 5000baseT Full +0x1000 10000baseT Full +0x40000 10000baseKX4 Full +0x80000 10000baseKR Full +0x100000 10000baseR_FEC +0x40000000000 10000baseCR Full +0x80000000000 10000baseSR Full +0x100000000000 10000baseLR Full +0x200000000000 10000baseLRM Full +0x400000000000 10000baseER Full +0x200000 20000baseMLD2 Full (not supported by IEEE standards) +0x400000 20000baseKR2 Full (not supported by IEEE standards) +0x80000000 25000baseCR Full +0x100000000 25000baseKR Full +0x200000000 25000baseSR Full +0x800000 40000baseKR4 Full +0x1000000 40000baseCR4 Full +0x2000000 40000baseSR4 Full +0x4000000 40000baseLR4 Full +0x400000000 50000baseCR2 Full +0x800000000 50000baseKR2 Full +0x10000000000 50000baseSR2 Full +0x10000000000000 50000baseKR Full +0x20000000000000 50000baseSR Full +0x40000000000000 50000baseCR Full +0x80000000000000 50000baseLR_ER_FR Full +0x100000000000000 50000baseDR Full +0x8000000 56000baseKR4 Full +0x10000000 56000baseCR4 Full +0x20000000 56000baseSR4 Full +0x40000000 56000baseLR4 Full +0x1000000000 100000baseKR4 Full +0x2000000000 100000baseSR4 Full +0x4000000000 100000baseCR4 Full +0x8000000000 100000baseLR4_ER4 Full +0x200000000000000 100000baseKR2 Full +0x400000000000000 100000baseSR2 Full +0x800000000000000 100000baseCR2 Full +0x1000000000000000 100000baseLR2_ER2_FR2 Full +0x2000000000000000 100000baseDR2 Full +0x8000000000000000000 100000baseKR Full +0x10000000000000000000 100000baseSR Full +0x20000000000000000000 100000baseLR_ER_FR Full +0x40000000000000000000 100000baseCR Full +0x80000000000000000000 100000baseDR Full +0x4000000000000000 200000baseKR4 Full +0x8000000000000000 200000baseSR4 Full +0x10000000000000000 200000baseLR4_ER4_FR4 Full +0x20000000000000000 200000baseDR4 Full +0x40000000000000000 200000baseCR4 Full +0x100000000000000000000 200000baseKR2 Full +0x200000000000000000000 200000baseSR2 Full +0x400000000000000000000 200000baseLR2_ER2_FR2 Full +0x800000000000000000000 200000baseDR2 Full +0x1000000000000000000000 200000baseCR2 Full +0x200000000000000000 400000baseKR8 Full +0x400000000000000000 400000baseSR8 Full +0x800000000000000000 400000baseLR8_ER8_FR8 Full +0x1000000000000000000 400000baseDR8 Full +0x2000000000000000000 400000baseCR8 Full +0x2000000000000000000000 400000baseKR4 Full +0x4000000000000000000000 400000baseSR4 Full +0x8000000000000000000000 400000baseLR4_ER4_FR4 Full +0x10000000000000000000000 400000baseDR4 Full +0x20000000000000000000000 400000baseCR4 Full +.TE +.TP +.BI phyad \ N +PHY address. +.TP +.A2 xcvr internal external +Selects transceiver type. Currently only internal and external can be +specified, in the future further types might be added. +.TP +.BR wol \ \*(WO +Sets Wake-on-LAN options. Not all devices support this. The argument to +this option is a string of characters specifying which options to enable. +.TS +nokeep; +lB l. +p Wake on PHY activity +u Wake on unicast messages +m Wake on multicast messages +b Wake on broadcast messages +a Wake on ARP +g Wake on MagicPacket\[tm] +s Enable SecureOn\[tm] password for MagicPacket\[tm] +f Wake on filter(s) +d T{ +Disable (wake on nothing). This option clears all previous options. +T} +.TE +.TP +.B sopass \*(MA +Sets the SecureOn\[tm] password. The argument to this option must be 6 +bytes in Ethernet MAC hex format (\*(MA). +.PP +.BI msglvl \ N +.br +.BI msglvl \ type +.A1 on off +.RB ... +.RS +Sets the driver message type flags by name or number. \fItype\fR +names the type of message to enable or disable; \fIN\fR specifies the +new flags numerically. The defined type names and numbers are: +.TS +nokeep; +lB l l. +drv 0x0001 General driver status +probe 0x0002 Hardware probing +link 0x0004 Link state +timer 0x0008 Periodic status check +ifdown 0x0010 Interface being brought down +ifup 0x0020 Interface being brought up +rx_err 0x0040 Receive error +tx_err 0x0080 Transmit error +tx_queued 0x0100 Transmit queueing +intr 0x0200 Interrupt handling +tx_done 0x0400 Transmit completion +rx_status 0x0800 Receive completion +pktdata 0x1000 Packet contents +hw 0x2000 Hardware status +wol 0x4000 Wake-on-LAN status +.TE +.PP +The precise meanings of these type flags differ between drivers. +.RE +.PD +.RE +.TP +.B \-n \-u \-\-show\-nfc \-\-show\-ntuple +Retrieves receive network flow classification options or rules. +.RS 4 +.TP +.BR rx\-flow\-hash \ \*(FL +Retrieves the hash options for the specified flow type. +.TS +nokeep; +lB l. +tcp4 TCP over IPv4 +udp4 UDP over IPv4 +ah4 IPSEC AH over IPv4 +esp4 IPSEC ESP over IPv4 +sctp4 SCTP over IPv4 +tcp6 TCP over IPv6 +udp6 UDP over IPv6 +ah6 IPSEC AH over IPv6 +esp6 IPSEC ESP over IPv6 +sctp6 SCTP over IPv6 +.TE +.TP +.BI rule \ N +Retrieves the RX classification rule with the given ID. +.RE +.PD +.RE +.TP +.B \-N \-U \-\-config\-nfc \-\-config\-ntuple +Configures receive network flow classification options or rules. +.RS 4 +.TP +.BR rx\-flow\-hash \ \*(FL \: \*(HO +Configures the hash options for the specified flow type. +.TS +nokeep; +lB l. +m Hash on the Layer 2 destination address of the rx packet. +v Hash on the VLAN tag of the rx packet. +t Hash on the Layer 3 protocol field of the rx packet. +s Hash on the IP source address of the rx packet. +d Hash on the IP destination address of the rx packet. +f Hash on bytes 0 and 1 of the Layer 4 header of the rx packet. +n Hash on bytes 2 and 3 of the Layer 4 header of the rx packet. +r T{ +Discard all packets of this flow type. When this option is set, all +other options are ignored. +T} +.TE +.TP +.B flow\-type \*(NC +Inserts or updates a classification rule for the specified flow type. +.TS +nokeep; +lB l. +ether Ethernet +ip4 Raw IPv4 +tcp4 TCP over IPv4 +udp4 UDP over IPv4 +sctp4 SCTP over IPv4 +ah4 IPSEC AH over IPv4 +esp4 IPSEC ESP over IPv4 +ip6 Raw IPv6 +tcp6 TCP over IPv6 +udp6 UDP over IPv6 +sctp6 SCTP over IPv6 +ah6 IPSEC AH over IPv6 +esp6 IPSEC ESP over IPv6 +.TE +.PP +For all fields that allow both a value and a mask to be specified, the +mask may be specified immediately after the value using the \fBm\fR +keyword, or separately using the field name keyword with \fB-mask\fR +appended, e.g. \fBsrc-mask\fR. +.PD +.TP +.BR src \ \*(MA\ [ m \ \*(MA] +Includes the source MAC address, specified as 6 bytes in hexadecimal +separated by colons, along with an optional mask. Valid only for +flow-type ether. +.TP +.BR dst \ \*(MA\ [ m \ \*(MA] +Includes the destination MAC address, specified as 6 bytes in hexadecimal +separated by colons, along with an optional mask. Valid only for +flow-type ether. +.TP +.BI proto \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes the Ethernet protocol number (ethertype) and an optional mask. +Valid only for flow-type ether. +.TP +.BR src\-ip \ \*(PA\ [ m \ \*(PA] +Specify the source IP address of the incoming packet to match along with +an optional mask. Valid for all IP based flow-types. +.TP +.BR dst\-ip \ \*(PA\ [ m \ \*(PA] +Specify the destination IP address of the incoming packet to match along +with an optional mask. Valid for all IP based flow-types. +.TP +.BI tos \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the Type of Service field in the incoming packet to +match along with an optional mask. Applies to all IPv4 based flow-types. +.TP +.BI tclass \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the Traffic Class field in the incoming packet to +match along with an optional mask. Applies to all IPv6 based flow-types. +.TP +.BI l4proto \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes the layer 4 protocol number and optional mask. Valid only for +flow-types ip4 and ip6. +.TP +.BI src\-port \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the source port field (applicable to TCP/UDP packets) +in the incoming packet to match along with an optional mask. Valid for +flow-types ip4, tcp4, udp4, and sctp4 and their IPv6 equivalents. +.TP +.BI dst\-port \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the destination port field (applicable to TCP/UDP +packets)in the incoming packet to match along with an optional mask. +Valid for flow-types ip4, tcp4, udp4, and sctp4 and their IPv6 equivalents. +.TP +.BI spi \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the security parameter index field (applicable to +AH/ESP packets)in the incoming packet to match along with an optional +mask. Valid for flow-types ip4, ah4, and esp4 and their IPv6 equivalents. +.TP +.BI l4data \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the first 4 Bytes of Layer 4 in the incoming packet to +match along with an optional mask. Valid for ip4 and ip6 flow-types. +.TP +.BI vlan\-etype \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes the VLAN tag Ethertype and an optional mask. +.TP +.BI vlan \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes the VLAN tag and an optional mask. +.TP +.BI user\-def \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes 64-bits of user-specific data and an optional mask. +.TP +.BR dst-mac \ \*(MA\ [ m \ \*(MA] +Includes the destination MAC address, specified as 6 bytes in hexadecimal +separated by colons, along with an optional mask. +Valid for all IP based flow-types. +.TP +.BI action \ N +Specifies the Rx queue to send packets to, or some other action. +.TS +nokeep; +lB l. +-1 Drop the matched flow +-2 Use the matched flow as a Wake-on-LAN filter +0 or higher Rx queue to route the flow +.TE +.TP +.BI context \ N +Specifies the RSS context to spread packets over multiple queues; either +.B 0 +for the default RSS context, or a value returned by +.BI ethtool\ -X\ ... \ context +.BR new . +.TP +.BI vf \ N +Specifies the Virtual Function the filter applies to. Not compatible with action. +.TP +.BI queue \ N +Specifies the Rx queue to send packets to. Not compatible with action. +.TP +.BI loc \ N +Specify the location/ID to insert the rule. This will overwrite +any rule present in that location and will not go through any +of the rule ordering process. +.TP +.BI delete \ N +Deletes the RX classification rule with the given ID. +.RE +.TP +.B \-w \-\-get\-dump +Retrieves and prints firmware dump for the specified network device. +By default, it prints out the dump flag, version and length of the dump data. +When +.I data +is indicated, then ethtool fetches the dump data and directs it to a +.I file. +.TP +.B \-W \-\-set\-dump +Sets the dump flag for the device. +.TP +.B \-T \-\-show\-time\-stamping +Show the device's time stamping capabilities and associated PTP +hardware clock. +.TP +.B \-x \-\-show\-rxfh\-indir \-\-show\-rxfh +Retrieves the receive flow hash indirection table and/or RSS hash key. +.TP +.B \-X \-\-set\-rxfh\-indir \-\-rxfh +Configures the receive flow hash indirection table and/or RSS hash key. +.RS 4 +.TP +.BI hkey +Sets RSS hash key of the specified network device. RSS hash key should be of device supported length. +Hash key format must be in xx:yy:zz:aa:bb:cc format meaning both the nibbles of a byte should be mentioned +even if a nibble is zero. +.TP +.BI hfunc +Sets RSS hash function of the specified network device. +List of RSS hash functions which kernel supports is shown as a part of the --show-rxfh command output. +.TP +.BI start\ N +For the \fBequal\fR and \fBweight\fR options, sets the starting receive queue +for spreading flows to \fIN\fR. +.TP +.BI equal\ N +Sets the receive flow hash indirection table to spread flows evenly +between the first \fIN\fR receive queues. +.TP +\fBweight\fR \fIW0 W1\fR ... +Sets the receive flow hash indirection table to spread flows between +receive queues according to the given weights. The sum of the weights +must be non-zero and must not exceed the size of the indirection table. +.TP +.BI default +Sets the receive flow hash indirection table to its default value. +.TP +\fBcontext \fICTX\fR | \fBnew\fR +Specifies an RSS context to act on; either +.B new +to allocate a new RSS context, or +.IR CTX , +a value returned by a previous +.IB ... \ context +.BR new . +.TP +.B delete +Delete the specified RSS context. May only be used in conjunction with +.B context +and a non-zero +.I CTX +value. +.RE +.TP +.B \-f \-\-flash +Write a firmware image to flash or other non-volatile memory on the +device. +.RS 4 +.TP +.I file +Specifies the filename of the firmware image. The firmware must first +be installed in one of the directories where the kernel firmware +loader or firmware agent will look, such as /lib/firmware. +.TP +.I N +If the device stores multiple firmware images in separate regions of +non-volatile memory, this parameter may be used to specify which +region is to be written. The default is 0, requesting that all +regions are written. All other values are driver-dependent. +.RE +.PD +.TP +.B \-l \-\-show\-channels +Queries the specified network device for the numbers of channels it has. +A channel is an IRQ and the set of queues that can trigger that IRQ. +.TP +.B \-L \-\-set\-channels +Changes the numbers of channels of the specified network device. +.RS 4 +.TP +.BI rx \ N +Changes the number of channels with only receive queues. +.TP +.BI tx \ N +Changes the number of channels with only transmit queues. +.TP +.BI other \ N +Changes the number of channels used only for other purposes e.g. link interrupts or SR-IOV co-ordination. +.TP +.BI combined \ N +Changes the number of multi-purpose channels. +.RE +.TP +.B \-m \-\-dump\-module\-eeprom \-\-module\-info +Retrieves and if possible decodes the EEPROM from plugin modules, e.g SFP+, QSFP. +If the driver and module support it, the optical diagnostic information is also +read and decoded. +When either one of +.I page, +.I bank +or +.I i2c +parameters is specified, dumps only of a single page or its portion is +allowed. In such a case +.I offset +and +.I length +parameters are treated relatively to EEPROM page boundaries. +.TP +.B \-\-show\-priv\-flags +Queries the specified network device for its private flags. The +names and meanings of private flags (if any) are defined by each +network device driver. +.TP +.B \-\-set\-priv\-flags +Sets the device's private flags as specified. +.RS 4 +.PP +.I flag +.A1 on off +Sets the state of the named private flag. +.RE +.TP +.B \-\-show\-eee +Queries the specified network device for its support of Energy-Efficient +Ethernet (according to the IEEE 802.3az specifications) +.TP +.B \-\-set\-eee +Sets the device EEE behaviour. +.RS 4 +.TP +.A2 eee on off +Enables/disables the device support of EEE. +.TP +.A2 tx-lpi on off +Determines whether the device should assert its Tx LPI. +.TP +.BI advertise \ N +Sets the speeds for which the device should advertise EEE capabilities. +Values are as for +.B \-\-change advertise +.TP +.BI tx-timer \ N +Sets the amount of time the device should stay in idle mode prior to asserting +its Tx LPI (in microseconds). This has meaning only when Tx LPI is enabled. +.RE +.TP +.B \-\-set\-phy\-tunable +Sets the PHY tunable parameters. +.RS 4 +.TP +.A2 downshift on off +Specifies whether downshift should be enabled. +.TS +nokeep; +lB l. +.BI count \ N + Sets the PHY downshift re-tries count. +.TE +.TP +.A2 fast-link-down on off +Specifies whether Fast Link Down should be enabled and time until link down (if supported). +.TS +nokeep; +lB l. +.BI msecs \ N + Sets the period after which the link is reported as down. Note that the PHY may choose + the closest supported value. Only on reading back the tunable do you get the actual value. +.TE +.TP +.A2 energy-detect-power-down on off +Specifies whether Energy Detect Power Down (EDPD) should be enabled (if supported). +This will put the RX and TX circuit blocks into a low power mode, and the PHY will +wake up periodically to send link pulses to avoid any lock-up situation with a peer +PHY that may also have EDPD enabled. By default, this setting will also enable the +periodic transmission of TX pulses. +.TS +nokeep; +lB l. +.BI msecs \ N + Some PHYs support configuration of the wake-up interval to send TX pulses. + This setting allows the control of this interval, and 0 disables TX pulses + if the PHY supports this. Disabling TX pulses can create a lock-up situation + where neither of the PHYs wakes the other one. If unspecified the default + value (in milliseconds) will be used by the PHY. +.TE +.TP +.PD +.RE +.TP +.B \-\-get\-phy\-tunable +Gets the PHY tunable parameters. +.RS 4 +.TP +.B downshift +For operation in cabling environments that are incompatible with 1000BASE-T, +PHY device provides an automatic link speed downshift operation. +Link speed downshift after N failed 1000BASE-T auto-negotiation attempts. +Downshift is useful where cable does not have the 4 pairs instance. + +Gets the PHY downshift count/status. +.TP +.B fast\-link\-down +Depending on the mode it may take 0.5s - 1s until a broken link is reported as down. +In certain use cases a link-down event needs to be reported as soon as possible. +Some PHYs support a Fast Link Down Feature and may allow configuration of the delay +before a broken link is reported as being down. + +Gets the PHY Fast Link Down status / period. +.TP +.B energy\-detect\-power\-down +Gets the current configured setting for Energy Detect Power Down (if supported). + +.RE +.TP +.B \-\-get\-tunable +Get the tunable parameters. +.RS 4 +.TP +.B rx\-copybreak +Get the current rx copybreak value in bytes. +.TP +.B tx\-copybreak +Get the current tx copybreak value in bytes. +.TP +.B tx\-buf\-size +Get the current tx copybreak buffer size in bytes. +.TP +.B pfc\-prevention\-tout +Get the current pfc prevention timeout value in msecs. +.RE +.TP +.B \-\-set\-tunable +Set driver's tunable parameters. +.RS 4 +.TP +.BI rx\-copybreak \ N +Set the rx copybreak value in bytes. +.TP +.BI tx\-copybreak \ N +Set the tx copybreak value in bytes. +.TP +.BI tx\-buf\-size \ N +Set the tx copybreak buffer size in bytes. +.TP +.BI pfc\-prevention\-tout \ N +Set pfc prevention timeout in msecs. Value of 0 means disable and 65535 means auto. +.RE +.TP +.B \-\-reset +Reset hardware components specified by flags and components listed below +.RS 4 +.TP +.BI flags \ N +Resets the components based on direct flags mask +.TP +.B mgmt +Management processor +.TP +.B irq +Interrupt requester +.TP +.B dma +DMA engine +.TP +.B filter +Filtering/flow direction +.TP +.B offload +Protocol offload +.TP +.B mac +Media access controller +.TP +.B phy +Transceiver/PHY +.TP +.B ram +RAM shared between multiple components +.B ap +Application Processor +.TP +.B dedicated +All components dedicated to this interface +.TP +.B all +All components used by this interface, even if shared +.RE +.TP +.B \-\-show\-fec +Queries the specified network device for its support of Forward Error Correction. +.TP +.B \-\-set\-fec +Configures Forward Error Correction for the specified network device. + +Forward Error Correction modes selected by a user are expected to be persisted +after any hotplug events. If a module is swapped that does not support the +current FEC mode, the driver or firmware must take the link down +administratively and report the problem in the system logs for users to correct. +.RS 4 +.TP +.BR encoding\ auto | off | rs | baser | llrs \ [...] + +Sets the FEC encoding for the device. Combinations of options are specified as +e.g. +.B encoding auto rs +; the semantics of such combinations vary between drivers. +.TS +nokeep; +lB l. +auto Use the driver's default encoding +off Turn off FEC +RS Force RS-FEC encoding +BaseR Force BaseR encoding +LLRS Force LLRS-FEC encoding +.TE +.RE +.TP +.B \-Q|\-\-per\-queue +Applies provided sub command to specific queues. +.RS 4 +.TP +.B queue_mask %x +Sets the specific queues which the sub command is applied to. +If queue_mask is not set, the sub command will be applied to all queues. +.TP +.B sub_command +Sub command to apply. The supported sub commands include --show-coalesce and +--coalesce. +.RE +.TP +.B \-\-cable\-test +Perform a cable test and report the results. What results are returned depends +on the capabilities of the network interface. Typically open pairs and shorted +pairs can be reported, along with pairs being O.K. When a fault is detected +the approximate distance to the fault may be reported. +.TP +.B \-\-cable\-test\-tdr +Perform a cable test and report the raw Time Domain Reflectometer +data. A pulse is sent down a cable pair and the amplitude of the +reflection, for a given distance, is reported. A break in the cable +returns a big reflection. Minor damage to the cable returns a small +reflection. If the cable is shorted, the amplitude of the reflection +can be negative. By default, data is returned for lengths between 0 +and 150m at 1m steps, for all pairs. However parameters can be passed +to restrict the collection of data. It should be noted, that the +interface will round the distances to whatever granularity is actually +implemented. This is often 0.8 of a meter. The results should include +the actual rounded first and last distance and step size. +.RS 4 +.TP +.B first \ N +Distance along the cable, in meters, where the first measurement +should be made. +.TP +.B last \ N +Distance along the cable, in meters, where the last measurement should +be made. +.TP +.B step \ N +Distance, in meters, between each measurement. +.TP +.B pair \ N +Which pair should be measured. Typically a cable has 4 pairs. 0 = Pair A, 1 = Pair B, ... +.RE +.TP +.B \-\-monitor +Listens to netlink notification and displays them. +.RS 4 +.TP +.I command +If argument matching a command is used, ethtool only shows notifications of +this type. Without such argument or with --all, all notification types are +shown. +.TP +.I devname +If a device name is used as argument, only notification for this device are +shown. Default is to show notifications for all devices. +.RE +.TP +.B \-\-show\-tunnels +Show tunnel-related device capabilities and state. +List UDP ports kernel has programmed the device to parse as VxLAN, +or GENEVE tunnels. +.RE +.TP +.B \-\-show\-module +Show the transceiver module's parameters. +.RE +.TP +.B \-\-set\-module +Set the transceiver module's parameters. +.RS 4 +.TP +.A2 power-mode-policy high auto +Set the power mode policy for the module. When set to \fBhigh\fR, the module +always operates at high power mode. When set to \fBauto\fR, the module is +transitioned by the host to high power mode when the first port using it is put +administratively up and to low power mode when the last port using it is put +administratively down. The power mode policy can be set before a module is +plugged-in. +.RE +.SH BUGS +Not supported (in part or whole) on all network drivers. +.SH AUTHOR +.B ethtool +was written by David Miller. + +Modifications by +Jeff Garzik, +Tim Hockin, +Jakub Jelinek, +Andre Majorel, +Eli Kupermann, +Scott Feldman, +Andi Kleen, +Alexander Duyck, +Sucheta Chakraborty, +Jesse Brandeburg, +Ben Hutchings, +Scott Branden. +.SH AVAILABILITY +.B ethtool +is available from +.UR http://www.kernel.org/pub/software/network/ethtool/ +.UE diff --git a/ethtool.8.in b/ethtool.8.in new file mode 100644 index 0000000..bee47f2 --- /dev/null +++ b/ethtool.8.in @@ -0,0 +1,1531 @@ +.\" -*- nroff -*- +.\" Copyright 1999 by David S. Miller. All Rights Reserved. +.\" Portions Copyright 2001 Sun Microsystems +.\" Portions Copyright 2007, 2009 Free Software Foundation, Inc. +.\" This file may be copied under the terms of the GNU Public License. +.\" +.\" There must be no text lines before .TH. Use '.' for vertical spacing. +.\" +.\" .An - list of n alternative values as in "flav vanilla|strawberry" +.\" +.de A1 +\\fB\\$1\\fP|\\fB\\$2\\fP +.. +.de A2 +\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP +.. +.de A3 +\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP|\\fB\\$4\\fP +.. +.de A4 +\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP|\\fB\\$4\\fP|\\fB\\$5\\fP +.. +.\" +.\" .Bn - same as above but framed by square brackets +.\" +.de B1 +[\\fB\\$1\\fP|\\fB\\$2\\fP] +.. +.de B2 +[\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP] +.. +.de B3 +[\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP|\\fB\\$4\\fP] +.. +.de B4 +[\\fB\\$1\\fP\ \\fB\\$2\\fP|\\fB\\$3\\fP|\\fB\\$4\\fP|\\fB\\$5\\fP] +.. +.\" +.\" .BN - value with a numeric input as in "[value N]" +.\" +.de BN +[\\fB\\$1\\fP\ \\fIN\\fP] +.. +.\" +.\" .BM - same as above but has a mask field for format "[value N [m N]]" +.\" +.de BM +[\\fB\\$1\\fP\ \\fIN\\fP\ [\\fBm\\fP\ \\fIN\\fP]] +.. +.\" +.\" \(*MA - mac address +.\" +.ds MA \fIxx\fP\fB:\fP\fIyy\fP\fB:\fP\fIzz\fP\fB:\fP\fIaa\fP\fB:\fP\fIbb\fP\fB:\fP\fIcc\fP +.\" +.\" \(*MS - master-slave property +.\" +.ds MS \fBpreferred-master\fP|\fBpreferred-slave\fP|\fBforced-master\fP|\fBforced-slave\fP +.\" +.\" \(*PA - IP address +.\" +.ds PA \fIip-address\fP +.\" +.\" \(*WO - wol flags +.\" +.ds WO \fBp\fP|\fBu\fP|\fBm\fP|\fBb\fP|\fBa\fP|\fBg\fP|\fBs\fP|\fBf|\fBd\fP... +.\" +.\" \(*FL - flow type values +.\" +.ds FL \fBtcp4\fP|\fBudp4\fP|\fBah4\fP|\fBesp4\fP|\fBsctp4\fP|\fBtcp6\fP|\fBudp6\fP|\fBah6\fP|\fBesp6\fP|\fBsctp6\fP +.\" +.\" \(*HO - hash options +.\" +.ds HO \fBm\fP|\fBv\fP|\fBt\fP|\fBs\fP|\fBd\fP|\fBf\fP|\fBn\fP|\fBr\fP... +.\" +.\" \(*SD - Self-diag test values +.\" +.ds SD \fBoffline\fP|\fBonline\fP|\fBexternal_lb\fP +.\" +.\" \(*NC - Network Classifier type values +.\" +.ds NC \fBether\fP|\fBip4\fP|\fBtcp4\fP|\fBudp4\fP|\fBsctp4\fP|\fBah4\fP|\fBesp4\fP|\fBip6\fP|\fBtcp6\fP|\fBudp6\fP|\fBah6\fP|\fBesp6\fP|\fBsctp6\fP +. +.\" +.\" Start URL. +.de UR +. ds m1 \\$1\" +. nh +. if \\n(mH \{\ +. \" Start diversion in a new environment. +. do ev URL-div +. do di URL-div +. \} +.. +.\" End URL. +.de UE +. ie \\n(mH \{\ +. br +. di +. ev +. +. \" Has there been one or more input lines for the link text? +. ie \\n(dn \{\ +. do HTML-NS "" +. \" Yes, strip off final newline of diversion and emit it. +. do chop URL-div +. do URL-div +\c +. do HTML-NS +. \} +. el \ +. do HTML-NS "\\*(m1" +\&\\$*\" +. \} +. el \ +\\*(la\\*(m1\\*(ra\\$*\" +. +. hy \\n(HY +.. +. +.TH ETHTOOL 8 "December 2022" "Ethtool version @VERSION@" +.SH NAME +ethtool \- query or control network driver and hardware settings +. +.SH SYNOPSIS +.\" Do not adjust lines (i.e. left justification) and do not hyphenate. +.na +.nh +.HP +.B ethtool +.I devname +.HP +.B ethtool \-h|\-\-help +.HP +.B ethtool \-\-version +.HP +.B ethtool +.BN --debug +.I args +.HP +.B ethtool [--json] +.I args +.HP +.B ethtool [-I | --include-statistics] +.I args +.HP +.B ethtool \-\-monitor +[ +.I command +] [ +.I devname +] +.HP +.B ethtool \-a|\-\-show\-pause +.I devname +.HP +.B ethtool \-A|\-\-pause +.I devname +.B2 autoneg on off +.B2 rx on off +.B2 tx on off +.HP +.B ethtool \-c|\-\-show\-coalesce +.I devname +.HP +.B ethtool \-C|\-\-coalesce +.I devname +.B2 adaptive\-rx on off +.B2 adaptive\-tx on off +.BN rx\-usecs +.BN rx\-frames +.BN rx\-usecs\-irq +.BN rx\-frames\-irq +.BN tx\-usecs +.BN tx\-frames +.BN tx\-usecs\-irq +.BN tx\-frames\-irq +.BN stats\-block\-usecs +.BN pkt\-rate\-low +.BN rx\-usecs\-low +.BN rx\-frames\-low +.BN tx\-usecs\-low +.BN tx\-frames\-low +.BN pkt\-rate\-high +.BN rx\-usecs\-high +.BN rx\-frames\-high +.BN tx\-usecs\-high +.BN tx\-frames\-high +.BN sample\-interval +.B2 cqe\-mode\-rx on off +.B2 cqe\-mode\-tx on off +.HP +.B ethtool \-g|\-\-show\-ring +.I devname +.HP +.B ethtool \-G|\-\-set\-ring +.I devname +.BN rx +.BN rx\-mini +.BN rx\-jumbo +.BN tx +.BN rx\-buf\-len +.BN cqe\-size +.BN tx\-push +.HP +.B ethtool \-i|\-\-driver +.I devname +.HP +.B ethtool \-d|\-\-register\-dump +.I devname +.B2 raw on off +.B2 hex on off +.RB [ file +.IR name ] +.HP +.B ethtool \-e|\-\-eeprom\-dump +.I devname +.B2 raw on off +.BN offset +.BN length +.HP +.B ethtool \-E|\-\-change\-eeprom +.I devname +.BN magic +.BN offset +.BN length +.BN value +.HP +.B ethtool \-k|\-\-show\-features|\-\-show\-offload +.I devname +.HP +.B ethtool \-K|\-\-features|\-\-offload +.I devname feature +.A1 on off +.RB ... +.HP +.B ethtool \-p|\-\-identify +.I devname +.RI [ N ] +.HP +.B ethtool \-P|\-\-show\-permaddr +.I devname +.HP +.B ethtool \-r|\-\-negotiate +.I devname +.HP +.B ethtool \-S|\-\-statistics +.I devname +.RB [\fB\-\-all\-groups\fP|\fB\-\-groups +.RB [\fBeth\-phy\fP] +.RB [\fBeth\-mac\fP] +.RB [\fBeth\-ctrl\fP] +.RB [\fBrmon\fP] +.RB ] +.HP +.B ethtool \-\-phy\-statistics +.I devname +.HP +.B ethtool \-t|\-\-test +.I devname +.RI [\*(SD] +.HP +.B ethtool \-s +.I devname +.BN speed +.BN lanes +.B2 duplex half full +.B4 port tp aui bnc mii fibre da +.B3 mdix auto on off +.B2 autoneg on off +.RB [ advertise \ \fIN\fP[\fB/\fP\fIM\fP] +| +.BI advertise \ mode +.A1 on off +.RB ...] +.BN phyad +.B2 xcvr internal external +.RB [ wol \ \fIN\fP[\fB/\fP\fIM\fP] +.RB | \ wol \ \*(WO] +.RB [ sopass \ \*(MA] +.RB [ master-slave \ \*(MS] +.RB [ msglvl +.IR N\fP[/\fIM\fP] \ | +.BI msglvl \ type +.A1 on off +.RB ...] +.HP +.B ethtool \-n|\-u|\-\-show\-nfc|\-\-show\-ntuple +.I devname +.RB [\ rx\-flow\-hash \ \*(FL \ | +.br +.BI rule \ N +.RB ] +.HP +.B ethtool \-N|\-U|\-\-config\-nfc|\-\-config\-ntuple +.I devname +.BR rx\-flow\-hash \ \*(FL \ \: \*(HO \ | +.br +.B flow\-type \*(NC +.RB [ src \ \*(MA\ [ m \ \*(MA]] +.RB [ dst \ \*(MA\ [ m \ \*(MA]] +.BM proto +.RB [ src\-ip \ \*(PA\ [ m \ \*(PA]] +.RB [ dst\-ip \ \*(PA\ [ m \ \*(PA]] +.BM tos +.BM tclass +.BM l4proto +.BM src\-port +.BM dst\-port +.BM spi +.BM l4data +.BM vlan\-etype +.BM vlan +.BM user\-def +.RB [ dst-mac \ \*(MA\ [ m \ \*(MA]] +.BN action +.BN context +.BN loc +.RB | +.br +.BI delete \ N +.HP +.B ethtool \-w|\-\-get\-dump +.I devname +.RB [ data +.IR filename ] +.HP +.B ethtool\ \-W|\-\-set\-dump +.I devname N +.HP +.B ethtool \-T|\-\-show\-time\-stamping +.I devname +.HP +.B ethtool \-x|\-\-show\-rxfh\-indir|\-\-show\-rxfh +.I devname +.HP +.B ethtool \-X|\-\-set\-rxfh\-indir|\-\-rxfh +.I devname +.RB [ hkey \ \*(MA:\...] +.RB [ start +.IR N ] +.RB [\ equal +.IR N \ | +.BI weight\ W0 +.IR W1 +.RB ...\ | \ default \ ] +.RB [ hfunc +.IR FUNC ] +.RB [ context +.I CTX +.RB |\ new ] +.RB [ delete ] +.HP +.B ethtool \-f|\-\-flash +.I devname file +.RI [ N ] +.HP +.B ethtool \-l|\-\-show\-channels +.I devname +.HP +.B ethtool \-L|\-\-set\-channels +.I devname +.BN rx +.BN tx +.BN other +.BN combined +.HP +.B ethtool \-m|\-\-dump\-module\-eeprom|\-\-module\-info +.I devname +.B2 raw on off +.B2 hex on off +.BN offset +.BN length +.BN page +.BN bank +.BN i2c +.HP +.B ethtool \-\-show\-priv\-flags +.I devname +.HP +.B ethtool \-\-set\-priv\-flags +.I devname flag +.A1 on off +.RB ... +.HP +.B ethtool \-\-show\-eee +.I devname +.HP +.B ethtool \-\-set\-eee +.I devname +.B2 eee on off +.B2 tx-lpi on off +.BN tx-timer +.BN advertise +.HP +.B ethtool \-\-set\-phy\-tunable +.I devname +.RB [ +.B downshift +.A1 on off +.BN count +.RB ] +.RB [ +.B fast\-link\-down +.A1 on off +.BN msecs +.RB ] +.RB [ +.B energy\-detect\-power\-down +.A1 on off +.BN msecs +.RB ] +.HP +.B ethtool \-\-get\-phy\-tunable +.I devname +.RB [ downshift ] +.RB [ fast-link-down ] +.RB [ energy-detect-power-down ] +.HP +.B ethtool \-\-get\-tunable +.I devname +.RB [ rx-copybreak ] +.RB [ tx-copybreak ] +.RB [ tx-buf-size ] +.RB [ pfc-prevention-tout ] +.HP +.B ethtool \-\-set\-tunable +.I devname +.BN rx\-copybreak +.BN tx\-copybreak +.BN tx\-buf\-size +.BN pfc\-prevention\-tout +.HP +.B ethtool \-\-reset +.I devname +.BN flags +.RB [ mgmt ] +.RB [ mgmt-shared ] +.RB [ irq ] +.RB [ irq-shared ] +.RB [ dma ] +.RB [ dma-shared ] +.RB [ filter ] +.RB [ filter-shared ] +.RB [ offload ] +.RB [ offload-shared ] +.RB [ mac ] +.RB [ mac-shared ] +.RB [ phy ] +.RB [ phy-shared ] +.RB [ ram ] +.RB [ ram-shared ] +.RB [ ap ] +.RB [ ap-shared ] +.RB [ dedicated ] +.RB [ all ] +.HP +.B ethtool \-\-show\-fec +.I devname +.HP +.B ethtool \-\-set\-fec +.I devname +.B encoding +.BR auto | off | rs | baser | llrs \ [...] +.HP +.B ethtool \-Q|\-\-per\-queue +.I devname +.RB [ queue_mask +.IR %x ] +.I sub_command +.RB ... + . +.HP +.B ethtool \-\-cable\-test +.I devname +.HP +.B ethtool \-\-cable\-test\-tdr +.I devname +.BN first N +.BN last N +.BN step N +.BN pair N +.HP +.B ethtool \-\-show\-tunnels +.I devname +.HP +.B ethtool \-\-show\-module +.I devname +.HP +.B ethtool \-\-set\-module +.I devname +.RB [ power\-mode\-policy +.BR high | auto ] +. +.\" Adjust lines (i.e. full justification) and hyphenate. +.ad +.hy + +.SH DESCRIPTION +.BI ethtool +is used to query and control network device driver and hardware +settings, particularly for wired Ethernet devices. + +.I devname +is the name of the network device on which ethtool should operate. + +.SH OPTIONS +.B ethtool +with a single argument specifying the device name prints current +settings of the specified device. +.TP +.B \-h \-\-help +Shows a short help message. +.TP +.B \-\-version +Shows the ethtool version number. +.TP +.BI \-\-debug \ N +Turns on debugging messages. Argument is interpreted as a mask: +.TS +nokeep; +lB l. +0x01 Parser information +.TE +.TP +.BI \-\-json +Output results in JavaScript Object Notation (JSON). Only a subset of +options support this. Those which do not will continue to output +plain text in the presence of this option. +.TP +.B \-I \-\-include\-statistics +Include command-related statistics in the output. This option allows +displaying relevant device statistics for selected get commands. +.TP +.B \-a \-\-show\-pause +Queries the specified Ethernet device for pause parameter information. +.TP +.B \-A \-\-pause +Changes the pause parameters of the specified Ethernet device. +.RS 4 +.TP +.A2 autoneg on off +Specifies whether pause autonegotiation should be enabled. +.TP +.A2 rx on off +Specifies whether RX pause should be enabled. +.TP +.A2 tx on off +Specifies whether TX pause should be enabled. +.RE +.TP +.B \-c \-\-show\-coalesce +Queries the specified network device for coalescing information. +.TP +.B \-C \-\-coalesce +Changes the coalescing settings of the specified network device. +.TP +.B \-g \-\-show\-ring +Queries the specified network device for rx/tx ring parameter information. +.TP +.B \-G \-\-set\-ring +Changes the rx/tx ring parameters of the specified network device. +.RS 4 +.TP +.BI rx \ N +Changes the number of ring entries for the Rx ring. +.TP +.BI rx\-mini \ N +Changes the number of ring entries for the Rx Mini ring. +.TP +.BI rx\-jumbo \ N +Changes the number of ring entries for the Rx Jumbo ring. +.TP +.BI tx \ N +Changes the number of ring entries for the Tx ring. +.TP +.BI rx\-buf\-len \ N +Changes the size of a buffer in the Rx ring. +.TP +.BI cqe\-size \ N +Changes the size of completion queue event. +.TP +.BI tx\-push \ on|off +Specifies whether TX push should be enabled. +.RE +.TP +.B \-i \-\-driver +Queries the specified network device for associated driver information. +.TP +.B \-d \-\-register\-dump +Retrieves and prints a register dump for the specified network device. +The register format for some devices is known and decoded others +are printed in hex. +When +.I raw +is enabled, then ethtool dumps the raw register data to stdout. +If +.I file +is specified, then use contents of previous raw register dump, rather +than reading from the device. +.TP +.B \-e \-\-eeprom\-dump +Retrieves and prints an EEPROM dump for the specified network device. +When raw is enabled, then it dumps the raw EEPROM data to stdout. The +length and offset parameters allow dumping certain portions of the EEPROM. +Default is to dump the entire EEPROM. +.RS 4 +.TP +.BI raw \ on|off +.TP +.BI offset \ N +.TP +.BI length \ N +.RE +.TP +.B \-E \-\-change\-eeprom +If value is specified, changes EEPROM byte for the specified network device. +offset and value specify which byte and it's new value. If value is not +specified, stdin is read and written to the EEPROM. The length and offset +parameters allow writing to certain portions of the EEPROM. +Because of the persistent nature of writing to the EEPROM, a device-specific +magic key must be specified to prevent the accidental writing to the EEPROM. +.TP +.B \-k \-\-show\-features \-\-show\-offload +Queries the specified network device for the state of protocol +offload and other features. +.TP +.B \-K \-\-features \-\-offload +Changes the offload parameters and other features of the specified +network device. The following feature names are built-in and others +may be defined by the kernel. +.RS 4 +.TP +.A2 rx on off +Specifies whether RX checksumming should be enabled. +.TP +.A2 tx on off +Specifies whether TX checksumming should be enabled. +.TP +.A2 sg on off +Specifies whether scatter-gather should be enabled. +.TP +.A2 tso on off +Specifies whether TCP segmentation offload should be enabled. +.TP +.A2 ufo on off +Specifies whether UDP fragmentation offload should be enabled +.TP +.A2 gso on off +Specifies whether generic segmentation offload should be enabled +.TP +.A2 gro on off +Specifies whether generic receive offload should be enabled +.TP +.A2 lro on off +Specifies whether large receive offload should be enabled +.TP +.A2 rxvlan on off +Specifies whether RX VLAN acceleration should be enabled +.TP +.A2 txvlan on off +Specifies whether TX VLAN acceleration should be enabled +.TP +.A2 ntuple on off +Specifies whether Rx ntuple filters and actions should be enabled +.TP +.A2 rxhash on off +Specifies whether receive hashing offload should be enabled +.RE +.TP +.B \-p \-\-identify +Initiates adapter-specific action intended to enable an operator to +easily identify the adapter by sight. Typically this involves +blinking one or more LEDs on the specific network port. +.RS 4 +.TP +.BN +Length of time to perform phys-id, in seconds. +.RE +.TP +.B \-P \-\-show\-permaddr +Queries the specified network device for permanent hardware address. +.TP +.B \-r \-\-negotiate +Restarts auto-negotiation on the specified Ethernet device, if +auto-negotiation is enabled. +.TP +.B \-S \-\-statistics +Queries the specified network device for standard (IEEE, IETF, etc.), or NIC- +and driver-specific statistics. NIC- and driver-specific statistics are +requested when no group of statistics is specified. + +NIC- and driver-specific statistics and standard statistics are independent, +devices may implement either, both or none. There is little commonality between +naming of NIC- and driver-specific statistics across vendors. +.RS 4 +.TP +.B \fB\-\-all\-groups +.TP +.B \fB\-\-groups [\fBeth\-phy\fP] [\fBeth\-mac\fP] [\fBeth\-ctrl\fP] [\fBrmon\fP] +Request groups of standard device statistics. +.RE +.TP +.B \-\-phy\-statistics +Queries the specified network device for PHY specific statistics. +.TP +.B \-t \-\-test +Executes adapter selftest on the specified network device. Possible test modes are: +.RS 4 +.TP +.B offline +Perform full set of tests, possibly interrupting normal operation +during the tests, +.TP +.B online +Perform limited set of tests, not interrupting normal operation, +.TP +.B external_lb +Perform full set of tests, as for \fBoffline\fR, and additionally an +external-loopback test. +.RE +.TP +.B \-s \-\-change +Allows changing some or all settings of the specified network device. +All following options only apply if +.B \-s +was specified. +.RS 4 +.TP +.BI speed \ N +Set speed in Mb/s. +.B ethtool +with just the device name as an argument will show you the supported device speeds. +.TP +.BI lanes \ N +Set number of lanes. +.TP +.A2 duplex half full +Sets full or half duplex mode. +.TP +.A4 port tp aui bnc mii fibre da +Selects device port. +.TP +.BR master-slave \ \*(MS +Configure MASTER/SLAVE role of the PHY. When the PHY is configured as MASTER, +the PMA Transmit function shall source TX_TCLK from a local clock source. When +configured as SLAVE, the PMA Transmit function shall source TX_TCLK from the +clock recovered from data stream provided by MASTER. Not all devices support this. +.TS +nokeep; +lB l. +preferred-master Prefer MASTER role on autonegotiation +preferred-slave Prefer SLAVE role on autonegotiation +forced-master Force the PHY in MASTER role. Can be used without autonegotiation +forced-slave Force the PHY in SLAVE role. Can be used without autonegotiation +.TE +.TP +.A3 mdix auto on off +Selects MDI-X mode for port. May be used to override the automatic +detection feature of most adapters. An argument of \fBauto\fR means +automatic detection of MDI status, \fBon\fR forces MDI-X (crossover) +mode, while \fBoff\fR means MDI (straight through) mode. The driver +should guarantee that this command takes effect immediately, and if +necessary may reset the link to cause the change to take effect. +.TP +.A2 autoneg on off +Specifies whether autonegotiation should be enabled. Autonegotiation +is enabled by default, but in some network devices may have trouble +with it, so you can disable it if really necessary. +.TP +.BI advertise \ N +Sets the speed and duplex advertised by autonegotiation. The argument is +a hexadecimal value using one or a combination of the following values: +.TS +nokeep; +lB l lB. +0x001 10baseT Half +0x002 10baseT Full +0x100000000000000000000000 10baseT1L Full +0x004 100baseT Half +0x008 100baseT Full +0x80000000000000000 100baseT1 Full +0x40000000000000000000000 100baseFX Half +0x80000000000000000000000 100baseFX Full +0x010 1000baseT Half (not supported by IEEE standards) +0x020 1000baseT Full +0x20000 1000baseKX Full +0x20000000000 1000baseX Full +0x100000000000000000 1000baseT1 Full +0x8000 2500baseX Full (not supported by IEEE standards) +0x800000000000 2500baseT Full +0x1000000000000 5000baseT Full +0x1000 10000baseT Full +0x40000 10000baseKX4 Full +0x80000 10000baseKR Full +0x100000 10000baseR_FEC +0x40000000000 10000baseCR Full +0x80000000000 10000baseSR Full +0x100000000000 10000baseLR Full +0x200000000000 10000baseLRM Full +0x400000000000 10000baseER Full +0x200000 20000baseMLD2 Full (not supported by IEEE standards) +0x400000 20000baseKR2 Full (not supported by IEEE standards) +0x80000000 25000baseCR Full +0x100000000 25000baseKR Full +0x200000000 25000baseSR Full +0x800000 40000baseKR4 Full +0x1000000 40000baseCR4 Full +0x2000000 40000baseSR4 Full +0x4000000 40000baseLR4 Full +0x400000000 50000baseCR2 Full +0x800000000 50000baseKR2 Full +0x10000000000 50000baseSR2 Full +0x10000000000000 50000baseKR Full +0x20000000000000 50000baseSR Full +0x40000000000000 50000baseCR Full +0x80000000000000 50000baseLR_ER_FR Full +0x100000000000000 50000baseDR Full +0x8000000 56000baseKR4 Full +0x10000000 56000baseCR4 Full +0x20000000 56000baseSR4 Full +0x40000000 56000baseLR4 Full +0x1000000000 100000baseKR4 Full +0x2000000000 100000baseSR4 Full +0x4000000000 100000baseCR4 Full +0x8000000000 100000baseLR4_ER4 Full +0x200000000000000 100000baseKR2 Full +0x400000000000000 100000baseSR2 Full +0x800000000000000 100000baseCR2 Full +0x1000000000000000 100000baseLR2_ER2_FR2 Full +0x2000000000000000 100000baseDR2 Full +0x8000000000000000000 100000baseKR Full +0x10000000000000000000 100000baseSR Full +0x20000000000000000000 100000baseLR_ER_FR Full +0x40000000000000000000 100000baseCR Full +0x80000000000000000000 100000baseDR Full +0x4000000000000000 200000baseKR4 Full +0x8000000000000000 200000baseSR4 Full +0x10000000000000000 200000baseLR4_ER4_FR4 Full +0x20000000000000000 200000baseDR4 Full +0x40000000000000000 200000baseCR4 Full +0x100000000000000000000 200000baseKR2 Full +0x200000000000000000000 200000baseSR2 Full +0x400000000000000000000 200000baseLR2_ER2_FR2 Full +0x800000000000000000000 200000baseDR2 Full +0x1000000000000000000000 200000baseCR2 Full +0x200000000000000000 400000baseKR8 Full +0x400000000000000000 400000baseSR8 Full +0x800000000000000000 400000baseLR8_ER8_FR8 Full +0x1000000000000000000 400000baseDR8 Full +0x2000000000000000000 400000baseCR8 Full +0x2000000000000000000000 400000baseKR4 Full +0x4000000000000000000000 400000baseSR4 Full +0x8000000000000000000000 400000baseLR4_ER4_FR4 Full +0x10000000000000000000000 400000baseDR4 Full +0x20000000000000000000000 400000baseCR4 Full +.TE +.TP +.BI phyad \ N +PHY address. +.TP +.A2 xcvr internal external +Selects transceiver type. Currently only internal and external can be +specified, in the future further types might be added. +.TP +.BR wol \ \*(WO +Sets Wake-on-LAN options. Not all devices support this. The argument to +this option is a string of characters specifying which options to enable. +.TS +nokeep; +lB l. +p Wake on PHY activity +u Wake on unicast messages +m Wake on multicast messages +b Wake on broadcast messages +a Wake on ARP +g Wake on MagicPacket\[tm] +s Enable SecureOn\[tm] password for MagicPacket\[tm] +f Wake on filter(s) +d T{ +Disable (wake on nothing). This option clears all previous options. +T} +.TE +.TP +.B sopass \*(MA +Sets the SecureOn\[tm] password. The argument to this option must be 6 +bytes in Ethernet MAC hex format (\*(MA). +.PP +.BI msglvl \ N +.br +.BI msglvl \ type +.A1 on off +.RB ... +.RS +Sets the driver message type flags by name or number. \fItype\fR +names the type of message to enable or disable; \fIN\fR specifies the +new flags numerically. The defined type names and numbers are: +.TS +nokeep; +lB l l. +drv 0x0001 General driver status +probe 0x0002 Hardware probing +link 0x0004 Link state +timer 0x0008 Periodic status check +ifdown 0x0010 Interface being brought down +ifup 0x0020 Interface being brought up +rx_err 0x0040 Receive error +tx_err 0x0080 Transmit error +tx_queued 0x0100 Transmit queueing +intr 0x0200 Interrupt handling +tx_done 0x0400 Transmit completion +rx_status 0x0800 Receive completion +pktdata 0x1000 Packet contents +hw 0x2000 Hardware status +wol 0x4000 Wake-on-LAN status +.TE +.PP +The precise meanings of these type flags differ between drivers. +.RE +.PD +.RE +.TP +.B \-n \-u \-\-show\-nfc \-\-show\-ntuple +Retrieves receive network flow classification options or rules. +.RS 4 +.TP +.BR rx\-flow\-hash \ \*(FL +Retrieves the hash options for the specified flow type. +.TS +nokeep; +lB l. +tcp4 TCP over IPv4 +udp4 UDP over IPv4 +ah4 IPSEC AH over IPv4 +esp4 IPSEC ESP over IPv4 +sctp4 SCTP over IPv4 +tcp6 TCP over IPv6 +udp6 UDP over IPv6 +ah6 IPSEC AH over IPv6 +esp6 IPSEC ESP over IPv6 +sctp6 SCTP over IPv6 +.TE +.TP +.BI rule \ N +Retrieves the RX classification rule with the given ID. +.RE +.PD +.RE +.TP +.B \-N \-U \-\-config\-nfc \-\-config\-ntuple +Configures receive network flow classification options or rules. +.RS 4 +.TP +.BR rx\-flow\-hash \ \*(FL \: \*(HO +Configures the hash options for the specified flow type. +.TS +nokeep; +lB l. +m Hash on the Layer 2 destination address of the rx packet. +v Hash on the VLAN tag of the rx packet. +t Hash on the Layer 3 protocol field of the rx packet. +s Hash on the IP source address of the rx packet. +d Hash on the IP destination address of the rx packet. +f Hash on bytes 0 and 1 of the Layer 4 header of the rx packet. +n Hash on bytes 2 and 3 of the Layer 4 header of the rx packet. +r T{ +Discard all packets of this flow type. When this option is set, all +other options are ignored. +T} +.TE +.TP +.B flow\-type \*(NC +Inserts or updates a classification rule for the specified flow type. +.TS +nokeep; +lB l. +ether Ethernet +ip4 Raw IPv4 +tcp4 TCP over IPv4 +udp4 UDP over IPv4 +sctp4 SCTP over IPv4 +ah4 IPSEC AH over IPv4 +esp4 IPSEC ESP over IPv4 +ip6 Raw IPv6 +tcp6 TCP over IPv6 +udp6 UDP over IPv6 +sctp6 SCTP over IPv6 +ah6 IPSEC AH over IPv6 +esp6 IPSEC ESP over IPv6 +.TE +.PP +For all fields that allow both a value and a mask to be specified, the +mask may be specified immediately after the value using the \fBm\fR +keyword, or separately using the field name keyword with \fB-mask\fR +appended, e.g. \fBsrc-mask\fR. +.PD +.TP +.BR src \ \*(MA\ [ m \ \*(MA] +Includes the source MAC address, specified as 6 bytes in hexadecimal +separated by colons, along with an optional mask. Valid only for +flow-type ether. +.TP +.BR dst \ \*(MA\ [ m \ \*(MA] +Includes the destination MAC address, specified as 6 bytes in hexadecimal +separated by colons, along with an optional mask. Valid only for +flow-type ether. +.TP +.BI proto \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes the Ethernet protocol number (ethertype) and an optional mask. +Valid only for flow-type ether. +.TP +.BR src\-ip \ \*(PA\ [ m \ \*(PA] +Specify the source IP address of the incoming packet to match along with +an optional mask. Valid for all IP based flow-types. +.TP +.BR dst\-ip \ \*(PA\ [ m \ \*(PA] +Specify the destination IP address of the incoming packet to match along +with an optional mask. Valid for all IP based flow-types. +.TP +.BI tos \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the Type of Service field in the incoming packet to +match along with an optional mask. Applies to all IPv4 based flow-types. +.TP +.BI tclass \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the Traffic Class field in the incoming packet to +match along with an optional mask. Applies to all IPv6 based flow-types. +.TP +.BI l4proto \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes the layer 4 protocol number and optional mask. Valid only for +flow-types ip4 and ip6. +.TP +.BI src\-port \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the source port field (applicable to TCP/UDP packets) +in the incoming packet to match along with an optional mask. Valid for +flow-types ip4, tcp4, udp4, and sctp4 and their IPv6 equivalents. +.TP +.BI dst\-port \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the destination port field (applicable to TCP/UDP +packets)in the incoming packet to match along with an optional mask. +Valid for flow-types ip4, tcp4, udp4, and sctp4 and their IPv6 equivalents. +.TP +.BI spi \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the security parameter index field (applicable to +AH/ESP packets)in the incoming packet to match along with an optional +mask. Valid for flow-types ip4, ah4, and esp4 and their IPv6 equivalents. +.TP +.BI l4data \ N \\fR\ [\\fPm \ N \\fR]\\fP +Specify the value of the first 4 Bytes of Layer 4 in the incoming packet to +match along with an optional mask. Valid for ip4 and ip6 flow-types. +.TP +.BI vlan\-etype \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes the VLAN tag Ethertype and an optional mask. +.TP +.BI vlan \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes the VLAN tag and an optional mask. +.TP +.BI user\-def \ N \\fR\ [\\fPm \ N \\fR]\\fP +Includes 64-bits of user-specific data and an optional mask. +.TP +.BR dst-mac \ \*(MA\ [ m \ \*(MA] +Includes the destination MAC address, specified as 6 bytes in hexadecimal +separated by colons, along with an optional mask. +Valid for all IP based flow-types. +.TP +.BI action \ N +Specifies the Rx queue to send packets to, or some other action. +.TS +nokeep; +lB l. +-1 Drop the matched flow +-2 Use the matched flow as a Wake-on-LAN filter +0 or higher Rx queue to route the flow +.TE +.TP +.BI context \ N +Specifies the RSS context to spread packets over multiple queues; either +.B 0 +for the default RSS context, or a value returned by +.BI ethtool\ -X\ ... \ context +.BR new . +.TP +.BI vf \ N +Specifies the Virtual Function the filter applies to. Not compatible with action. +.TP +.BI queue \ N +Specifies the Rx queue to send packets to. Not compatible with action. +.TP +.BI loc \ N +Specify the location/ID to insert the rule. This will overwrite +any rule present in that location and will not go through any +of the rule ordering process. +.TP +.BI delete \ N +Deletes the RX classification rule with the given ID. +.RE +.TP +.B \-w \-\-get\-dump +Retrieves and prints firmware dump for the specified network device. +By default, it prints out the dump flag, version and length of the dump data. +When +.I data +is indicated, then ethtool fetches the dump data and directs it to a +.I file. +.TP +.B \-W \-\-set\-dump +Sets the dump flag for the device. +.TP +.B \-T \-\-show\-time\-stamping +Show the device's time stamping capabilities and associated PTP +hardware clock. +.TP +.B \-x \-\-show\-rxfh\-indir \-\-show\-rxfh +Retrieves the receive flow hash indirection table and/or RSS hash key. +.TP +.B \-X \-\-set\-rxfh\-indir \-\-rxfh +Configures the receive flow hash indirection table and/or RSS hash key. +.RS 4 +.TP +.BI hkey +Sets RSS hash key of the specified network device. RSS hash key should be of device supported length. +Hash key format must be in xx:yy:zz:aa:bb:cc format meaning both the nibbles of a byte should be mentioned +even if a nibble is zero. +.TP +.BI hfunc +Sets RSS hash function of the specified network device. +List of RSS hash functions which kernel supports is shown as a part of the --show-rxfh command output. +.TP +.BI start\ N +For the \fBequal\fR and \fBweight\fR options, sets the starting receive queue +for spreading flows to \fIN\fR. +.TP +.BI equal\ N +Sets the receive flow hash indirection table to spread flows evenly +between the first \fIN\fR receive queues. +.TP +\fBweight\fR \fIW0 W1\fR ... +Sets the receive flow hash indirection table to spread flows between +receive queues according to the given weights. The sum of the weights +must be non-zero and must not exceed the size of the indirection table. +.TP +.BI default +Sets the receive flow hash indirection table to its default value. +.TP +\fBcontext \fICTX\fR | \fBnew\fR +Specifies an RSS context to act on; either +.B new +to allocate a new RSS context, or +.IR CTX , +a value returned by a previous +.IB ... \ context +.BR new . +.TP +.B delete +Delete the specified RSS context. May only be used in conjunction with +.B context +and a non-zero +.I CTX +value. +.RE +.TP +.B \-f \-\-flash +Write a firmware image to flash or other non-volatile memory on the +device. +.RS 4 +.TP +.I file +Specifies the filename of the firmware image. The firmware must first +be installed in one of the directories where the kernel firmware +loader or firmware agent will look, such as /lib/firmware. +.TP +.I N +If the device stores multiple firmware images in separate regions of +non-volatile memory, this parameter may be used to specify which +region is to be written. The default is 0, requesting that all +regions are written. All other values are driver-dependent. +.RE +.PD +.TP +.B \-l \-\-show\-channels +Queries the specified network device for the numbers of channels it has. +A channel is an IRQ and the set of queues that can trigger that IRQ. +.TP +.B \-L \-\-set\-channels +Changes the numbers of channels of the specified network device. +.RS 4 +.TP +.BI rx \ N +Changes the number of channels with only receive queues. +.TP +.BI tx \ N +Changes the number of channels with only transmit queues. +.TP +.BI other \ N +Changes the number of channels used only for other purposes e.g. link interrupts or SR-IOV co-ordination. +.TP +.BI combined \ N +Changes the number of multi-purpose channels. +.RE +.TP +.B \-m \-\-dump\-module\-eeprom \-\-module\-info +Retrieves and if possible decodes the EEPROM from plugin modules, e.g SFP+, QSFP. +If the driver and module support it, the optical diagnostic information is also +read and decoded. +When either one of +.I page, +.I bank +or +.I i2c +parameters is specified, dumps only of a single page or its portion is +allowed. In such a case +.I offset +and +.I length +parameters are treated relatively to EEPROM page boundaries. +.TP +.B \-\-show\-priv\-flags +Queries the specified network device for its private flags. The +names and meanings of private flags (if any) are defined by each +network device driver. +.TP +.B \-\-set\-priv\-flags +Sets the device's private flags as specified. +.RS 4 +.PP +.I flag +.A1 on off +Sets the state of the named private flag. +.RE +.TP +.B \-\-show\-eee +Queries the specified network device for its support of Energy-Efficient +Ethernet (according to the IEEE 802.3az specifications) +.TP +.B \-\-set\-eee +Sets the device EEE behaviour. +.RS 4 +.TP +.A2 eee on off +Enables/disables the device support of EEE. +.TP +.A2 tx-lpi on off +Determines whether the device should assert its Tx LPI. +.TP +.BI advertise \ N +Sets the speeds for which the device should advertise EEE capabilities. +Values are as for +.B \-\-change advertise +.TP +.BI tx-timer \ N +Sets the amount of time the device should stay in idle mode prior to asserting +its Tx LPI (in microseconds). This has meaning only when Tx LPI is enabled. +.RE +.TP +.B \-\-set\-phy\-tunable +Sets the PHY tunable parameters. +.RS 4 +.TP +.A2 downshift on off +Specifies whether downshift should be enabled. +.TS +nokeep; +lB l. +.BI count \ N + Sets the PHY downshift re-tries count. +.TE +.TP +.A2 fast-link-down on off +Specifies whether Fast Link Down should be enabled and time until link down (if supported). +.TS +nokeep; +lB l. +.BI msecs \ N + Sets the period after which the link is reported as down. Note that the PHY may choose + the closest supported value. Only on reading back the tunable do you get the actual value. +.TE +.TP +.A2 energy-detect-power-down on off +Specifies whether Energy Detect Power Down (EDPD) should be enabled (if supported). +This will put the RX and TX circuit blocks into a low power mode, and the PHY will +wake up periodically to send link pulses to avoid any lock-up situation with a peer +PHY that may also have EDPD enabled. By default, this setting will also enable the +periodic transmission of TX pulses. +.TS +nokeep; +lB l. +.BI msecs \ N + Some PHYs support configuration of the wake-up interval to send TX pulses. + This setting allows the control of this interval, and 0 disables TX pulses + if the PHY supports this. Disabling TX pulses can create a lock-up situation + where neither of the PHYs wakes the other one. If unspecified the default + value (in milliseconds) will be used by the PHY. +.TE +.TP +.PD +.RE +.TP +.B \-\-get\-phy\-tunable +Gets the PHY tunable parameters. +.RS 4 +.TP +.B downshift +For operation in cabling environments that are incompatible with 1000BASE-T, +PHY device provides an automatic link speed downshift operation. +Link speed downshift after N failed 1000BASE-T auto-negotiation attempts. +Downshift is useful where cable does not have the 4 pairs instance. + +Gets the PHY downshift count/status. +.TP +.B fast\-link\-down +Depending on the mode it may take 0.5s - 1s until a broken link is reported as down. +In certain use cases a link-down event needs to be reported as soon as possible. +Some PHYs support a Fast Link Down Feature and may allow configuration of the delay +before a broken link is reported as being down. + +Gets the PHY Fast Link Down status / period. +.TP +.B energy\-detect\-power\-down +Gets the current configured setting for Energy Detect Power Down (if supported). + +.RE +.TP +.B \-\-get\-tunable +Get the tunable parameters. +.RS 4 +.TP +.B rx\-copybreak +Get the current rx copybreak value in bytes. +.TP +.B tx\-copybreak +Get the current tx copybreak value in bytes. +.TP +.B tx\-buf\-size +Get the current tx copybreak buffer size in bytes. +.TP +.B pfc\-prevention\-tout +Get the current pfc prevention timeout value in msecs. +.RE +.TP +.B \-\-set\-tunable +Set driver's tunable parameters. +.RS 4 +.TP +.BI rx\-copybreak \ N +Set the rx copybreak value in bytes. +.TP +.BI tx\-copybreak \ N +Set the tx copybreak value in bytes. +.TP +.BI tx\-buf\-size \ N +Set the tx copybreak buffer size in bytes. +.TP +.BI pfc\-prevention\-tout \ N +Set pfc prevention timeout in msecs. Value of 0 means disable and 65535 means auto. +.RE +.TP +.B \-\-reset +Reset hardware components specified by flags and components listed below +.RS 4 +.TP +.BI flags \ N +Resets the components based on direct flags mask +.TP +.B mgmt +Management processor +.TP +.B irq +Interrupt requester +.TP +.B dma +DMA engine +.TP +.B filter +Filtering/flow direction +.TP +.B offload +Protocol offload +.TP +.B mac +Media access controller +.TP +.B phy +Transceiver/PHY +.TP +.B ram +RAM shared between multiple components +.B ap +Application Processor +.TP +.B dedicated +All components dedicated to this interface +.TP +.B all +All components used by this interface, even if shared +.RE +.TP +.B \-\-show\-fec +Queries the specified network device for its support of Forward Error Correction. +.TP +.B \-\-set\-fec +Configures Forward Error Correction for the specified network device. + +Forward Error Correction modes selected by a user are expected to be persisted +after any hotplug events. If a module is swapped that does not support the +current FEC mode, the driver or firmware must take the link down +administratively and report the problem in the system logs for users to correct. +.RS 4 +.TP +.BR encoding\ auto | off | rs | baser | llrs \ [...] + +Sets the FEC encoding for the device. Combinations of options are specified as +e.g. +.B encoding auto rs +; the semantics of such combinations vary between drivers. +.TS +nokeep; +lB l. +auto Use the driver's default encoding +off Turn off FEC +RS Force RS-FEC encoding +BaseR Force BaseR encoding +LLRS Force LLRS-FEC encoding +.TE +.RE +.TP +.B \-Q|\-\-per\-queue +Applies provided sub command to specific queues. +.RS 4 +.TP +.B queue_mask %x +Sets the specific queues which the sub command is applied to. +If queue_mask is not set, the sub command will be applied to all queues. +.TP +.B sub_command +Sub command to apply. The supported sub commands include --show-coalesce and +--coalesce. +.RE +.TP +.B \-\-cable\-test +Perform a cable test and report the results. What results are returned depends +on the capabilities of the network interface. Typically open pairs and shorted +pairs can be reported, along with pairs being O.K. When a fault is detected +the approximate distance to the fault may be reported. +.TP +.B \-\-cable\-test\-tdr +Perform a cable test and report the raw Time Domain Reflectometer +data. A pulse is sent down a cable pair and the amplitude of the +reflection, for a given distance, is reported. A break in the cable +returns a big reflection. Minor damage to the cable returns a small +reflection. If the cable is shorted, the amplitude of the reflection +can be negative. By default, data is returned for lengths between 0 +and 150m at 1m steps, for all pairs. However parameters can be passed +to restrict the collection of data. It should be noted, that the +interface will round the distances to whatever granularity is actually +implemented. This is often 0.8 of a meter. The results should include +the actual rounded first and last distance and step size. +.RS 4 +.TP +.B first \ N +Distance along the cable, in meters, where the first measurement +should be made. +.TP +.B last \ N +Distance along the cable, in meters, where the last measurement should +be made. +.TP +.B step \ N +Distance, in meters, between each measurement. +.TP +.B pair \ N +Which pair should be measured. Typically a cable has 4 pairs. 0 = Pair A, 1 = Pair B, ... +.RE +.TP +.B \-\-monitor +Listens to netlink notification and displays them. +.RS 4 +.TP +.I command +If argument matching a command is used, ethtool only shows notifications of +this type. Without such argument or with --all, all notification types are +shown. +.TP +.I devname +If a device name is used as argument, only notification for this device are +shown. Default is to show notifications for all devices. +.RE +.TP +.B \-\-show\-tunnels +Show tunnel-related device capabilities and state. +List UDP ports kernel has programmed the device to parse as VxLAN, +or GENEVE tunnels. +.RE +.TP +.B \-\-show\-module +Show the transceiver module's parameters. +.RE +.TP +.B \-\-set\-module +Set the transceiver module's parameters. +.RS 4 +.TP +.A2 power-mode-policy high auto +Set the power mode policy for the module. When set to \fBhigh\fR, the module +always operates at high power mode. When set to \fBauto\fR, the module is +transitioned by the host to high power mode when the first port using it is put +administratively up and to low power mode when the last port using it is put +administratively down. The power mode policy can be set before a module is +plugged-in. +.RE +.SH BUGS +Not supported (in part or whole) on all network drivers. +.SH AUTHOR +.B ethtool +was written by David Miller. + +Modifications by +Jeff Garzik, +Tim Hockin, +Jakub Jelinek, +Andre Majorel, +Eli Kupermann, +Scott Feldman, +Andi Kleen, +Alexander Duyck, +Sucheta Chakraborty, +Jesse Brandeburg, +Ben Hutchings, +Scott Branden. +.SH AVAILABILITY +.B ethtool +is available from +.UR http://www.kernel.org/pub/software/network/ethtool/ +.UE diff --git a/ethtool.c b/ethtool.c new file mode 100644 index 0000000..526be4c --- /dev/null +++ b/ethtool.c @@ -0,0 +1,6428 @@ +/* + * ethtool.c: Linux ethernet device configuration tool. + * + * Copyright (C) 1998 David S. Miller (davem@dm.cobaltmicro.com) + * Portions Copyright 2001 Sun Microsystems + * Kernel 2.4 update Copyright 2001 Jeff Garzik + * Wake-on-LAN,natsemi,misc support by Tim Hockin + * Portions Copyright 2002 Intel + * Portions Copyright (C) Sun Microsystems 2008 + * do_test support by Eli Kupermann + * ETHTOOL_PHYS_ID support by Chris Leech + * e1000 support by Scott Feldman + * e100 support by Wen Tao + * ixgb support by Nicholas Nunley + * amd8111e support by Reeja John + * long arguments by Andi Kleen. + * SMSC LAN911x support by Steve Glendinning + * Rx Network Flow Control configuration support + * Various features by Ben Hutchings ; + * Copyright 2009, 2010 Solarflare Communications + * MDI-X set support by Jesse Brandeburg + * Copyright 2012 Intel Corporation + * vmxnet3 support by Shrikrishna Khare + * Various features by Ben Hutchings ; + * Copyright 2008-2010, 2013-2016 Ben Hutchings + * QSFP+/QSFP28 DOM support by Vidya Sagar Ravipati + * + * TODO: + * * show settings for all devices + */ + +#include "internal.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "common.h" +#include "netlink/extapi.h" + +#ifndef MAX_ADDR_LEN +#define MAX_ADDR_LEN 32 +#endif + +#ifndef NETLINK_GENERIC +#define NETLINK_GENERIC 16 +#endif + +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) + +static void exit_bad_args(void) __attribute__((noreturn)); + +static void exit_bad_args(void) +{ + fprintf(stderr, + "ethtool: bad command line argument(s)\n" + "For more information run ethtool -h\n"); + exit(1); +} + +static void exit_nlonly_param(const char *name) __attribute__((noreturn)); + +static void exit_nlonly_param(const char *name) +{ + fprintf(stderr, + "ethtool: parameter '%s' can be used only with netlink\n", + name); + exit(1); +} + +typedef enum { + CMDL_NONE, + CMDL_BOOL, + CMDL_S32, + CMDL_U8, + CMDL_U16, + CMDL_U32, + CMDL_U64, + CMDL_BE16, + CMDL_IP4, + CMDL_STR, + CMDL_FLAG, + CMDL_MAC, +} cmdline_type_t; + +struct cmdline_info { + const char *name; + cmdline_type_t type; + /* Points to int (BOOL), s32, u16, u32 (U32/FLAG/IP4), u64, + * char * (STR) or u8[6] (MAC). For FLAG, the value accumulates + * all flags to be set. */ + void *wanted_val; + void *ioctl_val; + /* For FLAG, the flag value to be set/cleared */ + u32 flag_val; + /* For FLAG, points to u32 and accumulates all flags seen. + * For anything else, points to int and is set if the option is + * seen. */ + void *seen_val; +}; + +struct feature_def { + char name[ETH_GSTRING_LEN]; + int off_flag_index; /* index in off_flag_def; negative if none match */ +}; + +struct feature_defs { + size_t n_features; + /* Number of features each offload flag is associated with */ + unsigned int off_flag_matched[OFF_FLAG_DEF_SIZE]; + /* Name and offload flag index for each feature */ + struct feature_def def[0]; +}; + +#define FEATURE_BITS_TO_BLOCKS(n_bits) DIV_ROUND_UP(n_bits, 32U) +#define FEATURE_WORD(blocks, index, field) ((blocks)[(index) / 32U].field) +#define FEATURE_FIELD_FLAG(index) (1U << (index) % 32U) +#define FEATURE_BIT_SET(blocks, index, field) \ + (FEATURE_WORD(blocks, index, field) |= FEATURE_FIELD_FLAG(index)) +#define FEATURE_BIT_CLEAR(blocks, index, field) \ + (FEATURE_WORD(blocks, index, filed) &= ~FEATURE_FIELD_FLAG(index)) +#define FEATURE_BIT_IS_SET(blocks, index, field) \ + (FEATURE_WORD(blocks, index, field) & FEATURE_FIELD_FLAG(index)) + +static long long +get_int_range(char *str, int base, long long min, long long max) +{ + long long v; + char *endp; + + if (!str) + exit_bad_args(); + errno = 0; + v = strtoll(str, &endp, base); + if (errno || *endp || v < min || v > max) + exit_bad_args(); + return v; +} + +static unsigned long long +get_uint_range(char *str, int base, unsigned long long max) +{ + unsigned long long v; + char *endp; + + if (!str) + exit_bad_args(); + errno = 0; + v = strtoull(str, &endp, base); + if (errno || *endp || v > max) + exit_bad_args(); + return v; +} + +static int get_int(char *str, int base) +{ + return get_int_range(str, base, INT_MIN, INT_MAX); +} + +static u32 get_u32(char *str, int base) +{ + return get_uint_range(str, base, 0xffffffff); +} + +static void get_mac_addr(char *src, unsigned char *dest) +{ + int count; + int i; + int buf[ETH_ALEN]; + + count = sscanf(src, "%2x:%2x:%2x:%2x:%2x:%2x", + &buf[0], &buf[1], &buf[2], &buf[3], &buf[4], &buf[5]); + if (count != ETH_ALEN) + exit_bad_args(); + + for (i = 0; i < count; i++) + dest[i] = buf[i]; +} + +static int parse_hex_u32_bitmap(const char *s, + unsigned int nbits, u32 *result) +{ + const unsigned int nwords = __KERNEL_DIV_ROUND_UP(nbits, 32); + size_t slen = strlen(s); + size_t i; + + /* ignore optional '0x' prefix */ + if ((slen > 2) && (strncasecmp(s, "0x", 2) == 0)) { + slen -= 2; + s += 2; + } + + if (slen > 8 * nwords) /* up to 2 digits per byte */ + return -1; + + memset(result, 0, 4 * nwords); + for (i = 0; i < slen; ++i) { + const unsigned int shift = (slen - 1 - i) * 4; + u32 *dest = &result[shift / 32]; + u32 nibble; + + if ('a' <= s[i] && s[i] <= 'f') + nibble = 0xa + (s[i] - 'a'); + else if ('A' <= s[i] && s[i] <= 'F') + nibble = 0xa + (s[i] - 'A'); + else if ('0' <= s[i] && s[i] <= '9') + nibble = (s[i] - '0'); + else + return -1; + + *dest |= (nibble << (shift % 32)); + } + + return 0; +} + +static void parse_generic_cmdline(struct cmd_context *ctx, + int *changed, + struct cmdline_info *info, + unsigned int n_info) +{ + unsigned int argc = ctx->argc; + char **argp = ctx->argp; + unsigned int i, idx; + int found; + + for (i = 0; i < argc; i++) { + found = 0; + for (idx = 0; idx < n_info; idx++) { + if (!strcmp(info[idx].name, argp[i])) { + found = 1; + *changed = 1; + if (info[idx].type != CMDL_FLAG && + info[idx].seen_val) + *(int *)info[idx].seen_val = 1; + i += 1; + if (i >= argc) + exit_bad_args(); + switch (info[idx].type) { + case CMDL_BOOL: { + int *p = info[idx].wanted_val; + if (!strcmp(argp[i], "on")) + *p = 1; + else if (!strcmp(argp[i], "off")) + *p = 0; + else + exit_bad_args(); + break; + } + case CMDL_S32: { + s32 *p = info[idx].wanted_val; + *p = get_int_range(argp[i], 0, + -0x80000000LL, + 0x7fffffff); + break; + } + case CMDL_U8: { + u8 *p = info[idx].wanted_val; + *p = get_uint_range(argp[i], 0, 0xff); + break; + } + case CMDL_U16: { + u16 *p = info[idx].wanted_val; + *p = get_uint_range(argp[i], 0, 0xffff); + break; + } + case CMDL_U32: { + u32 *p = info[idx].wanted_val; + *p = get_uint_range(argp[i], 0, + 0xffffffff); + break; + } + case CMDL_U64: { + u64 *p = info[idx].wanted_val; + *p = get_uint_range( + argp[i], 0, + 0xffffffffffffffffLL); + break; + } + case CMDL_BE16: { + u16 *p = info[idx].wanted_val; + *p = cpu_to_be16( + get_uint_range(argp[i], 0, + 0xffff)); + break; + } + case CMDL_IP4: { + u32 *p = info[idx].wanted_val; + struct in_addr in; + if (!inet_pton(AF_INET, argp[i], &in)) + exit_bad_args(); + *p = in.s_addr; + break; + } + case CMDL_MAC: + get_mac_addr(argp[i], + info[idx].wanted_val); + break; + case CMDL_FLAG: { + u32 *p; + p = info[idx].seen_val; + *p |= info[idx].flag_val; + if (!strcmp(argp[i], "on")) { + p = info[idx].wanted_val; + *p |= info[idx].flag_val; + } else if (strcmp(argp[i], "off")) { + exit_bad_args(); + } + break; + } + case CMDL_STR: { + char **s = info[idx].wanted_val; + *s = strdup(argp[i]); + break; + } + default: + exit_bad_args(); + } + break; + } + } + if (!found) + exit_bad_args(); + } +} + +static void flag_to_cmdline_info(const char *name, u32 value, + u32 *wanted, u32 *mask, + struct cmdline_info *cli) +{ + memset(cli, 0, sizeof(*cli)); + cli->name = name; + cli->type = CMDL_FLAG; + cli->flag_val = value; + cli->wanted_val = wanted; + cli->seen_val = mask; +} + +static int rxflow_str_to_type(const char *str) +{ + int flow_type = 0; + + if (!strcmp(str, "tcp4")) + flow_type = TCP_V4_FLOW; + else if (!strcmp(str, "udp4")) + flow_type = UDP_V4_FLOW; + else if (!strcmp(str, "ah4") || !strcmp(str, "esp4")) + flow_type = AH_ESP_V4_FLOW; + else if (!strcmp(str, "sctp4")) + flow_type = SCTP_V4_FLOW; + else if (!strcmp(str, "tcp6")) + flow_type = TCP_V6_FLOW; + else if (!strcmp(str, "udp6")) + flow_type = UDP_V6_FLOW; + else if (!strcmp(str, "ah6") || !strcmp(str, "esp6")) + flow_type = AH_ESP_V6_FLOW; + else if (!strcmp(str, "sctp6")) + flow_type = SCTP_V6_FLOW; + else if (!strcmp(str, "ether")) + flow_type = ETHER_FLOW; + + return flow_type; +} + +static int do_version(struct cmd_context *ctx __maybe_unused) +{ + fprintf(stdout, + PACKAGE " version " VERSION +#ifndef ETHTOOL_ENABLE_PRETTY_DUMP + " (pretty dumps disabled)" +#endif + "\n"); + return 0; +} + +/* link mode routines */ + +static ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_modes); +static ETHTOOL_DECLARE_LINK_MODE_MASK(all_advertised_flags); + +static void init_global_link_mode_masks(void) +{ + static const enum ethtool_link_mode_bit_indices + all_advertised_modes_bits[] = { + ETHTOOL_LINK_MODE_10baseT_Half_BIT, + ETHTOOL_LINK_MODE_10baseT_Full_BIT, + ETHTOOL_LINK_MODE_100baseT_Half_BIT, + ETHTOOL_LINK_MODE_100baseT_Full_BIT, + ETHTOOL_LINK_MODE_1000baseT_Half_BIT, + ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + ETHTOOL_LINK_MODE_10000baseT_Full_BIT, + ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, + ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, + ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, + ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, + ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT, + ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT, + ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, + ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, + ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, + ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, + ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT, + ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, + ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, + ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, + ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, + ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, + ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, + ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, + ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, + ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, + ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, + ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, + ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, + ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, + ETHTOOL_LINK_MODE_1000baseX_Full_BIT, + ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, + ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, + ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, + ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, + ETHTOOL_LINK_MODE_10000baseER_Full_BIT, + ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, + ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, + ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, + ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, + ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, + ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, + ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, + ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, + ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, + ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, + ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, + ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, + ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, + ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, + ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, + ETHTOOL_LINK_MODE_100baseT1_Full_BIT, + ETHTOOL_LINK_MODE_1000baseT1_Full_BIT, + ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT, + ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT, + ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT, + ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT, + ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT, + ETHTOOL_LINK_MODE_100000baseKR_Full_BIT, + ETHTOOL_LINK_MODE_100000baseSR_Full_BIT, + ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT, + ETHTOOL_LINK_MODE_100000baseCR_Full_BIT, + ETHTOOL_LINK_MODE_100000baseDR_Full_BIT, + ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT, + ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT, + ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT, + ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT, + ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT, + ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT, + ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT, + ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT, + ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT, + ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT, + ETHTOOL_LINK_MODE_100baseFX_Half_BIT, + ETHTOOL_LINK_MODE_100baseFX_Full_BIT, + ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, + }; + static const enum ethtool_link_mode_bit_indices + additional_advertised_flags_bits[] = { + ETHTOOL_LINK_MODE_Autoneg_BIT, + ETHTOOL_LINK_MODE_TP_BIT, + ETHTOOL_LINK_MODE_AUI_BIT, + ETHTOOL_LINK_MODE_MII_BIT, + ETHTOOL_LINK_MODE_FIBRE_BIT, + ETHTOOL_LINK_MODE_BNC_BIT, + ETHTOOL_LINK_MODE_Pause_BIT, + ETHTOOL_LINK_MODE_Asym_Pause_BIT, + ETHTOOL_LINK_MODE_Backplane_BIT, + ETHTOOL_LINK_MODE_FEC_NONE_BIT, + ETHTOOL_LINK_MODE_FEC_RS_BIT, + ETHTOOL_LINK_MODE_FEC_BASER_BIT, + ETHTOOL_LINK_MODE_FEC_LLRS_BIT, + }; + unsigned int i; + + ethtool_link_mode_zero(all_advertised_modes); + ethtool_link_mode_zero(all_advertised_flags); + for (i = 0; i < ARRAY_SIZE(all_advertised_modes_bits); ++i) { + ethtool_link_mode_set_bit(all_advertised_modes_bits[i], + all_advertised_modes); + ethtool_link_mode_set_bit(all_advertised_modes_bits[i], + all_advertised_flags); + } + + for (i = 0; i < ARRAY_SIZE(additional_advertised_flags_bits); ++i) { + ethtool_link_mode_set_bit( + additional_advertised_flags_bits[i], + all_advertised_flags); + } +} + +static void dump_link_caps(const char *prefix, const char *an_prefix, + const u32 *mask, int link_mode_only); + +static void dump_supported(const struct ethtool_link_usettings *link_usettings) +{ + fprintf(stdout, " Supported ports: [ "); + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_TP_BIT, + link_usettings->link_modes.supported)) + fprintf(stdout, "TP "); + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_AUI_BIT, + link_usettings->link_modes.supported)) + fprintf(stdout, "AUI "); + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_BNC_BIT, + link_usettings->link_modes.supported)) + fprintf(stdout, "BNC "); + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_MII_BIT, + link_usettings->link_modes.supported)) + fprintf(stdout, "MII "); + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_FIBRE_BIT, + link_usettings->link_modes.supported)) + fprintf(stdout, "FIBRE "); + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_Backplane_BIT, + link_usettings->link_modes.supported)) + fprintf(stdout, "Backplane "); + fprintf(stdout, "]\n"); + + dump_link_caps("Supported", "Supports", + link_usettings->link_modes.supported, 0); +} + +/* Print link capability flags (supported, advertised or lp_advertised). + * Assumes that the corresponding SUPPORTED and ADVERTISED flags are equal. + */ +static void dump_link_caps(const char *prefix, const char *an_prefix, + const u32 *mask, int link_mode_only) +{ + static const struct { + int same_line; /* print on same line as previous */ + unsigned int bit_index; + const char *name; + } mode_defs[] = { + { 0, ETHTOOL_LINK_MODE_10baseT_Half_BIT, + "10baseT/Half" }, + { 1, ETHTOOL_LINK_MODE_10baseT_Full_BIT, + "10baseT/Full" }, + { 0, ETHTOOL_LINK_MODE_100baseT_Half_BIT, + "100baseT/Half" }, + { 1, ETHTOOL_LINK_MODE_100baseT_Full_BIT, + "100baseT/Full" }, + { 0, ETHTOOL_LINK_MODE_1000baseT_Half_BIT, + "1000baseT/Half" }, + { 1, ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + "1000baseT/Full" }, + { 0, ETHTOOL_LINK_MODE_10000baseT_Full_BIT, + "10000baseT/Full" }, + { 0, ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + "2500baseX/Full" }, + { 0, ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, + "1000baseKX/Full" }, + { 0, ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, + "10000baseKX4/Full" }, + { 0, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, + "10000baseKR/Full" }, + { 0, ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, + "10000baseR_FEC" }, + { 0, ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT, + "20000baseMLD2/Full" }, + { 0, ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT, + "20000baseKR2/Full" }, + { 0, ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, + "40000baseKR4/Full" }, + { 0, ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, + "40000baseCR4/Full" }, + { 0, ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, + "40000baseSR4/Full" }, + { 0, ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, + "40000baseLR4/Full" }, + { 0, ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT, + "56000baseKR4/Full" }, + { 0, ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, + "56000baseCR4/Full" }, + { 0, ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, + "56000baseSR4/Full" }, + { 0, ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, + "56000baseLR4/Full" }, + { 0, ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, + "25000baseCR/Full" }, + { 0, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, + "25000baseKR/Full" }, + { 0, ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, + "25000baseSR/Full" }, + { 0, ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, + "50000baseCR2/Full" }, + { 0, ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, + "50000baseKR2/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, + "100000baseKR4/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, + "100000baseSR4/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, + "100000baseCR4/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, + "100000baseLR4_ER4/Full" }, + { 0, ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, + "50000baseSR2/Full" }, + { 0, ETHTOOL_LINK_MODE_1000baseX_Full_BIT, + "1000baseX/Full" }, + { 0, ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, + "10000baseCR/Full" }, + { 0, ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, + "10000baseSR/Full" }, + { 0, ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, + "10000baseLR/Full" }, + { 0, ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, + "10000baseLRM/Full" }, + { 0, ETHTOOL_LINK_MODE_10000baseER_Full_BIT, + "10000baseER/Full" }, + { 0, ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + "2500baseT/Full" }, + { 0, ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + "5000baseT/Full" }, + { 0, ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, + "50000baseKR/Full" }, + { 0, ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, + "50000baseSR/Full" }, + { 0, ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, + "50000baseCR/Full" }, + { 0, ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, + "50000baseLR_ER_FR/Full" }, + { 0, ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, + "50000baseDR/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, + "100000baseKR2/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, + "100000baseSR2/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, + "100000baseCR2/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, + "100000baseLR2_ER2_FR2/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, + "100000baseDR2/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, + "200000baseKR4/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, + "200000baseSR4/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, + "200000baseLR4_ER4_FR4/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, + "200000baseDR4/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, + "200000baseCR4/Full" }, + { 0, ETHTOOL_LINK_MODE_100baseT1_Full_BIT, + "100baseT1/Full" }, + { 0, ETHTOOL_LINK_MODE_1000baseT1_Full_BIT, + "1000baseT1/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT, + "400000baseKR8/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT, + "400000baseSR8/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT, + "400000baseLR8_ER8_FR8/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT, + "400000baseDR8/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT, + "400000baseCR8/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseKR_Full_BIT, + "100000baseKR/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseSR_Full_BIT, + "100000baseSR/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT, + "100000baseLR_ER_FR/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseDR_Full_BIT, + "100000baseDR/Full" }, + { 0, ETHTOOL_LINK_MODE_100000baseCR_Full_BIT, + "100000baseCR/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT, + "200000baseKR2/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT, + "200000baseSR2/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT, + "200000baseLR2_ER2_FR2/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT, + "200000baseDR2/Full" }, + { 0, ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT, + "200000baseCR2/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT, + "400000baseKR4/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT, + "400000baseSR4/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT, + "400000baseLR4_ER4_FR4/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT, + "400000baseDR4/Full" }, + { 0, ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT, + "400000baseCR4/Full" }, + { 0, ETHTOOL_LINK_MODE_100baseFX_Half_BIT, + "100baseFX/Half" }, + { 1, ETHTOOL_LINK_MODE_100baseFX_Full_BIT, + "100baseFX/Full" }, + { 0, ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, + "10baseT1L/Full" }, + }; + int indent; + int did1, new_line_pend; + int fecreported = 0; + unsigned int i; + + /* Indent just like the separate functions used to */ + indent = strlen(prefix) + 14; + if (indent < 24) + indent = 24; + + fprintf(stdout, " %s link modes:%*s", prefix, + indent - (int)strlen(prefix) - 12, ""); + did1 = 0; + new_line_pend = 0; + for (i = 0; i < ARRAY_SIZE(mode_defs); i++) { + if (did1 && !mode_defs[i].same_line) + new_line_pend = 1; + if (ethtool_link_mode_test_bit(mode_defs[i].bit_index, + mask)) { + if (new_line_pend) { + fprintf(stdout, "\n"); + fprintf(stdout, " %*s", indent, ""); + new_line_pend = 0; + } + did1++; + fprintf(stdout, "%s ", mode_defs[i].name); + } + } + if (did1 == 0) + fprintf(stdout, "Not reported"); + fprintf(stdout, "\n"); + + if (!link_mode_only) { + fprintf(stdout, " %s pause frame use: ", prefix); + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_Pause_BIT, mask)) { + fprintf(stdout, "Symmetric"); + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask)) + fprintf(stdout, " Receive-only"); + fprintf(stdout, "\n"); + } else { + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask)) + fprintf(stdout, "Transmit-only\n"); + else + fprintf(stdout, "No\n"); + } + + fprintf(stdout, " %s auto-negotiation: ", an_prefix); + if (ethtool_link_mode_test_bit( + ETHTOOL_LINK_MODE_Autoneg_BIT, mask)) + fprintf(stdout, "Yes\n"); + else + fprintf(stdout, "No\n"); + + fprintf(stdout, " %s FEC modes:", prefix); + if (ethtool_link_mode_test_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT, + mask)) { + fprintf(stdout, " None"); + fecreported = 1; + } + if (ethtool_link_mode_test_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT, + mask)) { + fprintf(stdout, " BaseR"); + fecreported = 1; + } + if (ethtool_link_mode_test_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, + mask)) { + fprintf(stdout, " RS"); + fecreported = 1; + } + if (ethtool_link_mode_test_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT, + mask)) { + fprintf(stdout, " LLRS"); + fecreported = 1; + } + + if (!fecreported) + fprintf(stdout, " Not reported"); + fprintf(stdout, "\n"); + } +} + +static int +dump_link_usettings(const struct ethtool_link_usettings *link_usettings) +{ + dump_supported(link_usettings); + dump_link_caps("Advertised", "Advertised", + link_usettings->link_modes.advertising, 0); + if (!ethtool_link_mode_is_empty( + link_usettings->link_modes.lp_advertising)) + dump_link_caps("Link partner advertised", + "Link partner advertised", + link_usettings->link_modes.lp_advertising, 0); + + fprintf(stdout, " Speed: "); + if (link_usettings->base.speed == 0 + || link_usettings->base.speed == (u16)(-1) + || link_usettings->base.speed == (u32)(-1)) + fprintf(stdout, "Unknown!\n"); + else + fprintf(stdout, "%uMb/s\n", link_usettings->base.speed); + + fprintf(stdout, " Duplex: "); + switch (link_usettings->base.duplex) { + case DUPLEX_HALF: + fprintf(stdout, "Half\n"); + break; + case DUPLEX_FULL: + fprintf(stdout, "Full\n"); + break; + default: + fprintf(stdout, "Unknown! (%i)\n", link_usettings->base.duplex); + break; + }; + + fprintf(stdout, " Port: "); + switch (link_usettings->base.port) { + case PORT_TP: + fprintf(stdout, "Twisted Pair\n"); + break; + case PORT_AUI: + fprintf(stdout, "AUI\n"); + break; + case PORT_BNC: + fprintf(stdout, "BNC\n"); + break; + case PORT_MII: + fprintf(stdout, "MII\n"); + break; + case PORT_FIBRE: + fprintf(stdout, "FIBRE\n"); + break; + case PORT_DA: + fprintf(stdout, "Direct Attach Copper\n"); + break; + case PORT_NONE: + fprintf(stdout, "None\n"); + break; + case PORT_OTHER: + fprintf(stdout, "Other\n"); + break; + default: + fprintf(stdout, "Unknown! (%i)\n", link_usettings->base.port); + break; + }; + + fprintf(stdout, " PHYAD: %d\n", link_usettings->base.phy_address); + fprintf(stdout, " Transceiver: "); + switch (link_usettings->deprecated.transceiver) { + case XCVR_INTERNAL: + fprintf(stdout, "internal\n"); + break; + case XCVR_EXTERNAL: + fprintf(stdout, "external\n"); + break; + default: + fprintf(stdout, "Unknown!\n"); + break; + }; + + fprintf(stdout, " Auto-negotiation: %s\n", + (link_usettings->base.autoneg == AUTONEG_DISABLE) ? + "off" : "on"); + + if (link_usettings->base.port == PORT_TP) + dump_mdix(link_usettings->base.eth_tp_mdix, + link_usettings->base.eth_tp_mdix_ctrl); + + return 0; +} + +static int dump_drvinfo(struct ethtool_drvinfo *info) +{ + fprintf(stdout, + "driver: %.*s\n" + "version: %.*s\n" + "firmware-version: %.*s\n" + "expansion-rom-version: %.*s\n" + "bus-info: %.*s\n" + "supports-statistics: %s\n" + "supports-test: %s\n" + "supports-eeprom-access: %s\n" + "supports-register-dump: %s\n" + "supports-priv-flags: %s\n", + (int)sizeof(info->driver), info->driver, + (int)sizeof(info->version), info->version, + (int)sizeof(info->fw_version), info->fw_version, + (int)sizeof(info->erom_version), info->erom_version, + (int)sizeof(info->bus_info), info->bus_info, + info->n_stats ? "yes" : "no", + info->testinfo_len ? "yes" : "no", + info->eedump_len ? "yes" : "no", + info->regdump_len ? "yes" : "no", + info->n_priv_flags ? "yes" : "no"); + + return 0; +} + +static int parse_wolopts(char *optstr, u32 *data) +{ + *data = 0; + while (*optstr) { + switch (*optstr) { + case 'p': + *data |= WAKE_PHY; + break; + case 'u': + *data |= WAKE_UCAST; + break; + case 'm': + *data |= WAKE_MCAST; + break; + case 'b': + *data |= WAKE_BCAST; + break; + case 'a': + *data |= WAKE_ARP; + break; + case 'g': + *data |= WAKE_MAGIC; + break; + case 's': + *data |= WAKE_MAGICSECURE; + break; + case 'f': + *data |= WAKE_FILTER; + break; + case 'd': + *data = 0; + break; + default: + return -1; + } + optstr++; + } + return 0; +} + +static int parse_rxfhashopts(char *optstr, u32 *data) +{ + *data = 0; + while (*optstr) { + switch (*optstr) { + case 'm': + *data |= RXH_L2DA; + break; + case 'v': + *data |= RXH_VLAN; + break; + case 't': + *data |= RXH_L3_PROTO; + break; + case 's': + *data |= RXH_IP_SRC; + break; + case 'd': + *data |= RXH_IP_DST; + break; + case 'f': + *data |= RXH_L4_B_0_1; + break; + case 'n': + *data |= RXH_L4_B_2_3; + break; + case 'r': + *data |= RXH_DISCARD; + break; + default: + return -1; + } + optstr++; + } + return 0; +} + +static char *unparse_rxfhashopts(u64 opts) +{ + static char buf[300]; + + memset(buf, 0, sizeof(buf)); + + if (opts) { + if (opts & RXH_L2DA) + strcat(buf, "L2DA\n"); + if (opts & RXH_VLAN) + strcat(buf, "VLAN tag\n"); + if (opts & RXH_L3_PROTO) + strcat(buf, "L3 proto\n"); + if (opts & RXH_IP_SRC) + strcat(buf, "IP SA\n"); + if (opts & RXH_IP_DST) + strcat(buf, "IP DA\n"); + if (opts & RXH_L4_B_0_1) + strcat(buf, "L4 bytes 0 & 1 [TCP/UDP src port]\n"); + if (opts & RXH_L4_B_2_3) + strcat(buf, "L4 bytes 2 & 3 [TCP/UDP dst port]\n"); + } else { + sprintf(buf, "None"); + } + + return buf; +} + +static int convert_string_to_hashkey(char *rss_hkey, u32 key_size, + const char *rss_hkey_string) +{ + u32 i = 0; + int hex_byte, len; + + do { + if (i > (key_size - 1)) { + fprintf(stderr, + "Key is too long for device (%u > %u)\n", + i + 1, key_size); + goto err; + } + + if (sscanf(rss_hkey_string, "%2x%n", &hex_byte, &len) < 1 || + len != 2) { + fprintf(stderr, "Invalid RSS hash key format\n"); + goto err; + } + + rss_hkey[i++] = hex_byte; + rss_hkey_string += 2; + + if (*rss_hkey_string == ':') { + rss_hkey_string++; + } else if (*rss_hkey_string != '\0') { + fprintf(stderr, "Invalid RSS hash key format\n"); + goto err; + } + + } while (*rss_hkey_string); + + if (i != key_size) { + fprintf(stderr, "Key is too short for device (%u < %u)\n", + i, key_size); + goto err; + } + + return 0; +err: + return 2; +} + +static int parse_hkey(char **rss_hkey, u32 key_size, + const char *rss_hkey_string) +{ + if (!key_size) { + fprintf(stderr, + "Cannot set RX flow hash configuration:\n" + " Hash key setting not supported\n"); + return 1; + } + + *rss_hkey = malloc(key_size); + if (!(*rss_hkey)) { + perror("Cannot allocate memory for RSS hash key"); + return 1; + } + + if (convert_string_to_hashkey(*rss_hkey, key_size, + rss_hkey_string)) { + free(*rss_hkey); + *rss_hkey = NULL; + return 2; + } + return 0; +} + +#ifdef ETHTOOL_ENABLE_PRETTY_DUMP +static const struct { + const char *name; + int (*func)(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +} driver_list[] = { + { "8139cp", realtek_dump_regs }, + { "8139too", realtek_dump_regs }, + { "r8169", realtek_dump_regs }, + { "de2104x", de2104x_dump_regs }, + { "e1000", e1000_dump_regs }, + { "e1000e", e1000_dump_regs }, + { "igb", igb_dump_regs }, + { "ixgb", ixgb_dump_regs }, + { "ixgbe", ixgbe_dump_regs }, + { "ixgbevf", ixgbevf_dump_regs }, + { "natsemi", natsemi_dump_regs }, + { "e100", e100_dump_regs }, + { "amd8111e", amd8111e_dump_regs }, + { "pcnet32", pcnet32_dump_regs }, + { "fec_8xx", fec_8xx_dump_regs }, + { "ibm_emac", ibm_emac_dump_regs }, + { "tg3", tg3_dump_regs }, + { "skge", skge_dump_regs }, + { "sky2", sky2_dump_regs }, + { "vioc", vioc_dump_regs }, + { "smsc911x", smsc911x_dump_regs }, + { "at76c50x-usb", at76c50x_usb_dump_regs }, + { "sfc", sfc_dump_regs }, + { "st_mac100", st_mac100_dump_regs }, + { "st_gmac", st_gmac_dump_regs }, + { "et131x", et131x_dump_regs }, + { "altera_tse", altera_tse_dump_regs }, + { "vmxnet3", vmxnet3_dump_regs }, + { "fjes", fjes_dump_regs }, + { "lan78xx", lan78xx_dump_regs }, + { "dsa", dsa_dump_regs }, + { "fec", fec_dump_regs }, + { "igc", igc_dump_regs }, + { "bnxt_en", bnxt_dump_regs }, + { "cpsw-switch", cpsw_dump_regs }, + { "lan743x", lan743x_dump_regs }, + { "fsl_enetc", fsl_enetc_dump_regs }, + { "fsl_enetc_vf", fsl_enetc_dump_regs }, +}; +#endif + +void dump_hex(FILE *file, const u8 *data, int len, int offset) +{ + int i; + + fprintf(file, "Offset\t\tValues\n"); + fprintf(file, "------\t\t------"); + for (i = 0; i < len; i++) { + if (i % 16 == 0) + fprintf(file, "\n0x%04x:\t\t", i + offset); + fprintf(file, "%02x ", data[i]); + } + fprintf(file, "\n"); +} + +static int dump_regs(int gregs_dump_raw, int gregs_dump_hex, + struct ethtool_drvinfo *info, struct ethtool_regs *regs) +{ + if (gregs_dump_raw) { + fwrite(regs->data, regs->len, 1, stdout); + goto nested; + } + +#ifdef ETHTOOL_ENABLE_PRETTY_DUMP + if (!gregs_dump_hex) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(driver_list); i++) + if (!strncmp(driver_list[i].name, info->driver, + ETHTOOL_BUSINFO_LEN)) { + if (driver_list[i].func(info, regs) == 0) + goto nested; + /* This version (or some other + * variation in the dump format) is + * not handled; fall back to hex + */ + break; + } + } +#endif + + dump_hex(stdout, regs->data, regs->len, 0); + +nested: + /* Recurse dump if some drvinfo and regs structures are nested */ + if (info->regdump_len > regs->len + sizeof(*info) + sizeof(*regs)) { + info = (struct ethtool_drvinfo *)(®s->data[0] + regs->len); + regs = (struct ethtool_regs *)(®s->data[0] + regs->len + sizeof(*info)); + + return dump_regs(gregs_dump_raw, gregs_dump_hex, info, regs); + } + + return 0; +} + +static int dump_eeprom(int geeprom_dump_raw, + struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_eeprom *ee) +{ + if (geeprom_dump_raw) { + fwrite(ee->data, 1, ee->len, stdout); + return 0; + } +#ifdef ETHTOOL_ENABLE_PRETTY_DUMP + if (!strncmp("natsemi", info->driver, ETHTOOL_BUSINFO_LEN)) { + return natsemi_dump_eeprom(info, ee); + } else if (!strncmp("tg3", info->driver, ETHTOOL_BUSINFO_LEN)) { + return tg3_dump_eeprom(info, ee); + } +#endif + dump_hex(stdout, ee->data, ee->len, ee->offset); + + return 0; +} + +static int dump_test(struct ethtool_test *test, + struct ethtool_gstrings *strings) +{ + unsigned int i; + int rc; + + rc = test->flags & ETH_TEST_FL_FAILED; + fprintf(stdout, "The test result is %s\n", rc ? "FAIL" : "PASS"); + + if (test->flags & ETH_TEST_FL_EXTERNAL_LB) + fprintf(stdout, "External loopback test was %sexecuted\n", + (test->flags & ETH_TEST_FL_EXTERNAL_LB_DONE) ? + "" : "not "); + + if (strings->len) + fprintf(stdout, "The test extra info:\n"); + + for (i = 0; i < strings->len; i++) { + fprintf(stdout, "%s\t %d\n", + (char *)(strings->data + i * ETH_GSTRING_LEN), + (u32) test->data[i]); + } + + fprintf(stdout, "\n"); + return rc; +} + +static int dump_pause(const struct ethtool_pauseparam *epause, + u32 advertising, u32 lp_advertising) +{ + fprintf(stdout, + "Autonegotiate: %s\n" + "RX: %s\n" + "TX: %s\n", + epause->autoneg ? "on" : "off", + epause->rx_pause ? "on" : "off", + epause->tx_pause ? "on" : "off"); + + if (lp_advertising) { + int an_rx = 0, an_tx = 0; + + /* Work out negotiated pause frame usage per + * IEEE 802.3-2005 table 28B-3. + */ + if (advertising & lp_advertising & ADVERTISED_Pause) { + an_tx = 1; + an_rx = 1; + } else if (advertising & lp_advertising & + ADVERTISED_Asym_Pause) { + if (advertising & ADVERTISED_Pause) + an_rx = 1; + else if (lp_advertising & ADVERTISED_Pause) + an_tx = 1; + } + + fprintf(stdout, + "RX negotiated: %s\n" + "TX negotiated: %s\n", + an_rx ? "on" : "off", + an_tx ? "on" : "off"); + } + + fprintf(stdout, "\n"); + return 0; +} + +static int dump_ring(const struct ethtool_ringparam *ering) +{ + fprintf(stdout, + "Pre-set maximums:\n" + "RX: %u\n" + "RX Mini: %u\n" + "RX Jumbo: %u\n" + "TX: %u\n", + ering->rx_max_pending, + ering->rx_mini_max_pending, + ering->rx_jumbo_max_pending, + ering->tx_max_pending); + + fprintf(stdout, + "Current hardware settings:\n" + "RX: %u\n" + "RX Mini: %u\n" + "RX Jumbo: %u\n" + "TX: %u\n", + ering->rx_pending, + ering->rx_mini_pending, + ering->rx_jumbo_pending, + ering->tx_pending); + + fprintf(stdout, "\n"); + return 0; +} + +static int dump_channels(const struct ethtool_channels *echannels) +{ + fprintf(stdout, + "Pre-set maximums:\n" + "RX: %u\n" + "TX: %u\n" + "Other: %u\n" + "Combined: %u\n", + echannels->max_rx, echannels->max_tx, + echannels->max_other, + echannels->max_combined); + + fprintf(stdout, + "Current hardware settings:\n" + "RX: %u\n" + "TX: %u\n" + "Other: %u\n" + "Combined: %u\n", + echannels->rx_count, echannels->tx_count, + echannels->other_count, + echannels->combined_count); + + fprintf(stdout, "\n"); + return 0; +} + +static int dump_coalesce(const struct ethtool_coalesce *ecoal) +{ + fprintf(stdout, "Adaptive RX: %s TX: %s\n", + ecoal->use_adaptive_rx_coalesce ? "on" : "off", + ecoal->use_adaptive_tx_coalesce ? "on" : "off"); + + fprintf(stdout, + "stats-block-usecs: %u\n" + "sample-interval: %u\n" + "pkt-rate-low: %u\n" + "pkt-rate-high: %u\n" + "\n" + "rx-usecs: %u\n" + "rx-frames: %u\n" + "rx-usecs-irq: %u\n" + "rx-frames-irq: %u\n" + "\n" + "tx-usecs: %u\n" + "tx-frames: %u\n" + "tx-usecs-irq: %u\n" + "tx-frames-irq: %u\n" + "\n" + "rx-usecs-low: %u\n" + "rx-frames-low: %u\n" + "tx-usecs-low: %u\n" + "tx-frames-low: %u\n" + "\n" + "rx-usecs-high: %u\n" + "rx-frames-high: %u\n" + "tx-usecs-high: %u\n" + "tx-frames-high: %u\n" + "\n", + ecoal->stats_block_coalesce_usecs, + ecoal->rate_sample_interval, + ecoal->pkt_rate_low, + ecoal->pkt_rate_high, + + ecoal->rx_coalesce_usecs, + ecoal->rx_max_coalesced_frames, + ecoal->rx_coalesce_usecs_irq, + ecoal->rx_max_coalesced_frames_irq, + + ecoal->tx_coalesce_usecs, + ecoal->tx_max_coalesced_frames, + ecoal->tx_coalesce_usecs_irq, + ecoal->tx_max_coalesced_frames_irq, + + ecoal->rx_coalesce_usecs_low, + ecoal->rx_max_coalesced_frames_low, + ecoal->tx_coalesce_usecs_low, + ecoal->tx_max_coalesced_frames_low, + + ecoal->rx_coalesce_usecs_high, + ecoal->rx_max_coalesced_frames_high, + ecoal->tx_coalesce_usecs_high, + ecoal->tx_max_coalesced_frames_high); + + return 0; +} + +void dump_per_queue_coalesce(struct ethtool_per_queue_op *per_queue_opt, + __u32 *queue_mask, int n_queues) +{ + struct ethtool_coalesce *ecoal; + int i, idx = 0; + + ecoal = (struct ethtool_coalesce *)(per_queue_opt + 1); + for (i = 0; i < __KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32); i++) { + int queue = i * 32; + __u32 mask = queue_mask[i]; + + while (mask > 0) { + if (mask & 0x1) { + fprintf(stdout, "Queue: %d\n", queue); + dump_coalesce(ecoal + idx); + idx++; + } + mask = mask >> 1; + queue++; + } + if (idx == n_queues) + break; + } +} + +struct feature_state { + u32 off_flags; + struct ethtool_gfeatures features; +}; + +static void dump_one_feature(const char *indent, const char *name, + const struct feature_state *state, + const struct feature_state *ref_state, + u32 index) +{ + if (ref_state && + !(FEATURE_BIT_IS_SET(state->features.features, index, active) ^ + FEATURE_BIT_IS_SET(ref_state->features.features, index, active))) + return; + + printf("%s%s: %s%s\n", + indent, name, + FEATURE_BIT_IS_SET(state->features.features, index, active) ? + "on" : "off", + (!FEATURE_BIT_IS_SET(state->features.features, index, available) + || FEATURE_BIT_IS_SET(state->features.features, index, + never_changed)) + ? " [fixed]" + : (FEATURE_BIT_IS_SET(state->features.features, index, requested) + ^ FEATURE_BIT_IS_SET(state->features.features, index, active)) + ? (FEATURE_BIT_IS_SET(state->features.features, index, requested) + ? " [requested on]" : " [requested off]") + : ""); +} + +static unsigned int linux_version_code(void) +{ + struct utsname utsname; + unsigned version, patchlevel, sublevel = 0; + + if (uname(&utsname)) + return -1; + if (sscanf(utsname.release, "%u.%u.%u", &version, &patchlevel, &sublevel) < 2) + return -1; + return KERNEL_VERSION(version, patchlevel, sublevel); +} + +static void dump_features(const struct feature_defs *defs, + const struct feature_state *state, + const struct feature_state *ref_state) +{ + unsigned int kernel_ver = linux_version_code(); + unsigned int i, j; + int indent; + u32 value; + + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { + /* Don't show features whose state is unknown on this + * kernel version + */ + if (defs->off_flag_matched[i] == 0 && + ((off_flag_def[i].get_cmd == 0 && + kernel_ver < off_flag_def[i].min_kernel_ver) || + (off_flag_def[i].get_cmd == ETHTOOL_GUFO && + kernel_ver >= KERNEL_VERSION(4, 14, 0)))) + continue; + + value = off_flag_def[i].value; + + /* If this offload flag matches exactly one generic + * feature then it's redundant to show the flag and + * feature states separately. Otherwise, show the + * flag state first. + */ + if (defs->off_flag_matched[i] != 1 && + (!ref_state || + (state->off_flags ^ ref_state->off_flags) & value)) { + printf("%s: %s\n", + off_flag_def[i].long_name, + (state->off_flags & value) ? "on" : "off"); + indent = 1; + } else { + indent = 0; + } + + /* Show matching features */ + for (j = 0; j < defs->n_features; j++) { + if (defs->def[j].off_flag_index != (int)i) + continue; + if (defs->off_flag_matched[i] != 1) + /* Show all matching feature states */ + dump_one_feature(indent ? "\t" : "", + defs->def[j].name, + state, ref_state, j); + else + /* Show full state with the old flag name */ + dump_one_feature("", off_flag_def[i].long_name, + state, ref_state, j); + } + } + + /* Show all unmatched features that have non-null names */ + for (j = 0; j < defs->n_features; j++) + if (defs->def[j].off_flag_index < 0 && defs->def[j].name[0]) + dump_one_feature("", defs->def[j].name, + state, ref_state, j); +} + +static int dump_rxfhash(int fhash, u64 val) +{ + switch (fhash & ~FLOW_RSS) { + case TCP_V4_FLOW: + fprintf(stdout, "TCP over IPV4 flows"); + break; + case UDP_V4_FLOW: + fprintf(stdout, "UDP over IPV4 flows"); + break; + case SCTP_V4_FLOW: + fprintf(stdout, "SCTP over IPV4 flows"); + break; + case AH_ESP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + fprintf(stdout, "IPSEC AH/ESP over IPV4 flows"); + break; + case TCP_V6_FLOW: + fprintf(stdout, "TCP over IPV6 flows"); + break; + case UDP_V6_FLOW: + fprintf(stdout, "UDP over IPV6 flows"); + break; + case SCTP_V6_FLOW: + fprintf(stdout, "SCTP over IPV6 flows"); + break; + case AH_ESP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + fprintf(stdout, "IPSEC AH/ESP over IPV6 flows"); + break; + default: + break; + } + + if (val & RXH_DISCARD) { + fprintf(stdout, " - All matching flows discarded on RX\n"); + return 0; + } + fprintf(stdout, " use these fields for computing Hash flow key:\n"); + + fprintf(stdout, "%s\n", unparse_rxfhashopts(val)); + + return 0; +} + +static void dump_eeecmd(struct ethtool_eee *ep) +{ + ETHTOOL_DECLARE_LINK_MODE_MASK(link_mode); + + fprintf(stdout, " EEE status: "); + if (!ep->supported) { + fprintf(stdout, "not supported\n"); + return; + } else if (!ep->eee_enabled) { + fprintf(stdout, "disabled\n"); + } else { + fprintf(stdout, "enabled - "); + if (ep->eee_active) + fprintf(stdout, "active\n"); + else + fprintf(stdout, "inactive\n"); + } + + fprintf(stdout, " Tx LPI:"); + if (ep->tx_lpi_enabled) + fprintf(stdout, " %d (us)\n", ep->tx_lpi_timer); + else + fprintf(stdout, " disabled\n"); + + ethtool_link_mode_zero(link_mode); + + link_mode[0] = ep->supported; + dump_link_caps("Supported EEE", "", link_mode, 1); + + link_mode[0] = ep->advertised; + dump_link_caps("Advertised EEE", "", link_mode, 1); + + link_mode[0] = ep->lp_advertised; + dump_link_caps("Link partner advertised EEE", "", link_mode, 1); +} + +static void dump_fec(u32 fec) +{ + if (fec & ETHTOOL_FEC_NONE) + fprintf(stdout, " None"); + if (fec & ETHTOOL_FEC_AUTO) + fprintf(stdout, " Auto"); + if (fec & ETHTOOL_FEC_OFF) + fprintf(stdout, " Off"); + if (fec & ETHTOOL_FEC_BASER) + fprintf(stdout, " BaseR"); + if (fec & ETHTOOL_FEC_RS) + fprintf(stdout, " RS"); + if (fec & ETHTOOL_FEC_LLRS) + fprintf(stdout, " LLRS"); +} + +#define N_SOTS 7 + +static char *so_timestamping_labels[N_SOTS] = { + "hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE)", + "software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE)", + "hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE)", + "software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)", + "software-system-clock (SOF_TIMESTAMPING_SOFTWARE)", + "hardware-legacy-clock (SOF_TIMESTAMPING_SYS_HARDWARE)", + "hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE)", +}; + +#define N_TX_TYPES (HWTSTAMP_TX_ONESTEP_SYNC + 1) + +static char *tx_type_labels[N_TX_TYPES] = { + "off (HWTSTAMP_TX_OFF)", + "on (HWTSTAMP_TX_ON)", + "one-step-sync (HWTSTAMP_TX_ONESTEP_SYNC)", +}; + +#define N_RX_FILTERS (HWTSTAMP_FILTER_NTP_ALL + 1) + +static char *rx_filter_labels[N_RX_FILTERS] = { + "none (HWTSTAMP_FILTER_NONE)", + "all (HWTSTAMP_FILTER_ALL)", + "some (HWTSTAMP_FILTER_SOME)", + "ptpv1-l4-event (HWTSTAMP_FILTER_PTP_V1_L4_EVENT)", + "ptpv1-l4-sync (HWTSTAMP_FILTER_PTP_V1_L4_SYNC)", + "ptpv1-l4-delay-req (HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ)", + "ptpv2-l4-event (HWTSTAMP_FILTER_PTP_V2_L4_EVENT)", + "ptpv2-l4-sync (HWTSTAMP_FILTER_PTP_V2_L4_SYNC)", + "ptpv2-l4-delay-req (HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ)", + "ptpv2-l2-event (HWTSTAMP_FILTER_PTP_V2_L2_EVENT)", + "ptpv2-l2-sync (HWTSTAMP_FILTER_PTP_V2_L2_SYNC)", + "ptpv2-l2-delay-req (HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ)", + "ptpv2-event (HWTSTAMP_FILTER_PTP_V2_EVENT)", + "ptpv2-sync (HWTSTAMP_FILTER_PTP_V2_SYNC)", + "ptpv2-delay-req (HWTSTAMP_FILTER_PTP_V2_DELAY_REQ)", + "ntp-all (HWTSTAMP_FILTER_NTP_ALL)", +}; + +static int dump_tsinfo(const struct ethtool_ts_info *info) +{ + int i; + + fprintf(stdout, "Capabilities:\n"); + + for (i = 0; i < N_SOTS; i++) { + if (info->so_timestamping & (1 << i)) + fprintf(stdout, "\t%s\n", so_timestamping_labels[i]); + } + + fprintf(stdout, "PTP Hardware Clock: "); + + if (info->phc_index < 0) + fprintf(stdout, "none\n"); + else + fprintf(stdout, "%d\n", info->phc_index); + + fprintf(stdout, "Hardware Transmit Timestamp Modes:"); + + if (!info->tx_types) + fprintf(stdout, " none\n"); + else + fprintf(stdout, "\n"); + + for (i = 0; i < N_TX_TYPES; i++) { + if (info->tx_types & (1 << i)) + fprintf(stdout, "\t%s\n", tx_type_labels[i]); + } + + fprintf(stdout, "Hardware Receive Filter Modes:"); + + if (!info->rx_filters) + fprintf(stdout, " none\n"); + else + fprintf(stdout, "\n"); + + for (i = 0; i < N_RX_FILTERS; i++) { + if (info->rx_filters & (1 << i)) + fprintf(stdout, "\t%s\n", rx_filter_labels[i]); + } + + return 0; +} + +static struct ethtool_gstrings * +get_stringset(struct cmd_context *ctx, enum ethtool_stringset set_id, + ptrdiff_t drvinfo_offset, int null_terminate) +{ + struct { + struct ethtool_sset_info hdr; + u32 buf[1]; + } sset_info; + struct ethtool_drvinfo drvinfo; + u32 len, i; + struct ethtool_gstrings *strings; + + sset_info.hdr.cmd = ETHTOOL_GSSET_INFO; + sset_info.hdr.reserved = 0; + sset_info.hdr.sset_mask = 1ULL << set_id; + if (send_ioctl(ctx, &sset_info) == 0) { + const u32 *sset_lengths = sset_info.hdr.data; + + len = sset_info.hdr.sset_mask ? sset_lengths[0] : 0; + } else if (errno == EOPNOTSUPP && drvinfo_offset != 0) { + /* Fallback for old kernel versions */ + drvinfo.cmd = ETHTOOL_GDRVINFO; + if (send_ioctl(ctx, &drvinfo)) + return NULL; + len = *(u32 *)((char *)&drvinfo + drvinfo_offset); + } else { + return NULL; + } + + strings = calloc(1, sizeof(*strings) + len * ETH_GSTRING_LEN); + if (!strings) + return NULL; + + strings->cmd = ETHTOOL_GSTRINGS; + strings->string_set = set_id; + strings->len = len; + if (len != 0 && send_ioctl(ctx, strings)) { + free(strings); + return NULL; + } + + if (null_terminate) + for (i = 0; i < len; i++) + strings->data[(i + 1) * ETH_GSTRING_LEN - 1] = 0; + + return strings; +} + +static struct feature_defs *get_feature_defs(struct cmd_context *ctx) +{ + struct ethtool_gstrings *names; + struct feature_defs *defs; + unsigned int i, j; + u32 n_features; + + names = get_stringset(ctx, ETH_SS_FEATURES, 0, 1); + if (names) { + n_features = names->len; + } else if (errno == EOPNOTSUPP || errno == EINVAL) { + /* Kernel doesn't support named features; not an error */ + n_features = 0; + } else if (errno == EPERM) { + /* Kernel bug: ETHTOOL_GSSET_INFO was privileged. + * Work around it. */ + n_features = 0; + } else { + return NULL; + } + + defs = malloc(sizeof(*defs) + sizeof(defs->def[0]) * n_features); + if (!defs) { + free(names); + return NULL; + } + + defs->n_features = n_features; + memset(defs->off_flag_matched, 0, sizeof(defs->off_flag_matched)); + + /* Copy out feature names and find those associated with legacy flags */ + for (i = 0; i < defs->n_features; i++) { + memcpy(defs->def[i].name, names->data + i * ETH_GSTRING_LEN, + ETH_GSTRING_LEN); + defs->def[i].off_flag_index = -1; + + for (j = 0; + j < OFF_FLAG_DEF_SIZE && + defs->def[i].off_flag_index < 0; + j++) { + const char *pattern = + off_flag_def[j].kernel_name; + const char *name = defs->def[i].name; + for (;;) { + if (*pattern == '*') { + /* There is only one wildcard; so + * switch to a suffix comparison */ + size_t pattern_len = + strlen(pattern + 1); + size_t name_len = strlen(name); + if (name_len < pattern_len) + break; /* name is too short */ + name += name_len - pattern_len; + ++pattern; + } else if (*pattern != *name) { + break; /* mismatch */ + } else if (*pattern == 0) { + defs->def[i].off_flag_index = j; + defs->off_flag_matched[j]++; + break; + } else { + ++name; + ++pattern; + } + } + } + } + + free(names); + return defs; +} + +static int do_gdrv(struct cmd_context *ctx) +{ + int err; + struct ethtool_drvinfo drvinfo; + + if (ctx->argc != 0) + exit_bad_args(); + + drvinfo.cmd = ETHTOOL_GDRVINFO; + err = send_ioctl(ctx, &drvinfo); + if (err < 0) { + perror("Cannot get driver information"); + return 71; + } + return dump_drvinfo(&drvinfo); +} + +static int do_gpause(struct cmd_context *ctx) +{ + struct ethtool_pauseparam epause; + struct ethtool_cmd ecmd; + int err; + + if (ctx->argc != 0) + exit_bad_args(); + + fprintf(stdout, "Pause parameters for %s:\n", ctx->devname); + + epause.cmd = ETHTOOL_GPAUSEPARAM; + err = send_ioctl(ctx, &epause); + if (err) { + perror("Cannot get device pause settings"); + return 76; + } + + if (epause.autoneg) { + ecmd.cmd = ETHTOOL_GSET; + err = send_ioctl(ctx, &ecmd); + if (err) { + perror("Cannot get device settings"); + return 1; + } + dump_pause(&epause, ecmd.advertising, ecmd.lp_advertising); + } else { + dump_pause(&epause, 0, 0); + } + + return 0; +} + +static void do_generic_set1(struct cmdline_info *info, int *changed_out) +{ + int wanted, *v1, *v2; + + v1 = info->wanted_val; + wanted = *v1; + + if (wanted < 0) + return; + + v2 = info->ioctl_val; + if (wanted == *v2) { + fprintf(stderr, "%s unmodified, ignoring\n", info->name); + } else { + *v2 = wanted; + *changed_out = 1; + } +} + +static void do_generic_set(struct cmdline_info *info, + unsigned int n_info, + int *changed_out) +{ + unsigned int i; + + for (i = 0; i < n_info; i++) + do_generic_set1(&info[i], changed_out); +} + +static int do_spause(struct cmd_context *ctx) +{ + struct ethtool_pauseparam epause; + int gpause_changed = 0; + int pause_autoneg_wanted = -1; + int pause_rx_wanted = -1; + int pause_tx_wanted = -1; + struct cmdline_info cmdline_pause[] = { + { + .name = "autoneg", + .type = CMDL_BOOL, + .wanted_val = &pause_autoneg_wanted, + .ioctl_val = &epause.autoneg, + }, + { + .name = "rx", + .type = CMDL_BOOL, + .wanted_val = &pause_rx_wanted, + .ioctl_val = &epause.rx_pause, + }, + { + .name = "tx", + .type = CMDL_BOOL, + .wanted_val = &pause_tx_wanted, + .ioctl_val = &epause.tx_pause, + }, + }; + int err, changed = 0; + + parse_generic_cmdline(ctx, &gpause_changed, + cmdline_pause, ARRAY_SIZE(cmdline_pause)); + + epause.cmd = ETHTOOL_GPAUSEPARAM; + err = send_ioctl(ctx, &epause); + if (err) { + perror("Cannot get device pause settings"); + return 77; + } + + do_generic_set(cmdline_pause, ARRAY_SIZE(cmdline_pause), &changed); + + if (!changed) { + fprintf(stderr, "no pause parameters changed, aborting\n"); + return 78; + } + + epause.cmd = ETHTOOL_SPAUSEPARAM; + err = send_ioctl(ctx, &epause); + if (err) { + perror("Cannot set device pause parameters"); + return 79; + } + + return 0; +} + +static int do_sring(struct cmd_context *ctx) +{ + struct ethtool_ringparam ering; + int gring_changed = 0; + s32 ring_rx_wanted = -1; + s32 ring_rx_mini_wanted = -1; + s32 ring_rx_jumbo_wanted = -1; + s32 ring_tx_wanted = -1; + struct cmdline_info cmdline_ring[] = { + { + .name = "rx", + .type = CMDL_S32, + .wanted_val = &ring_rx_wanted, + .ioctl_val = &ering.rx_pending, + }, + { + .name = "rx-mini", + .type = CMDL_S32, + .wanted_val = &ring_rx_mini_wanted, + .ioctl_val = &ering.rx_mini_pending, + }, + { + .name = "rx-jumbo", + .type = CMDL_S32, + .wanted_val = &ring_rx_jumbo_wanted, + .ioctl_val = &ering.rx_jumbo_pending, + }, + { + .name = "tx", + .type = CMDL_S32, + .wanted_val = &ring_tx_wanted, + .ioctl_val = &ering.tx_pending, + }, + }; + int err, changed = 0; + + parse_generic_cmdline(ctx, &gring_changed, + cmdline_ring, ARRAY_SIZE(cmdline_ring)); + + ering.cmd = ETHTOOL_GRINGPARAM; + err = send_ioctl(ctx, &ering); + if (err) { + perror("Cannot get device ring settings"); + return 76; + } + + do_generic_set(cmdline_ring, ARRAY_SIZE(cmdline_ring), &changed); + + if (!changed) { + fprintf(stderr, "no ring parameters changed, aborting\n"); + return 80; + } + + ering.cmd = ETHTOOL_SRINGPARAM; + err = send_ioctl(ctx, &ering); + if (err) { + perror("Cannot set device ring parameters"); + return 81; + } + + return 0; +} + +static int do_gring(struct cmd_context *ctx) +{ + struct ethtool_ringparam ering; + int err; + + if (ctx->argc != 0) + exit_bad_args(); + + fprintf(stdout, "Ring parameters for %s:\n", ctx->devname); + + ering.cmd = ETHTOOL_GRINGPARAM; + err = send_ioctl(ctx, &ering); + if (err == 0) { + err = dump_ring(&ering); + if (err) + return err; + } else { + perror("Cannot get device ring settings"); + return 76; + } + + return 0; +} + +static int do_schannels(struct cmd_context *ctx) +{ + struct ethtool_channels echannels; + int gchannels_changed; + s32 channels_rx_wanted = -1; + s32 channels_tx_wanted = -1; + s32 channels_other_wanted = -1; + s32 channels_combined_wanted = -1; + struct cmdline_info cmdline_channels[] = { + { + .name = "rx", + .type = CMDL_S32, + .wanted_val = &channels_rx_wanted, + .ioctl_val = &echannels.rx_count, + }, + { + .name = "tx", + .type = CMDL_S32, + .wanted_val = &channels_tx_wanted, + .ioctl_val = &echannels.tx_count, + }, + { + .name = "other", + .type = CMDL_S32, + .wanted_val = &channels_other_wanted, + .ioctl_val = &echannels.other_count, + }, + { + .name = "combined", + .type = CMDL_S32, + .wanted_val = &channels_combined_wanted, + .ioctl_val = &echannels.combined_count, + }, + }; + int err, changed = 0; + + parse_generic_cmdline(ctx, &gchannels_changed, + cmdline_channels, ARRAY_SIZE(cmdline_channels)); + + echannels.cmd = ETHTOOL_GCHANNELS; + err = send_ioctl(ctx, &echannels); + if (err) { + perror("Cannot get device channel parameters"); + return 1; + } + + do_generic_set(cmdline_channels, ARRAY_SIZE(cmdline_channels), + &changed); + + if (!changed) { + fprintf(stderr, "no channel parameters changed.\n"); + fprintf(stderr, "current values: rx %u tx %u other %u" + " combined %u\n", echannels.rx_count, + echannels.tx_count, echannels.other_count, + echannels.combined_count); + return 0; + } + + echannels.cmd = ETHTOOL_SCHANNELS; + err = send_ioctl(ctx, &echannels); + if (err) { + perror("Cannot set device channel parameters"); + return 1; + } + + return 0; +} + +static int do_gchannels(struct cmd_context *ctx) +{ + struct ethtool_channels echannels; + int err; + + if (ctx->argc != 0) + exit_bad_args(); + + fprintf(stdout, "Channel parameters for %s:\n", ctx->devname); + + echannels.cmd = ETHTOOL_GCHANNELS; + err = send_ioctl(ctx, &echannels); + if (err == 0) { + err = dump_channels(&echannels); + if (err) + return err; + } else { + perror("Cannot get device channel parameters"); + return 1; + } + return 0; + +} + +static int do_gcoalesce(struct cmd_context *ctx) +{ + struct ethtool_coalesce ecoal = {}; + int err; + + if (ctx->argc != 0) + exit_bad_args(); + + fprintf(stdout, "Coalesce parameters for %s:\n", ctx->devname); + + ecoal.cmd = ETHTOOL_GCOALESCE; + err = send_ioctl(ctx, &ecoal); + if (err == 0) { + err = dump_coalesce(&ecoal); + if (err) + return err; + } else { + perror("Cannot get device coalesce settings"); + return 82; + } + + return 0; +} + +#define DECLARE_COALESCE_OPTION_VARS() \ + s32 coal_stats_wanted = -1; \ + int coal_adaptive_rx_wanted = -1; \ + int coal_adaptive_tx_wanted = -1; \ + s32 coal_sample_rate_wanted = -1; \ + s32 coal_pkt_rate_low_wanted = -1; \ + s32 coal_pkt_rate_high_wanted = -1; \ + s32 coal_rx_usec_wanted = -1; \ + s32 coal_rx_frames_wanted = -1; \ + s32 coal_rx_usec_irq_wanted = -1; \ + s32 coal_rx_frames_irq_wanted = -1; \ + s32 coal_tx_usec_wanted = -1; \ + s32 coal_tx_frames_wanted = -1; \ + s32 coal_tx_usec_irq_wanted = -1; \ + s32 coal_tx_frames_irq_wanted = -1; \ + s32 coal_rx_usec_low_wanted = -1; \ + s32 coal_rx_frames_low_wanted = -1; \ + s32 coal_tx_usec_low_wanted = -1; \ + s32 coal_tx_frames_low_wanted = -1; \ + s32 coal_rx_usec_high_wanted = -1; \ + s32 coal_rx_frames_high_wanted = -1; \ + s32 coal_tx_usec_high_wanted = -1; \ + s32 coal_tx_frames_high_wanted = -1 + +#define COALESCE_CMDLINE_INFO(__ecoal) \ +{ \ + { \ + .name = "adaptive-rx", \ + .type = CMDL_BOOL, \ + .wanted_val = &coal_adaptive_rx_wanted, \ + .ioctl_val = &__ecoal.use_adaptive_rx_coalesce, \ + }, \ + { \ + .name = "adaptive-tx", \ + .type = CMDL_BOOL, \ + .wanted_val = &coal_adaptive_tx_wanted, \ + .ioctl_val = &__ecoal.use_adaptive_tx_coalesce, \ + }, \ + { \ + .name = "sample-interval", \ + .type = CMDL_S32, \ + .wanted_val = &coal_sample_rate_wanted, \ + .ioctl_val = &__ecoal.rate_sample_interval, \ + }, \ + { \ + .name = "stats-block-usecs", \ + .type = CMDL_S32, \ + .wanted_val = &coal_stats_wanted, \ + .ioctl_val = &__ecoal.stats_block_coalesce_usecs, \ + }, \ + { \ + .name = "pkt-rate-low", \ + .type = CMDL_S32, \ + .wanted_val = &coal_pkt_rate_low_wanted, \ + .ioctl_val = &__ecoal.pkt_rate_low, \ + }, \ + { \ + .name = "pkt-rate-high", \ + .type = CMDL_S32, \ + .wanted_val = &coal_pkt_rate_high_wanted, \ + .ioctl_val = &__ecoal.pkt_rate_high, \ + }, \ + { \ + .name = "rx-usecs", \ + .type = CMDL_S32, \ + .wanted_val = &coal_rx_usec_wanted, \ + .ioctl_val = &__ecoal.rx_coalesce_usecs, \ + }, \ + { \ + .name = "rx-frames", \ + .type = CMDL_S32, \ + .wanted_val = &coal_rx_frames_wanted, \ + .ioctl_val = &__ecoal.rx_max_coalesced_frames, \ + }, \ + { \ + .name = "rx-usecs-irq", \ + .type = CMDL_S32, \ + .wanted_val = &coal_rx_usec_irq_wanted, \ + .ioctl_val = &__ecoal.rx_coalesce_usecs_irq, \ + }, \ + { \ + .name = "rx-frames-irq", \ + .type = CMDL_S32, \ + .wanted_val = &coal_rx_frames_irq_wanted, \ + .ioctl_val = &__ecoal.rx_max_coalesced_frames_irq, \ + }, \ + { \ + .name = "tx-usecs", \ + .type = CMDL_S32, \ + .wanted_val = &coal_tx_usec_wanted, \ + .ioctl_val = &__ecoal.tx_coalesce_usecs, \ + }, \ + { \ + .name = "tx-frames", \ + .type = CMDL_S32, \ + .wanted_val = &coal_tx_frames_wanted, \ + .ioctl_val = &__ecoal.tx_max_coalesced_frames, \ + }, \ + { \ + .name = "tx-usecs-irq", \ + .type = CMDL_S32, \ + .wanted_val = &coal_tx_usec_irq_wanted, \ + .ioctl_val = &__ecoal.tx_coalesce_usecs_irq, \ + }, \ + { \ + .name = "tx-frames-irq", \ + .type = CMDL_S32, \ + .wanted_val = &coal_tx_frames_irq_wanted, \ + .ioctl_val = &__ecoal.tx_max_coalesced_frames_irq, \ + }, \ + { \ + .name = "rx-usecs-low", \ + .type = CMDL_S32, \ + .wanted_val = &coal_rx_usec_low_wanted, \ + .ioctl_val = &__ecoal.rx_coalesce_usecs_low, \ + }, \ + { \ + .name = "rx-frames-low", \ + .type = CMDL_S32, \ + .wanted_val = &coal_rx_frames_low_wanted, \ + .ioctl_val = &__ecoal.rx_max_coalesced_frames_low, \ + }, \ + { \ + .name = "tx-usecs-low", \ + .type = CMDL_S32, \ + .wanted_val = &coal_tx_usec_low_wanted, \ + .ioctl_val = &__ecoal.tx_coalesce_usecs_low, \ + }, \ + { \ + .name = "tx-frames-low", \ + .type = CMDL_S32, \ + .wanted_val = &coal_tx_frames_low_wanted, \ + .ioctl_val = &__ecoal.tx_max_coalesced_frames_low, \ + }, \ + { \ + .name = "rx-usecs-high", \ + .type = CMDL_S32, \ + .wanted_val = &coal_rx_usec_high_wanted, \ + .ioctl_val = &__ecoal.rx_coalesce_usecs_high, \ + }, \ + { \ + .name = "rx-frames-high", \ + .type = CMDL_S32, \ + .wanted_val = &coal_rx_frames_high_wanted, \ + .ioctl_val = &__ecoal.rx_max_coalesced_frames_high,\ + }, \ + { \ + .name = "tx-usecs-high", \ + .type = CMDL_S32, \ + .wanted_val = &coal_tx_usec_high_wanted, \ + .ioctl_val = &__ecoal.tx_coalesce_usecs_high, \ + }, \ + { \ + .name = "tx-frames-high", \ + .type = CMDL_S32, \ + .wanted_val = &coal_tx_frames_high_wanted, \ + .ioctl_val = &__ecoal.tx_max_coalesced_frames_high,\ + }, \ +} + +static int do_scoalesce(struct cmd_context *ctx) +{ + struct ethtool_coalesce ecoal; + int gcoalesce_changed = 0; + DECLARE_COALESCE_OPTION_VARS(); + struct cmdline_info cmdline_coalesce[] = COALESCE_CMDLINE_INFO(ecoal); + int err, changed = 0; + + parse_generic_cmdline(ctx, &gcoalesce_changed, + cmdline_coalesce, ARRAY_SIZE(cmdline_coalesce)); + + ecoal.cmd = ETHTOOL_GCOALESCE; + err = send_ioctl(ctx, &ecoal); + if (err) { + perror("Cannot get device coalesce settings"); + return 76; + } + + do_generic_set(cmdline_coalesce, ARRAY_SIZE(cmdline_coalesce), + &changed); + + if (!changed) { + fprintf(stderr, "no coalesce parameters changed, aborting\n"); + return 80; + } + + ecoal.cmd = ETHTOOL_SCOALESCE; + err = send_ioctl(ctx, &ecoal); + if (err) { + perror("Cannot set device coalesce parameters"); + return 81; + } + + return 0; +} + +static struct feature_state * +get_features(struct cmd_context *ctx, const struct feature_defs *defs) +{ + struct feature_state *state; + struct ethtool_value eval; + int err, allfail = 1; + u32 value; + int i; + + state = malloc(sizeof(*state) + + FEATURE_BITS_TO_BLOCKS(defs->n_features) * + sizeof(state->features.features[0])); + if (!state) + return NULL; + + state->off_flags = 0; + + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { + value = off_flag_def[i].value; + if (!off_flag_def[i].get_cmd) + continue; + eval.cmd = off_flag_def[i].get_cmd; + err = send_ioctl(ctx, &eval); + if (err) { + if (errno == EOPNOTSUPP && + off_flag_def[i].get_cmd == ETHTOOL_GUFO) + continue; + + fprintf(stderr, + "Cannot get device %s settings: %m\n", + off_flag_def[i].long_name); + } else { + if (eval.data) + state->off_flags |= value; + allfail = 0; + } + } + + eval.cmd = ETHTOOL_GFLAGS; + err = send_ioctl(ctx, &eval); + if (err) { + perror("Cannot get device flags"); + } else { + state->off_flags |= eval.data & ETH_FLAG_EXT_MASK; + allfail = 0; + } + + if (defs->n_features) { + state->features.cmd = ETHTOOL_GFEATURES; + state->features.size = FEATURE_BITS_TO_BLOCKS(defs->n_features); + err = send_ioctl(ctx, &state->features); + if (err) + perror("Cannot get device generic features"); + else + allfail = 0; + } + + if (allfail) { + free(state); + return NULL; + } + + return state; +} + +static int do_gfeatures(struct cmd_context *ctx) +{ + struct feature_defs *defs; + struct feature_state *features; + + if (ctx->argc != 0) + exit_bad_args(); + + defs = get_feature_defs(ctx); + if (!defs) { + perror("Cannot get device feature names"); + return 1; + } + + fprintf(stdout, "Features for %s:\n", ctx->devname); + + features = get_features(ctx, defs); + if (!features) { + fprintf(stdout, "no feature info available\n"); + free(defs); + return 1; + } + + dump_features(defs, features, NULL); + free(features); + free(defs); + return 0; +} + +static int do_sfeatures(struct cmd_context *ctx) +{ + struct feature_defs *defs; + int any_changed = 0, any_mismatch = 0; + u32 off_flags_wanted = 0; + u32 off_flags_mask = 0; + struct ethtool_sfeatures *efeatures = NULL; + struct feature_state *old_state = NULL; + struct feature_state *new_state = NULL; + struct cmdline_info *cmdline_features; + struct ethtool_value eval; + unsigned int i, j; + int err, rc; + + defs = get_feature_defs(ctx); + if (!defs) { + perror("Cannot get device feature names"); + return 1; + } + if (defs->n_features) { + efeatures = malloc(sizeof(*efeatures) + + FEATURE_BITS_TO_BLOCKS(defs->n_features) * + sizeof(efeatures->features[0])); + if (!efeatures) { + perror("Cannot parse arguments"); + rc = 1; + goto err; + } + efeatures->cmd = ETHTOOL_SFEATURES; + efeatures->size = FEATURE_BITS_TO_BLOCKS(defs->n_features); + memset(efeatures->features, 0, + FEATURE_BITS_TO_BLOCKS(defs->n_features) * + sizeof(efeatures->features[0])); + } + + /* Generate cmdline_info for legacy flags and kernel-named + * features, and parse our arguments. + */ + cmdline_features = calloc(2 * OFF_FLAG_DEF_SIZE + defs->n_features, + sizeof(cmdline_features[0])); + if (!cmdline_features) { + perror("Cannot parse arguments"); + rc = 1; + goto err; + } + j = 0; + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { + flag_to_cmdline_info(off_flag_def[i].short_name, + off_flag_def[i].value, + &off_flags_wanted, &off_flags_mask, + &cmdline_features[j++]); + flag_to_cmdline_info(off_flag_def[i].long_name, + off_flag_def[i].value, + &off_flags_wanted, &off_flags_mask, + &cmdline_features[j++]); + } + for (i = 0; i < defs->n_features; i++) + flag_to_cmdline_info( + defs->def[i].name, FEATURE_FIELD_FLAG(i), + &FEATURE_WORD(efeatures->features, i, requested), + &FEATURE_WORD(efeatures->features, i, valid), + &cmdline_features[j++]); + parse_generic_cmdline(ctx, &any_changed, cmdline_features, + 2 * OFF_FLAG_DEF_SIZE + defs->n_features); + free(cmdline_features); + + if (!any_changed) { + fprintf(stdout, "no features changed\n"); + rc = 0; + goto err; + } + + old_state = get_features(ctx, defs); + if (!old_state) { + rc = 1; + goto err; + } + + if (efeatures) { + /* For each offload that the user specified, update any + * related features that the user did not specify and that + * are not fixed. Warn if all related features are fixed. + */ + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { + int fixed = 1; + + if (!(off_flags_mask & off_flag_def[i].value)) + continue; + + for (j = 0; j < defs->n_features; j++) { + if (defs->def[j].off_flag_index != (int)i || + !FEATURE_BIT_IS_SET( + old_state->features.features, + j, available) || + FEATURE_BIT_IS_SET( + old_state->features.features, + j, never_changed)) + continue; + + fixed = 0; + if (!FEATURE_BIT_IS_SET(efeatures->features, + j, valid)) { + FEATURE_BIT_SET(efeatures->features, + j, valid); + if (off_flags_wanted & + off_flag_def[i].value) + FEATURE_BIT_SET( + efeatures->features, + j, requested); + } + } + + if (fixed) + fprintf(stderr, "Cannot change %s\n", + off_flag_def[i].long_name); + } + + err = send_ioctl(ctx, efeatures); + if (err < 0) { + perror("Cannot set device feature settings"); + rc = 1; + goto err; + } + } else { + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { + if (!off_flag_def[i].set_cmd) + continue; + if (off_flags_mask & off_flag_def[i].value) { + eval.cmd = off_flag_def[i].set_cmd; + eval.data = !!(off_flags_wanted & + off_flag_def[i].value); + err = send_ioctl(ctx, &eval); + if (err) { + fprintf(stderr, + "Cannot set device %s settings: %m\n", + off_flag_def[i].long_name); + rc = 1; + goto err; + } + } + } + + if (off_flags_mask & ETH_FLAG_EXT_MASK) { + eval.cmd = ETHTOOL_SFLAGS; + eval.data = (old_state->off_flags & ~off_flags_mask & + ETH_FLAG_EXT_MASK); + eval.data |= off_flags_wanted & ETH_FLAG_EXT_MASK; + + err = send_ioctl(ctx, &eval); + if (err) { + perror("Cannot set device flag settings"); + rc = 92; + goto err; + } + } + } + + /* Compare new state with requested state */ + new_state = get_features(ctx, defs); + if (!new_state) { + rc = 1; + goto err; + } + any_changed = new_state->off_flags != old_state->off_flags; + any_mismatch = (new_state->off_flags != + ((old_state->off_flags & ~off_flags_mask) | + off_flags_wanted)); + for (i = 0; i < FEATURE_BITS_TO_BLOCKS(defs->n_features); i++) { + if (new_state->features.features[i].active != + old_state->features.features[i].active) + any_changed = 1; + if (new_state->features.features[i].active != + ((old_state->features.features[i].active & + ~efeatures->features[i].valid) | + efeatures->features[i].requested)) + any_mismatch = 1; + } + if (any_mismatch) { + if (!any_changed) { + fprintf(stderr, + "Could not change any device features\n"); + rc = 1; + goto err; + } + printf("Actual changes:\n"); + dump_features(defs, new_state, old_state); + } + + rc = 0; + +err: + free(new_state); + free(old_state); + free(defs); + free(efeatures); + + return rc; +} + +static struct ethtool_link_usettings * +do_ioctl_glinksettings(struct cmd_context *ctx) +{ + int err; + struct { + struct ethtool_link_settings req; + __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32]; + } ecmd; + struct ethtool_link_usettings *link_usettings; + unsigned int u32_offs; + + /* Handshake with kernel to determine number of words for link + * mode bitmaps. When requested number of bitmap words is not + * the one expected by kernel, the latter returns the integer + * opposite of what it is expecting. We request length 0 below + * (aka. invalid bitmap length) to get this info. + */ + memset(&ecmd, 0, sizeof(ecmd)); + ecmd.req.cmd = ETHTOOL_GLINKSETTINGS; + err = send_ioctl(ctx, &ecmd); + if (err < 0) + return NULL; + + /* see above: we expect a strictly negative value from kernel. + */ + if (ecmd.req.link_mode_masks_nwords >= 0 + || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) + return NULL; + + /* got the real ecmd.req.link_mode_masks_nwords, + * now send the real request + */ + ecmd.req.cmd = ETHTOOL_GLINKSETTINGS; + ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords; + err = send_ioctl(ctx, &ecmd); + if (err < 0) + return NULL; + + if (ecmd.req.link_mode_masks_nwords <= 0 + || ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) + return NULL; + + /* Convert to usettings struct */ + link_usettings = calloc(1, sizeof(*link_usettings)); + if (link_usettings == NULL) + return NULL; + + memcpy(&link_usettings->base, &ecmd.req, sizeof(link_usettings->base)); + link_usettings->deprecated.transceiver = ecmd.req.transceiver; + + /* copy link mode bitmaps */ + u32_offs = 0; + memcpy(link_usettings->link_modes.supported, + &ecmd.link_mode_data[u32_offs], + 4 * ecmd.req.link_mode_masks_nwords); + + u32_offs += ecmd.req.link_mode_masks_nwords; + memcpy(link_usettings->link_modes.advertising, + &ecmd.link_mode_data[u32_offs], + 4 * ecmd.req.link_mode_masks_nwords); + + u32_offs += ecmd.req.link_mode_masks_nwords; + memcpy(link_usettings->link_modes.lp_advertising, + &ecmd.link_mode_data[u32_offs], + 4 * ecmd.req.link_mode_masks_nwords); + + return link_usettings; +} + +static int +do_ioctl_slinksettings(struct cmd_context *ctx, + const struct ethtool_link_usettings *link_usettings) +{ + struct { + struct ethtool_link_settings req; + __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32]; + } ecmd; + unsigned int u32_offs; + + /* refuse to send ETHTOOL_SLINKSETTINGS ioctl if + * link_usettings was retrieved with ETHTOOL_GSET + */ + if (link_usettings->base.cmd != ETHTOOL_GLINKSETTINGS) + return -1; + + /* refuse to send ETHTOOL_SLINKSETTINGS ioctl if deprecated fields + * were set + */ + if (link_usettings->deprecated.transceiver) + return -1; + + if (link_usettings->base.link_mode_masks_nwords <= 0) + return -1; + + memcpy(&ecmd.req, &link_usettings->base, sizeof(ecmd.req)); + ecmd.req.cmd = ETHTOOL_SLINKSETTINGS; + + /* copy link mode bitmaps */ + u32_offs = 0; + memcpy(&ecmd.link_mode_data[u32_offs], + link_usettings->link_modes.supported, + 4 * ecmd.req.link_mode_masks_nwords); + + u32_offs += ecmd.req.link_mode_masks_nwords; + memcpy(&ecmd.link_mode_data[u32_offs], + link_usettings->link_modes.advertising, + 4 * ecmd.req.link_mode_masks_nwords); + + u32_offs += ecmd.req.link_mode_masks_nwords; + memcpy(&ecmd.link_mode_data[u32_offs], + link_usettings->link_modes.lp_advertising, + 4 * ecmd.req.link_mode_masks_nwords); + + return send_ioctl(ctx, &ecmd); +} + +static struct ethtool_link_usettings * +do_ioctl_gset(struct cmd_context *ctx) +{ + int err; + struct ethtool_cmd ecmd; + struct ethtool_link_usettings *link_usettings; + + memset(&ecmd, 0, sizeof(ecmd)); + ecmd.cmd = ETHTOOL_GSET; + err = send_ioctl(ctx, &ecmd); + if (err < 0) + return NULL; + + link_usettings = calloc(1, sizeof(*link_usettings)); + if (link_usettings == NULL) + return NULL; + + /* remember that ETHTOOL_GSET was used */ + link_usettings->base.cmd = ETHTOOL_GSET; + + link_usettings->base.link_mode_masks_nwords = 1; + link_usettings->link_modes.supported[0] = ecmd.supported; + link_usettings->link_modes.advertising[0] = ecmd.advertising; + link_usettings->link_modes.lp_advertising[0] = ecmd.lp_advertising; + link_usettings->base.speed = ethtool_cmd_speed(&ecmd); + link_usettings->base.duplex = ecmd.duplex; + link_usettings->base.port = ecmd.port; + link_usettings->base.phy_address = ecmd.phy_address; + link_usettings->deprecated.transceiver = ecmd.transceiver; + link_usettings->base.autoneg = ecmd.autoneg; + link_usettings->base.mdio_support = ecmd.mdio_support; + /* ignored (fully deprecated): maxrxpkt, maxtxpkt */ + link_usettings->base.eth_tp_mdix = ecmd.eth_tp_mdix; + link_usettings->base.eth_tp_mdix_ctrl = ecmd.eth_tp_mdix_ctrl; + + return link_usettings; +} + +static bool ethtool_link_mode_is_backward_compatible(const u32 *mask) +{ + unsigned int i; + + for (i = 1; i < ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32; ++i) + if (mask[i]) + return false; + + return true; +} + +static int +do_ioctl_sset(struct cmd_context *ctx, + const struct ethtool_link_usettings *link_usettings) +{ + struct ethtool_cmd ecmd; + + /* refuse to send ETHTOOL_SSET ioctl if link_usettings was + * retrieved with ETHTOOL_GLINKSETTINGS + */ + if (link_usettings->base.cmd != ETHTOOL_GSET) + return -1; + + if (link_usettings->base.link_mode_masks_nwords <= 0) + return -1; + + /* refuse to sset if any bit > 31 is set */ + if (!ethtool_link_mode_is_backward_compatible( + link_usettings->link_modes.supported)) + return -1; + if (!ethtool_link_mode_is_backward_compatible( + link_usettings->link_modes.advertising)) + return -1; + if (!ethtool_link_mode_is_backward_compatible( + link_usettings->link_modes.lp_advertising)) + return -1; + + memset(&ecmd, 0, sizeof(ecmd)); + ecmd.cmd = ETHTOOL_SSET; + + ecmd.supported = link_usettings->link_modes.supported[0]; + ecmd.advertising = link_usettings->link_modes.advertising[0]; + ecmd.lp_advertising = link_usettings->link_modes.lp_advertising[0]; + ethtool_cmd_speed_set(&ecmd, link_usettings->base.speed); + ecmd.duplex = link_usettings->base.duplex; + ecmd.port = link_usettings->base.port; + ecmd.phy_address = link_usettings->base.phy_address; + ecmd.transceiver = link_usettings->deprecated.transceiver; + ecmd.autoneg = link_usettings->base.autoneg; + ecmd.mdio_support = link_usettings->base.mdio_support; + /* ignored (fully deprecated): maxrxpkt, maxtxpkt */ + ecmd.eth_tp_mdix = link_usettings->base.eth_tp_mdix; + ecmd.eth_tp_mdix_ctrl = link_usettings->base.eth_tp_mdix_ctrl; + return send_ioctl(ctx, &ecmd); +} + +static int do_gset(struct cmd_context *ctx) +{ + int err; + struct ethtool_link_usettings *link_usettings; + struct ethtool_wolinfo wolinfo; + struct ethtool_value edata; + int allfail = 1; + + if (ctx->argc != 0) + exit_bad_args(); + + fprintf(stdout, "Settings for %s:\n", ctx->devname); + + link_usettings = do_ioctl_glinksettings(ctx); + if (link_usettings == NULL) + link_usettings = do_ioctl_gset(ctx); + if (link_usettings != NULL) { + err = dump_link_usettings(link_usettings); + free(link_usettings); + if (err) + return err; + allfail = 0; + } else if (errno != EOPNOTSUPP) { + perror("Cannot get device settings"); + } + + wolinfo.cmd = ETHTOOL_GWOL; + err = send_ioctl(ctx, &wolinfo); + if (err == 0) { + err = dump_wol(&wolinfo); + if (err) + return err; + allfail = 0; + } else if (errno != EOPNOTSUPP) { + perror("Cannot get wake-on-lan settings"); + } + + edata.cmd = ETHTOOL_GMSGLVL; + err = send_ioctl(ctx, &edata); + if (err == 0) { + fprintf(stdout, " Current message level: 0x%08x (%d)\n" + " ", + edata.data, edata.data); + print_flags(flags_msglvl, n_flags_msglvl, edata.data); + fprintf(stdout, "\n"); + allfail = 0; + } else if (errno != EOPNOTSUPP) { + perror("Cannot get message level"); + } + + edata.cmd = ETHTOOL_GLINK; + err = send_ioctl(ctx, &edata); + if (err == 0) { + fprintf(stdout, " Link detected: %s\n", + edata.data ? "yes":"no"); + allfail = 0; + } else if (errno != EOPNOTSUPP) { + perror("Cannot get link status"); + } + + if (allfail) { + fprintf(stdout, "No data available\n"); + return 75; + } + return 0; +} + +static int do_sset(struct cmd_context *ctx) +{ + int speed_wanted = -1; + int duplex_wanted = -1; + int port_wanted = -1; + int mdix_wanted = -1; + int autoneg_wanted = -1; + int phyad_wanted = -1; + int xcvr_wanted = -1; + u32 *full_advertising_wanted = NULL; + u32 *advertising_wanted = NULL; + ETHTOOL_DECLARE_LINK_MODE_MASK(mask_full_advertising_wanted); + ETHTOOL_DECLARE_LINK_MODE_MASK(mask_advertising_wanted); + int gset_changed = 0; /* did anything in GSET change? */ + u32 wol_wanted = 0; + int wol_change = 0; + u8 sopass_wanted[SOPASS_MAX]; + int sopass_change = 0; + int gwol_changed = 0; /* did anything in GWOL change? */ + int msglvl_changed = 0; + u32 msglvl_wanted = 0; + u32 msglvl_mask = 0; + struct cmdline_info cmdline_msglvl[n_flags_msglvl]; + unsigned int argc = ctx->argc; + char **argp = ctx->argp; + unsigned int i; + int err = 0; + + for (i = 0; i < n_flags_msglvl; i++) + flag_to_cmdline_info(flags_msglvl[i].name, + flags_msglvl[i].value, + &msglvl_wanted, &msglvl_mask, + &cmdline_msglvl[i]); + + for (i = 0; i < argc; i++) { + if (!strcmp(argp[i], "speed")) { + gset_changed = 1; + i += 1; + if (i >= argc) + exit_bad_args(); + speed_wanted = get_int(argp[i], 10); + } else if (!strcmp(argp[i], "duplex")) { + gset_changed = 1; + i += 1; + if (i >= argc) + exit_bad_args(); + if (!strcmp(argp[i], "half")) + duplex_wanted = DUPLEX_HALF; + else if (!strcmp(argp[i], "full")) + duplex_wanted = DUPLEX_FULL; + else + exit_bad_args(); + } else if (!strcmp(argp[i], "port")) { + gset_changed = 1; + i += 1; + if (i >= argc) + exit_bad_args(); + if (!strcmp(argp[i], "tp")) + port_wanted = PORT_TP; + else if (!strcmp(argp[i], "aui")) + port_wanted = PORT_AUI; + else if (!strcmp(argp[i], "bnc")) + port_wanted = PORT_BNC; + else if (!strcmp(argp[i], "mii")) + port_wanted = PORT_MII; + else if (!strcmp(argp[i], "fibre")) + port_wanted = PORT_FIBRE; + else + exit_bad_args(); + } else if (!strcmp(argp[i], "mdix")) { + gset_changed = 1; + i += 1; + if (i >= argc) + exit_bad_args(); + if (!strcmp(argp[i], "auto")) + mdix_wanted = ETH_TP_MDI_AUTO; + else if (!strcmp(argp[i], "on")) + mdix_wanted = ETH_TP_MDI_X; + else if (!strcmp(argp[i], "off")) + mdix_wanted = ETH_TP_MDI; + else + exit_bad_args(); + } else if (!strcmp(argp[i], "autoneg")) { + i += 1; + if (i >= argc) + exit_bad_args(); + if (!strcmp(argp[i], "on")) { + gset_changed = 1; + autoneg_wanted = AUTONEG_ENABLE; + } else if (!strcmp(argp[i], "off")) { + gset_changed = 1; + autoneg_wanted = AUTONEG_DISABLE; + } else { + exit_bad_args(); + } + } else if (!strcmp(argp[i], "advertise")) { + gset_changed = 1; + i += 1; + if (i >= argc) + exit_bad_args(); + if (parse_hex_u32_bitmap( + argp[i], + ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS, + mask_full_advertising_wanted)) + exit_bad_args(); + full_advertising_wanted = mask_full_advertising_wanted; + } else if (!strcmp(argp[i], "phyad")) { + gset_changed = 1; + i += 1; + if (i >= argc) + exit_bad_args(); + phyad_wanted = get_int(argp[i], 0); + } else if (!strcmp(argp[i], "xcvr")) { + gset_changed = 1; + i += 1; + if (i >= argc) + exit_bad_args(); + if (!strcmp(argp[i], "internal")) + xcvr_wanted = XCVR_INTERNAL; + else if (!strcmp(argp[i], "external")) + xcvr_wanted = XCVR_EXTERNAL; + else + exit_bad_args(); + } else if (!strcmp(argp[i], "wol")) { + gwol_changed = 1; + i++; + if (i >= argc) + exit_bad_args(); + if (parse_wolopts(argp[i], &wol_wanted) < 0) + exit_bad_args(); + wol_change = 1; + } else if (!strcmp(argp[i], "sopass")) { + gwol_changed = 1; + i++; + if (i >= argc) + exit_bad_args(); + get_mac_addr(argp[i], sopass_wanted); + sopass_change = 1; + } else if (!strcmp(argp[i], "msglvl")) { + i++; + if (i >= argc) + exit_bad_args(); + if (isdigit((unsigned char)argp[i][0])) { + msglvl_changed = 1; + msglvl_mask = ~0; + msglvl_wanted = + get_uint_range(argp[i], 0, + 0xffffffff); + } else { + ctx->argc -= i; + ctx->argp += i; + parse_generic_cmdline( + ctx, &msglvl_changed, + cmdline_msglvl, + ARRAY_SIZE(cmdline_msglvl)); + break; + } + } else if (!strcmp(argp[i], "master-slave")) { + exit_nlonly_param(argp[i]); + } else { + exit_bad_args(); + } + } + + if (full_advertising_wanted == NULL) { + /* User didn't supply a full advertisement bitfield: + * construct one from the specified speed and duplex. + */ + int adv_bit = -1; + + if (speed_wanted == SPEED_10 && duplex_wanted == DUPLEX_HALF) + adv_bit = ETHTOOL_LINK_MODE_10baseT_Half_BIT; + else if (speed_wanted == SPEED_10 && + duplex_wanted == DUPLEX_FULL) + adv_bit = ETHTOOL_LINK_MODE_10baseT_Full_BIT; + else if (speed_wanted == SPEED_100 && + duplex_wanted == DUPLEX_HALF) + adv_bit = ETHTOOL_LINK_MODE_100baseT_Half_BIT; + else if (speed_wanted == SPEED_100 && + duplex_wanted == DUPLEX_FULL) + adv_bit = ETHTOOL_LINK_MODE_100baseT_Full_BIT; + else if (speed_wanted == SPEED_1000 && + duplex_wanted == DUPLEX_HALF) + adv_bit = ETHTOOL_LINK_MODE_1000baseT_Half_BIT; + else if (speed_wanted == SPEED_1000 && + duplex_wanted == DUPLEX_FULL) + adv_bit = ETHTOOL_LINK_MODE_1000baseT_Full_BIT; + else if (speed_wanted == SPEED_2500 && + duplex_wanted == DUPLEX_FULL) + adv_bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT; + else if (speed_wanted == SPEED_10000 && + duplex_wanted == DUPLEX_FULL) + adv_bit = ETHTOOL_LINK_MODE_10000baseT_Full_BIT; + + if (adv_bit >= 0) { + advertising_wanted = mask_advertising_wanted; + ethtool_link_mode_zero(advertising_wanted); + ethtool_link_mode_set_bit( + adv_bit, advertising_wanted); + } + /* otherwise: auto negotiate without forcing, + * all supported speed will be assigned below + */ + } + + if (gset_changed) { + struct ethtool_link_usettings *link_usettings; + + link_usettings = do_ioctl_glinksettings(ctx); + if (link_usettings == NULL) + link_usettings = do_ioctl_gset(ctx); + else + memset(&link_usettings->deprecated, 0, + sizeof(link_usettings->deprecated)); + if (link_usettings == NULL) { + perror("Cannot get current device settings"); + err = -1; + } else { + /* Change everything the user specified. */ + if (speed_wanted != -1) + link_usettings->base.speed = speed_wanted; + if (duplex_wanted != -1) + link_usettings->base.duplex = duplex_wanted; + if (port_wanted != -1) + link_usettings->base.port = port_wanted; + if (mdix_wanted != -1) { + /* check driver supports MDI-X */ + if (link_usettings->base.eth_tp_mdix_ctrl + != ETH_TP_MDI_INVALID) + link_usettings->base.eth_tp_mdix_ctrl + = mdix_wanted; + else + fprintf(stderr, + "setting MDI not supported\n"); + } + if (autoneg_wanted != -1) + link_usettings->base.autoneg = autoneg_wanted; + if (phyad_wanted != -1) + link_usettings->base.phy_address = phyad_wanted; + if (xcvr_wanted != -1) + link_usettings->deprecated.transceiver + = xcvr_wanted; + /* XXX If the user specified speed or duplex + * then we should mask the advertised modes + * accordingly. For now, warn that we aren't + * doing that. + */ + if ((speed_wanted != -1 || duplex_wanted != -1) && + link_usettings->base.autoneg && + advertising_wanted == NULL) { + fprintf(stderr, "Cannot advertise"); + if (speed_wanted >= 0) + fprintf(stderr, " speed %d", + speed_wanted); + if (duplex_wanted >= 0) + fprintf(stderr, " duplex %s", + duplex_wanted ? + "full" : "half"); + fprintf(stderr, "\n"); + } + if (autoneg_wanted == AUTONEG_ENABLE && + advertising_wanted == NULL && + full_advertising_wanted == NULL) { + unsigned int i; + + /* Auto negotiation enabled, but with + * unspecified speed and duplex: enable all + * supported speeds and duplexes. + */ + ethtool_link_mode_for_each_u32(i) { + u32 sup = link_usettings->link_modes.supported[i]; + u32 *adv = link_usettings->link_modes.advertising + i; + + *adv = ((*adv & ~all_advertised_modes[i]) + | (sup & all_advertised_modes[i])); + } + + /* If driver supports unknown flags, we cannot + * be sure that we enable all link modes. + */ + ethtool_link_mode_for_each_u32(i) { + u32 sup = link_usettings->link_modes.supported[i]; + + if ((sup & all_advertised_flags[i]) != sup) { + fprintf(stderr, "Driver supports one or more unknown flags\n"); + break; + } + } + } else if (advertising_wanted != NULL) { + unsigned int i; + + /* Enable all requested modes */ + ethtool_link_mode_for_each_u32(i) { + u32 *adv = link_usettings->link_modes.advertising + i; + + *adv = ((*adv & ~all_advertised_modes[i]) + | advertising_wanted[i]); + } + } else if (full_advertising_wanted != NULL) { + ethtool_link_mode_copy( + link_usettings->link_modes.advertising, + full_advertising_wanted); + } + + /* Try to perform the update. */ + if (link_usettings->base.cmd == ETHTOOL_GLINKSETTINGS) + err = do_ioctl_slinksettings(ctx, + link_usettings); + else + err = do_ioctl_sset(ctx, link_usettings); + free(link_usettings); + if (err < 0) + perror("Cannot set new settings"); + } + if (err < 0) { + if (speed_wanted != -1) + fprintf(stderr, " not setting speed\n"); + if (duplex_wanted != -1) + fprintf(stderr, " not setting duplex\n"); + if (port_wanted != -1) + fprintf(stderr, " not setting port\n"); + if (autoneg_wanted != -1) + fprintf(stderr, " not setting autoneg\n"); + if (phyad_wanted != -1) + fprintf(stderr, " not setting phy_address\n"); + if (xcvr_wanted != -1) + fprintf(stderr, " not setting transceiver\n"); + if (mdix_wanted != -1) + fprintf(stderr, " not setting mdix\n"); + } + } + + if (gwol_changed) { + struct ethtool_wolinfo wol; + + wol.cmd = ETHTOOL_GWOL; + err = send_ioctl(ctx, &wol); + if (err < 0) { + perror("Cannot get current wake-on-lan settings"); + } else { + /* Change everything the user specified. */ + if (wol_change) + wol.wolopts = wol_wanted; + if (sopass_change) { + int i; + for (i = 0; i < SOPASS_MAX; i++) + wol.sopass[i] = sopass_wanted[i]; + } + + /* Try to perform the update. */ + wol.cmd = ETHTOOL_SWOL; + err = send_ioctl(ctx, &wol); + if (err < 0) + perror("Cannot set new wake-on-lan settings"); + } + if (err < 0) { + if (wol_change) + fprintf(stderr, " not setting wol\n"); + if (sopass_change) + fprintf(stderr, " not setting sopass\n"); + } + } + + if (msglvl_changed) { + struct ethtool_value edata; + + edata.cmd = ETHTOOL_GMSGLVL; + err = send_ioctl(ctx, &edata); + if (err < 0) { + perror("Cannot get msglvl"); + } else { + edata.cmd = ETHTOOL_SMSGLVL; + edata.data = ((edata.data & ~msglvl_mask) | + msglvl_wanted); + err = send_ioctl(ctx, &edata); + if (err < 0) + perror("Cannot set new msglvl"); + } + } + + return 0; +} + +static int do_gregs(struct cmd_context *ctx) +{ + int gregs_changed = 0; + int gregs_dump_raw = 0; + int gregs_dump_hex = 0; + char *gregs_dump_file = NULL; + struct cmdline_info cmdline_gregs[] = { + { + .name = "raw", + .type = CMDL_BOOL, + .wanted_val = &gregs_dump_raw, + }, + { + .name = "hex", + .type = CMDL_BOOL, + .wanted_val = &gregs_dump_hex, + }, + { + .name = "file", + .type = CMDL_STR, + .wanted_val = &gregs_dump_file, + }, + }; + int err; + struct ethtool_drvinfo drvinfo; + struct ethtool_regs *regs; + + parse_generic_cmdline(ctx, &gregs_changed, + cmdline_gregs, ARRAY_SIZE(cmdline_gregs)); + + drvinfo.cmd = ETHTOOL_GDRVINFO; + err = send_ioctl(ctx, &drvinfo); + if (err < 0) { + perror("Cannot get driver information"); + return 72; + } + + regs = calloc(1, sizeof(*regs)+drvinfo.regdump_len); + if (!regs) { + perror("Cannot allocate memory for register dump"); + return 73; + } + regs->cmd = ETHTOOL_GREGS; + regs->len = drvinfo.regdump_len; + err = send_ioctl(ctx, regs); + if (err < 0) { + perror("Cannot get register dump"); + free(regs); + return 74; + } + + if (!gregs_dump_raw && gregs_dump_file != NULL) { + /* overwrite reg values from file dump */ + FILE *f = fopen(gregs_dump_file, "r"); + struct ethtool_regs *nregs; + struct stat st; + size_t nread; + + if (!f || fstat(fileno(f), &st) < 0) { + fprintf(stderr, "Can't open '%s': %s\n", + gregs_dump_file, strerror(errno)); + if (f) + fclose(f); + free(regs); + return 75; + } + + nregs = realloc(regs, sizeof(*regs) + st.st_size); + if (!nregs) { + perror("Cannot allocate memory for register dump"); + free(regs); /* was not freed by realloc */ + return 73; + } + regs = nregs; + regs->len = st.st_size; + nread = fread(regs->data, regs->len, 1, f); + fclose(f); + if (nread != 1) { + free(regs); + return 75; + } + } + + if (dump_regs(gregs_dump_raw, gregs_dump_hex, + &drvinfo, regs) < 0) { + fprintf(stderr, "Cannot dump registers\n"); + free(regs); + return 75; + } + free(regs); + + return 0; +} + +static int do_nway_rst(struct cmd_context *ctx) +{ + struct ethtool_value edata; + int err; + + if (ctx->argc != 0) + exit_bad_args(); + + edata.cmd = ETHTOOL_NWAY_RST; + err = send_ioctl(ctx, &edata); + if (err < 0) + perror("Cannot restart autonegotiation"); + + return err; +} + +static int do_geeprom(struct cmd_context *ctx) +{ + int geeprom_changed = 0; + int geeprom_dump_raw = 0; + u32 geeprom_offset = 0; + u32 geeprom_length = 0; + int geeprom_length_seen = 0; + struct cmdline_info cmdline_geeprom[] = { + { + .name = "offset", + .type = CMDL_U32, + .wanted_val = &geeprom_offset, + }, + { + .name = "length", + .type = CMDL_U32, + .wanted_val = &geeprom_length, + .seen_val = &geeprom_length_seen, + }, + { + .name = "raw", + .type = CMDL_BOOL, + .wanted_val = &geeprom_dump_raw, + }, + }; + int err; + struct ethtool_drvinfo drvinfo; + struct ethtool_eeprom *eeprom; + + parse_generic_cmdline(ctx, &geeprom_changed, + cmdline_geeprom, ARRAY_SIZE(cmdline_geeprom)); + + drvinfo.cmd = ETHTOOL_GDRVINFO; + err = send_ioctl(ctx, &drvinfo); + if (err < 0) { + perror("Cannot get driver information"); + return 74; + } + + if (!geeprom_length_seen) + geeprom_length = drvinfo.eedump_len; + + if (drvinfo.eedump_len < geeprom_offset + geeprom_length) + geeprom_length = drvinfo.eedump_len - geeprom_offset; + + eeprom = calloc(1, sizeof(*eeprom)+geeprom_length); + if (!eeprom) { + perror("Cannot allocate memory for EEPROM data"); + return 75; + } + eeprom->cmd = ETHTOOL_GEEPROM; + eeprom->len = geeprom_length; + eeprom->offset = geeprom_offset; + err = send_ioctl(ctx, eeprom); + if (err < 0) { + perror("Cannot get EEPROM data"); + free(eeprom); + return 74; + } + err = dump_eeprom(geeprom_dump_raw, &drvinfo, eeprom); + free(eeprom); + + return err; +} + +static int do_seeprom(struct cmd_context *ctx) +{ + int seeprom_changed = 0; + u32 seeprom_magic = 0; + u32 seeprom_length = 0; + u32 seeprom_offset = 0; + u8 seeprom_value = 0; + int seeprom_length_seen = 0; + int seeprom_value_seen = 0; + struct cmdline_info cmdline_seeprom[] = { + { + .name = "magic", + .type = CMDL_U32, + .wanted_val = &seeprom_magic, + }, + { + .name = "offset", + .type = CMDL_U32, + .wanted_val = &seeprom_offset, + }, + { + .name = "length", + .type = CMDL_U32, + .wanted_val = &seeprom_length, + .seen_val = &seeprom_length_seen, + }, + { + .name = "value", + .type = CMDL_U8, + .wanted_val = &seeprom_value, + .seen_val = &seeprom_value_seen, + }, + }; + int err; + struct ethtool_drvinfo drvinfo; + struct ethtool_eeprom *eeprom; + + parse_generic_cmdline(ctx, &seeprom_changed, + cmdline_seeprom, ARRAY_SIZE(cmdline_seeprom)); + + drvinfo.cmd = ETHTOOL_GDRVINFO; + err = send_ioctl(ctx, &drvinfo); + if (err < 0) { + perror("Cannot get driver information"); + return 74; + } + + if (seeprom_value_seen && !seeprom_length_seen) + seeprom_length = 1; + else if (!seeprom_length_seen) + seeprom_length = drvinfo.eedump_len; + + if (seeprom_value_seen && (seeprom_length != 1)) { + fprintf(stderr, "value requires length 1\n"); + return 1; + } + + if (drvinfo.eedump_len < seeprom_offset + seeprom_length) { + fprintf(stderr, "offset & length out of bounds\n"); + return 1; + } + + eeprom = calloc(1, sizeof(*eeprom)+seeprom_length); + if (!eeprom) { + perror("Cannot allocate memory for EEPROM data"); + return 75; + } + + eeprom->cmd = ETHTOOL_SEEPROM; + eeprom->len = seeprom_length; + eeprom->offset = seeprom_offset; + eeprom->magic = seeprom_magic; + eeprom->data[0] = seeprom_value; + + /* Multi-byte write: read input from stdin */ + if (!seeprom_value_seen) { + if (fread(eeprom->data, eeprom->len, 1, stdin) != 1) { + fprintf(stderr, "not enough data from stdin\n"); + free(eeprom); + return 75; + } + if ((fgetc(stdin) != EOF) || !feof(stdin)) { + fprintf(stderr, "too much data from stdin\n"); + free(eeprom); + return 75; + } + } + + err = send_ioctl(ctx, eeprom); + if (err < 0) { + perror("Cannot set EEPROM data"); + err = 87; + } + free(eeprom); + + return err; +} + +static int do_test(struct cmd_context *ctx) +{ + enum { + ONLINE = 0, + OFFLINE, + EXTERNAL_LB, + } test_type; + int err; + struct ethtool_test *test; + struct ethtool_gstrings *strings; + + if (ctx->argc > 1) + exit_bad_args(); + if (ctx->argc == 1) { + if (!strcmp(ctx->argp[0], "online")) + test_type = ONLINE; + else if (!strcmp(*ctx->argp, "offline")) + test_type = OFFLINE; + else if (!strcmp(*ctx->argp, "external_lb")) + test_type = EXTERNAL_LB; + else + exit_bad_args(); + } else { + test_type = OFFLINE; + } + + strings = get_stringset(ctx, ETH_SS_TEST, + offsetof(struct ethtool_drvinfo, testinfo_len), + 1); + if (!strings) { + perror("Cannot get strings"); + return 74; + } + + test = calloc(1, sizeof(*test) + strings->len * sizeof(u64)); + if (!test) { + perror("Cannot allocate memory for test info"); + free(strings); + return 73; + } + memset(test->data, 0, strings->len * sizeof(u64)); + test->cmd = ETHTOOL_TEST; + test->len = strings->len; + if (test_type == EXTERNAL_LB) + test->flags = (ETH_TEST_FL_OFFLINE | ETH_TEST_FL_EXTERNAL_LB); + else if (test_type == OFFLINE) + test->flags = ETH_TEST_FL_OFFLINE; + else + test->flags = 0; + err = send_ioctl(ctx, test); + if (err < 0) { + perror("Cannot test"); + free(test); + free(strings); + return 74; + } + + err = dump_test(test, strings); + free(test); + free(strings); + + return err; +} + +static int do_phys_id(struct cmd_context *ctx) +{ + int err; + struct ethtool_value edata; + int phys_id_time; + + if (ctx->argc > 1) + exit_bad_args(); + if (ctx->argc == 1) + phys_id_time = get_int(*ctx->argp, 0); + else + phys_id_time = 0; + + edata.cmd = ETHTOOL_PHYS_ID; + edata.data = phys_id_time; + err = send_ioctl(ctx, &edata); + if (err < 0) + perror("Cannot identify NIC"); + + return err; +} + +static int do_gstats(struct cmd_context *ctx, int cmd, int stringset, + const char *name) +{ + struct ethtool_gstrings *strings; + struct ethtool_stats *stats; + unsigned int n_stats, sz_stats, i; + int err; + + if (ctx->argc != 0) + exit_bad_args(); + + strings = get_stringset(ctx, stringset, + offsetof(struct ethtool_drvinfo, n_stats), + 0); + if (!strings) { + perror("Cannot get stats strings information"); + return 96; + } + + n_stats = strings->len; + if (n_stats < 1) { + fprintf(stderr, "no stats available\n"); + free(strings); + return 94; + } + + sz_stats = n_stats * sizeof(u64); + + stats = calloc(1, sz_stats + sizeof(struct ethtool_stats)); + if (!stats) { + fprintf(stderr, "no memory available\n"); + free(strings); + return 95; + } + + stats->cmd = cmd; + stats->n_stats = n_stats; + err = send_ioctl(ctx, stats); + if (err < 0) { + perror("Cannot get stats information"); + free(strings); + free(stats); + return 97; + } + + /* todo - pretty-print the strings per-driver */ + fprintf(stdout, "%s statistics:\n", name); + for (i = 0; i < n_stats; i++) { + fprintf(stdout, " %.*s: %llu\n", + ETH_GSTRING_LEN, + &strings->data[i * ETH_GSTRING_LEN], + stats->data[i]); + } + free(strings); + free(stats); + + return 0; +} + +static int do_gnicstats(struct cmd_context *ctx) +{ + return do_gstats(ctx, ETHTOOL_GSTATS, ETH_SS_STATS, "NIC"); +} + +static int do_gphystats(struct cmd_context *ctx) +{ + return do_gstats(ctx, ETHTOOL_GPHYSTATS, ETH_SS_PHY_STATS, "PHY"); +} + +static int do_srxntuple(struct cmd_context *ctx, + struct ethtool_rx_flow_spec *rx_rule_fs); + +static int do_srxclass(struct cmd_context *ctx) +{ + int err; + + if (ctx->argc < 2) + exit_bad_args(); + + if (!strcmp(ctx->argp[0], "rx-flow-hash")) { + int rx_fhash_set; + u32 rx_fhash_val; + struct ethtool_rxnfc nfccmd; + bool flow_rss = false; + + if (ctx->argc == 5) { + if (strcmp(ctx->argp[3], "context")) + exit_bad_args(); + flow_rss = true; + nfccmd.rss_context = get_u32(ctx->argp[4], 0); + } else if (ctx->argc != 3) { + exit_bad_args(); + } + rx_fhash_set = rxflow_str_to_type(ctx->argp[1]); + if (!rx_fhash_set) + exit_bad_args(); + if (parse_rxfhashopts(ctx->argp[2], &rx_fhash_val) < 0) + exit_bad_args(); + + nfccmd.cmd = ETHTOOL_SRXFH; + nfccmd.flow_type = rx_fhash_set; + nfccmd.data = rx_fhash_val; + if (flow_rss) + nfccmd.flow_type |= FLOW_RSS; + + err = send_ioctl(ctx, &nfccmd); + if (err < 0) + perror("Cannot change RX network flow hashing options"); + } else if (!strcmp(ctx->argp[0], "flow-type")) { + struct ethtool_rx_flow_spec rx_rule_fs; + __u32 rss_context = 0; + + ctx->argc--; + ctx->argp++; + if (rxclass_parse_ruleopts(ctx, &rx_rule_fs, &rss_context) < 0) + exit_bad_args(); + + /* attempt to add rule via N-tuple specifier */ + err = do_srxntuple(ctx, &rx_rule_fs); + if (!err) + return 0; + + /* attempt to add rule via network flow classifier */ + err = rxclass_rule_ins(ctx, &rx_rule_fs, rss_context); + if (err < 0) { + fprintf(stderr, "Cannot insert" + " classification rule\n"); + return 1; + } + } else if (!strcmp(ctx->argp[0], "delete")) { + int rx_class_rule_del = + get_uint_range(ctx->argp[1], 0, INT_MAX); + + err = rxclass_rule_del(ctx, rx_class_rule_del); + + if (err < 0) { + fprintf(stderr, "Cannot delete" + " classification rule\n"); + return 1; + } + } else { + exit_bad_args(); + } + + return 0; +} + +static int do_grxclass(struct cmd_context *ctx) +{ + struct ethtool_rxnfc nfccmd; + int err; + + if (ctx->argc > 0 && !strcmp(ctx->argp[0], "rx-flow-hash")) { + int rx_fhash_get; + bool flow_rss = false; + + if (ctx->argc == 4) { + if (strcmp(ctx->argp[2], "context")) + exit_bad_args(); + flow_rss = true; + nfccmd.rss_context = get_u32(ctx->argp[3], 0); + } else if (ctx->argc != 2) { + exit_bad_args(); + } + + rx_fhash_get = rxflow_str_to_type(ctx->argp[1]); + if (!rx_fhash_get) + exit_bad_args(); + + nfccmd.cmd = ETHTOOL_GRXFH; + nfccmd.flow_type = rx_fhash_get; + if (flow_rss) + nfccmd.flow_type |= FLOW_RSS; + err = send_ioctl(ctx, &nfccmd); + if (err < 0) { + perror("Cannot get RX network flow hashing options"); + } else { + if (flow_rss) + fprintf(stdout, "For RSS context %u:\n", + nfccmd.rss_context); + dump_rxfhash(rx_fhash_get, nfccmd.data); + } + } else if (ctx->argc == 2 && !strcmp(ctx->argp[0], "rule")) { + int rx_class_rule_get = + get_uint_range(ctx->argp[1], 0, INT_MAX); + + err = rxclass_rule_get(ctx, rx_class_rule_get); + if (err < 0) + fprintf(stderr, "Cannot get RX classification rule\n"); + } else if (ctx->argc == 0) { + nfccmd.cmd = ETHTOOL_GRXRINGS; + err = send_ioctl(ctx, &nfccmd); + if (err < 0) + perror("Cannot get RX rings"); + else + fprintf(stdout, "%d RX rings available\n", + (int)nfccmd.data); + + err = rxclass_rule_getall(ctx); + if (err < 0) + fprintf(stderr, "RX classification rule retrieval failed\n"); + + } else { + exit_bad_args(); + } + + return err ? 1 : 0; +} + +static void print_indir_table(struct cmd_context *ctx, + struct ethtool_rxnfc *ring_count, + u32 indir_size, u32 *indir) +{ + u32 i; + + printf("RX flow hash indirection table for %s with %llu RX ring(s):\n", + ctx->devname, ring_count->data); + + if (!indir_size) + printf("Operation not supported\n"); + + for (i = 0; i < indir_size; i++) { + if (i % 8 == 0) + printf("%5u: ", i); + printf(" %5u", indir[i]); + if (i % 8 == 7 || i == indir_size - 1) + fputc('\n', stdout); + } +} + +static int do_grxfhindir(struct cmd_context *ctx, + struct ethtool_rxnfc *ring_count) +{ + struct ethtool_rxfh_indir indir_head; + struct ethtool_rxfh_indir *indir; + int err; + + indir_head.cmd = ETHTOOL_GRXFHINDIR; + indir_head.size = 0; + err = send_ioctl(ctx, &indir_head); + if (err < 0) { + perror("Cannot get RX flow hash indirection table size"); + return 1; + } + + indir = malloc(sizeof(*indir) + + indir_head.size * sizeof(*indir->ring_index)); + if (!indir) { + perror("Cannot allocate memory for indirection table"); + return 1; + } + + indir->cmd = ETHTOOL_GRXFHINDIR; + indir->size = indir_head.size; + err = send_ioctl(ctx, indir); + if (err < 0) { + perror("Cannot get RX flow hash indirection table"); + free(indir); + return 1; + } + + print_indir_table(ctx, ring_count, indir->size, indir->ring_index); + + free(indir); + return 0; +} + +static int do_grxfh(struct cmd_context *ctx) +{ + struct ethtool_gstrings *hfuncs = NULL; + struct ethtool_rxfh rss_head = {0}; + struct ethtool_rxnfc ring_count; + struct ethtool_rxfh *rss; + u32 rss_context = 0; + u32 i, indir_bytes; + unsigned int arg_num = 0; + char *hkey; + int err; + + while (arg_num < ctx->argc) { + if (!strcmp(ctx->argp[arg_num], "context")) { + ++arg_num; + rss_context = get_int_range(ctx->argp[arg_num], 0, 1, + ETH_RXFH_CONTEXT_ALLOC - 1); + ++arg_num; + } else { + exit_bad_args(); + } + } + + ring_count.cmd = ETHTOOL_GRXRINGS; + err = send_ioctl(ctx, &ring_count); + if (err < 0) { + perror("Cannot get RX ring count"); + return 1; + } + + rss_head.cmd = ETHTOOL_GRSSH; + rss_head.rss_context = rss_context; + err = send_ioctl(ctx, &rss_head); + if (err < 0 && errno == EOPNOTSUPP && !rss_context) { + return do_grxfhindir(ctx, &ring_count); + } else if (err < 0) { + perror("Cannot get RX flow hash indir size and/or key size"); + return 1; + } + + rss = calloc(1, sizeof(*rss) + + rss_head.indir_size * sizeof(rss_head.rss_config[0]) + + rss_head.key_size); + if (!rss) { + perror("Cannot allocate memory for RX flow hash config"); + return 1; + } + + rss->cmd = ETHTOOL_GRSSH; + rss->rss_context = rss_context; + rss->indir_size = rss_head.indir_size; + rss->key_size = rss_head.key_size; + err = send_ioctl(ctx, rss); + if (err < 0) { + perror("Cannot get RX flow hash configuration"); + free(rss); + return 1; + } + + print_indir_table(ctx, &ring_count, rss->indir_size, rss->rss_config); + + indir_bytes = rss->indir_size * sizeof(rss->rss_config[0]); + hkey = ((char *)rss->rss_config + indir_bytes); + + printf("RSS hash key:\n"); + if (!rss->key_size) + printf("Operation not supported\n"); + + for (i = 0; i < rss->key_size; i++) { + if (i == (rss->key_size - 1)) + printf("%02x\n", (u8) hkey[i]); + else + printf("%02x:", (u8) hkey[i]); + } + + printf("RSS hash function:\n"); + if (!rss->hfunc) { + printf(" Operation not supported\n"); + goto out; + } + + hfuncs = get_stringset(ctx, ETH_SS_RSS_HASH_FUNCS, 0, 1); + if (!hfuncs) { + perror("Cannot get hash functions names"); + free(rss); + return 1; + } + + for (i = 0; i < hfuncs->len; i++) + printf(" %s: %s\n", + (const char *)hfuncs->data + i * ETH_GSTRING_LEN, + (rss->hfunc & (1 << i)) ? "on" : "off"); + +out: + free(hfuncs); + free(rss); + return 0; +} + +static int fill_indir_table(u32 *indir_size, u32 *indir, int rxfhindir_default, + int rxfhindir_start, int rxfhindir_equal, + char **rxfhindir_weight, u32 num_weights) +{ + u32 i; + + if (rxfhindir_equal) { + for (i = 0; i < *indir_size; i++) + indir[i] = rxfhindir_start + (i % rxfhindir_equal); + } else if (rxfhindir_weight) { + u32 j, weight, sum = 0, partial = 0; + + for (j = 0; j < num_weights; j++) { + weight = get_u32(rxfhindir_weight[j], 0); + sum += weight; + } + + if (sum == 0) { + fprintf(stderr, + "At least one weight must be non-zero\n"); + return 2; + } + + if (sum > *indir_size) { + fprintf(stderr, + "Total weight exceeds the size of the " + "indirection table\n"); + return 2; + } + + j = -1; + for (i = 0; i < *indir_size; i++) { + while (i >= (*indir_size) * partial / sum) { + j += 1; + weight = get_u32(rxfhindir_weight[j], 0); + partial += weight; + } + indir[i] = rxfhindir_start + j; + } + } else if (rxfhindir_default) { + /* "*indir_size == 0" ==> reset indir to default */ + *indir_size = 0; + } else { + *indir_size = ETH_RXFH_INDIR_NO_CHANGE; + } + + return 0; +} + +static int do_srxfhindir(struct cmd_context *ctx, int rxfhindir_default, + int rxfhindir_start, int rxfhindir_equal, + char **rxfhindir_weight, u32 num_weights) +{ + struct ethtool_rxfh_indir indir_head; + struct ethtool_rxfh_indir *indir; + int err; + + indir_head.cmd = ETHTOOL_GRXFHINDIR; + indir_head.size = 0; + err = send_ioctl(ctx, &indir_head); + if (err < 0) { + perror("Cannot get RX flow hash indirection table size"); + return 1; + } + + indir = malloc(sizeof(*indir) + + indir_head.size * sizeof(*indir->ring_index)); + + if (!indir) { + perror("Cannot allocate memory for indirection table"); + return 1; + } + + indir->cmd = ETHTOOL_SRXFHINDIR; + indir->size = indir_head.size; + + if (fill_indir_table(&indir->size, indir->ring_index, + rxfhindir_default, rxfhindir_start, + rxfhindir_equal, rxfhindir_weight, num_weights)) { + free(indir); + return 1; + } + + err = send_ioctl(ctx, indir); + if (err < 0) { + perror("Cannot set RX flow hash indirection table"); + free(indir); + return 1; + } + + free(indir); + return 0; +} + +static int do_srxfh(struct cmd_context *ctx) +{ + struct ethtool_rxfh rss_head = {0}; + struct ethtool_rxfh *rss = NULL; + struct ethtool_rxnfc ring_count; + int rxfhindir_equal = 0, rxfhindir_default = 0, rxfhindir_start = 0; + struct ethtool_gstrings *hfuncs = NULL; + char **rxfhindir_weight = NULL; + char *rxfhindir_key = NULL; + char *req_hfunc_name = NULL; + char *hfunc_name = NULL; + char *hkey = NULL; + int err = 0; + unsigned int i; + u32 arg_num = 0, indir_bytes = 0; + u32 req_hfunc = 0; + u32 entry_size = sizeof(rss_head.rss_config[0]); + u32 num_weights = 0; + u32 rss_context = 0; + int delete = 0; + + if (ctx->argc < 1) + exit_bad_args(); + + while (arg_num < ctx->argc) { + if (!strcmp(ctx->argp[arg_num], "equal")) { + ++arg_num; + rxfhindir_equal = get_int_range(ctx->argp[arg_num], + 0, 1, INT_MAX); + ++arg_num; + } else if (!strcmp(ctx->argp[arg_num], "start")) { + ++arg_num; + rxfhindir_start = get_int_range(ctx->argp[arg_num], + 0, 0, INT_MAX); + ++arg_num; + } else if (!strcmp(ctx->argp[arg_num], "weight")) { + ++arg_num; + rxfhindir_weight = ctx->argp + arg_num; + while (arg_num < ctx->argc && + isdigit((unsigned char)ctx->argp[arg_num][0])) { + ++arg_num; + ++num_weights; + } + if (!num_weights) + exit_bad_args(); + } else if (!strcmp(ctx->argp[arg_num], "hkey")) { + ++arg_num; + rxfhindir_key = ctx->argp[arg_num]; + if (!rxfhindir_key) + exit_bad_args(); + ++arg_num; + } else if (!strcmp(ctx->argp[arg_num], "default")) { + ++arg_num; + rxfhindir_default = 1; + } else if (!strcmp(ctx->argp[arg_num], "hfunc")) { + ++arg_num; + req_hfunc_name = ctx->argp[arg_num]; + if (!req_hfunc_name) + exit_bad_args(); + ++arg_num; + } else if (!strcmp(ctx->argp[arg_num], "context")) { + ++arg_num; + if(!strcmp(ctx->argp[arg_num], "new")) + rss_context = ETH_RXFH_CONTEXT_ALLOC; + else + rss_context = get_int_range( + ctx->argp[arg_num], 0, 1, + ETH_RXFH_CONTEXT_ALLOC - 1); + ++arg_num; + } else if (!strcmp(ctx->argp[arg_num], "delete")) { + ++arg_num; + delete = 1; + } else { + exit_bad_args(); + } + } + + if (rxfhindir_equal && rxfhindir_weight) { + fprintf(stderr, + "Equal and weight options are mutually exclusive\n"); + return 1; + } + + if (rxfhindir_equal && rxfhindir_default) { + fprintf(stderr, + "Equal and default options are mutually exclusive\n"); + return 1; + } + + if (rxfhindir_weight && rxfhindir_default) { + fprintf(stderr, + "Weight and default options are mutually exclusive\n"); + return 1; + } + + if (rxfhindir_start && rxfhindir_default) { + fprintf(stderr, + "Start and default options are mutually exclusive\n"); + return 1; + } + + if (rxfhindir_start && !(rxfhindir_equal || rxfhindir_weight)) { + fprintf(stderr, + "Start must be used with equal or weight options\n"); + return 1; + } + + if (rxfhindir_default && rss_context) { + fprintf(stderr, + "Default and context options are mutually exclusive\n"); + return 1; + } + + if (delete && !rss_context) { + fprintf(stderr, "Delete option requires context option\n"); + return 1; + } + + if (delete && rxfhindir_weight) { + fprintf(stderr, + "Delete and weight options are mutually exclusive\n"); + return 1; + } + + if (delete && rxfhindir_equal) { + fprintf(stderr, + "Delete and equal options are mutually exclusive\n"); + return 1; + } + + if (delete && rxfhindir_default) { + fprintf(stderr, + "Delete and default options are mutually exclusive\n"); + return 1; + } + + if (delete && rxfhindir_key) { + fprintf(stderr, + "Delete and hkey options are mutually exclusive\n"); + return 1; + } + + ring_count.cmd = ETHTOOL_GRXRINGS; + err = send_ioctl(ctx, &ring_count); + if (err < 0) { + perror("Cannot get RX ring count"); + return 1; + } + + rss_head.cmd = ETHTOOL_GRSSH; + err = send_ioctl(ctx, &rss_head); + if (err < 0 && errno == EOPNOTSUPP && !rxfhindir_key && + !req_hfunc_name && !rss_context) { + return do_srxfhindir(ctx, rxfhindir_default, rxfhindir_start, + rxfhindir_equal, rxfhindir_weight, + num_weights); + } else if (err < 0) { + perror("Cannot get RX flow hash indir size and key size"); + return 1; + } + + if (rxfhindir_key) { + err = parse_hkey(&hkey, rss_head.key_size, + rxfhindir_key); + if (err) + return err; + } + + if (rxfhindir_equal || rxfhindir_weight) + indir_bytes = rss_head.indir_size * entry_size; + + if (rss_head.hfunc && req_hfunc_name) { + hfuncs = get_stringset(ctx, ETH_SS_RSS_HASH_FUNCS, 0, 1); + if (!hfuncs) { + perror("Cannot get hash functions names"); + err = 1; + goto free; + } + + for (i = 0; i < hfuncs->len && !req_hfunc ; i++) { + hfunc_name = (char *)(hfuncs->data + + i * ETH_GSTRING_LEN); + if (!strncmp(hfunc_name, req_hfunc_name, + ETH_GSTRING_LEN)) + req_hfunc = (u32)1 << i; + } + + if (!req_hfunc) { + fprintf(stderr, + "Unknown hash function: %s\n", req_hfunc_name); + err = 1; + goto free; + } + } + + rss = calloc(1, sizeof(*rss) + indir_bytes + rss_head.key_size); + if (!rss) { + perror("Cannot allocate memory for RX flow hash config"); + err = 1; + goto free; + } + rss->cmd = ETHTOOL_SRSSH; + rss->rss_context = rss_context; + rss->hfunc = req_hfunc; + if (delete) { + rss->indir_size = rss->key_size = 0; + } else { + rss->indir_size = rss_head.indir_size; + rss->key_size = rss_head.key_size; + if (fill_indir_table(&rss->indir_size, rss->rss_config, + rxfhindir_default, rxfhindir_start, + rxfhindir_equal, rxfhindir_weight, + num_weights)) { + err = 1; + goto free; + } + } + + if (hkey) + memcpy((char *)rss->rss_config + indir_bytes, + hkey, rss->key_size); + else + rss->key_size = 0; + + err = send_ioctl(ctx, rss); + if (err < 0) { + perror("Cannot set RX flow hash configuration"); + err = 1; + } else if (rss_context == ETH_RXFH_CONTEXT_ALLOC) { + printf("New RSS context is %d\n", rss->rss_context); + } + +free: + free(hkey); + free(rss); + free(hfuncs); + return err; +} + +static int do_flash(struct cmd_context *ctx) +{ + char *flash_file; + int flash_region; + struct ethtool_flash efl; + int err; + + if (ctx->argc < 1 || ctx->argc > 2) + exit_bad_args(); + flash_file = ctx->argp[0]; + if (ctx->argc == 2) { + flash_region = strtol(ctx->argp[1], NULL, 0); + if (flash_region < 0) + exit_bad_args(); + } else { + flash_region = -1; + } + + if (strlen(flash_file) > ETHTOOL_FLASH_MAX_FILENAME - 1) { + fprintf(stdout, "Filename too long\n"); + return 99; + } + + efl.cmd = ETHTOOL_FLASHDEV; + strcpy(efl.data, flash_file); + + if (flash_region < 0) + efl.region = ETHTOOL_FLASH_ALL_REGIONS; + else + efl.region = flash_region; + + err = send_ioctl(ctx, &efl); + if (err < 0) + perror("Flashing failed"); + + return err; +} + +static int do_permaddr(struct cmd_context *ctx) +{ + unsigned int i; + int err; + struct ethtool_perm_addr *epaddr; + + epaddr = malloc(sizeof(struct ethtool_perm_addr) + MAX_ADDR_LEN); + if (!epaddr) { + perror("Cannot allocate memory for operation"); + return 1; + } + + epaddr->cmd = ETHTOOL_GPERMADDR; + epaddr->size = MAX_ADDR_LEN; + + err = send_ioctl(ctx, epaddr); + if (err < 0) + perror("Cannot read permanent address"); + else { + printf("Permanent address:"); + for (i = 0; i < epaddr->size; i++) + printf("%c%02x", (i == 0) ? ' ' : ':', + epaddr->data[i]); + printf("\n"); + } + free(epaddr); + + return err; +} + +static bool flow_type_is_ntuple_supported(__u32 flow_type) +{ + switch (flow_type) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + case SCTP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case IPV4_USER_FLOW: + case ETHER_FLOW: + return true; + default: + return false; + } +} + +static int flow_spec_to_ntuple(struct ethtool_rx_flow_spec *fsp, + struct ethtool_rx_ntuple_flow_spec *ntuple) +{ + size_t i; + + /* verify location is not specified */ + if (fsp->location != RX_CLS_LOC_ANY) + return -1; + + /* destination MAC address in L3/L4 rules is not supported by ntuple */ + if (fsp->flow_type & FLOW_MAC_EXT) + return -1; + + /* verify ring cookie can transfer to action */ + if (fsp->ring_cookie > INT_MAX && fsp->ring_cookie < (u64)(-2)) + return -1; + + /* verify only one field is setting data field */ + if ((fsp->flow_type & FLOW_EXT) && + (fsp->m_ext.data[0] || fsp->m_ext.data[1]) && + fsp->m_ext.vlan_etype) + return -1; + + /* IPv6 flow types are not supported by ntuple */ + if (!flow_type_is_ntuple_supported(fsp->flow_type & ~FLOW_EXT)) + return -1; + + /* Set entire ntuple to ~0 to guarantee all masks are set */ + memset(ntuple, ~0, sizeof(*ntuple)); + + /* set non-filter values */ + ntuple->flow_type = fsp->flow_type; + ntuple->action = fsp->ring_cookie; + + /* + * Copy over header union, they are identical in layout however + * the ntuple union contains additional padding on the end + */ + memcpy(&ntuple->h_u, &fsp->h_u, sizeof(fsp->h_u)); + + /* + * The same rule mentioned above applies to the mask union. However, + * in addition we need to invert the mask bits to match the ntuple + * mask which is 1 for masked, versus 0 for masked as seen in nfc. + */ + memcpy(&ntuple->m_u, &fsp->m_u, sizeof(fsp->m_u)); + for (i = 0; i < sizeof(fsp->m_u); i++) + ntuple->m_u.hdata[i] ^= 0xFF; + + /* copy extended fields */ + if (fsp->flow_type & FLOW_EXT) { + ntuple->vlan_tag = + ntohs(fsp->h_ext.vlan_tci); + ntuple->vlan_tag_mask = + ~ntohs(fsp->m_ext.vlan_tci); + if (fsp->m_ext.vlan_etype) { + /* + * vlan_etype and user data are mutually exclusive + * in ntuple configuration as they occupy the same + * space. + */ + if (fsp->m_ext.data[0] || fsp->m_ext.data[1]) + return -1; + ntuple->data = + ntohl(fsp->h_ext.vlan_etype); + ntuple->data_mask = + ~(u64)ntohl(fsp->m_ext.vlan_etype); + } else { + ntuple->data = + (u64)ntohl(fsp->h_ext.data[0]) << 32; + ntuple->data |= + (u64)ntohl(fsp->h_ext.data[1]); + ntuple->data_mask = + (u64)ntohl(~fsp->m_ext.data[0]) << 32; + ntuple->data_mask |= + (u64)ntohl(~fsp->m_ext.data[1]); + } + } + + /* Mask out the extended bit, because ntuple does not know it! */ + ntuple->flow_type &= ~FLOW_EXT; + + return 0; +} + +static int do_srxntuple(struct cmd_context *ctx, + struct ethtool_rx_flow_spec *rx_rule_fs) +{ + struct ethtool_rx_ntuple ntuplecmd; + struct ethtool_value eval; + int err; + + /* attempt to convert the flow classifier to an ntuple classifier */ + err = flow_spec_to_ntuple(rx_rule_fs, &ntuplecmd.fs); + if (err) + return -1; + + /* + * Check to see if the flag is set for N-tuple, this allows + * us to avoid the possible EINVAL response for the N-tuple + * flag not being set on the device + */ + eval.cmd = ETHTOOL_GFLAGS; + err = send_ioctl(ctx, &eval); + if (err || !(eval.data & ETH_FLAG_NTUPLE)) + return -1; + + /* send rule via N-tuple */ + ntuplecmd.cmd = ETHTOOL_SRXNTUPLE; + err = send_ioctl(ctx, &ntuplecmd); + + /* + * Display error only if response is something other than op not + * supported. It is possible that the interface uses the network + * flow classifier interface instead of N-tuple. + */ + if (err < 0) { + if (errno != EOPNOTSUPP) + perror("Cannot add new rule via N-tuple"); + return -1; + } + + return 0; +} + +static int do_writefwdump(struct ethtool_dump *dump, const char *dump_file) +{ + int err = 0; + FILE *f; + size_t bytes; + + f = fopen(dump_file, "wb+"); + + if (!f) { + fprintf(stderr, "Can't open file %s: %s\n", + dump_file, strerror(errno)); + return 1; + } + bytes = fwrite(dump->data, 1, dump->len, f); + if (bytes != dump->len) { + fprintf(stderr, "Can not write all of dump data\n"); + err = 1; + } + if (fclose(f)) { + fprintf(stderr, "Can't close file %s: %s\n", + dump_file, strerror(errno)); + err = 1; + } + return err; +} + +static int do_getfwdump(struct cmd_context *ctx) +{ + u32 dump_flag; + char *dump_file; + int err; + struct ethtool_dump edata; + struct ethtool_dump *data; + + if (ctx->argc == 2 && !strcmp(ctx->argp[0], "data")) { + dump_flag = ETHTOOL_GET_DUMP_DATA; + dump_file = ctx->argp[1]; + } else if (ctx->argc == 0) { + dump_flag = 0; + dump_file = NULL; + } else { + exit_bad_args(); + } + + edata.cmd = ETHTOOL_GET_DUMP_FLAG; + + err = send_ioctl(ctx, &edata); + if (err < 0) { + perror("Can not get dump level"); + return 1; + } + if (dump_flag != ETHTOOL_GET_DUMP_DATA) { + fprintf(stdout, "flag: %u, version: %u, length: %u\n", + edata.flag, edata.version, edata.len); + return 0; + } + data = calloc(1, offsetof(struct ethtool_dump, data) + edata.len); + if (!data) { + perror("Can not allocate enough memory"); + return 1; + } + data->cmd = ETHTOOL_GET_DUMP_DATA; + data->len = edata.len; + err = send_ioctl(ctx, data); + if (err < 0) { + perror("Can not get dump data"); + err = 1; + goto free; + } + err = do_writefwdump(data, dump_file); +free: + free(data); + return err; +} + +static int do_setfwdump(struct cmd_context *ctx) +{ + u32 dump_flag; + int err; + struct ethtool_dump dump; + + if (ctx->argc != 1) + exit_bad_args(); + dump_flag = get_u32(ctx->argp[0], 0); + + dump.cmd = ETHTOOL_SET_DUMP; + dump.flag = dump_flag; + err = send_ioctl(ctx, &dump); + if (err < 0) { + perror("Can not set dump level"); + return 1; + } + return 0; +} + +static int do_gprivflags(struct cmd_context *ctx) +{ + struct ethtool_gstrings *strings; + struct ethtool_value flags; + unsigned int i; + int max_len = 0, cur_len, rc; + + if (ctx->argc != 0) + exit_bad_args(); + + strings = get_stringset(ctx, ETH_SS_PRIV_FLAGS, + offsetof(struct ethtool_drvinfo, n_priv_flags), + 1); + if (!strings) { + perror("Cannot get private flag names"); + return 1; + } + if (strings->len == 0) { + fprintf(stderr, "No private flags defined\n"); + rc = 1; + goto err; + } + if (strings->len > 32) { + /* ETHTOOL_GPFLAGS can only cover 32 flags */ + fprintf(stderr, "Only showing first 32 private flags\n"); + strings->len = 32; + } + + flags.cmd = ETHTOOL_GPFLAGS; + if (send_ioctl(ctx, &flags)) { + perror("Cannot get private flags"); + rc = 1; + goto err; + } + + /* Find longest string and align all strings accordingly */ + for (i = 0; i < strings->len; i++) { + cur_len = strlen((const char *)strings->data + + i * ETH_GSTRING_LEN); + if (cur_len > max_len) + max_len = cur_len; + } + + printf("Private flags for %s:\n", ctx->devname); + for (i = 0; i < strings->len; i++) + printf("%-*s: %s\n", + max_len, + (const char *)strings->data + i * ETH_GSTRING_LEN, + (flags.data & (1U << i)) ? "on" : "off"); + + rc = 0; + +err: + free(strings); + return rc; +} + +static int do_sprivflags(struct cmd_context *ctx) +{ + struct ethtool_gstrings *strings; + struct cmdline_info *cmdline; + struct ethtool_value flags; + u32 wanted_flags = 0, seen_flags = 0; + int any_changed, rc; + unsigned int i; + + strings = get_stringset(ctx, ETH_SS_PRIV_FLAGS, + offsetof(struct ethtool_drvinfo, n_priv_flags), + 1); + if (!strings) { + perror("Cannot get private flag names"); + return 1; + } + if (strings->len == 0) { + fprintf(stderr, "No private flags defined\n"); + rc = 1; + goto err; + } + if (strings->len > 32) { + /* ETHTOOL_{G,S}PFLAGS can only cover 32 flags */ + fprintf(stderr, "Only setting first 32 private flags\n"); + strings->len = 32; + } + + cmdline = calloc(strings->len, sizeof(*cmdline)); + if (!cmdline) { + perror("Cannot parse arguments"); + rc = 1; + goto err; + } + for (i = 0; i < strings->len; i++) { + cmdline[i].name = ((const char *)strings->data + + i * ETH_GSTRING_LEN); + cmdline[i].type = CMDL_FLAG; + cmdline[i].wanted_val = &wanted_flags; + cmdline[i].flag_val = 1U << i; + cmdline[i].seen_val = &seen_flags; + } + parse_generic_cmdline(ctx, &any_changed, cmdline, strings->len); + free(cmdline); + + flags.cmd = ETHTOOL_GPFLAGS; + if (send_ioctl(ctx, &flags)) { + perror("Cannot get private flags"); + rc = 1; + goto err; + } + + flags.cmd = ETHTOOL_SPFLAGS; + flags.data = (flags.data & ~seen_flags) | wanted_flags; + if (send_ioctl(ctx, &flags)) { + perror("Cannot set private flags"); + rc = 1; + goto err; + } + + rc = 0; +err: + free(strings); + return rc; +} + +static int do_tsinfo(struct cmd_context *ctx) +{ + struct ethtool_ts_info info; + + if (ctx->argc != 0) + exit_bad_args(); + + fprintf(stdout, "Time stamping parameters for %s:\n", ctx->devname); + info.cmd = ETHTOOL_GET_TS_INFO; + if (send_ioctl(ctx, &info)) { + perror("Cannot get device time stamping settings"); + return -1; + } + dump_tsinfo(&info); + return 0; +} + +static int do_getmodule(struct cmd_context *ctx) +{ + struct ethtool_modinfo modinfo; + struct ethtool_eeprom *eeprom; + u32 geeprom_offset = 0; + u32 geeprom_length = 0; + int geeprom_changed = 0; + int geeprom_dump_raw = 0; + int geeprom_dump_hex = 0; + int geeprom_length_seen = 0; + int err; + + struct cmdline_info cmdline_geeprom[] = { + { + .name = "offset", + .type = CMDL_U32, + .wanted_val = &geeprom_offset, + }, + { + .name = "length", + .type = CMDL_U32, + .wanted_val = &geeprom_length, + .seen_val = &geeprom_length_seen, + }, + { + .name = "raw", + .type = CMDL_BOOL, + .wanted_val = &geeprom_dump_raw, + }, + { + .name = "hex", + .type = CMDL_BOOL, + .wanted_val = &geeprom_dump_hex, + }, + }; + + parse_generic_cmdline(ctx, &geeprom_changed, + cmdline_geeprom, ARRAY_SIZE(cmdline_geeprom)); + + if (geeprom_dump_raw && geeprom_dump_hex) { + printf("Hex and raw dump cannot be specified together\n"); + return 1; + } + + modinfo.cmd = ETHTOOL_GMODULEINFO; + err = send_ioctl(ctx, &modinfo); + if (err < 0) { + perror("Cannot get module EEPROM information"); + return 1; + } + + if (!geeprom_length_seen) + geeprom_length = modinfo.eeprom_len; + + if (modinfo.eeprom_len < geeprom_offset + geeprom_length) + geeprom_length = modinfo.eeprom_len - geeprom_offset; + + eeprom = calloc(1, sizeof(*eeprom)+geeprom_length); + if (!eeprom) { + perror("Cannot allocate memory for Module EEPROM data"); + return 1; + } + + eeprom->cmd = ETHTOOL_GMODULEEEPROM; + eeprom->len = geeprom_length; + eeprom->offset = geeprom_offset; + err = send_ioctl(ctx, eeprom); + if (err < 0) { + int saved_errno = errno; + + perror("Cannot get Module EEPROM data"); + if (saved_errno == ENODEV || saved_errno == EIO || + saved_errno == ENXIO) + fprintf(stderr, "SFP module not in cage?\n"); + free(eeprom); + return 1; + } + + /* + * SFF-8079 EEPROM layout contains the memory available at A0 address on + * the PHY EEPROM. + * SFF-8472 defines a virtual extension of the EEPROM, where the + * microcontroller on the SFP/SFP+ generates a page at the A2 address, + * which contains data relative to optical diagnostics. + * The current kernel implementation returns a blob, which contains: + * - ETH_MODULE_SFF_8079 => The A0 page only. + * - ETH_MODULE_SFF_8472 => The A0 and A2 page concatenated. + */ + if (geeprom_dump_raw) { + fwrite(eeprom->data, 1, eeprom->len, stdout); + } else { + if (eeprom->offset != 0 || + (eeprom->len != modinfo.eeprom_len)) { + geeprom_dump_hex = 1; + } else if (!geeprom_dump_hex) { + switch (modinfo.type) { +#ifdef ETHTOOL_ENABLE_PRETTY_DUMP + case ETH_MODULE_SFF_8079: + sff8079_show_all_ioctl(eeprom->data); + break; + case ETH_MODULE_SFF_8472: + sff8079_show_all_ioctl(eeprom->data); + sff8472_show_all(eeprom->data); + break; + case ETH_MODULE_SFF_8436: + case ETH_MODULE_SFF_8636: + sff8636_show_all_ioctl(eeprom->data, + modinfo.eeprom_len); + break; +#endif + default: + geeprom_dump_hex = 1; + break; + } + } + if (geeprom_dump_hex) + dump_hex(stdout, eeprom->data, + eeprom->len, eeprom->offset); + } + + free(eeprom); + + return 0; +} + +static int do_geee(struct cmd_context *ctx) +{ + struct ethtool_eee eeecmd; + + if (ctx->argc != 0) + exit_bad_args(); + + eeecmd.cmd = ETHTOOL_GEEE; + if (send_ioctl(ctx, &eeecmd)) { + perror("Cannot get EEE settings"); + return 1; + } + + fprintf(stdout, "EEE Settings for %s:\n", ctx->devname); + dump_eeecmd(&eeecmd); + + return 0; +} + +static int do_seee(struct cmd_context *ctx) +{ + int adv_c = -1, lpi_c = -1, lpi_time_c = -1, eee_c = -1; + int change = -1, change2 = 0; + struct ethtool_eee eeecmd; + struct cmdline_info cmdline_eee[] = { + { + .name = "advertise", + .type = CMDL_U32, + .wanted_val = &adv_c, + .ioctl_val = &eeecmd.advertised, + }, + { + .name = "tx-lpi", + .type = CMDL_BOOL, + .wanted_val = &lpi_c, + .ioctl_val = &eeecmd.tx_lpi_enabled, + }, + { + .name = "tx-timer", + .type = CMDL_U32, + .wanted_val = &lpi_time_c, + .ioctl_val = &eeecmd.tx_lpi_timer, + }, + { + .name = "eee", + .type = CMDL_BOOL, + .wanted_val = &eee_c, + .ioctl_val = &eeecmd.eee_enabled, + }, + }; + + if (ctx->argc == 0) + exit_bad_args(); + + parse_generic_cmdline(ctx, &change, cmdline_eee, + ARRAY_SIZE(cmdline_eee)); + + eeecmd.cmd = ETHTOOL_GEEE; + if (send_ioctl(ctx, &eeecmd)) { + perror("Cannot get EEE settings"); + return 1; + } + + do_generic_set(cmdline_eee, ARRAY_SIZE(cmdline_eee), &change2); + + if (change2) { + eeecmd.cmd = ETHTOOL_SEEE; + if (send_ioctl(ctx, &eeecmd)) { + perror("Cannot set EEE settings"); + return 1; + } + } + + return 0; +} + +/* copy of net/ethtool/common.c */ +char +tunable_strings[__ETHTOOL_TUNABLE_COUNT][ETH_GSTRING_LEN] = { + [ETHTOOL_ID_UNSPEC] = "Unspec", + [ETHTOOL_RX_COPYBREAK] = "rx-copybreak", + [ETHTOOL_TX_COPYBREAK] = "tx-copybreak", + [ETHTOOL_TX_COPYBREAK_BUF_SIZE] = "tx-buf-size", + [ETHTOOL_PFC_PREVENTION_TOUT] = "pfc-prevention-tout", +}; + +union ethtool_tunable_info_val { + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + int8_t s8; + int16_t s16; + int32_t s32; + int64_t s64; +}; + +struct ethtool_tunable_info { + enum tunable_id t_id; + enum tunable_type_id t_type_id; + size_t size; + cmdline_type_t type; + union ethtool_tunable_info_val wanted; + int seen; +}; + +static struct ethtool_tunable_info tunables_info[] = { + { .t_id = ETHTOOL_RX_COPYBREAK, + .t_type_id = ETHTOOL_TUNABLE_U32, + .size = sizeof(u32), + .type = CMDL_U32, + }, + { .t_id = ETHTOOL_TX_COPYBREAK, + .t_type_id = ETHTOOL_TUNABLE_U32, + .size = sizeof(u32), + .type = CMDL_U32, + }, + { .t_id = ETHTOOL_PFC_PREVENTION_TOUT, + .t_type_id = ETHTOOL_TUNABLE_U16, + .size = sizeof(u16), + .type = CMDL_U16, + }, + { .t_id = ETHTOOL_TX_COPYBREAK_BUF_SIZE, + .t_type_id = ETHTOOL_TUNABLE_U32, + .size = sizeof(u32), + .type = CMDL_U32, + }, +}; +#define TUNABLES_INFO_SIZE ARRAY_SIZE(tunables_info) + +static int do_stunable(struct cmd_context *ctx) +{ + struct cmdline_info cmdline_tunable[TUNABLES_INFO_SIZE]; + struct ethtool_tunable_info *tinfo = tunables_info; + int changed = 0; + unsigned int i; + + for (i = 0; i < TUNABLES_INFO_SIZE; i++) { + cmdline_tunable[i].name = tunable_strings[tinfo[i].t_id]; + cmdline_tunable[i].type = tinfo[i].type; + cmdline_tunable[i].wanted_val = &tinfo[i].wanted; + cmdline_tunable[i].seen_val = &tinfo[i].seen; + } + + parse_generic_cmdline(ctx, &changed, cmdline_tunable, TUNABLES_INFO_SIZE); + if (!changed) + exit_bad_args(); + + for (i = 0; i < TUNABLES_INFO_SIZE; i++) { + struct ethtool_tunable *tuna; + size_t size; + int ret; + + if (!tinfo[i].seen) + continue; + + size = sizeof(*tuna) + tinfo[i].size; + tuna = calloc(1, size); + if (!tuna) { + perror(tunable_strings[tinfo[i].t_id]); + return 1; + } + tuna->cmd = ETHTOOL_STUNABLE; + tuna->id = tinfo[i].t_id; + tuna->type_id = tinfo[i].t_type_id; + tuna->len = tinfo[i].size; + memcpy(tuna->data, &tinfo[i].wanted, tuna->len); + ret = send_ioctl(ctx, tuna); + if (ret) { + perror(tunable_strings[tuna->id]); + free(tuna); + return ret; + } + free(tuna); + } + return 0; +} + +static void print_tunable(struct ethtool_tunable *tuna) +{ + char *name = tunable_strings[tuna->id]; + union ethtool_tunable_info_val *val; + + val = (union ethtool_tunable_info_val *)tuna->data; + switch (tuna->type_id) { + case ETHTOOL_TUNABLE_U8: + fprintf(stdout, "%s: %" PRIu8 "\n", name, val->u8); + break; + case ETHTOOL_TUNABLE_U16: + fprintf(stdout, "%s: %" PRIu16 "\n", name, val->u16); + break; + case ETHTOOL_TUNABLE_U32: + fprintf(stdout, "%s: %" PRIu32 "\n", name, val->u32); + break; + case ETHTOOL_TUNABLE_U64: + fprintf(stdout, "%s: %" PRIu64 "\n", name, val->u64); + break; + case ETHTOOL_TUNABLE_S8: + fprintf(stdout, "%s: %" PRId8 "\n", name, val->s8); + break; + case ETHTOOL_TUNABLE_S16: + fprintf(stdout, "%s: %" PRId16 "\n", name, val->s16); + break; + case ETHTOOL_TUNABLE_S32: + fprintf(stdout, "%s: %" PRId32 "\n", name, val->s32); + break; + case ETHTOOL_TUNABLE_S64: + fprintf(stdout, "%s: %" PRId64 "\n", name, val->s64); + break; + default: + fprintf(stdout, "%s: Unknown format\n", name); + } +} + +static int do_gtunable(struct cmd_context *ctx) +{ + struct ethtool_tunable_info *tinfo = tunables_info; + char **argp = ctx->argp; + unsigned int argc = ctx->argc; + unsigned int i, j; + + if (argc < 1) + exit_bad_args(); + + for (i = 0; i < argc; i++) { + int valid = 0; + + for (j = 0; j < TUNABLES_INFO_SIZE; j++) { + char *ts = tunable_strings[tinfo[j].t_id]; + struct ethtool_tunable *tuna; + int ret; + + if (strcmp(argp[i], ts)) + continue; + valid = 1; + + tuna = calloc(1, sizeof(*tuna) + tinfo[j].size); + if (!tuna) { + perror(ts); + return 1; + } + tuna->cmd = ETHTOOL_GTUNABLE; + tuna->id = tinfo[j].t_id; + tuna->type_id = tinfo[j].t_type_id; + tuna->len = tinfo[j].size; + ret = send_ioctl(ctx, tuna); + if (ret) { + fprintf(stderr, "%s: Cannot get tunable\n", ts); + free(tuna); + return ret; + } + print_tunable(tuna); + free(tuna); + } + if (!valid) + exit_bad_args(); + } + return 0; +} + +static int do_get_phy_tunable(struct cmd_context *ctx) +{ + unsigned int argc = ctx->argc; + char **argp = ctx->argp; + + if (argc < 1) + exit_bad_args(); + + if (!strcmp(argp[0], "downshift")) { + struct { + struct ethtool_tunable ds; + u8 count; + } cont; + + cont.ds.cmd = ETHTOOL_PHY_GTUNABLE; + cont.ds.id = ETHTOOL_PHY_DOWNSHIFT; + cont.ds.type_id = ETHTOOL_TUNABLE_U8; + cont.ds.len = 1; + if (send_ioctl(ctx, &cont.ds) < 0) { + perror("Cannot Get PHY downshift count"); + return 87; + } + if (cont.count) + fprintf(stdout, "Downshift count: %d\n", cont.count); + else + fprintf(stdout, "Downshift disabled\n"); + } else if (!strcmp(argp[0], "fast-link-down")) { + struct { + struct ethtool_tunable fld; + u8 msecs; + } cont; + + cont.fld.cmd = ETHTOOL_PHY_GTUNABLE; + cont.fld.id = ETHTOOL_PHY_FAST_LINK_DOWN; + cont.fld.type_id = ETHTOOL_TUNABLE_U8; + cont.fld.len = 1; + if (send_ioctl(ctx, &cont.fld) < 0) { + perror("Cannot Get PHY Fast Link Down value"); + return 87; + } + + if (cont.msecs == ETHTOOL_PHY_FAST_LINK_DOWN_ON) + fprintf(stdout, "Fast Link Down enabled\n"); + else if (cont.msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF) + fprintf(stdout, "Fast Link Down disabled\n"); + else + fprintf(stdout, "Fast Link Down enabled, %d msecs\n", + cont.msecs); + } else if (!strcmp(argp[0], "energy-detect-power-down")) { + struct { + struct ethtool_tunable ds; + u16 msecs; + } cont; + + cont.ds.cmd = ETHTOOL_PHY_GTUNABLE; + cont.ds.id = ETHTOOL_PHY_EDPD; + cont.ds.type_id = ETHTOOL_TUNABLE_U16; + cont.ds.len = 2; + if (send_ioctl(ctx, &cont.ds) < 0) { + perror("Cannot Get PHY Energy Detect Power Down value"); + return 87; + } + + if (cont.msecs == ETHTOOL_PHY_EDPD_DISABLE) + fprintf(stdout, "Energy Detect Power Down: disabled\n"); + else if (cont.msecs == ETHTOOL_PHY_EDPD_NO_TX) + fprintf(stdout, + "Energy Detect Power Down: enabled, TX disabled\n"); + else + fprintf(stdout, + "Energy Detect Power Down: enabled, TX %u msecs\n", + cont.msecs); + } else { + exit_bad_args(); + } + + return 0; +} + +static __u32 parse_reset(char *val, __u32 bitset, char *arg, __u32 *data) +{ + __u32 bitval = 0; + int i; + + /* Check for component match */ + for (i = 0; val[i] != '\0'; i++) + if (arg[i] != val[i]) + return 0; + + /* Check if component has -shared specified or not */ + if (arg[i] == '\0') + bitval = bitset; + else if (!strcmp(arg+i, "-shared")) + bitval = bitset << ETH_RESET_SHARED_SHIFT; + + if (bitval) { + *data |= bitval; + return 1; + } + return 0; +} + +static int do_reset(struct cmd_context *ctx) +{ + struct ethtool_value resetinfo; + __u32 data; + unsigned int argc = ctx->argc; + char **argp = ctx->argp; + unsigned int i; + + if (argc == 0) + exit_bad_args(); + + data = 0; + + for (i = 0; i < argc; i++) { + if (!strcmp(argp[i], "flags")) { + __u32 flags; + + i++; + if (i >= argc) + exit_bad_args(); + flags = strtoul(argp[i], NULL, 0); + if (flags == 0) + exit_bad_args(); + else + data |= flags; + } else if (parse_reset("mgmt", ETH_RESET_MGMT, + argp[i], &data)) { + } else if (parse_reset("irq", ETH_RESET_IRQ, + argp[i], &data)) { + } else if (parse_reset("dma", ETH_RESET_DMA, + argp[i], &data)) { + } else if (parse_reset("filter", ETH_RESET_FILTER, + argp[i], &data)) { + } else if (parse_reset("offload", ETH_RESET_OFFLOAD, + argp[i], &data)) { + } else if (parse_reset("mac", ETH_RESET_MAC, + argp[i], &data)) { + } else if (parse_reset("phy", ETH_RESET_PHY, + argp[i], &data)) { + } else if (parse_reset("ram", ETH_RESET_RAM, + argp[i], &data)) { + } else if (parse_reset("ap", ETH_RESET_AP, + argp[i], &data)) { + } else if (!strcmp(argp[i], "dedicated")) { + data |= ETH_RESET_DEDICATED; + } else if (!strcmp(argp[i], "all")) { + data |= ETH_RESET_ALL; + } else { + exit_bad_args(); + } + } + + resetinfo.cmd = ETHTOOL_RESET; + resetinfo.data = data; + fprintf(stdout, "ETHTOOL_RESET 0x%x\n", resetinfo.data); + + if (send_ioctl(ctx, &resetinfo)) { + perror("Cannot issue ETHTOOL_RESET"); + return 1; + } + + fprintf(stdout, "Components reset: 0x%x\n", data & ~resetinfo.data); + if (resetinfo.data) + fprintf(stdout, "Components not reset: 0x%x\n", resetinfo.data); + + return 0; +} + +static int parse_named_bool(struct cmd_context *ctx, const char *name, u8 *on) +{ + if (ctx->argc < 2) + return 0; + + if (strcmp(*ctx->argp, name)) + return 0; + + if (!strcmp(*(ctx->argp + 1), "on")) { + *on = 1; + } else if (!strcmp(*(ctx->argp + 1), "off")) { + *on = 0; + } else { + fprintf(stderr, "Invalid boolean\n"); + exit_bad_args(); + } + + ctx->argc -= 2; + ctx->argp += 2; + + return 1; +} + +static int parse_named_uint(struct cmd_context *ctx, + const char *name, + unsigned long long *val, + unsigned long long max) +{ + if (ctx->argc < 2) + return 0; + + if (strcmp(*ctx->argp, name)) + return 0; + + *val = get_uint_range(*(ctx->argp + 1), 0, max); + + ctx->argc -= 2; + ctx->argp += 2; + + return 1; +} + +static int parse_named_u8(struct cmd_context *ctx, const char *name, u8 *val) +{ + unsigned long long val1; + int ret; + + ret = parse_named_uint(ctx, name, &val1, 0xff); + if (ret) + *val = val1; + + return ret; +} + +static int parse_named_u16(struct cmd_context *ctx, const char *name, u16 *val) +{ + unsigned long long val1; + int ret; + + ret = parse_named_uint(ctx, name, &val1, 0xffff); + if (ret) + *val = val1; + + return ret; +} + +static int do_set_phy_tunable(struct cmd_context *ctx) +{ + int err = 0; + u8 ds_cnt = DOWNSHIFT_DEV_DEFAULT_COUNT; + u8 ds_changed = 0, ds_has_cnt = 0, ds_enable = 0; + u8 fld_changed = 0, fld_enable = 0; + u8 fld_msecs = ETHTOOL_PHY_FAST_LINK_DOWN_ON; + u8 edpd_changed = 0, edpd_enable = 0; + u16 edpd_tx_interval = ETHTOOL_PHY_EDPD_DFLT_TX_MSECS; + + /* Parse arguments */ + if (parse_named_bool(ctx, "downshift", &ds_enable)) { + ds_changed = 1; + ds_has_cnt = parse_named_u8(ctx, "count", &ds_cnt); + } else if (parse_named_bool(ctx, "fast-link-down", &fld_enable)) { + fld_changed = 1; + if (fld_enable) + parse_named_u8(ctx, "msecs", &fld_msecs); + } else if (parse_named_bool(ctx, "energy-detect-power-down", + &edpd_enable)) { + edpd_changed = 1; + if (edpd_enable) + parse_named_u16(ctx, "msecs", &edpd_tx_interval); + } else { + exit_bad_args(); + } + + /* Validate parameters */ + if (ds_changed) { + if (!ds_enable && ds_has_cnt) { + fprintf(stderr, "'count' may not be set when downshift " + "is off.\n"); + exit_bad_args(); + } + + if (ds_enable && ds_has_cnt && ds_cnt == 0) { + fprintf(stderr, "'count' may not be zero.\n"); + exit_bad_args(); + } + + if (!ds_enable) + ds_cnt = DOWNSHIFT_DEV_DISABLE; + } else if (fld_changed) { + if (!fld_enable) + fld_msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF; + else if (fld_msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF) + exit_bad_args(); + } else if (edpd_changed) { + if (!edpd_enable) + edpd_tx_interval = ETHTOOL_PHY_EDPD_DISABLE; + else if (edpd_tx_interval == 0) + edpd_tx_interval = ETHTOOL_PHY_EDPD_NO_TX; + else if (edpd_tx_interval > ETHTOOL_PHY_EDPD_NO_TX) { + fprintf(stderr, "'msecs' max value is %d.\n", + (ETHTOOL_PHY_EDPD_NO_TX - 1)); + exit_bad_args(); + } + } + + /* Do it */ + if (ds_changed) { + struct { + struct ethtool_tunable ds; + u8 count; + } cont; + + cont.ds.cmd = ETHTOOL_PHY_STUNABLE; + cont.ds.id = ETHTOOL_PHY_DOWNSHIFT; + cont.ds.type_id = ETHTOOL_TUNABLE_U8; + cont.ds.len = 1; + cont.count = ds_cnt; + err = send_ioctl(ctx, &cont.ds); + if (err < 0) { + perror("Cannot Set PHY downshift count"); + err = 87; + } + } else if (fld_changed) { + struct { + struct ethtool_tunable fld; + u8 msecs; + } cont; + + cont.fld.cmd = ETHTOOL_PHY_STUNABLE; + cont.fld.id = ETHTOOL_PHY_FAST_LINK_DOWN; + cont.fld.type_id = ETHTOOL_TUNABLE_U8; + cont.fld.len = 1; + cont.msecs = fld_msecs; + err = send_ioctl(ctx, &cont.fld); + if (err < 0) { + perror("Cannot Set PHY Fast Link Down value"); + err = 87; + } + } else if (edpd_changed) { + struct { + struct ethtool_tunable fld; + u16 msecs; + } cont; + + cont.fld.cmd = ETHTOOL_PHY_STUNABLE; + cont.fld.id = ETHTOOL_PHY_EDPD; + cont.fld.type_id = ETHTOOL_TUNABLE_U16; + cont.fld.len = 2; + cont.msecs = edpd_tx_interval; + err = send_ioctl(ctx, &cont.fld); + if (err < 0) { + perror("Cannot Set PHY Energy Detect Power Down"); + err = 87; + } + } + + return err; +} + +static int fecmode_str_to_type(const char *str) +{ + if (!strcasecmp(str, "auto")) + return ETHTOOL_FEC_AUTO; + if (!strcasecmp(str, "off")) + return ETHTOOL_FEC_OFF; + if (!strcasecmp(str, "rs")) + return ETHTOOL_FEC_RS; + if (!strcasecmp(str, "baser")) + return ETHTOOL_FEC_BASER; + if (!strcasecmp(str, "llrs")) + return ETHTOOL_FEC_LLRS; + return 0; +} + +static int do_gfec(struct cmd_context *ctx) +{ + struct ethtool_fecparam feccmd = { 0 }; + int rv; + + if (ctx->argc != 0) + exit_bad_args(); + + feccmd.cmd = ETHTOOL_GFECPARAM; + rv = send_ioctl(ctx, &feccmd); + if (rv != 0) { + perror("Cannot get FEC settings"); + return rv; + } + + fprintf(stdout, "FEC parameters for %s:\n", ctx->devname); + fprintf(stdout, "Supported/Configured FEC encodings:"); + dump_fec(feccmd.fec); + fprintf(stdout, "\n"); + + fprintf(stdout, "Active FEC encoding:"); + dump_fec(feccmd.active_fec); + fprintf(stdout, "\n"); + + return 0; +} + +static int do_sfec(struct cmd_context *ctx) +{ + enum { ARG_NONE, ARG_ENCODING } state = ARG_NONE; + struct ethtool_fecparam feccmd; + int fecmode = 0, newmode; + unsigned int i; + int rv; + + for (i = 0; i < ctx->argc; i++) { + if (!strcmp(ctx->argp[i], "encoding")) { + state = ARG_ENCODING; + continue; + } + if (state == ARG_ENCODING) { + newmode = fecmode_str_to_type(ctx->argp[i]); + if (!newmode) + exit_bad_args(); + fecmode |= newmode; + continue; + } + exit_bad_args(); + } + + if (!fecmode) + exit_bad_args(); + + feccmd.cmd = ETHTOOL_SFECPARAM; + feccmd.fec = fecmode; + rv = send_ioctl(ctx, &feccmd); + if (rv != 0) { + perror("Cannot set FEC settings"); + return rv; + } + + return 0; +} + +static int do_perqueue(struct cmd_context *ctx); + +#ifndef TEST_ETHTOOL +int send_ioctl(struct cmd_context *ctx, void *cmd) +{ + ctx->ifr.ifr_data = cmd; + return ioctl(ctx->fd, SIOCETHTOOL, &ctx->ifr); +} +#endif + +static int show_usage(struct cmd_context *ctx); + +struct option { + const char *opts; + bool no_dev; + bool json; + int (*func)(struct cmd_context *); + nl_chk_t nlchk; + nl_func_t nlfunc; + const char *help; + const char *xhelp; +}; + +static const struct option args[] = { + { + /* "default" entry when no switch is used */ + .opts = "", + .func = do_gset, + .nlfunc = nl_gset, + .help = "Display standard information about device", + }, + { + .opts = "-s|--change", + .func = do_sset, + .nlfunc = nl_sset, + .help = "Change generic options", + .xhelp = " [ speed %d ]\n" + " [ lanes %d ]\n" + " [ duplex half|full ]\n" + " [ port tp|aui|bnc|mii|fibre|da ]\n" + " [ mdix auto|on|off ]\n" + " [ autoneg on|off ]\n" + " [ advertise %x[/%x] | mode on|off ... [--] ]\n" + " [ phyad %d ]\n" + " [ xcvr internal|external ]\n" + " [ wol %d[/%d] | p|u|m|b|a|g|s|f|d... ]\n" + " [ sopass %x:%x:%x:%x:%x:%x ]\n" + " [ msglvl %d[/%d] | type on|off ... [--] ]\n" + " [ master-slave preferred-master|preferred-slave|forced-master|forced-slave ]\n" + }, + { + .opts = "-a|--show-pause", + .json = true, + .func = do_gpause, + .nlfunc = nl_gpause, + .help = "Show pause options" + }, + { + .opts = "-A|--pause", + .func = do_spause, + .nlfunc = nl_spause, + .help = "Set pause options", + .xhelp = " [ autoneg on|off ]\n" + " [ rx on|off ]\n" + " [ tx on|off ]\n" + }, + { + .opts = "-c|--show-coalesce", + .func = do_gcoalesce, + .nlfunc = nl_gcoalesce, + .help = "Show coalesce options" + }, + { + .opts = "-C|--coalesce", + .func = do_scoalesce, + .nlfunc = nl_scoalesce, + .help = "Set coalesce options", + .xhelp = " [adaptive-rx on|off]\n" + " [adaptive-tx on|off]\n" + " [rx-usecs N]\n" + " [rx-frames N]\n" + " [rx-usecs-irq N]\n" + " [rx-frames-irq N]\n" + " [tx-usecs N]\n" + " [tx-frames N]\n" + " [tx-usecs-irq N]\n" + " [tx-frames-irq N]\n" + " [stats-block-usecs N]\n" + " [pkt-rate-low N]\n" + " [rx-usecs-low N]\n" + " [rx-frames-low N]\n" + " [tx-usecs-low N]\n" + " [tx-frames-low N]\n" + " [pkt-rate-high N]\n" + " [rx-usecs-high N]\n" + " [rx-frames-high N]\n" + " [tx-usecs-high N]\n" + " [tx-frames-high N]\n" + " [sample-interval N]\n" + " [cqe-mode-rx on|off]\n" + " [cqe-mode-tx on|off]\n" + }, + { + .opts = "-g|--show-ring", + .func = do_gring, + .nlfunc = nl_gring, + .help = "Query RX/TX ring parameters" + }, + { + .opts = "-G|--set-ring", + .func = do_sring, + .nlfunc = nl_sring, + .help = "Set RX/TX ring parameters", + .xhelp = " [ rx N ]\n" + " [ rx-mini N ]\n" + " [ rx-jumbo N ]\n" + " [ tx N ]\n" + " [ rx-buf-len N]\n" + " [ cqe-size N]\n" + " [ tx-push on|off]\n" + }, + { + .opts = "-k|--show-features|--show-offload", + .json = true, + .func = do_gfeatures, + .nlfunc = nl_gfeatures, + .help = "Get state of protocol offload and other features" + }, + { + .opts = "-K|--features|--offload", + .func = do_sfeatures, + .nlfunc = nl_sfeatures, + .help = "Set protocol offload and other features", + .xhelp = " FEATURE on|off ...\n" + }, + { + .opts = "-i|--driver", + .func = do_gdrv, + .help = "Show driver information" + }, + { + .opts = "-d|--register-dump", + .func = do_gregs, + .help = "Do a register dump", + .xhelp = " [ raw on|off ]\n" + " [ file FILENAME ]\n" + }, + { + .opts = "-e|--eeprom-dump", + .func = do_geeprom, + .help = "Do a EEPROM dump", + .xhelp = " [ raw on|off ]\n" + " [ offset N ]\n" + " [ length N ]\n" + }, + { + .opts = "-E|--change-eeprom", + .func = do_seeprom, + .help = "Change bytes in device EEPROM", + .xhelp = " [ magic N ]\n" + " [ offset N ]\n" + " [ length N ]\n" + " [ value N ]\n" + }, + { + .opts = "-r|--negotiate", + .func = do_nway_rst, + .help = "Restart N-WAY negotiation" + }, + { + .opts = "-p|--identify", + .func = do_phys_id, + .help = "Show visible port identification (e.g. blinking)", + .xhelp = " [ TIME-IN-SECONDS ]\n" + }, + { + .opts = "-t|--test", + .func = do_test, + .help = "Execute adapter self test", + .xhelp = " [ online | offline | external_lb ]\n" + }, + { + .opts = "-S|--statistics", + .json = true, + .func = do_gnicstats, + .nlchk = nl_gstats_chk, + .nlfunc = nl_gstats, + .help = "Show adapter statistics", + .xhelp = " [ --all-groups | --groups [eth-phy] [eth-mac] [eth-ctrl] [rmon] ]\n" + }, + { + .opts = "--phy-statistics", + .func = do_gphystats, + .help = "Show phy statistics" + }, + { + .opts = "-n|-u|--show-nfc|--show-ntuple", + .func = do_grxclass, + .help = "Show Rx network flow classification options or rules", + .xhelp = " [ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|" + "tcp6|udp6|ah6|esp6|sctp6 [context %d] |\n" + " rule %d ]\n" + }, + { + .opts = "-N|-U|--config-nfc|--config-ntuple", + .func = do_srxclass, + .help = "Configure Rx network flow classification options or rules", + .xhelp = " rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|" + "tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... [context %d] |\n" + " flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4|" + "ip6|tcp6|udp6|ah6|esp6|sctp6\n" + " [ src %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n" + " [ dst %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n" + " [ proto %d [m %x] ]\n" + " [ src-ip IP-ADDRESS [m IP-ADDRESS] ]\n" + " [ dst-ip IP-ADDRESS [m IP-ADDRESS] ]\n" + " [ tos %d [m %x] ]\n" + " [ tclass %d [m %x] ]\n" + " [ l4proto %d [m %x] ]\n" + " [ src-port %d [m %x] ]\n" + " [ dst-port %d [m %x] ]\n" + " [ spi %d [m %x] ]\n" + " [ vlan-etype %x [m %x] ]\n" + " [ vlan %x [m %x] ]\n" + " [ user-def %x [m %x] ]\n" + " [ dst-mac %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n" + " [ action %d ] | [ vf %d queue %d ]\n" + " [ context %d ]\n" + " [ loc %d]] |\n" + " delete %d\n" + }, + { + .opts = "-T|--show-time-stamping", + .func = do_tsinfo, + .nlfunc = nl_tsinfo, + .help = "Show time stamping capabilities" + }, + { + .opts = "-x|--show-rxfh-indir|--show-rxfh", + .func = do_grxfh, + .help = "Show Rx flow hash indirection table and/or RSS hash key", + .xhelp = " [ context %d ]\n" + }, + { + .opts = "-X|--set-rxfh-indir|--rxfh", + .func = do_srxfh, + .help = "Set Rx flow hash indirection table and/or RSS hash key", + .xhelp = " [ context %d|new ]\n" + " [ equal N | weight W0 W1 ... | default ]\n" + " [ hkey %x:%x:%x:%x:%x:.... ]\n" + " [ hfunc FUNC ]\n" + " [ delete ]\n" + }, + { + .opts = "-f|--flash", + .func = do_flash, + .help = "Flash firmware image from the specified file to a region on the device", + .xhelp = " FILENAME [ REGION-NUMBER-TO-FLASH ]\n" + }, + { + .opts = "-P|--show-permaddr", + .func = do_permaddr, + .nlfunc = nl_permaddr, + .help = "Show permanent hardware address" + }, + { + .opts = "-w|--get-dump", + .func = do_getfwdump, + .help = "Get dump flag, data", + .xhelp = " [ data FILENAME ]\n" + }, + { + .opts = "-W|--set-dump", + .func = do_setfwdump, + .help = "Set dump flag of the device", + .xhelp = " N\n" + }, + { + .opts = "-l|--show-channels", + .func = do_gchannels, + .nlfunc = nl_gchannels, + .help = "Query Channels" + }, + { + .opts = "-L|--set-channels", + .func = do_schannels, + .nlfunc = nl_schannels, + .help = "Set Channels", + .xhelp = " [ rx N ]\n" + " [ tx N ]\n" + " [ other N ]\n" + " [ combined N ]\n" + }, + { + .opts = "--show-priv-flags", + .func = do_gprivflags, + .nlfunc = nl_gprivflags, + .help = "Query private flags" + }, + { + .opts = "--set-priv-flags", + .func = do_sprivflags, + .nlfunc = nl_sprivflags, + .help = "Set private flags", + .xhelp = " FLAG on|off ...\n" + }, + { + .opts = "-m|--dump-module-eeprom|--module-info", + .func = do_getmodule, + .nlfunc = nl_getmodule, + .help = "Query/Decode Module EEPROM information and optical diagnostics if available", + .xhelp = " [ raw on|off ]\n" + " [ hex on|off ]\n" + " [ offset N ]\n" + " [ length N ]\n" + " [ page N ]\n" + " [ bank N ]\n" + " [ i2c N ]\n" + }, + { + .opts = "--show-eee", + .func = do_geee, + .nlfunc = nl_geee, + .help = "Show EEE settings", + }, + { + .opts = "--set-eee", + .func = do_seee, + .nlfunc = nl_seee, + .help = "Set EEE settings", + .xhelp = " [ eee on|off ]\n" + " [ advertise %x ]\n" + " [ tx-lpi on|off ]\n" + " [ tx-timer %d ]\n" + }, + { + .opts = "--set-phy-tunable", + .func = do_set_phy_tunable, + .help = "Set PHY tunable", + .xhelp = " [ downshift on|off [count N] ]\n" + " [ fast-link-down on|off [msecs N] ]\n" + " [ energy-detect-power-down on|off [msecs N] ]\n" + }, + { + .opts = "--get-phy-tunable", + .func = do_get_phy_tunable, + .help = "Get PHY tunable", + .xhelp = " [ downshift ]\n" + " [ fast-link-down ]\n" + " [ energy-detect-power-down ]\n" + }, + { + .opts = "--get-tunable", + .func = do_gtunable, + .help = "Get tunable", + .xhelp = " [ rx-copybreak ]\n" + " [ tx-copybreak ]\n" + " [ tx-buf-size ]\n" + " [ pfc-precention-tout ]\n" + }, + { + .opts = "--set-tunable", + .func = do_stunable, + .help = "Set tunable", + .xhelp = " [ rx-copybreak N]\n" + " [ tx-copybreak N]\n" + " [ tx-buf-size N]\n" + " [ pfc-precention-tout N]\n" + }, + { + .opts = "--reset", + .func = do_reset, + .help = "Reset components", + .xhelp = " [ flags %x ]\n" + " [ mgmt ]\n" + " [ mgmt-shared ]\n" + " [ irq ]\n" + " [ irq-shared ]\n" + " [ dma ]\n" + " [ dma-shared ]\n" + " [ filter ]\n" + " [ filter-shared ]\n" + " [ offload ]\n" + " [ offload-shared ]\n" + " [ mac ]\n" + " [ mac-shared ]\n" + " [ phy ]\n" + " [ phy-shared ]\n" + " [ ram ]\n" + " [ ram-shared ]\n" + " [ ap ]\n" + " [ ap-shared ]\n" + " [ dedicated ]\n" + " [ all ]\n" + }, + { + .opts = "--show-fec", + .json = true, + .func = do_gfec, + .nlfunc = nl_gfec, + .help = "Show FEC settings", + }, + { + .opts = "--set-fec", + .func = do_sfec, + .nlfunc = nl_sfec, + .help = "Set FEC settings", + .xhelp = " [ encoding auto|off|rs|baser|llrs [...]]\n" + }, + { + .opts = "-Q|--per-queue", + .func = do_perqueue, + .help = "Apply per-queue command. ", + .xhelp = "The supported sub commands include --show-coalesce, --coalesce" + " [queue_mask %x] SUB_COMMAND\n", + }, + { + .opts = "--cable-test", + .json = true, + .nlfunc = nl_cable_test, + .help = "Perform a cable test", + }, + { + .opts = "--cable-test-tdr", + .json = true, + .nlfunc = nl_cable_test_tdr, + .help = "Print cable test time domain reflectrometery data", + .xhelp = " [ first N ]\n" + " [ last N ]\n" + " [ step N ]\n" + " [ pair N ]\n" + }, + { + .opts = "--show-tunnels", + .nlfunc = nl_gtunnels, + .help = "Show NIC tunnel offload information", + }, + { + .opts = "--show-module", + .json = true, + .nlfunc = nl_gmodule, + .help = "Show transceiver module settings", + }, + { + .opts = "--set-module", + .nlfunc = nl_smodule, + .help = "Set transceiver module settings", + .xhelp = " [ power-mode-policy high|auto ]\n" + }, + { + .opts = "-h|--help", + .no_dev = true, + .func = show_usage, + .help = "Show this help" + }, + { + .opts = "--version", + .no_dev = true, + .func = do_version, + .help = "Show version number" + }, + {} +}; + +static int show_usage(struct cmd_context *ctx __maybe_unused) +{ + int i; + + /* ethtool -h */ + fprintf(stdout, PACKAGE " version " VERSION "\n"); + fprintf(stdout, "Usage:\n"); + for (i = 0; args[i].opts; i++) { + fputs(" ethtool [ FLAGS ] ", stdout); + fprintf(stdout, "%s %s\t%s\n", + args[i].opts, + args[i].no_dev ? "\t" : "DEVNAME", + args[i].help); + if (args[i].xhelp) + fputs(args[i].xhelp, stdout); + } + nl_monitor_usage(); + fprintf(stdout, "\n"); + fprintf(stdout, "FLAGS:\n"); + fprintf(stdout, " --debug MASK turn on debugging messages\n"); + fprintf(stdout, " --json enable JSON output format (not supported by all commands)\n"); + fprintf(stdout, " -I|--include-statistics request device statistics related to the command (not supported by all commands)\n"); + + return 0; +} + +static int find_option(char *arg) +{ + const char *opt; + size_t len; + int k; + + for (k = 1; args[k].opts; k++) { + opt = args[k].opts; + for (;;) { + len = strcspn(opt, "|"); + if (strncmp(arg, opt, len) == 0 && arg[len] == 0) + return k; + + if (opt[len] == 0) + break; + opt += len + 1; + } + } + + return -1; +} + +#define MAX(x, y) (x > y ? x : y) + +static int find_max_num_queues(struct cmd_context *ctx) +{ + struct ethtool_channels echannels; + + echannels.cmd = ETHTOOL_GCHANNELS; + if (send_ioctl(ctx, &echannels)) + return -1; + + return MAX(echannels.rx_count, echannels.tx_count) + + echannels.combined_count; +} + +static struct ethtool_per_queue_op * +get_per_queue_coalesce(struct cmd_context *ctx, __u32 *queue_mask, int n_queues) +{ + struct ethtool_per_queue_op *per_queue_opt; + + per_queue_opt = malloc(sizeof(*per_queue_opt) + n_queues * + sizeof(struct ethtool_coalesce)); + if (!per_queue_opt) + return NULL; + + memcpy(per_queue_opt->queue_mask, queue_mask, + __KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32) * sizeof(__u32)); + per_queue_opt->cmd = ETHTOOL_PERQUEUE; + per_queue_opt->sub_command = ETHTOOL_GCOALESCE; + if (send_ioctl(ctx, per_queue_opt)) { + free(per_queue_opt); + perror("Cannot get device per queue parameters"); + return NULL; + } + + return per_queue_opt; +} + +static void set_per_queue_coalesce(struct cmd_context *ctx, + struct ethtool_per_queue_op *per_queue_opt, + int n_queues) +{ + struct ethtool_coalesce ecoal; + DECLARE_COALESCE_OPTION_VARS(); + struct cmdline_info cmdline_coalesce[] = COALESCE_CMDLINE_INFO(ecoal); + __u32 *queue_mask = per_queue_opt->queue_mask; + struct ethtool_coalesce *ecoal_q; + int gcoalesce_changed = 0; + int i, idx = 0; + + parse_generic_cmdline(ctx, &gcoalesce_changed, + cmdline_coalesce, ARRAY_SIZE(cmdline_coalesce)); + + ecoal_q = (struct ethtool_coalesce *)(per_queue_opt + 1); + for (i = 0; i < __KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32); i++) { + int queue = i * 32; + __u32 mask = queue_mask[i]; + + while (mask > 0) { + if (mask & 0x1) { + int changed = 0; + + memcpy(&ecoal, ecoal_q + idx, + sizeof(struct ethtool_coalesce)); + do_generic_set(cmdline_coalesce, + ARRAY_SIZE(cmdline_coalesce), + &changed); + if (!changed) + fprintf(stderr, + "Queue %d, no coalesce parameters changed\n", + queue); + memcpy(ecoal_q + idx, &ecoal, + sizeof(struct ethtool_coalesce)); + idx++; + } + mask = mask >> 1; + queue++; + } + if (idx == n_queues) + break; + } + + per_queue_opt->cmd = ETHTOOL_PERQUEUE; + per_queue_opt->sub_command = ETHTOOL_SCOALESCE; + + if (send_ioctl(ctx, per_queue_opt)) + perror("Cannot set device per queue parameters"); +} + +static int do_perqueue(struct cmd_context *ctx) +{ + struct ethtool_per_queue_op *per_queue_opt; + __u32 queue_mask[__KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32)] = {0}; + int i, n_queues = 0; + + if (ctx->argc == 0) + exit_bad_args(); + + /* + * The sub commands will be applied to + * all queues if no queue_mask set + */ + if (strncmp(*ctx->argp, "queue_mask", 11)) { + n_queues = find_max_num_queues(ctx); + if (n_queues < 0) { + perror("Cannot get number of queues"); + return -EFAULT; + } else if (n_queues > MAX_NUM_QUEUE) { + n_queues = MAX_NUM_QUEUE; + } + for (i = 0; i < n_queues / 32; i++) + queue_mask[i] = ~0; + if (n_queues % 32) + queue_mask[i] = (1 << (n_queues - i * 32)) - 1; + fprintf(stdout, + "The sub commands will be applied to all %d queues\n", + n_queues); + } else { + if (ctx->argc <= 2) + exit_bad_args(); + ctx->argc--; + ctx->argp++; + if (parse_hex_u32_bitmap(*ctx->argp, MAX_NUM_QUEUE, + queue_mask)) { + fprintf(stdout, "Invalid queue mask\n"); + return -1; + } + for (i = 0; i < __KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32); i++) { + __u32 mask = queue_mask[i]; + + while (mask > 0) { + if (mask & 0x1) + n_queues++; + mask = mask >> 1; + } + } + ctx->argc--; + ctx->argp++; + } + + i = find_option(ctx->argp[0]); + if (i < 0) + exit_bad_args(); + + if (strstr(args[i].opts, "--show-coalesce") != NULL) { + per_queue_opt = get_per_queue_coalesce(ctx, queue_mask, + n_queues); + if (per_queue_opt == NULL) { + perror("Cannot get device per queue parameters"); + return -EFAULT; + } + dump_per_queue_coalesce(per_queue_opt, queue_mask, n_queues); + free(per_queue_opt); + } else if (strstr(args[i].opts, "--coalesce") != NULL) { + ctx->argc--; + ctx->argp++; + per_queue_opt = get_per_queue_coalesce(ctx, queue_mask, + n_queues); + if (per_queue_opt == NULL) { + perror("Cannot get device per queue parameters"); + return -EFAULT; + } + set_per_queue_coalesce(ctx, per_queue_opt, n_queues); + free(per_queue_opt); + } else { + perror("The subcommand is not supported yet"); + return -EOPNOTSUPP; + } + + return 0; +} + +static int ioctl_init(struct cmd_context *ctx, bool no_dev) +{ + if (no_dev) { + ctx->fd = -1; + return 0; + } + if (strlen(ctx->devname) >= IFNAMSIZ) { + fprintf(stderr, "Device name longer than %u characters\n", + IFNAMSIZ - 1); + exit_bad_args(); + } + + /* Setup our control structures. */ + memset(&ctx->ifr, 0, sizeof(ctx->ifr)); + strcpy(ctx->ifr.ifr_name, ctx->devname); + + /* Open control socket. */ + ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); + if (ctx->fd < 0) + ctx->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); + if (ctx->fd < 0) { + perror("Cannot get control socket"); + return 70; + } + + return 0; +} + +int main(int argc, char **argp) +{ + struct cmd_context ctx = {}; + int ret; + int k; + + init_global_link_mode_masks(); + + /* Skip command name */ + argp++; + argc--; + + while (true) { + if (*argp && !strcmp(*argp, "--debug")) { + char *eptr; + + if (argc < 2) + exit_bad_args(); + ctx.debug = strtoul(argp[1], &eptr, 0); + if (!argp[1][0] || *eptr) + exit_bad_args(); + + argp += 2; + argc -= 2; + continue; + } + if (*argp && !strcmp(*argp, "--json")) { + ctx.json = true; + argp += 1; + argc -= 1; + continue; + } + if (*argp && (!strcmp(*argp, "--include-statistics") || + !strcmp(*argp, "-I"))) { + ctx.show_stats = true; + argp += 1; + argc -= 1; + continue; + } + break; + } + if (*argp && !strcmp(*argp, "--monitor")) { + ctx.argp = ++argp; + ctx.argc = --argc; + ret = nl_monitor(&ctx); + return ret ? 1 : 0; + } + + /* First argument must be either a valid option or a device + * name to get settings for (which we don't expect to begin + * with '-'). + */ + if (argc == 0) + exit_bad_args(); + + k = find_option(*argp); + if (k > 0) { + argp++; + argc--; + } else { + if ((*argp)[0] == '-') + exit_bad_args(); + k = 0; + } + + if (!args[k].no_dev) { + ctx.devname = *argp++; + argc--; + + if (!ctx.devname) + exit_bad_args(); + } + if (ctx.json && !args[k].json) + exit_bad_args(); + ctx.argc = argc; + ctx.argp = argp; + netlink_run_handler(&ctx, args[k].nlchk, args[k].nlfunc, !args[k].func); + + if (ctx.json) /* no IOCTL command supports JSON output */ + exit_bad_args(); + + ret = ioctl_init(&ctx, args[k].no_dev); + if (ret) + return ret; + + return args[k].func(&ctx); +} diff --git a/ethtool.spec b/ethtool.spec new file mode 100644 index 0000000..2327f6c --- /dev/null +++ b/ethtool.spec @@ -0,0 +1,41 @@ +Name : ethtool +Version : 6.1 +Release : 1 +Group : Utilities + +Summary : Settings tool for Ethernet and other network devices + +License : GPL +URL : https://ftp.kernel.org/pub/software/network/ethtool/ + +Buildroot : %{_tmppath}/%{name}-%{version} +Source : %{name}-%{version}.tar.gz + + +%description +This utility allows querying and changing settings such as speed, +port, auto-negotiation, PCI locations and checksum offload on many +network devices, especially Ethernet devices. + +%prep +%setup -q + + +%build +CFLAGS="${RPM_OPT_FLAGS}" ./configure --prefix=%{_prefix} --mandir=%{_mandir} +make + + +%install +make install DESTDIR=${RPM_BUILD_ROOT} + + +%files +%defattr(-,root,root) +%{_sbindir}/ethtool +%{_mandir}/man8/ethtool.8* +%{_datadir}/bash-completion/completions/ethtool +%doc AUTHORS COPYING NEWS README + + +%changelog diff --git a/ethtool.spec.in b/ethtool.spec.in new file mode 100644 index 0000000..75f9be6 --- /dev/null +++ b/ethtool.spec.in @@ -0,0 +1,41 @@ +Name : @PACKAGE@ +Version : @VERSION@ +Release : 1 +Group : Utilities + +Summary : Settings tool for Ethernet and other network devices + +License : GPL +URL : https://ftp.kernel.org/pub/software/network/ethtool/ + +Buildroot : %{_tmppath}/%{name}-%{version} +Source : %{name}-%{version}.tar.gz + + +%description +This utility allows querying and changing settings such as speed, +port, auto-negotiation, PCI locations and checksum offload on many +network devices, especially Ethernet devices. + +%prep +%setup -q + + +%build +CFLAGS="${RPM_OPT_FLAGS}" ./configure --prefix=%{_prefix} --mandir=%{_mandir} +make + + +%install +make install DESTDIR=${RPM_BUILD_ROOT} + + +%files +%defattr(-,root,root) +%{_sbindir}/ethtool +%{_mandir}/man8/ethtool.8* +%{_datadir}/bash-completion/completions/ethtool +%doc AUTHORS COPYING NEWS README + + +%changelog diff --git a/fec.c b/fec.c new file mode 100644 index 0000000..d2373d6 --- /dev/null +++ b/fec.c @@ -0,0 +1,220 @@ +#include +#include + +#include "internal.h" + +/* Macros and dump functions for the 32-bit "fec" driver registers */ + +#define REG(_reg, _name, _val) \ + printf("0x%.03x: %-44.44s 0x%.8x\n", _reg, _name, _val) + +#define FIELD(_name, _fmt, ...) \ + printf(" %-47.47s " _fmt "\n", _name, ##__VA_ARGS__) + +static void fec_dump_reg_v1(int reg, u32 val) +{ + switch (reg) { + case 0x000: /* FEC_ECNTRL */ + case 0x004: /* FEC_IEVENT */ + case 0x008: /* FEC_IMASK */ + case 0x00c: /* FEC_IVEC */ + case 0x010: /* FEC_R_DES_ACTIVE_0 */ + case 0x014: /* FEC_X_DES_ACTIVE_0 */ + case 0x040: /* FEC_MII_DATA */ + case 0x044: /* FEC_MII_SPEED */ + case 0x08c: /* FEC_R_BOUND */ + case 0x090: /* FEC_R_FSTART */ + case 0x0a4: /* FEC_X_WMRK */ + case 0x0ac: /* FEC_X_FSTART */ + case 0x104: /* FEC_R_CNTRL */ + case 0x108: /* FEC_MAX_FRM_LEN */ + case 0x144: /* FEC_X_CNTRL */ + case 0x3c0: /* FEC_ADDR_LOW */ + case 0x3c4: /* FEC_ADDR_HIGH */ + case 0x3c8: /* FEC_GRP_HASH_TABLE_HIGH */ + case 0x3cc: /* FEC_GRP_HASH_TABLE_LOW */ + case 0x3d0: /* FEC_R_DES_START_0 */ + case 0x3d4: /* FEC_X_DES_START_0 */ + case 0x3d8: /* FEC_R_BUFF_SIZE_0 */ + REG(reg, "", val); + break; + } +} + +static void fec_dump_reg_v2(int reg, u32 val) +{ + switch (reg) { + case 0x084: /* FEC_R_CNTRL */ + REG(reg, "RCR (Receive Control Register)", val); + FIELD("MAX_FL (Maximum frame length)", "%u", (val & 0x07ff0000) >> 16); + FIELD("FCE (Flow control enable)", "%u", !!(val & 0x00000020)); + FIELD("BC_REJ (Broadcast frame reject)", "%u", !!(val & 0x00000010)); + FIELD("PROM (Promiscuous mode)", "%u", !!(val & 0x00000008)); + FIELD("DRT (Disable receive on transmit)", "%u", !!(val & 0x00000002)); + FIELD("LOOP (Internal loopback)", "%u", !!(val & 0x00000001)); + break; + case 0x0c4: /* FEC_X_CNTRL */ + REG(reg, "TCR (Transmit Control Register)", val); + FIELD("RFC_PAUSE (Receive frame control pause)", "%u", !!(val & 0x00000010)); + FIELD("TFC_PAUSE (Transmit frame control pause)", "%u", !!(val & 0x00000008)); + FIELD("FDEN (Full duplex enable)", "%u", !!(val & 0x00000004)); + FIELD("HBC (Heartbeat control)", "%u", !!(val & 0x00000002)); + FIELD("GTS (Graceful transmit stop)", "%u", !!(val & 0x00000001)); + break; + case 0x118: /* FEC_HASH_TABLE_HIGH */ + REG(reg, "IAUR (Individual Address Upper Register)", val); + FIELD("IADDR1", "0x%.16llx", (u64)((u64)val) << 32); + break; + case 0x11c: /* FEC_HASH_TABLE_LOW */ + REG(reg, "IALR (Individual Address Lower Register)", val); + FIELD("IADDR2", "0x%.16x", val); + break; + case 0x120: /* FEC_GRP_HASH_TABLE_HIGH */ + REG(reg, "GAUR (Group Address Upper Register)", val); + FIELD("GADDR1", "0x%.16llx", (u64)((u64)val) << 32); + break; + case 0x124: /* FEC_GRP_HASH_TABLE_LOW */ + REG(reg, "GALR (Group Address Lower Register)", val); + FIELD("GADDR2", "0x%.16x", val); + break; + case 0x144: /* FEC_X_WMRK */ + REG(reg, "TFWR (Transmit FIFO Watermark Register)", val); + FIELD("X_WMRK", "%s", + (val & 0x00000003) == 0x00000000 ? "64 bytes" : + (val & 0x00000003) == 0x00000002 ? "128 bytes" : + (val & 0x00000003) == 0x00000003 ? "192 bytes" : "?"); + break; + case 0x14c: /* FEC_R_BOUND */ + REG(reg, "FRBR (FIFO Receive Bound Register)", val); + FIELD("R_BOUND (Highest valid FIFO RAM address)", "0x%.2x", (val & 0x000003fc) >> 2); + break; + case 0x188: /* FEC_R_BUFF_SIZE_0 */ + REG(reg, "EMRBR (Maximum Receive Buffer Size)", val); + FIELD("R_BUF_SIZE (Receive buffer size)", "%u", (val & 0x000007f0) >> 4); + break; + case 0x004: /* FEC_IEVENT */ + case 0x008: /* FEC_IMASK */ + case 0x010: /* FEC_R_DES_ACTIVE_0 */ + case 0x014: /* FEC_X_DES_ACTIVE_0 */ + case 0x024: /* FEC_ECNTRL */ + case 0x040: /* FEC_MII_DATA */ + case 0x044: /* FEC_MII_SPEED */ + case 0x064: /* FEC_MIB_CTRLSTAT */ + case 0x0e4: /* FEC_ADDR_LOW */ + case 0x0e8: /* FEC_ADDR_HIGH */ + case 0x0ec: /* FEC_OPD */ + case 0x0f0: /* FEC_TXIC0 */ + case 0x0f4: /* FEC_TXIC1 */ + case 0x0f8: /* FEC_TXIC2 */ + case 0x100: /* FEC_RXIC0 */ + case 0x104: /* FEC_RXIC1 */ + case 0x108: /* FEC_RXIC2 */ + case 0x150: /* FEC_R_FSTART */ + case 0x160: /* FEC_R_DES_START_1 */ + case 0x164: /* FEC_X_DES_START_1 */ + case 0x168: /* FEC_R_BUFF_SIZE_1 */ + case 0x16c: /* FEC_R_DES_START_2 */ + case 0x170: /* FEC_X_DES_START_2 */ + case 0x174: /* FEC_R_BUFF_SIZE_2 */ + case 0x180: /* FEC_R_DES_START_0 */ + case 0x184: /* FEC_X_DES_START_0 */ + case 0x190: /* FEC_R_FIFO_RSFL */ + case 0x194: /* FEC_R_FIFO_RSEM */ + case 0x198: /* FEC_R_FIFO_RAEM */ + case 0x19c: /* FEC_R_FIFO_RAFL */ + case 0x1c4: /* FEC_RACC */ + case 0x1c8: /* FEC_RCMR_1 */ + case 0x1cc: /* FEC_RCMR_2 */ + case 0x1d8: /* FEC_DMA_CFG_1 */ + case 0x1dc: /* FEC_DMA_CFG_2 */ + case 0x1e0: /* FEC_R_DES_ACTIVE_1 */ + case 0x1e4: /* FEC_X_DES_ACTIVE_1 */ + case 0x1e8: /* FEC_R_DES_ACTIVE_2 */ + case 0x1ec: /* FEC_X_DES_ACTIVE_2 */ + case 0x1f0: /* FEC_QOS_SCHEME */ + case 0x200: /* RMON_T_DROP */ + case 0x204: /* RMON_T_PACKETS */ + case 0x208: /* RMON_T_BC_PKT */ + case 0x20c: /* RMON_T_MC_PKT */ + case 0x210: /* RMON_T_CRC_ALIGN */ + case 0x214: /* RMON_T_UNDERSIZE */ + case 0x218: /* RMON_T_OVERSIZE */ + case 0x21c: /* RMON_T_FRAG */ + case 0x220: /* RMON_T_JAB */ + case 0x224: /* RMON_T_COL */ + case 0x228: /* RMON_T_P64 */ + case 0x22c: /* RMON_T_P65TO127 */ + case 0x230: /* RMON_T_P128TO255 */ + case 0x234: /* RMON_T_P256TO511 */ + case 0x238: /* RMON_T_P512TO1023 */ + case 0x23c: /* RMON_T_P1024TO2047 */ + case 0x240: /* RMON_T_P_GTE2048 */ + case 0x244: /* RMON_T_OCTETS */ + case 0x248: /* IEEE_T_DROP */ + case 0x24c: /* IEEE_T_FRAME_OK */ + case 0x250: /* IEEE_T_1COL */ + case 0x254: /* IEEE_T_MCOL */ + case 0x258: /* IEEE_T_DEF */ + case 0x25c: /* IEEE_T_LCOL */ + case 0x260: /* IEEE_T_EXCOL */ + case 0x264: /* IEEE_T_MACERR */ + case 0x268: /* IEEE_T_CSERR */ + case 0x26c: /* IEEE_T_SQE */ + case 0x270: /* IEEE_T_FDXFC */ + case 0x274: /* IEEE_T_OCTETS_OK */ + case 0x284: /* RMON_R_PACKETS */ + case 0x288: /* RMON_R_BC_PKT */ + case 0x28c: /* RMON_R_MC_PKT */ + case 0x290: /* RMON_R_CRC_ALIGN */ + case 0x294: /* RMON_R_UNDERSIZE */ + case 0x298: /* RMON_R_OVERSIZE */ + case 0x29c: /* RMON_R_FRAG */ + case 0x2a0: /* RMON_R_JAB */ + case 0x2a4: /* RMON_R_RESVD_O */ + case 0x2a8: /* RMON_R_P64 */ + case 0x2ac: /* RMON_R_P65TO127 */ + case 0x2b0: /* RMON_R_P128TO255 */ + case 0x2b4: /* RMON_R_P256TO511 */ + case 0x2b8: /* RMON_R_P512TO1023 */ + case 0x2bc: /* RMON_R_P1024TO2047 */ + case 0x2c0: /* RMON_R_P_GTE2048 */ + case 0x2c4: /* RMON_R_OCTETS */ + case 0x2c8: /* IEEE_R_DROP */ + case 0x2cc: /* IEEE_R_FRAME_OK */ + case 0x2d0: /* IEEE_R_CRC */ + case 0x2d4: /* IEEE_R_ALIGN */ + case 0x2d8: /* IEEE_R_MACERR */ + case 0x2dc: /* IEEE_R_FDXFC */ + case 0x2e0: /* IEEE_R_OCTETS_OK */ + REG(reg, "", val); + break; + } +} + +#undef FIELD +#undef REG + +int fec_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + const u32 *data = (u32 *)regs->data; + unsigned int offset; + u32 val; + + for (offset = 0; offset < regs->len; offset += 4) { + val = data[offset / 4]; + + switch (regs->version) { + case 1: + fec_dump_reg_v1(offset, val); + break; + case 2: + fec_dump_reg_v2(offset, val); + break; + default: + return 1; + } + } + + return 0; +} diff --git a/fec_8xx.c b/fec_8xx.c new file mode 100644 index 0000000..63352fc --- /dev/null +++ b/fec_8xx.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2004 Intracom S.A. + * Pantelis Antoniou + */ + +#include +#include +#include + +#include "internal.h" + +struct fec { + uint32_t addr_low; /* lower 32 bits of station address */ + uint32_t addr_high; /* upper 16 bits of station address||0 */ + uint32_t hash_table_high;/* upper 32-bits of hash table */ + uint32_t hash_table_low; /* lower 32-bits of hash table */ + uint32_t r_des_start; /* beginning of Rx descriptor ring */ + uint32_t x_des_start; /* beginning of Tx descriptor ring */ + uint32_t r_buff_size; /* Rx buffer size */ + uint32_t res2[9]; /* reserved */ + uint32_t ecntrl; /* ethernet control register */ + uint32_t ievent; /* interrupt event register */ + uint32_t imask; /* interrupt mask register */ + uint32_t ivec; /* interrupt level and vector status */ + uint32_t r_des_active; /* Rx ring updated flag */ + uint32_t x_des_active; /* Tx ring updated flag */ + uint32_t res3[10]; /* reserved */ + uint32_t mii_data; /* MII data register */ + uint32_t mii_speed; /* MII speed control register */ + uint32_t res4[17]; /* reserved */ + uint32_t r_bound; /* end of RAM (read-only) */ + uint32_t r_fstart; /* Rx FIFO start address */ + uint32_t res5[6]; /* reserved */ + uint32_t x_fstart; /* Tx FIFO start address */ + uint32_t res6[17]; /* reserved */ + uint32_t fun_code; /* fec SDMA function code */ + uint32_t res7[3]; /* reserved */ + uint32_t r_cntrl; /* Rx control register */ + uint32_t r_hash; /* Rx hash register */ + uint32_t res8[14]; /* reserved */ + uint32_t x_cntrl; /* Tx control register */ + uint32_t res9[0x1e]; /* reserved */ +}; + +#define DUMP_REG(f, x) fprintf(stdout, \ + "0x%04lx: %-16s 0x%08x\n", \ + (unsigned long)(offsetof(struct fec, x)), \ + #x, f->x) + +int fec_8xx_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + struct fec *f = (struct fec *)regs->data; + + fprintf(stdout, "Descriptor Registers\n"); + fprintf(stdout, "---------------------\n"); + + DUMP_REG(f, addr_low); + DUMP_REG(f, addr_high); + DUMP_REG(f, hash_table_high); + DUMP_REG(f, hash_table_low); + DUMP_REG(f, r_des_start); + DUMP_REG(f, x_des_start); + DUMP_REG(f, r_buff_size); + DUMP_REG(f, ecntrl); + DUMP_REG(f, ievent); + DUMP_REG(f, imask); + DUMP_REG(f, ivec); + DUMP_REG(f, r_des_active); + DUMP_REG(f, x_des_active); + DUMP_REG(f, mii_data); + DUMP_REG(f, mii_speed); + DUMP_REG(f, r_bound); + DUMP_REG(f, r_fstart); + DUMP_REG(f, x_fstart); + DUMP_REG(f, fun_code); + DUMP_REG(f, r_cntrl); + DUMP_REG(f, r_hash); + DUMP_REG(f, x_cntrl); + + return 0; +} diff --git a/fjes.c b/fjes.c new file mode 100644 index 0000000..05bd245 --- /dev/null +++ b/fjes.c @@ -0,0 +1,90 @@ +/* Copyright (c) 2016 FUJITSU LIMITED */ +#include +#include "internal.h" + +int fjes_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *regs_buff = (u32 *)regs->data; + + if (regs->version != 1) + return -1; + + /* Information registers */ + fprintf(stdout, + "0x0000: OWNER_EPID (Owner EPID) 0x%08X\n", + regs_buff[0]); + + fprintf(stdout, + "0x0004: MAX_EP (Maximum EP) 0x%08X\n", + regs_buff[1]); + + /* Device Control registers */ + fprintf(stdout, + "0x0010: DCTL (Device Control) 0x%08X\n", + regs_buff[4]); + + /* Command Control registers */ + fprintf(stdout, + "0x0020: CR (Command request) 0x%08X\n", + regs_buff[8]); + + fprintf(stdout, + "0x0024: CS (Command status) 0x%08X\n", + regs_buff[9]); + + fprintf(stdout, + "0x0028: SHSTSAL (Share status address Low) 0x%08X\n", + regs_buff[10]); + + fprintf(stdout, + "0x002C: SHSTSAH (Share status address High) 0x%08X\n", + regs_buff[11]); + + fprintf(stdout, + "0x0034: REQBL (Request Buffer length) 0x%08X\n", + regs_buff[13]); + + fprintf(stdout, + "0x0038: REQBAL (Request Buffer Address Low) 0x%08X\n", + regs_buff[14]); + + fprintf(stdout, + "0x003C: REQBAH (Request Buffer Address High) 0x%08X\n", + regs_buff[15]); + + fprintf(stdout, + "0x0044: RESPBL (Response Buffer Length) 0x%08X\n", + regs_buff[17]); + + fprintf(stdout, + "0x0048: RESPBAL (Response Buffer Address Low) 0x%08X\n", + regs_buff[18]); + + fprintf(stdout, + "0x004C: RESPBAH (Response Buffer Address High) 0x%08X\n", + regs_buff[19]); + + /* Interrupt Control registers */ + fprintf(stdout, + "0x0080: IS (Interrupt status) 0x%08X\n", + regs_buff[32]); + + fprintf(stdout, + "0x0084: IMS (Interrupt mask set) 0x%08X\n", + regs_buff[33]); + + fprintf(stdout, + "0x0088: IMC (Interrupt mask clear) 0x%08X\n", + regs_buff[34]); + + fprintf(stdout, + "0x008C: IG (Interrupt generator) 0x%08X\n", + regs_buff[35]); + + fprintf(stdout, + "0x0090: ICTL (Interrupt control) 0x%08X\n", + regs_buff[36]); + + return 0; +} diff --git a/fsl_enetc.c b/fsl_enetc.c new file mode 100644 index 0000000..1180a66 --- /dev/null +++ b/fsl_enetc.c @@ -0,0 +1,259 @@ +/* Code to dump registers for the Freescale/NXP ENETC controller. + * + * Copyright 2022 NXP + */ +#include +#include "internal.h" + +#define BIT(x) (1U << (x)) + +enum enetc_bdr_type {TX, RX}; +#define ENETC_SIMR 0 +#define ENETC_SIPMAR0 0x80 +#define ENETC_SIPMAR1 0x84 +#define ENETC_SICBDRMR 0x800 +#define ENETC_SICBDRSR 0x804 +#define ENETC_SICBDRBAR0 0x810 +#define ENETC_SICBDRBAR1 0x814 +#define ENETC_SICBDRPIR 0x818 +#define ENETC_SICBDRCIR 0x81c +#define ENETC_SICBDRLENR 0x820 +#define ENETC_SICAPR0 0x900 +#define ENETC_SICAPR1 0x904 +#define ENETC_SIUEFDCR 0xe28 + +#define ENETC_BDR_OFF(i) ((i) * 0x200) +#define ENETC_BDR(t, i, r) (0x8000 + (t) * 0x100 + ENETC_BDR_OFF(i) + (r)) + +/* RX BDR reg offsets */ +#define ENETC_RBMR 0 +#define ENETC_RBSR 0x4 +#define ENETC_RBBSR 0x8 +#define ENETC_RBCIR 0xc +#define ENETC_RBBAR0 0x10 +#define ENETC_RBBAR1 0x14 +#define ENETC_RBPIR 0x18 +#define ENETC_RBLENR 0x20 +#define ENETC_RBIER 0xa0 +#define ENETC_RBICR0 0xa8 +#define ENETC_RBICR1 0xac + +/* TX BDR reg offsets */ +#define ENETC_TBMR 0 +#define ENETC_TBSR 0x4 +#define ENETC_TBBAR0 0x10 +#define ENETC_TBBAR1 0x14 +#define ENETC_TBPIR 0x18 +#define ENETC_TBCIR 0x1c +#define ENETC_TBLENR 0x20 +#define ENETC_TBIER 0xa0 +#define ENETC_TBIDR 0xa4 +#define ENETC_TBICR0 0xa8 +#define ENETC_TBICR1 0xac + +/* Port registers */ +#define ENETC_PORT_BASE 0x10000 +#define ENETC_PMR ENETC_PORT_BASE + 0x0000 +#define ENETC_PSR ENETC_PORT_BASE + 0x0004 +#define ENETC_PSIPMR ENETC_PORT_BASE + 0x0018 +#define ENETC_PSIPMAR0(n) ENETC_PORT_BASE + (0x0100 + (n) * 0x8) /* n = SI index */ +#define ENETC_PSIPMAR1(n) ENETC_PORT_BASE + (0x0104 + (n) * 0x8) +#define ENETC_PTXMBAR ENETC_PORT_BASE + 0x0608 +#define ENETC_PCAPR0 ENETC_PORT_BASE + 0x0900 +#define ENETC_PCAPR1 ENETC_PORT_BASE + 0x0904 +#define ENETC_PSICFGR0(n) ENETC_PORT_BASE + (0x0940 + (n) * 0xc) /* n = SI index */ + +#define ENETC_PRFSCAPR ENETC_PORT_BASE + 0x1804 +#define ENETC_PTCMSDUR(n) ENETC_PORT_BASE + (0x2020 + (n) * 4) /* n = TC index [0..7] */ + +#define ENETC_PM0_CMD_CFG ENETC_PORT_BASE + 0x8008 +#define ENETC_PM0_CMD_TX_EN BIT(0) +#define ENETC_PM0_CMD_RX_EN BIT(1) +#define ENETC_PM0_CMD_WAN BIT(3) +#define ENETC_PM0_CMD_PROMISC BIT(4) +#define ENETC_PM0_CMD_PAD BIT(5) +#define ENETC_PM0_CMD_CRC BIT(6) +#define ENETC_PM0_CMD_PAUSE_FWD BIT(7) +#define ENETC_PM0_CMD_PAUSE_IGN BIT(8) +#define ENETC_PM0_CMD_TX_ADDR_INS BIT(9) +#define ENETC_PM0_CMD_XGLP BIT(10) +#define ENETC_PM0_CMD_TXP BIT(11) +#define ENETC_PM0_CMD_SWR BIT(12) +#define ENETC_PM0_CMD_CNT_FRM_EN BIT(13) +#define ENETC_PM0_CMD_SEND_IDLE BIT(16) +#define ENETC_PM0_CMD_NO_LEN_CHK BIT(17) +#define ENETC_PM0_CMD_SFD BIT(21) +#define ENETC_PM0_CMD_TX_LOWP_ENA BIT(23) +#define ENETC_PM0_CMD_REG_LOWP_RXETY BIT(24) +#define ENETC_PM0_CMD_RXSTP BIT(29) +#define ENETC_PM0_CMD_MG BIT(31) + +#define ENETC_PM0_MAXFRM ENETC_PORT_BASE + 0x8014 +#define ENETC_PM0_IF_MODE ENETC_PORT_BASE + 0x8300 + +struct enetc_register { + u32 addr; + const char *name; + void (*decode)(u32 val, char *buf); +}; + +#define REG(_reg, _name) { .addr = (_reg), .name = (_name) } + +#define REG_DEC(_reg, _name, _decode) \ + { .addr = (_reg), .name = (_name), .decode = (_decode) } + +static void decode_cmd_cfg(u32 val, char *buf) +{ + sprintf(buf, "\tMG %d\n\tRXSTP %d\n\tREG_LOWP_RXETY %d\n" + "\tTX_LOWP_ENA %d\n\tSFD %d\n\tNO_LEN_CHK %d\n\tSEND_IDLE %d\n" + "\tCNT_FRM_EN %d\n\tSWR %d\n\tTXP %d\n\tXGLP %d\n" + "\tTX_ADDR_INS %d\n\tPAUSE_IGN %d\n\tPAUSE_FWD %d\n\tCRC %d\n" + "\tPAD %d\n\tPROMIS %d\n\tWAN %d\n\tRX_EN %d\n\tTX_EN %d\n", + !!(val & ENETC_PM0_CMD_MG), + !!(val & ENETC_PM0_CMD_RXSTP), + !!(val & ENETC_PM0_CMD_REG_LOWP_RXETY), + !!(val & ENETC_PM0_CMD_TX_LOWP_ENA), + !!(val & ENETC_PM0_CMD_SFD), + !!(val & ENETC_PM0_CMD_NO_LEN_CHK), + !!(val & ENETC_PM0_CMD_SEND_IDLE), + !!(val & ENETC_PM0_CMD_CNT_FRM_EN), + !!(val & ENETC_PM0_CMD_SWR), + !!(val & ENETC_PM0_CMD_TXP), + !!(val & ENETC_PM0_CMD_XGLP), + !!(val & ENETC_PM0_CMD_TX_ADDR_INS), + !!(val & ENETC_PM0_CMD_PAUSE_IGN), + !!(val & ENETC_PM0_CMD_PAUSE_FWD), + !!(val & ENETC_PM0_CMD_CRC), + !!(val & ENETC_PM0_CMD_PAD), + !!(val & ENETC_PM0_CMD_PROMISC), + !!(val & ENETC_PM0_CMD_WAN), + !!(val & ENETC_PM0_CMD_RX_EN), + !!(val & ENETC_PM0_CMD_TX_EN)); +} + +#define RXBDR_REGS(_i) \ + REG(ENETC_BDR(RX, (_i), ENETC_RBMR), "RX BDR " #_i " mode register"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBSR), "RX BDR " #_i " status register"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBBSR), "RX BDR " #_i " buffer size register"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBPIR), "RX BDR " #_i " producer index register"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBCIR), "RX BDR " #_i " consumer index register"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBBAR0), "RX BDR " #_i " base address register 0"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBBAR1), "RX BDR " #_i " base address register 1"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBLENR), "RX BDR " #_i " length register"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBIER), "RX BDR " #_i " interrupt enable register"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBICR0), "RX BDR " #_i " interrupt coalescing register 0"), \ + REG(ENETC_BDR(RX, (_i), ENETC_RBICR1), "RX BDR " #_i " interrupt coalescing register 1") + +#define TXBDR_REGS(_i) \ + REG(ENETC_BDR(TX, (_i), ENETC_TBMR), "TX BDR " #_i " mode register"), \ + REG(ENETC_BDR(TX, (_i), ENETC_TBSR), "TX BDR " #_i " status register"), \ + REG(ENETC_BDR(TX, (_i), ENETC_TBBAR0), "TX BDR " #_i " base address register 0"), \ + REG(ENETC_BDR(TX, (_i), ENETC_TBBAR1), "TX BDR " #_i " base address register 1"), \ + REG(ENETC_BDR(TX, (_i), ENETC_TBPIR), "TX BDR " #_i " producer index register"), \ + REG(ENETC_BDR(TX, (_i), ENETC_TBCIR), "TX BDR " #_i " consumer index register"), \ + REG(ENETC_BDR(TX, (_i), ENETC_TBLENR), "TX BDR " #_i " length register"), \ + REG(ENETC_BDR(TX, (_i), ENETC_TBIER), "TX BDR " #_i " interrupt enable register"), \ + REG(ENETC_BDR(TX, (_i), ENETC_TBICR0), "TX BDR " #_i " interrupt coalescing register 0"), \ + REG(ENETC_BDR(TX, (_i), ENETC_TBICR1), "TX BDR " #_i " interrupt coalescing register 1") + +static const struct enetc_register known_enetc_regs[] = { + REG(ENETC_SIMR, "SI mode register"), + REG(ENETC_SIPMAR0, "SI primary MAC address register 0"), + REG(ENETC_SIPMAR1, "SI primary MAC address register 1"), + REG(ENETC_SICBDRMR, "SI control BDR mode register"), + REG(ENETC_SICBDRSR, "SI control BDR status register"), + REG(ENETC_SICBDRBAR0, "SI control BDR base address register 0"), + REG(ENETC_SICBDRBAR1, "SI control BDR base address register 1"), + REG(ENETC_SICBDRPIR, "SI control BDR producer index register"), + REG(ENETC_SICBDRCIR, "SI control BDR consumer index register"), + REG(ENETC_SICBDRLENR, "SI control BDR length register"), + REG(ENETC_SICAPR0, "SI capability register 0"), + REG(ENETC_SICAPR1, "SI capability register 1"), + REG(ENETC_SIUEFDCR, "SI uncorrectable error frame drop count register"), + + TXBDR_REGS(0), TXBDR_REGS(1), TXBDR_REGS(2), TXBDR_REGS(3), + TXBDR_REGS(4), TXBDR_REGS(5), TXBDR_REGS(6), TXBDR_REGS(7), + TXBDR_REGS(8), TXBDR_REGS(9), TXBDR_REGS(10), TXBDR_REGS(11), + TXBDR_REGS(12), TXBDR_REGS(13), TXBDR_REGS(14), TXBDR_REGS(15), + + RXBDR_REGS(0), RXBDR_REGS(1), RXBDR_REGS(2), RXBDR_REGS(3), + RXBDR_REGS(4), RXBDR_REGS(5), RXBDR_REGS(6), RXBDR_REGS(7), + RXBDR_REGS(8), RXBDR_REGS(9), RXBDR_REGS(10), RXBDR_REGS(11), + RXBDR_REGS(12), RXBDR_REGS(13), RXBDR_REGS(14), RXBDR_REGS(15), + + REG(ENETC_PMR, "Port mode register"), + REG(ENETC_PSR, "Port status register"), + REG(ENETC_PSIPMR, "Port SI promiscuous mode register"), + REG(ENETC_PSIPMAR0(0), "Port SI0 primary MAC address register 0"), + REG(ENETC_PSIPMAR1(0), "Port SI0 primary MAC address register 1"), + REG(ENETC_PTXMBAR, "Port HTA transmit memory buffer allocation register"), + REG(ENETC_PCAPR0, "Port capability register 0"), + REG(ENETC_PCAPR1, "Port capability register 1"), + REG(ENETC_PSICFGR0(0), "Port SI0 configuration register 0"), + REG(ENETC_PRFSCAPR, "Port RFS capability register"), + REG(ENETC_PTCMSDUR(0), "Port traffic class 0 maximum SDU register"), + REG_DEC(ENETC_PM0_CMD_CFG, "Port eMAC Command and Configuration Register", + decode_cmd_cfg), + REG(ENETC_PM0_MAXFRM, "Port eMAC Maximum Frame Length Register"), + REG(ENETC_PM0_IF_MODE, "Port eMAC Interface Mode Control Register"), +}; + +static void decode_known_reg(const struct enetc_register *reg, u32 val) +{ + char buf[512]; + + reg->decode(val, buf); + fprintf(stdout, "%s: 0x%x\n%s", reg->name, val, buf); +} + +static void dump_known_reg(const struct enetc_register *reg, u32 val) +{ + fprintf(stdout, "%s: 0x%x\n", reg->name, val); +} + +static void dump_unknown_reg(u32 addr, u32 val) +{ + fprintf(stdout, "Reg 0x%x: 0x%x\n", addr, val); +} + +static void dump_reg(u32 addr, u32 val) +{ + const struct enetc_register *reg; + u32 i; + + for (i = 0; i < ARRAY_SIZE(known_enetc_regs); i++) { + reg = &known_enetc_regs[i]; + if (reg->addr == addr) { + if (reg->decode) + decode_known_reg(reg, val); + else + dump_known_reg(reg, val); + return; + } + } + + dump_unknown_reg(addr, val); +} + +/* Registers are structured in an array of key/value u32 pairs. + * Compare each key to our list of known registers, or print it + * as a raw address otherwise. + */ +int fsl_enetc_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *data = (u32 *)regs->data; + u32 len = regs->len; + + if (len % 8) { + fprintf(stdout, "Expected length to be multiple of 8 bytes\n"); + return -1; + } + + while (len) { + dump_reg(data[0], data[1]); + data += 2; len -= 8; + } + + return 0; +} diff --git a/ibm_emac.c b/ibm_emac.c new file mode 100644 index 0000000..9f7cae6 --- /dev/null +++ b/ibm_emac.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2004, 2005 Zultys Technologies + * Eugene Surovegin or + */ +#include +#include +#include + +#include "internal.h" + +/* Ethtool get_regs complex data. + * we want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH + * when available. + * + * Returned BLOB consists of the ibm_emac_ethtool_regs_hdr, + * MAL registers, EMAC registers and optional ZMII, RGMII, TAH registers. + * Each register component is preceded with emac_ethtool_regs_subhdr. + * Order of the optional headers follows their relative bit posititions + * in emac_ethtool_regs_hdr.components + */ +#define EMAC_ETHTOOL_REGS_ZMII 0x00000001 +#define EMAC_ETHTOOL_REGS_RGMII 0x00000002 +#define EMAC_ETHTOOL_REGS_TAH 0x00000004 + +#define EMAC_VERSION 3 +#define EMAC4_VERSION 4 +#define EMAC4SYNC_VERSION 5 + +struct emac_ethtool_regs_hdr { + u32 components; +}; + +struct emac_ethtool_regs_subhdr { + u32 version; + u32 index; +}; + +struct emac_regs { + /* Common registers across all EMAC implementations. */ + u32 mr0; /* Special */ + u32 mr1; /* Reset */ + u32 tmr0; /* Special */ + u32 tmr1; /* Special */ + u32 rmr; /* Reset */ + u32 isr; /* Always */ + u32 iser; /* Reset */ + u32 iahr; /* Reset, R, T */ + u32 ialr; /* Reset, R, T */ + u32 vtpid; /* Reset, R, T */ + u32 vtci; /* Reset, R, T */ + u32 ptr; /* Reset, T */ + union { + /* Registers unique to EMAC4 implementations */ + struct { + u32 iaht1; /* Reset, R */ + u32 iaht2; /* Reset, R */ + u32 iaht3; /* Reset, R */ + u32 iaht4; /* Reset, R */ + u32 gaht1; /* Reset, R */ + u32 gaht2; /* Reset, R */ + u32 gaht3; /* Reset, R */ + u32 gaht4; /* Reset, R */ + } emac4; + /* Registers unique to EMAC4SYNC implementations */ + struct { + u32 mahr; /* Reset, R, T */ + u32 malr; /* Reset, R, T */ + u32 mmahr; /* Reset, R, T */ + u32 mmalr; /* Reset, R, T */ + u32 rsvd0[4]; + } emac4sync; + } u0; + /* Common registers across all EMAC implementations. */ + u32 lsah; + u32 lsal; + u32 ipgvr; /* Reset, T */ + u32 stacr; /* Special */ + u32 trtr; /* Special */ + u32 rwmr; /* Reset */ + u32 octx; + u32 ocrx; + union { + /* Registers unique to EMAC4 implementations */ + struct { + u32 ipcr; + } emac4; + /* Registers unique to EMAC4SYNC implementations */ + struct { + u32 rsvd1; + u32 revid; + u32 rsvd2[2]; + u32 iaht1; /* Reset, R */ + u32 iaht2; /* Reset, R */ + u32 iaht3; /* Reset, R */ + u32 iaht4; /* Reset, R */ + u32 iaht5; /* Reset, R */ + u32 iaht6; /* Reset, R */ + u32 iaht7; /* Reset, R */ + u32 iaht8; /* Reset, R */ + u32 gaht1; /* Reset, R */ + u32 gaht2; /* Reset, R */ + u32 gaht3; /* Reset, R */ + u32 gaht4; /* Reset, R */ + u32 gaht5; /* Reset, R */ + u32 gaht6; /* Reset, R */ + u32 gaht7; /* Reset, R */ + u32 gaht8; /* Reset, R */ + u32 tpc; /* Reset, T */ + } emac4sync; + } u1; +}; + +struct mal_regs { + u32 tx_count; + u32 rx_count; + + u32 cfg; + u32 esr; + u32 ier; + u32 tx_casr; + u32 tx_carr; + u32 tx_eobisr; + u32 tx_deir; + u32 rx_casr; + u32 rx_carr; + u32 rx_eobisr; + u32 rx_deir; + u32 tx_ctpr[32]; + u32 rx_ctpr[32]; + u32 rcbs[32]; +}; + +struct zmii_regs { + u32 fer; + u32 ssr; + u32 smiisr; +}; + +struct rgmii_regs { + u32 fer; + u32 ssr; +}; + +struct tah_regs { + u32 revid; + u32 pad[3]; + u32 mr; + u32 ssr0; + u32 ssr1; + u32 ssr2; + u32 ssr3; + u32 ssr4; + u32 ssr5; + u32 tsr; +}; + +static void *print_emac_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct emac_regs *p = (struct emac_regs *)(hdr + 1); + void *res = p + 1; + + if (!((hdr->version == EMAC_VERSION) || + (hdr->version == EMAC4_VERSION) || + (hdr->version == EMAC4SYNC_VERSION))) + { + printf("This driver version doesn't support information\n" + " output for EMAC area, please update it or use older\n" + " ethtool version\n"); + return res; + } + + printf("EMAC%d Registers\n", hdr->index); + printf("-----------------\n"); + printf("MR0 = 0x%08x MR1 = 0x%08x RMR = 0x%08x\n" + "ISR = 0x%08x ISER = 0x%08x\n" + "TMR0 = 0x%08x TMR1 = 0x%08x\n" + "TRTR = 0x%08x RWMR = 0x%08x\n" + "IAR = %04x%08x\n" + "LSA = %04x%08x\n" + "VTPID = 0x%04x VTCI = 0x%04x\n" + "IPGVR = 0x%04x STACR = 0x%08x\n" + "OCTX = 0x%08x OCRX = 0x%08x\n", + p->mr0, p->mr1, p->rmr, + p->isr, p->iser, + p->tmr0, p->tmr1, + p->trtr, p->rwmr, + p->iahr, p->ialr, + p->lsah, p->lsal, + p->vtpid, p->vtci, + p->ipgvr, p->stacr, p->octx, p->ocrx); + + if (hdr->version == EMAC4SYNC_VERSION) { + printf("MAHR = 0x%08x MALR = 0x%08x MMAHR = 0x%08x\n" + "MMALR = 0x%08x REVID = 0x%08x\n", + p->u0.emac4sync.mahr, p->u0.emac4sync.malr, + p->u0.emac4sync.mmahr, p->u0.emac4sync.mmalr, + p->u1.emac4sync.revid); + + printf("IAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n", + p->u1.emac4sync.iaht1, p->u1.emac4sync.iaht2, + p->u1.emac4sync.iaht3, p->u1.emac4sync.iaht4); + printf(" 0x%04x 0x%04x 0x%04x 0x%04x\n", + p->u1.emac4sync.iaht5, p->u1.emac4sync.iaht6, + p->u1.emac4sync.iaht7, p->u1.emac4sync.iaht8); + + + printf("GAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n", + p->u1.emac4sync.gaht1, p->u1.emac4sync.gaht2, + p->u1.emac4sync.gaht3, p->u1.emac4sync.gaht4); + printf(" 0x%04x 0x%04x 0x%04x 0x%04x\n\n", + p->u1.emac4sync.gaht5, p->u1.emac4sync.gaht6, + p->u1.emac4sync.gaht7, p->u1.emac4sync.gaht8); + + } else if (hdr->version == EMAC4_VERSION) { + printf("IAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n", + p->u0.emac4.iaht1, p->u0.emac4.iaht2, + p->u0.emac4.iaht3, p->u0.emac4.iaht4); + + printf("GAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n", + p->u0.emac4.gaht1, p->u0.emac4.gaht2, + p->u0.emac4.gaht3, p->u0.emac4.gaht4); + + printf(" IPCR = 0x%08x\n\n", p->u1.emac4.ipcr); + } else if (hdr->version == EMAC_VERSION) { + printf("IAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n", + p->u0.emac4.iaht1, p->u0.emac4.iaht2, + p->u0.emac4.iaht3, p->u0.emac4.iaht4); + + printf("GAHT = 0x%04x 0x%04x 0x%04x 0x%04x\n", + p->u0.emac4.gaht1, p->u0.emac4.gaht2, + p->u0.emac4.gaht3, p->u0.emac4.gaht4); + } + return res; +} + +static void *print_mal_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct mal_regs *p = (struct mal_regs *)(hdr + 1); + unsigned int i; + + printf("MAL%d Registers\n", hdr->index); + printf("-----------------\n"); + printf("CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n" + "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n" + "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n", + p->cfg, p->esr, p->ier, + p->tx_casr, p->tx_carr, p->tx_eobisr, p->tx_deir, + p->rx_casr, p->rx_carr, p->rx_eobisr, p->rx_deir); + + printf("TX|"); + for (i = 0; i < p->tx_count; ++i) { + if (i && !(i % 4)) + printf("\n "); + printf("CTP%d = 0x%08x ", i, p->tx_ctpr[i]); + } + printf("\nRX|"); + for (i = 0; i < p->rx_count; ++i) { + if (i && !(i % 4)) + printf("\n "); + printf("CTP%d = 0x%08x ", i, p->rx_ctpr[i]); + } + printf("\n "); + for (i = 0; i < p->rx_count; ++i) { + u32 r = p->rcbs[i]; + if (i && !(i % 3)) + printf("\n "); + printf("RCBS%d = 0x%08x (%d) ", i, r, r * 16); + } + printf("\n\n"); + return p + 1; +} + +static void *print_zmii_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct zmii_regs *p = (struct zmii_regs *)(hdr + 1); + + printf("ZMII%d Registers\n", hdr->index); + printf("-----------------\n"); + printf("FER = %08x SSR = %08x\n" + "SMIISR = %08x\n\n", p->fer, p->ssr, p->smiisr); + + return p + 1; +} + +static void *print_rgmii_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct rgmii_regs *p = (struct rgmii_regs *)(hdr + 1); + + printf("RGMII%d Registers\n", hdr->index); + printf("-----------------\n"); + printf("FER = %08x SSR = %08x\n\n", p->fer, p->ssr); + + return p + 1; +} + +static void *print_tah_regs(void *buf) +{ + struct emac_ethtool_regs_subhdr *hdr = buf; + struct tah_regs *p = (struct tah_regs *)(hdr + 1); + + printf("TAH%d Registers\n", hdr->index); + printf("-----------------\n"); + + printf("REVID = %08x MR = %08x TSR = %08x\n" + "SSR0 = %08x SSR1 = %08x SSR2 = %08x\n" + "SSR3 = %08x SSR4 = %08x SSR5 = %08x\n\n", + p->revid, p->mr, p->tsr, + p->ssr0, p->ssr1, p->ssr2, p->ssr3, p->ssr4, p->ssr5); + + return p + 1; +} + +int ibm_emac_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + struct emac_ethtool_regs_hdr *hdr = + (struct emac_ethtool_regs_hdr *)regs->data; + void *buf = hdr + 1; + + buf = print_mal_regs(buf); + buf = print_emac_regs(buf); + if (hdr->components & EMAC_ETHTOOL_REGS_ZMII) + buf = print_zmii_regs(buf); + if (hdr->components & EMAC_ETHTOOL_REGS_RGMII) + buf = print_rgmii_regs(buf); + if (hdr->components & EMAC_ETHTOOL_REGS_TAH) + print_tah_regs(buf); + + return 0; +} diff --git a/igb.c b/igb.c new file mode 100644 index 0000000..f358f53 --- /dev/null +++ b/igb.c @@ -0,0 +1,876 @@ +/* Copyright (c) 2007 Intel Corporation */ +#include +#include "internal.h" + +/* Register Bit Masks */ +/* Device Control */ +#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ +#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */ +#define E1000_CTRL_GIOMASTERD 0x00000008 /* GIO Master Disable*/ +#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */ +#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */ +#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */ +#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ +#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ +#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ +#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ +#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ +#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ +#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ +#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ +#define E1000_CTRL_SDP0_GPIEN 0x00010000 /* General Purpose Interrupt Detection Enable for SDP0 */ +#define E1000_CTRL_SDP1_GPIEN 0x00020000 /* General Purpose Interrupt Detection Enable for SDP1 */ +#define E1000_CTRL_SDP0_DATA 0x00040000 /* SDP0 Data */ +#define E1000_CTRL_SDP1_DATA 0x00080000 /* SDP1 Data */ +#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3Cold WakeUp Capability Advertisement Enable */ +#define E1000_CTRL_SDP0_WDE 0x00200000 /* Watchdog Indication for SDP0 */ +#define E1000_CTRL_SDP1_IODIR 0x00400000 /* SDP1 Directionality */ +#define E1000_CTRL_RST 0x04000000 /* Global reset */ +#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ +#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ +#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */ +#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ + +/* Device Status */ +#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */ +#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ +#define E1000_STATUS_LANID 0x00000008 /* LAN ID */ +#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ +#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */ +#define E1000_STATUS_SPEED_MASK 0x000000C0 /* Speed Mask */ +#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */ +#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ +#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ +#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ +#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */ +#define E1000_STATUS_GIOMASTEREN 0x00080000 /* GIO Master Enable Status */ +#define E1000_STATUS_DMA_CGEN 0x80000000 /* DMA clock gating Enable */ + +/* Receive Control */ +#define E1000_RCTL_EN 0x00000002 /* enable */ +#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ +#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */ +#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */ +#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ +#define E1000_RCTL_LBM_MASK 0x000000C0 /* Loopback mode mask */ +#define E1000_RCTL_LBM_NORM 0x00000000 /* normal loopback mode */ +#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ +#define E1000_RCTL_LBM_SERDES 0x000000C0 /* SERDES loopback mode */ +#define E1000_RCTL_RDMTS 0x00000300 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */ +#define E1000_RCTL_MO 0x00003000 /* multicast offset shift */ +#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 47:36 */ +#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 46:35 */ +#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 45:34 */ +#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 43:32 */ +#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ +#define E1000_RCTL_BSIZE 0x00030000 /* rx buffer size */ +#define E1000_RCTL_BSIZE_2048 0x00000000 /* rx buffer size 2048 */ +#define E1000_RCTL_BSIZE_1024 0x00010000 /* rx buffer size 1024 */ +#define E1000_RCTL_BSIZE_512 0x00020000 /* rx buffer size 512 */ +#define E1000_RCTL_BSIZE_256 0x00030000 /* rx buffer size 256 */ +#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ +#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ +#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ +#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ +#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ +#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC from packet.0=No strip;1=strip */ + +/* Transmit Control */ +#define E1000_TCTL_EN 0x00000002 /* enable tx */ +#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ +#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ +#define E1000_TCTL_BST 0x003ff000 /* Backoff Slot time */ +#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */ +#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ +#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ +#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ + +int igb_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *regs_buff = (u32 *)regs->data; + u32 reg; + u8 i; + u8 version = (u8)(regs->version >> 24); + + if (version != 1) + return -1; + + /* Device control register */ + reg = regs_buff[0]; + fprintf(stdout, + "0x00000: CTRL (Device control register) 0x%08X\n" + " Invert Loss-Of-Signal: %s\n" + " Receive flow control: %s\n" + " Transmit flow control: %s\n" + " VLAN mode: %s\n" + " Set link up: %s\n" + " D3COLD WakeUp capability advertisement: %s\n", + reg, + reg & E1000_CTRL_ILOS ? "yes" : "no", + reg & E1000_CTRL_RFCE ? "enabled" : "disabled", + reg & E1000_CTRL_TFCE ? "enabled" : "disabled", + reg & E1000_CTRL_VME ? "enabled" : "disabled", + reg & E1000_CTRL_SLU ? "1" : "0", + reg & E1000_CTRL_ADVD3WUC ? "enabled" : "disabled"); + fprintf(stdout, + " Auto speed detect: %s\n" + " Speed select: %s\n" + " Force speed: %s\n" + " Force duplex: %s\n", + reg & E1000_CTRL_ASDE ? "enabled" : "disabled", + (reg & E1000_CTRL_SPD_SEL) == E1000_CTRL_SPD_10 ? "10Mb/s" : + (reg & E1000_CTRL_SPD_SEL) == E1000_CTRL_SPD_100 ? "100Mb/s" : + (reg & E1000_CTRL_SPD_SEL) == E1000_CTRL_SPD_1000 ? "1000Mb/s" : + "not used", + reg & E1000_CTRL_FRCSPD ? "yes" : "no", + reg & E1000_CTRL_FRCDPX ? "yes" : "no"); + + /* Device status register */ + reg = regs_buff[1]; + fprintf(stdout, + "0x00008: STATUS (Device status register) 0x%08X\n" + " Duplex: %s\n" + " Link up: %s\n" + " Transmission: %s\n" + " DMA clock gating: %s\n", + reg, + reg & E1000_STATUS_FD ? "full" : "half", + reg & E1000_STATUS_LU ? "link config" : "no link config", + reg & E1000_STATUS_TXOFF ? "paused" : "on", + reg & E1000_STATUS_DMA_CGEN ? "enabled" : "disabled"); + fprintf(stdout, + " TBI mode: %s\n" + " Link speed: %s\n" + " Bus type: %s\n", + reg & E1000_STATUS_TBIMODE ? "enabled" : "disabled", + (reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_10 ? + "10Mb/s" : + (reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_100 ? + "100Mb/s" : + (reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_1000 ? + "1000Mb/s" : "not used", + "PCI Express"); + + /* Receive control register */ + reg = regs_buff[32]; + fprintf(stdout, + "0x00100: RCTL (Receive control register) 0x%08X\n" + " Receiver: %s\n" + " Store bad packets: %s\n" + " Unicast promiscuous: %s\n" + " Multicast promiscuous: %s\n" + " Long packet: %s\n" + " Descriptor minimum threshold size: %s\n" + " Broadcast accept mode: %s\n" + " VLAN filter: %s\n" + " Cononical form indicator: %s\n" + " Discard pause frames: %s\n" + " Pass MAC control frames: %s\n" + " Loopback mode: %s\n", + reg, + reg & E1000_RCTL_EN ? "enabled" : "disabled", + reg & E1000_RCTL_SBP ? "enabled" : "disabled", + reg & E1000_RCTL_UPE ? "enabled" : "disabled", + reg & E1000_RCTL_MPE ? "enabled" : "disabled", + reg & E1000_RCTL_LPE ? "enabled" : "disabled", + (reg & E1000_RCTL_RDMTS) == E1000_RCTL_RDMTS_HALF ? "1/2" : + (reg & E1000_RCTL_RDMTS) == E1000_RCTL_RDMTS_QUAT ? "1/4" : + (reg & E1000_RCTL_RDMTS) == E1000_RCTL_RDMTS_EIGTH ? "1/8" : + "reserved", + reg & E1000_RCTL_BAM ? "accept" : "ignore", + reg & E1000_RCTL_VFE ? "enabled" : "disabled", + reg & E1000_RCTL_CFIEN ? "enabled" : "disabled", + reg & E1000_RCTL_DPF ? "ignored" : "filtered", + reg & E1000_RCTL_PMCF ? "pass" : "don't pass", + (reg & E1000_RCTL_LBM_MASK) == E1000_RCTL_LBM_NORM ? "normal" : + (reg & E1000_RCTL_LBM_MASK) == E1000_RCTL_LBM_MAC ? "MAC": + (reg & E1000_RCTL_LBM_MASK) == E1000_RCTL_LBM_SERDES ? "SERDES": + "undefined"); + fprintf(stdout, + " Receive buffer size: %s\n", + (reg & E1000_RCTL_BSIZE)==E1000_RCTL_BSIZE_2048 ? "2048" : + (reg & E1000_RCTL_BSIZE)==E1000_RCTL_BSIZE_1024 ? "1024" : + (reg & E1000_RCTL_BSIZE)==E1000_RCTL_BSIZE_512 ? "512" : + "256"); + + /* Receive descriptor registers */ + fprintf(stdout, + "0x02808: RDLEN (Receive desc length) 0x%08X\n", + regs_buff[137]); + fprintf(stdout, + "0x02810: RDH (Receive desc head) 0x%08X\n", + regs_buff[141]); + fprintf(stdout, + "0x02818: RDT (Receive desc tail) 0x%08X\n", + regs_buff[145]); + + /* Transmit control register */ + reg = regs_buff[38]; + fprintf(stdout, + "0x00400: TCTL (Transmit ctrl register) 0x%08X\n" + " Transmitter: %s\n" + " Pad short packets: %s\n" + " Software XOFF Transmission: %s\n", + reg, + reg & E1000_TCTL_EN ? "enabled" : "disabled", + reg & E1000_TCTL_PSP ? "enabled" : "disabled", + reg & E1000_TCTL_SWXOFF ? "enabled" : "disabled"); + fprintf(stdout, + " Re-transmit on late collision: %s\n", + reg & E1000_TCTL_RTLC ? "enabled" : "disabled"); + + /* Transmit descriptor registers */ + fprintf(stdout, + "0x03808: TDLEN (Transmit desc length) 0x%08X\n", + regs_buff[219]); + fprintf(stdout, + "0x03810: TDH (Transmit desc head) 0x%08X\n", + regs_buff[223]); + fprintf(stdout, + "0x03818: TDT (Transmit desc tail) 0x%08X\n", + regs_buff[227]); + + + fprintf(stdout, + "0x00018: CTRL_EXT (Extended device control) 0x%08X\n", + regs_buff[2]); + + fprintf(stdout, + "0x00018: MDIC (MDI control) 0x%08X\n", + regs_buff[3]); + + fprintf(stdout, + "0x00024: SCTL (SERDES ANA) 0x%08X\n", + regs_buff[4]); + + fprintf(stdout, + "0x00034: CONNSW (Copper/Fiber switch control) 0x%08X\n", + regs_buff[5]); + + fprintf(stdout, + "0x00038: VET (VLAN Ether type) 0x%08X\n", + regs_buff[6]); + + fprintf(stdout, + "0x00E00: LEDCTL (LED control) 0x%08X\n", + regs_buff[7]); + + fprintf(stdout, + "0x01000: PBA (Packet buffer allocation) 0x%08X\n", + regs_buff[8]); + + fprintf(stdout, + "0x01008: PBS (Packet buffer size) 0x%08X\n", + regs_buff[9]); + + fprintf(stdout, + "0x01048: FRTIMER (Free running timer) 0x%08X\n", + regs_buff[10]); + + fprintf(stdout, + "0x0104C: TCPTIMER (TCP timer) 0x%08X\n", + regs_buff[11]); + + fprintf(stdout, + "0x00010: EEC (EEPROM/FLASH control) 0x%08X\n", + regs_buff[12]); + + fprintf(stdout, + "0x01580: EICR (Extended interrupt cause) 0x%08X\n", + regs_buff[13]); + + fprintf(stdout, + "0x01520: EICS (Extended interrupt cause set) 0x%08X\n", + regs_buff[14]); + + fprintf(stdout, + "0x01524: EIMS (Extended interrup set/read) 0x%08X\n", + regs_buff[15]); + + fprintf(stdout, + "0x01528: EIMC (Extended interrupt mask clear) 0x%08X\n", + regs_buff[16]); + + fprintf(stdout, + "0x0152C: EIAC (Extended interrupt auto clear) 0x%08X\n", + regs_buff[17]); + + fprintf(stdout, + "0x01530: EIAM (Extended interrupt auto mask) 0x%08X\n", + regs_buff[18]); + + fprintf(stdout, + "0x01500: ICR (Interrupt cause read) 0x%08X\n", + regs_buff[19]); + + fprintf(stdout, + "0x01504: ICS (Interrupt cause set) 0x%08X\n", + regs_buff[20]); + + fprintf(stdout, + "0x01508: IMS (Interrupt mask set/read) 0x%08X\n", + regs_buff[21]); + + fprintf(stdout, + "0x0150C: IMC (Interrupt mask clear) 0x%08X\n", + regs_buff[22]); + + fprintf(stdout, + "0x04100: IAC (Interrupt assertion count) 0x%08X\n", + regs_buff[23]); + + fprintf(stdout, + "0x01510: IAM (Interr acknowledge auto-mask) 0x%08X\n", + regs_buff[24]); + + fprintf(stdout, + "0x05AC0: IMIRVP (Immed interr rx VLAN priority) 0x%08X\n", + regs_buff[25]); + + fprintf(stdout, + "0x00028: FCAL (Flow control address low) 0x%08X\n", + regs_buff[26]); + + fprintf(stdout, + "0x0002C: FCAH (Flow control address high) 0x%08X\n", + regs_buff[27]); + + fprintf(stdout, + "0x00170: FCTTV (Flow control tx timer value) 0x%08X\n", + regs_buff[28]); + + fprintf(stdout, + "0x02160: FCRTL (Flow control rx threshold low) 0x%08X\n", + regs_buff[29]); + + fprintf(stdout, + "0x02168: FCRTH (Flow control rx threshold high) 0x%08X\n", + regs_buff[30]); + + fprintf(stdout, + "0x02460: FCRTV (Flow control refresh threshold) 0x%08X\n", + regs_buff[31]); + + fprintf(stdout, + "0x05000: RXCSUM (Receive checksum control) 0x%08X\n", + regs_buff[33]); + + fprintf(stdout, + "0x05004: RLPML (Receive long packet max length) 0x%08X\n", + regs_buff[34]); + + fprintf(stdout, + "0x05008: RFCTL (Receive filter control) 0x%08X\n", + regs_buff[35]); + + fprintf(stdout, + "0x05818: MRQC (Multiple rx queues command) 0x%08X\n", + regs_buff[36]); + + fprintf(stdout, + "0x0581C: VMD_CTL (VMDq control) 0x%08X\n", + regs_buff[37]); + + fprintf(stdout, + "0x00404: TCTL_EXT (Transmit control extended) 0x%08X\n", + regs_buff[39]); + + fprintf(stdout, + "0x00410: TIPG (Transmit IPG) 0x%08X\n", + regs_buff[40]); + + fprintf(stdout, + "0x03590: DTXCTL (DMA tx control) 0x%08X\n", + regs_buff[41]); + + fprintf(stdout, + "0x05800: WUC (Wake up control) 0x%08X\n", + regs_buff[42]); + + fprintf(stdout, + "0x05808: WUFC (Wake up filter control) 0x%08X\n", + regs_buff[43]); + + fprintf(stdout, + "0x05810: WUS (Wake up status) 0x%08X\n", + regs_buff[44]); + + fprintf(stdout, + "0x05838: IPAV (IP address valid) 0x%08X\n", + regs_buff[45]); + + fprintf(stdout, + "0x05900: WUPL (Wake up packet length) 0x%08X\n", + regs_buff[46]); + + fprintf(stdout, + "0x04200: PCS_CFG (PCS configuration 0) 0x%08X\n", + regs_buff[47]); + + fprintf(stdout, + "0x04208: PCS_LCTL (PCS link control) 0x%08X\n", + regs_buff[48]); + + fprintf(stdout, + "0x0420C: PCS_LSTS (PCS link status) 0x%08X\n", + regs_buff[49]); + + fprintf(stdout, + "0x04218: PCS_ANADV (AN advertisement) 0x%08X\n", + regs_buff[50]); + + fprintf(stdout, + "0x0421C: PCS_LPAB (Link partner ability) 0x%08X\n", + regs_buff[51]); + + fprintf(stdout, + "0x04220: PCS_NPTX (Next Page transmit) 0x%08X\n", + regs_buff[52]); + + fprintf(stdout, + "0x04224: PCS_LPABNP (Link partner ability Next Page) 0x%08X\n", + regs_buff[53]); + + fprintf(stdout, + "0x04000: CRCERRS (CRC error count) 0x%08X\n", + regs_buff[54]); + + fprintf(stdout, + "0x04004: ALGNERRC (Alignment error count) 0x%08X\n", + regs_buff[55]); + + fprintf(stdout, + "0x04008: SYMERRS (Symbol error count) 0x%08X\n", + regs_buff[56]); + + fprintf(stdout, + "0x0400C: RXERRC (RX error count) 0x%08X\n", + regs_buff[57]); + + fprintf(stdout, + "0x04010: MPC (Missed packets count) 0x%08X\n", + regs_buff[58]); + + fprintf(stdout, + "0x04014: SCC (Single collision count) 0x%08X\n", + regs_buff[59]); + + fprintf(stdout, + "0x04018: ECOL (Excessive collisions count) 0x%08X\n", + regs_buff[60]); + + fprintf(stdout, + "0x0401C: MCC (Multiple collision count) 0x%08X\n", + regs_buff[61]); + + fprintf(stdout, + "0x04020: LATECOL (Late collisions count) 0x%08X\n", + regs_buff[62]); + + fprintf(stdout, + "0x04028: COLC (Collision count) 0x%08X\n", + regs_buff[63]); + + fprintf(stdout, + "0x04030: DC (Defer count) 0x%08X\n", + regs_buff[64]); + + fprintf(stdout, + "0x04034: TNCRS (Transmit with no CRS) 0x%08X\n", + regs_buff[65]); + + fprintf(stdout, + "0x04038: SEC (Sequence error count) 0x%08X\n", + regs_buff[66]); + + fprintf(stdout, + "0x0403C: HTDPMC (Host tx discrd pkts MAC count) 0x%08X\n", + regs_buff[67]); + + fprintf(stdout, + "0x04040: RLEC (Receive length error count) 0x%08X\n", + regs_buff[68]); + + fprintf(stdout, + "0x04048: XONRXC (XON received count) 0x%08X\n", + regs_buff[69]); + + fprintf(stdout, + "0x0404C: XONTXC (XON transmitted count) 0x%08X\n", + regs_buff[70]); + + fprintf(stdout, + "0x04050: XOFFRXC (XOFF received count) 0x%08X\n", + regs_buff[71]); + + fprintf(stdout, + "0x04054: XOFFTXC (XOFF transmitted count) 0x%08X\n", + regs_buff[72]); + + fprintf(stdout, + "0x04058: FCRUC (FC received unsupported count) 0x%08X\n", + regs_buff[73]); + + fprintf(stdout, + "0x0405C: PRC64 (Packets rx (64 B) count) 0x%08X\n", + regs_buff[74]); + + fprintf(stdout, + "0x04060: PRC127 (Packets rx (65-127 B) count) 0x%08X\n", + regs_buff[75]); + + fprintf(stdout, + "0x04064: PRC255 (Packets rx (128-255 B) count) 0x%08X\n", + regs_buff[76]); + + fprintf(stdout, + "0x04068: PRC511 (Packets rx (256-511 B) count) 0x%08X\n", + regs_buff[77]); + + fprintf(stdout, + "0x0406C: PRC1023 (Packets rx (512-1023 B) count) 0x%08X\n", + regs_buff[78]); + + fprintf(stdout, + "0x04070: PRC1522 (Packets rx (1024-max B) count) 0x%08X\n", + regs_buff[79]); + + fprintf(stdout, + "0x04074: GPRC (Good packets received count) 0x%08X\n", + regs_buff[80]); + + fprintf(stdout, + "0x04078: BPRC (Broadcast packets rx count) 0x%08X\n", + regs_buff[81]); + + fprintf(stdout, + "0x0407C: MPRC (Multicast packets rx count) 0x%08X\n", + regs_buff[82]); + + fprintf(stdout, + "0x04080: GPTC (Good packets tx count) 0x%08X\n", + regs_buff[83]); + + fprintf(stdout, + "0x04088: GORCL (Good octets rx count lower) 0x%08X\n", + regs_buff[84]); + + fprintf(stdout, + "0x0408C: GORCH (Good octets rx count upper) 0x%08X\n", + regs_buff[85]); + + fprintf(stdout, + "0x04090: GOTCL (Good octets tx count lower) 0x%08X\n", + regs_buff[86]); + + fprintf(stdout, + "0x04094: GOTCH (Good octets tx count upper) 0x%08X\n", + regs_buff[87]); + + fprintf(stdout, + "0x040A0: RNBC (Receive no buffers count) 0x%08X\n", + regs_buff[88]); + + fprintf(stdout, + "0x040A4: RUC (Receive undersize count) 0x%08X\n", + regs_buff[89]); + + fprintf(stdout, + "0x040A8: RFC (Receive fragment count) 0x%08X\n", + regs_buff[90]); + + fprintf(stdout, + "0x040AC: ROC (Receive oversize count) 0x%08X\n", + regs_buff[91]); + + fprintf(stdout, + "0x040B0: RJC (Receive jabber count) 0x%08X\n", + regs_buff[92]); + + fprintf(stdout, + "0x040B4: MGPRC (Management packets rx count) 0x%08X\n", + regs_buff[93]); + + fprintf(stdout, + "0x040B8: MGPDC (Management pkts dropped count) 0x%08X\n", + regs_buff[94]); + + fprintf(stdout, + "0x040BC: MGPTC (Management packets tx count) 0x%08X\n", + regs_buff[95]); + + fprintf(stdout, + "0x040C0: TORL (Total octets received lower) 0x%08X\n", + regs_buff[96]); + + fprintf(stdout, + "0x040C4: TORH (Total octets received upper) 0x%08X\n", + regs_buff[97]); + + fprintf(stdout, + "0x040C8: TOTL (Total octets transmitted lower) 0x%08X\n", + regs_buff[98]); + + fprintf(stdout, + "0x040CC: TOTH (Total octets transmitted upper) 0x%08X\n", + regs_buff[99]); + + fprintf(stdout, + "0x040D0: TPR (Total packets received) 0x%08X\n", + regs_buff[100]); + + fprintf(stdout, + "0x040D4: TPT (Total packets transmitted) 0x%08X\n", + regs_buff[101]); + + fprintf(stdout, + "0x040D8: PTC64 (Packets tx (64 B) count) 0x%08X\n", + regs_buff[102]); + + fprintf(stdout, + "0x040DC: PTC127 (Packets tx (65-127 B) count) 0x%08X\n", + regs_buff[103]); + + fprintf(stdout, + "0x040E0: PTC255 (Packets tx (128-255 B) count) 0x%08X\n", + regs_buff[104]); + + fprintf(stdout, + "0x040E4: PTC511 (Packets tx (256-511 B) count) 0x%08X\n", + regs_buff[105]); + + fprintf(stdout, + "0x040E8: PTC1023 (Packets tx (512-1023 B) count) 0x%08X\n", + regs_buff[106]); + + fprintf(stdout, + "0x040EC: PTC1522 (Packets tx (> 1024 B) count) 0x%08X\n", + regs_buff[107]); + + fprintf(stdout, + "0x040F0: MPTC (Multicast packets tx count) 0x%08X\n", + regs_buff[108]); + + fprintf(stdout, + "0x040F4: BPTC (Broadcast packets tx count) 0x%08X\n", + regs_buff[109]); + + fprintf(stdout, + "0x040F8: TSCTC (TCP segment context tx count) 0x%08X\n", + regs_buff[110]); + + fprintf(stdout, + "0x04100: IAC (Interrupt assertion count) 0x%08X\n", + regs_buff[111]); + + fprintf(stdout, + "0x04104: RPTHC (Rx packets to host count) 0x%08X\n", + regs_buff[112]); + + fprintf(stdout, + "0x04118: HGPTC (Host good packets tx count) 0x%08X\n", + regs_buff[113]); + + fprintf(stdout, + "0x04128: HGORCL (Host good octets rx cnt lower) 0x%08X\n", + regs_buff[114]); + + fprintf(stdout, + "0x0412C: HGORCH (Host good octets rx cnt upper) 0x%08X\n", + regs_buff[115]); + + fprintf(stdout, + "0x04130: HGOTCL (Host good octets tx cnt lower) 0x%08X\n", + regs_buff[116]); + + fprintf(stdout, + "0x04134: HGOTCH (Host good octets tx cnt upper) 0x%08X\n", + regs_buff[117]); + + fprintf(stdout, + "0x04138: LENNERS (Length error count) 0x%08X\n", + regs_buff[118]); + + fprintf(stdout, + "0x04228: SCVPC (SerDes/SGMII code viol pkt cnt) 0x%08X\n", + regs_buff[119]); + + fprintf(stdout, + "0x0A018: HRMPC (Header redir missed pkt count) 0x%08X\n", + regs_buff[120]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: SRRCTL%d (Split and replic rx ctl%d) 0x%08X\n", + 0x0280C + (0x100 * i), i, i, regs_buff[121 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: PSRTYPE%d (Packet split receive type%d) 0x%08X\n", + 0x05480 + (0x4 * i), i, i, regs_buff[125 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: RDBAL%d (Rx desc base addr low%d) 0x%08X\n", + 0x02800 + (0x100 * i), i, i, regs_buff[129 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: RDBAH%d (Rx desc base addr high%d) 0x%08X\n", + 0x02804 + (0x100 * i), i, i, regs_buff[133 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: RDLEN%d (Rx descriptor length%d) 0x%08X\n", + 0x02808 + (0x100 * i), i, i, regs_buff[137 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: RDH%d (Rx descriptor head%d) 0x%08X\n", + 0x02810 + (0x100 * i), i, i, regs_buff[141 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: RDT%d (Rx descriptor tail%d) 0x%08X\n", + 0x02818 + (0x100 * i), i, i, regs_buff[145 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: RXDCTL%d (Rx descriptor control%d) 0x%08X\n", + 0x02828 + (0x100 * i), i, i, regs_buff[149 + i]); + + for (i = 0; i < 10; i++) + fprintf(stdout, + "0x0%02X: EITR%d (Interrupt throttle%d) 0x%08X\n", + 0x01680 + (0x4 * i), i, i, regs_buff[153 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x0%02X: IMIR%d (Immediate interrupt Rx%d) 0x%08X\n", + 0x05A80 + (0x4 * i), i, i, regs_buff[163 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x0%02X: IMIREXT%d (Immediate interr Rx extended%d) 0x%08X\n", + 0x05AA0 + (0x4 * i), i, i, regs_buff[171 + i]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x0%02X: RAL%02d (Receive address low%02d) 0x%08X\n", + 0x05400 + (0x8 * i), i,i, regs_buff[179 + i]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x0%02X: RAH%02d (Receive address high%02d) 0x%08X\n", + 0x05404 + (0x8 * i), i, i, regs_buff[195 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: TDBAL%d (Tx desc base address low%d) 0x%08X\n", + 0x03800 + (0x100 * i), i, i, regs_buff[211 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: TDBAH%d (Tx desc base address high%d) 0x%08X\n", + 0x03804 + (0x100 * i), i, i, regs_buff[215 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: TDLEN%d (Tx descriptor length%d) 0x%08X\n", + 0x03808 + (0x100 * i), i, i, regs_buff[219 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: TDH%d (Transmit descriptor head%d) 0x%08X\n", + 0x03810 + (0x100 * i), i, i, regs_buff[223 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: TDT%d (Transmit descriptor tail%d) 0x%08X\n", + 0x03818 + (0x100 * i), i, i, regs_buff[227 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: TXDCTL%d (Transmit descriptor control%d) 0x%08X\n", + 0x03828 + (0x100 * i), i, i, regs_buff[231 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: TDWBAL%d (Tx desc complete wb addr low%d) 0x%08X\n", + 0x03838 + (0x100 * i), i, i, regs_buff[235 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: TDWBAH%d (Tx desc complete wb addr hi%d) 0x%08X\n", + 0x0383C + (0x100 * i), i, i, regs_buff[239 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: DCA_TXCTRL%d (Tx DCA control%d) 0x%08X\n", + 0x03814 + (0x100 * i), i, i, regs_buff[243 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: IP4AT%d (IPv4 address table%d) 0x%08X\n", + 0x05840 + (0x8 * i), i, i, regs_buff[247 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: IP6AT%d (IPv6 address table%d) 0x%08X\n", + 0x05880 + (0x4 * i), i, i, regs_buff[251 + i]); + + for (i = 0; i < 32; i++) + fprintf(stdout, + "0x0%02X: WUPM%02d (Wake up packet memory%02d) 0x%08X\n", + 0x05A00 + (0x4 * i), i, i, regs_buff[255 + i]); + + for (i = 0; i < 128; i++) + fprintf(stdout, + "0x0%02X: FFMT%03d (Flexible filter mask table%03d) 0x%08X\n", + 0x09000 + (0x8 * i), i, i, regs_buff[287 + i]); + + for (i = 0; i < 128; i++) + fprintf(stdout, + "0x0%02X: FFVT%03d (Flexible filter value table%03d) 0x%08X\n", + 0x09800 + (0x8 * i), i, i, regs_buff[415 + i]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x0%02X: FFLT%d (Flexible filter length table%d) 0x%08X\n", + 0x05F00 + (0x8 * i), i, i, regs_buff[543 + i]); + + fprintf(stdout, + "0x03410: TDFH (Tx data FIFO head) 0x%08X\n", + regs_buff[547]); + + fprintf(stdout, + "0x03418: TDFT (Tx data FIFO tail) 0x%08X\n", + regs_buff[548]); + + fprintf(stdout, + "0x03420: TDFHS (Tx data FIFO head saved) 0x%08X\n", + regs_buff[549]); + + fprintf(stdout, + "0x03430: TDFPC (Tx data FIFO packet count) 0x%08X\n", + regs_buff[550]); + + /* + * Starting from kernel version 5.3 the registers dump buffer grew from + * 739 4-byte words to 740 words, and word 740 contains the RR2DCDELAY + * register. + */ + if (regs->len < 740) + return 0; + + fprintf(stdout, + "0x05BF4: RR2DCDELAY (Max. DMA read delay) 0x%08X\n", + regs_buff[739]); + + return 0; +} + diff --git a/igc.c b/igc.c new file mode 100644 index 0000000..1550ac0 --- /dev/null +++ b/igc.c @@ -0,0 +1,284 @@ +/* Copyright (c) 2020 Intel Corporation */ +#include +#include "internal.h" + +#define RAH_RAH 0x0000FFFF +#define RAH_ASEL 0x00010000 +#define RAH_QSEL 0x000C0000 +#define RAH_QSEL_EN 0x10000000 +#define RAH_AV 0x80000000 +#define RCTL_RXEN 0x00000002 +#define RCTL_SBP 0x00000004 +#define RCTL_UPE 0x00000008 +#define RCTL_MPE 0x00000010 +#define RCTL_LPE 0x00000020 +#define RCTL_LBM 0x000000C0 +#define RCTL_LBM_PHY 0x00000000 +#define RCTL_LBM_MAC 0x00000040 +#define RCTL_HSEL 0x00000300 +#define RCTL_HSEL_MULTICAST 0x00000000 +#define RCTL_HSEL_UNICAST 0x00000100 +#define RCTL_HSEL_BOTH 0x00000200 +#define RCTL_MO 0x00003000 +#define RCTL_MO_47_36 0x00000000 +#define RCTL_MO_43_32 0x00001000 +#define RCTL_MO_39_28 0x00002000 +#define RCTL_BAM 0x00008000 +#define RCTL_BSIZE 0x00030000 +#define RCTL_BSIZE_2048 0x00000000 +#define RCTL_BSIZE_1024 0x00010000 +#define RCTL_BSIZE_512 0x00020000 +#define RCTL_VFE 0x00040000 +#define RCTL_CFIEN 0x00080000 +#define RCTL_CFI 0x00100000 +#define RCTL_PSP 0x00200000 +#define RCTL_DPF 0x00400000 +#define RCTL_PMCF 0x00800000 +#define RCTL_SECRC 0x04000000 +#define VLANPQF_VP0QSEL 0x00000003 +#define VLANPQF_VP0PBSEL 0x00000004 +#define VLANPQF_VLANP0V 0x00000008 +#define VLANPQF_VP1QSEL 0x00000030 +#define VLANPQF_VP1PBSEL 0x00000040 +#define VLANPQF_VLANP1V 0x00000080 +#define VLANPQF_VP2QSEL 0x00000300 +#define VLANPQF_VP2PBSEL 0x00000400 +#define VLANPQF_VLANP2V 0x00000800 +#define VLANPQF_VP3QSEL 0x00003000 +#define VLANPQF_VP3PBSEL 0x00004000 +#define VLANPQF_VLANP3V 0x00008000 +#define VLANPQF_VP4QSEL 0x00030000 +#define VLANPQF_VP4PBSEL 0x00040000 +#define VLANPQF_VLANP4V 0x00080000 +#define VLANPQF_VP5QSEL 0x00300000 +#define VLANPQF_VP5PBSEL 0x00400000 +#define VLANPQF_VLANP5V 0x00800000 +#define VLANPQF_VP6QSEL 0x03000000 +#define VLANPQF_VP6PBSEL 0x04000000 +#define VLANPQF_VLANP6V 0x08000000 +#define VLANPQF_VP7QSEL 0x30000000 +#define VLANPQF_VP7PBSEL 0x40000000 +#define VLANPQF_VLANP7V 0x80000000 +#define ETQF_ETYPE 0x0000FFFF +#define ETQF_QUEUE 0x00070000 +#define ETQF_ETYPE_LEN 0x01F00000 +#define ETQF_ETYPE_LEN_EN 0x02000000 +#define ETQF_FILTER_EN 0x04000000 +#define ETQF_IMMEDIATE_INTR 0x20000000 +#define ETQF_1588_TIMESTAMP 0x40000000 +#define ETQF_QUEUE_EN 0x80000000 + +#define RAH_QSEL_SHIFT 18 +#define VLANPQF_VP1QSEL_SHIFT 4 +#define VLANPQF_VP2QSEL_SHIFT 8 +#define VLANPQF_VP3QSEL_SHIFT 12 +#define VLANPQF_VP4QSEL_SHIFT 16 +#define VLANPQF_VP5QSEL_SHIFT 20 +#define VLANPQF_VP6QSEL_SHIFT 24 +#define VLANPQF_VP7QSEL_SHIFT 28 +#define ETQF_QUEUE_SHIFT 16 +#define ETQF_ETYPE_LEN_SHIFT 20 + +static const char *bit_to_boolean(u32 val) +{ + return val ? "yes" : "no"; +} + +static const char *bit_to_enable(u32 val) +{ + return val ? "enabled" : "disabled"; +} + +static const char *bit_to_prio(u32 val) +{ + return val ? "low" : "high"; +} + +int igc_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 reg; + int offset, i; + u32 *regs_buff = (u32 *)regs->data; + u8 version = (u8)(regs->version >> 24); + + if (version != 2) + return -1; + + for (offset = 0; offset < 24; offset++) { + reg = regs_buff[offset]; + printf("%04d: 0x%08X\n", offset, reg); + } + + offset = 24; + + reg = regs_buff[offset]; + printf("%04d: RCTL (Receive Control Register) \n" + " Receiver: %s\n" + " Stop Bad Packets: %s\n" + " Unicast Promiscuous: %s\n" + " Multicast Promiscuous: %s\n" + " Long Packet Reception: %s\n" + " Loopback Model: %s\n" + " Hash Select for MTA: %s\n" + " Multicast/Unicast Table Offset: %s\n" + " Broadcast Accept Mode: %s\n" + " Receive Buffer Size: %s\n" + " VLAN Filter: %s\n" + " Canonical Form Indicator: %s\n" + " Canonical Form Indicator Bit: %s\n" + " Pad Small Receive Packets: %s\n" + " Discard Pause Frames: %s\n" + " Pass MAC Control Frames: %s\n" + " Strip Ethernet CRC: %s\n", + offset, + bit_to_enable(reg & RCTL_RXEN), + bit_to_enable(reg & RCTL_SBP), + bit_to_enable(reg & RCTL_UPE), + bit_to_enable(reg & RCTL_MPE), + bit_to_enable(reg & RCTL_LPE), + (reg & RCTL_LBM) == RCTL_LBM_PHY ? "PHY" : + (reg & RCTL_LBM) == RCTL_LBM_MAC ? "MAC" : + "undefined", + (reg & RCTL_HSEL) == RCTL_HSEL_MULTICAST ? "multicast only" : + (reg & RCTL_HSEL) == RCTL_HSEL_UNICAST ? "unicast only" : + (reg & RCTL_HSEL) == RCTL_HSEL_BOTH ? "multicast and unicast" : + "reserved", + (reg & RCTL_MO) == RCTL_MO_47_36 ? "bits [47:36]" : + (reg & RCTL_MO) == RCTL_MO_43_32 ? "bits [43:32]" : + (reg & RCTL_MO) == RCTL_MO_39_28 ? "bits [39:28]" : + "bits [35:24]", + bit_to_enable(reg & RCTL_BAM), + (reg & RCTL_BSIZE) == RCTL_BSIZE_2048 ? "2048 bytes" : + (reg & RCTL_BSIZE) == RCTL_BSIZE_1024 ? "1024 bytes" : + (reg & RCTL_BSIZE) == RCTL_BSIZE_512 ? "512 bytes" : + "256 bytes", + bit_to_enable(reg & RCTL_VFE), + bit_to_enable(reg & RCTL_CFIEN), + reg & RCTL_CFI ? "discarded" : "accepted", + bit_to_enable(reg & RCTL_PSP), + bit_to_enable(reg & RCTL_DPF), + bit_to_enable(reg & RCTL_PMCF), + bit_to_enable(reg & RCTL_SECRC)); + + for (offset = 25; offset < 172; offset++) { + reg = regs_buff[offset]; + printf("%04d: 0x%08X\n", offset, reg); + } + + offset = 172; + + for (i = 0; i < 16; i++) { + reg = regs_buff[offset + i]; + printf("%04d: RAL (Receive Address Low %02d) \n" + " Receive Address Low: %08X\n", + offset + i, i, + reg); + } + + offset = 188; + + for (i = 0; i < 16; i++) { + reg = regs_buff[offset + i]; + printf("%04d: RAH (Receive Address High %02d) \n" + " Receive Address High: %04X\n" + " Address Select: %s\n" + " Queue Select: %d\n" + " Queue Select Enable: %s\n" + " Address Valid: %s\n", + offset + i, i, + reg & RAH_RAH, + reg & RAH_ASEL ? "source" : "destination", + (reg & RAH_QSEL) >> RAH_QSEL_SHIFT, + bit_to_boolean(reg & RAH_QSEL_EN), + bit_to_boolean(reg & RAH_AV)); + } + + offset = 204; + + reg = regs_buff[offset]; + printf("%04d: VLANPQF (VLAN Priority Queue Filter) \n" + " Priority 0 \n" + " Queue: %d\n" + " Packet Buffer: %s\n" + " Valid: %s\n" + " Priority 1 \n" + " Queue: %d\n" + " Packet Buffer: %s\n" + " Valid: %s\n" + " Priority 2 \n" + " Queue: %d\n" + " Packet Buffer: %s\n" + " Valid: %s\n" + " Priority 3 \n" + " Queue: %d\n" + " Packet Buffer: %s\n" + " Valid: %s\n" + " Priority 4 \n" + " Queue: %d\n" + " Packet Buffer: %s\n" + " Valid: %s\n" + " Priority 5 \n" + " Queue: %d\n" + " Packet Buffer: %s\n" + " Valid: %s\n" + " Priority 6 \n" + " Queue: %d\n" + " Packet Buffer: %s\n" + " Valid: %s\n" + " Priority 7 \n" + " Queue: %d\n" + " Packet Buffer: %s\n" + " Valid: %s\n", + offset, + reg & VLANPQF_VP0QSEL, + bit_to_prio(reg & VLANPQF_VP0PBSEL), + bit_to_boolean(reg & VLANPQF_VLANP0V), + (reg & VLANPQF_VP1QSEL) >> VLANPQF_VP1QSEL_SHIFT, + bit_to_prio(reg & VLANPQF_VP1PBSEL), + bit_to_boolean(reg & VLANPQF_VLANP1V), + (reg & VLANPQF_VP2QSEL) >> VLANPQF_VP2QSEL_SHIFT, + bit_to_prio(reg & VLANPQF_VP2PBSEL), + bit_to_boolean(reg & VLANPQF_VLANP2V), + (reg & VLANPQF_VP3QSEL) >> VLANPQF_VP3QSEL_SHIFT, + bit_to_prio(reg & VLANPQF_VP3PBSEL), + bit_to_boolean(reg & VLANPQF_VLANP3V), + (reg & VLANPQF_VP4QSEL) >> VLANPQF_VP4QSEL_SHIFT, + bit_to_prio(reg & VLANPQF_VP4PBSEL), + bit_to_boolean(reg & VLANPQF_VLANP4V), + (reg & VLANPQF_VP5QSEL) >> VLANPQF_VP5QSEL_SHIFT, + bit_to_prio(reg & VLANPQF_VP5PBSEL), + bit_to_boolean(reg & VLANPQF_VLANP5V), + (reg & VLANPQF_VP6QSEL) >> VLANPQF_VP6QSEL_SHIFT, + bit_to_prio(reg & VLANPQF_VP6PBSEL), + bit_to_boolean(reg & VLANPQF_VLANP6V), + (reg & VLANPQF_VP7QSEL) >> VLANPQF_VP7QSEL_SHIFT, + bit_to_prio(reg & VLANPQF_VP7PBSEL), + bit_to_boolean(reg & VLANPQF_VLANP7V)); + + offset = 205; + + for (i = 0; i < 8; i++) { + reg = regs_buff[offset + i]; + printf("%04d: ETQF (EType Queue Filter %d) \n" + " EType: %04X\n" + " EType Length: %d\n" + " EType Length Enable: %s\n" + " Queue: %d\n" + " Queue Enable: %s\n" + " Immediate Interrupt: %s\n" + " 1588 Time Stamp: %s\n" + " Filter Enable: %s\n", + offset + i, i, + reg & ETQF_ETYPE, + (reg & ETQF_ETYPE_LEN) >> ETQF_ETYPE_LEN_SHIFT, + bit_to_boolean(reg & ETQF_ETYPE_LEN_EN), + (reg & ETQF_QUEUE) >> ETQF_QUEUE_SHIFT, + bit_to_boolean(reg & ETQF_QUEUE_EN), + bit_to_enable(reg & ETQF_IMMEDIATE_INTR), + bit_to_enable(reg & ETQF_1588_TIMESTAMP), + bit_to_boolean(reg & ETQF_FILTER_EN)); + } + + return 0; +} diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..0360b79 --- /dev/null +++ b/install-sh @@ -0,0 +1,501 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2016-01-11.22; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/internal.h b/internal.h new file mode 100644 index 0000000..b80f77a --- /dev/null +++ b/internal.h @@ -0,0 +1,424 @@ +/* Portions Copyright 2001 Sun Microsystems (thockin@sun.com) */ +/* Portions Copyright 2002 Intel (scott.feldman@intel.com) */ +#ifndef ETHTOOL_INTERNAL_H__ +#define ETHTOOL_INTERNAL_H__ + +/* Some platforms (eg. ppc64) need __SANE_USERSPACE_TYPES__ before + * to select 'int-ll64.h' and avoid compile warnings + * when printing __u64 with %llu. + */ +#define __SANE_USERSPACE_TYPES__ + +#ifdef HAVE_CONFIG_H +#include "ethtool-config.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "json_writer.h" +#include "json_print.h" + +#define __maybe_unused __attribute__((__unused__)) + +/* internal for netlink interface */ +#ifdef ETHTOOL_ENABLE_NETLINK +struct nl_context; +#endif + +/* ethtool.h expects these to be defined by */ +#ifndef HAVE_BE_TYPES +typedef uint16_t __be16; +typedef uint32_t __be32; +typedef unsigned long long __be64; +#endif + +typedef unsigned long long u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; +typedef int32_t s32; + +/* ethtool.h epxects __KERNEL_DIV_ROUND_UP to be defined by */ +#include +#ifndef __KERNEL_DIV_ROUND_UP +#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) +#endif + +#ifndef ALTIFNAMSIZ +#define ALTIFNAMSIZ 128 +#endif + +#include +#include + +#if __BYTE_ORDER == __BIG_ENDIAN +static inline u16 cpu_to_be16(u16 value) +{ + return value; +} +static inline u32 cpu_to_be32(u32 value) +{ + return value; +} +static inline u64 cpu_to_be64(u64 value) +{ + return value; +} +#else +static inline u16 cpu_to_be16(u16 value) +{ + return (value >> 8) | (value << 8); +} +static inline u32 cpu_to_be32(u32 value) +{ + return cpu_to_be16(value >> 16) | (cpu_to_be16(value) << 16); +} +static inline u64 cpu_to_be64(u64 value) +{ + return cpu_to_be32(value >> 32) | ((u64)cpu_to_be32(value) << 32); +} +#endif + +#define ntohll cpu_to_be64 +#define htonll cpu_to_be64 + +#define BITS_PER_BYTE 8 +#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long)) +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) +#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG) + +static inline void set_bit(unsigned int nr, unsigned long *addr) +{ + addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG); +} + +static inline void clear_bit(unsigned int nr, unsigned long *addr) +{ + addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG)); +} + +static inline int test_bit(unsigned int nr, const unsigned long *addr) +{ + return !!((1UL << (nr % BITS_PER_LONG)) & + (((unsigned long *)addr)[nr / BITS_PER_LONG])); +} + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#ifndef SIOCETHTOOL +#define SIOCETHTOOL 0x8946 +#endif + +/* debugging flags */ +enum { + DEBUG_PARSE, + DEBUG_NL_MSGS, /* incoming/outgoing netlink messages */ + DEBUG_NL_DUMP_SND, /* dump outgoing netlink messages */ + DEBUG_NL_DUMP_RCV, /* dump incoming netlink messages */ + DEBUG_NL_PRETTY_MSG, /* pretty print of messages and errors */ +}; + +static inline bool debug_on(unsigned long debug, unsigned int bit) +{ + return (debug & (1 << bit)); +} + +/* Internal values for old-style offload flags. Values and names + * must not clash with the flags defined for ETHTOOL_{G,S}FLAGS. + */ +#define ETH_FLAG_RXCSUM (1 << 0) +#define ETH_FLAG_TXCSUM (1 << 1) +#define ETH_FLAG_SG (1 << 2) +#define ETH_FLAG_TSO (1 << 3) +#define ETH_FLAG_UFO (1 << 4) +#define ETH_FLAG_GSO (1 << 5) +#define ETH_FLAG_GRO (1 << 6) +#define ETH_FLAG_INT_MASK (ETH_FLAG_RXCSUM | ETH_FLAG_TXCSUM | \ + ETH_FLAG_SG | ETH_FLAG_TSO | ETH_FLAG_UFO | \ + ETH_FLAG_GSO | ETH_FLAG_GRO), +/* Mask of all flags defined for ETHTOOL_{G,S}FLAGS. */ +#define ETH_FLAG_EXT_MASK (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | \ + ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE | \ + ETH_FLAG_RXHASH) + +/* internal API for link mode bitmap interaction with kernel. */ + +#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32 \ + (SCHAR_MAX) +#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS \ + (32 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32) +#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES \ + (4 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32) +#define ETHTOOL_DECLARE_LINK_MODE_MASK(name) \ + u32 name[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32] + +struct ethtool_link_usettings { + struct { + __u8 transceiver; + } deprecated; + struct ethtool_link_settings base; + struct { + ETHTOOL_DECLARE_LINK_MODE_MASK(supported); + ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); + ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising); + } link_modes; +}; + +#define ethtool_link_mode_for_each_u32(index) \ + for ((index) = 0; \ + (index) < ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32; \ + ++(index)) + +static inline void ethtool_link_mode_zero(u32 *dst) +{ + memset(dst, 0, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES); +} + +static inline bool ethtool_link_mode_is_empty(const u32 *mask) +{ + unsigned int i; + + ethtool_link_mode_for_each_u32(i) { + if (mask[i] != 0) + return false; + } + + return true; +} + +static inline void ethtool_link_mode_copy(u32 *dst, const u32 *src) +{ + memcpy(dst, src, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES); +} + +static inline int ethtool_link_mode_test_bit(unsigned int nr, const u32 *mask) +{ + if (nr >= ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS) + return !!0; + return !!(mask[nr / 32] & (1 << (nr % 32))); +} + +static inline int ethtool_link_mode_set_bit(unsigned int nr, u32 *mask) +{ + if (nr >= ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBITS) + return -1; + mask[nr / 32] |= (1 << (nr % 32)); + return 0; +} + +/* Struct for managing module EEPROM pages */ +struct ethtool_module_eeprom { + u32 offset; + u32 length; + u8 page; + u8 bank; + u8 i2c_address; + u8 *data; +}; + +/* Context for sub-commands */ +struct cmd_context { + const char *devname; /* net device name */ + int fd; /* socket suitable for ethtool ioctl */ + struct ifreq ifr; /* ifreq suitable for ethtool ioctl */ + unsigned int argc; /* number of arguments to the sub-command */ + char **argp; /* arguments to the sub-command */ + unsigned long debug; /* debugging mask */ + bool json; /* Output JSON, if supported */ + bool show_stats; /* include command-specific stats */ +#ifdef ETHTOOL_ENABLE_NETLINK + struct nl_context *nlctx; /* netlink context (opaque) */ +#endif +}; + +#ifdef TEST_ETHTOOL +int test_cmdline(const char *args); + +struct cmd_expect { + const void *cmd; /* expected command; NULL at end of list */ + size_t cmd_len; /* length to match (might be < sizeof struct) */ + int rc; /* kernel return code */ + const void *resp; /* response to write back; may be NULL */ + size_t resp_len; /* length to write back */ +}; +int test_ioctl(const struct cmd_expect *expect, void *cmd); +#define TEST_IOCTL_MISMATCH (-2) + +int test_main(int argc, char **argp); +void test_exit(int rc) __attribute__((noreturn)); + +#ifndef TEST_NO_WRAPPERS +#define main(...) test_main(__VA_ARGS__) +#undef exit +#define exit(rc) test_exit(rc) +void *test_malloc(size_t size); +#undef malloc +#define malloc(size) test_malloc(size) +void *test_calloc(size_t nmemb, size_t size); +#undef calloc +#define calloc(nmemb, size) test_calloc(nmemb, size) +char *test_strdup(const char *s); +#undef strdup +#define strdup(s) test_strdup(s) +void test_free(void *ptr); +#undef free +#define free(ptr) test_free(ptr) +void *test_realloc(void *ptr, size_t size); +#undef realloc +#define realloc(ptr, size) test_realloc(ptr, size) +int test_open(const char *pathname, int flag, ...); +#undef open +#define open(...) test_open(__VA_ARGS__) +int test_socket(int domain, int type, int protocol); +#undef socket +#define socket(...) test_socket(__VA_ARGS__) +int test_close(int fd); +#undef close +#define close(fd) test_close(fd) +FILE *test_fopen(const char *path, const char *mode); +#undef fopen +#define fopen(path, mode) test_fopen(path, mode) +int test_fclose(FILE *fh); +#undef fclose +#define fclose(fh) test_fclose(fh) +#endif +#endif + +int send_ioctl(struct cmd_context *ctx, void *cmd); + +void dump_hex(FILE *f, const u8 *data, int len, int offset); + +/* National Semiconductor DP83815, DP83816 */ +int natsemi_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); +int natsemi_dump_eeprom(struct ethtool_drvinfo *info, + struct ethtool_eeprom *ee); + +/* Digital/Intel 21040 and 21041 */ +int de2104x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Intel(R) PRO/1000 Gigabit Adapter Family */ +int e1000_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +int igb_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* RealTek PCI */ +int realtek_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Intel(R) PRO/100 Fast Ethernet Adapter Family */ +int e100_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Tigon3 */ +int tg3_dump_eeprom(struct ethtool_drvinfo *info, struct ethtool_eeprom *ee); + +/* Advanced Micro Devices AMD8111 based Adapter */ +int amd8111e_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Advanced Micro Devices PCnet32 Adapter */ +int pcnet32_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Motorola 8xx FEC Ethernet controller */ +int fec_8xx_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* PowerPC 4xx on-chip Ethernet controller */ +int ibm_emac_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Intel(R) PRO/10GBe Gigabit Adapter Family */ +int ixgb_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +int ixgbe_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +int ixgbevf_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Broadcom Tigon3 Ethernet controller */ +int tg3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* SysKonnect Gigabit (Genesis and Yukon) */ +int skge_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* SysKonnect Gigabit (Yukon2) */ +int sky2_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Fabric7 VIOC */ +int vioc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* SMSC LAN911x/LAN921x embedded ethernet controller */ +int smsc911x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +int at76c50x_usb_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Solarflare Solarstorm controllers */ +int sfc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* STMMAC embedded ethernet controller */ +int st_mac100_dump_regs(struct ethtool_drvinfo *info, + struct ethtool_regs *regs); +int st_gmac_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Et131x ethernet controller */ +int et131x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Altera TSE 10/100/1000 ethernet controller */ +int altera_tse_dump_regs(struct ethtool_drvinfo *info, + struct ethtool_regs *regs); + +/* VMware vmxnet3 ethernet controller */ +int vmxnet3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Rx flow classification */ +int rxclass_parse_ruleopts(struct cmd_context *ctx, + struct ethtool_rx_flow_spec *fsp, __u32 *rss_context); +int rxclass_rule_getall(struct cmd_context *ctx); +int rxclass_rule_get(struct cmd_context *ctx, __u32 loc); +int rxclass_rule_ins(struct cmd_context *ctx, + struct ethtool_rx_flow_spec *fsp, __u32 rss_context); +int rxclass_rule_del(struct cmd_context *ctx, __u32 loc); + +/* Module EEPROM parsing code */ +void sff8079_show_all_ioctl(const __u8 *id); +int sff8079_show_all_nl(struct cmd_context *ctx); + +/* Optics diagnostics */ +void sff8472_show_all(const __u8 *id); + +/* QSFP Optics diagnostics */ +void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len); +int sff8636_show_all_nl(struct cmd_context *ctx); + +/* FUJITSU Extended Socket network device */ +int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* MICROCHIP LAN78XX USB ETHERNET Controller */ +int lan78xx_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Distributed Switch Architecture */ +int dsa_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* i.MX Fast Ethernet Controller */ +int fec_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Freescale/NXP ENETC Ethernet Controller */ +int fsl_enetc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Intel(R) Ethernet Controller I225-LM/I225-V adapter family */ +int igc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Broadcom Ethernet Controller */ +int bnxt_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* TI CPSW Ethernet Switch */ +int cpsw_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +/* Microchip Ethernet Controller */ +int lan743x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + +#endif /* ETHTOOL_INTERNAL_H__ */ diff --git a/ixgb.c b/ixgb.c new file mode 100644 index 0000000..8aec9a9 --- /dev/null +++ b/ixgb.c @@ -0,0 +1,147 @@ +/* Copyright (c) 2006 Intel Corporation */ +#include +#include "internal.h" + +/* CTRL0 Bit Masks */ +#define IXGB_CTRL0_LRST 0x00000008 +#define IXGB_CTRL0_VME 0x40000000 + +/* STATUS Bit Masks */ +#define IXGB_STATUS_LU 0x00000002 +#define IXGB_STATUS_BUS64 0x00001000 +#define IXGB_STATUS_PCIX_MODE 0x00002000 +#define IXGB_STATUS_PCIX_SPD_100 0x00004000 +#define IXGB_STATUS_PCIX_SPD_133 0x00008000 + +/* RCTL Bit Masks */ +#define IXGB_RCTL_RXEN 0x00000002 +#define IXGB_RCTL_SBP 0x00000004 +#define IXGB_RCTL_UPE 0x00000008 +#define IXGB_RCTL_MPE 0x00000010 +#define IXGB_RCTL_RDMTS_MASK 0x00000300 +#define IXGB_RCTL_RDMTS_1_2 0x00000000 +#define IXGB_RCTL_RDMTS_1_4 0x00000100 +#define IXGB_RCTL_RDMTS_1_8 0x00000200 +#define IXGB_RCTL_BAM 0x00008000 +#define IXGB_RCTL_BSIZE_MASK 0x00030000 +#define IXGB_RCTL_BSIZE_4096 0x00010000 +#define IXGB_RCTL_BSIZE_8192 0x00020000 +#define IXGB_RCTL_BSIZE_16384 0x00030000 +#define IXGB_RCTL_VFE 0x00040000 +#define IXGB_RCTL_CFIEN 0x00080000 + +/* TCTL Bit Masks */ +#define IXGB_TCTL_TXEN 0x00000002 + +/* RAH Bit Masks */ +#define IXGB_RAH_ASEL_DEST 0x00000000 +#define IXGB_RAH_ASEL_SRC 0x00010000 +#define IXGB_RAH_AV 0x80000000 + +int ixgb_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *regs_buff = (u32 *)regs->data; + u8 version = (u8)(regs->version >> 24); + u32 reg; + + if (version != 1) + return -1; + fprintf(stdout, "MAC Registers\n"); + fprintf(stdout, "-------------\n"); + + /* Device control register */ + reg = regs_buff[0]; + fprintf(stdout, + "0x00000: CTRL0 (Device control register) 0x%08X\n" + " Link reset: %s\n" + " VLAN mode: %s\n", + reg, + reg & IXGB_CTRL0_LRST ? "reset" : "normal", + reg & IXGB_CTRL0_VME ? "enabled" : "disabled"); + + /* Device status register */ + reg = regs_buff[2]; + fprintf(stdout, + "0x00010: STATUS (Device status register) 0x%08X\n" + " Link up: %s\n" + " Bus type: %s\n" + " Bus speed: %s\n" + " Bus width: %s\n", + reg, + (reg & IXGB_STATUS_LU) ? "link config" : "no link config", + (reg & IXGB_STATUS_PCIX_MODE) ? "PCI-X" : "PCI", + ((reg & IXGB_STATUS_PCIX_SPD_133) ? "133MHz" : + (reg & IXGB_STATUS_PCIX_SPD_100) ? "100MHz" : + "66MHz"), + (reg & IXGB_STATUS_BUS64) ? "64-bit" : "32-bit"); + /* Receive control register */ + reg = regs_buff[9]; + fprintf(stdout, + "0x00100: RCTL (Receive control register) 0x%08X\n" + " Receiver: %s\n" + " Store bad packets: %s\n" + " Unicast promiscuous: %s\n" + " Multicast promiscuous: %s\n" + " Descriptor minimum threshold size: %s\n" + " Broadcast accept mode: %s\n" + " VLAN filter: %s\n" + " Cononical form indicator: %s\n", + reg, + reg & IXGB_RCTL_RXEN ? "enabled" : "disabled", + reg & IXGB_RCTL_SBP ? "enabled" : "disabled", + reg & IXGB_RCTL_UPE ? "enabled" : "disabled", + reg & IXGB_RCTL_MPE ? "enabled" : "disabled", + (reg & IXGB_RCTL_RDMTS_MASK) == IXGB_RCTL_RDMTS_1_2 ? "1/2" : + (reg & IXGB_RCTL_RDMTS_MASK) == IXGB_RCTL_RDMTS_1_4 ? "1/4" : + (reg & IXGB_RCTL_RDMTS_MASK) == IXGB_RCTL_RDMTS_1_8 ? "1/8" : + "reserved", + reg & IXGB_RCTL_BAM ? "accept" : "ignore", + reg & IXGB_RCTL_VFE ? "enabled" : "disabled", + reg & IXGB_RCTL_CFIEN ? "enabled" : "disabled"); + fprintf(stdout, + " Receive buffer size: %s\n", + (reg & IXGB_RCTL_BSIZE_MASK) == IXGB_RCTL_BSIZE_16384 ? "16384" : + (reg & IXGB_RCTL_BSIZE_MASK) == IXGB_RCTL_BSIZE_8192 ? "8192" : + (reg & IXGB_RCTL_BSIZE_MASK) == IXGB_RCTL_BSIZE_4096 ? "4096" : + "2048"); + + /* Receive descriptor registers */ + fprintf(stdout, + "0x00120: RDLEN (Receive desc length) 0x%08X\n", + regs_buff[14]); + fprintf(stdout, + "0x00128: RDH (Receive desc head) 0x%08X\n", + regs_buff[15]); + fprintf(stdout, + "0x00130: RDT (Receive desc tail) 0x%08X\n", + regs_buff[16]); + fprintf(stdout, + "0x00138: RDTR (Receive delay timer) 0x%08X\n", + regs_buff[17]); + + /* Transmit control register */ + reg = regs_buff[53]; + fprintf(stdout, + "0x00600: TCTL (Transmit ctrl register) 0x%08X\n" + " Transmitter: %s\n", + reg, + reg & IXGB_TCTL_TXEN ? "enabled" : "disabled"); + + /* Transmit descriptor registers */ + fprintf(stdout, + "0x00610: TDLEN (Transmit desc length) 0x%08X\n", + regs_buff[56]); + fprintf(stdout, + "0x00618: TDH (Transmit desc head) 0x%08X\n", + regs_buff[57]); + fprintf(stdout, + "0x00620: TDT (Transmit desc tail) 0x%08X\n", + regs_buff[58]); + fprintf(stdout, + "0x00628: TIDV (Transmit delay timer) 0x%08X\n", + regs_buff[59]); + + return 0; +} + diff --git a/ixgbe.c b/ixgbe.c new file mode 100644 index 0000000..6d509c8 --- /dev/null +++ b/ixgbe.c @@ -0,0 +1,1296 @@ +/* Copyright (c) 2007 Intel Corporation */ +#include +#include "internal.h" + +/* Register Bit Masks */ +#define IXGBE_FCTRL_SBP 0x00000002 +#define IXGBE_FCTRL_MPE 0x00000100 +#define IXGBE_FCTRL_UPE 0x00000200 +#define IXGBE_FCTRL_BAM 0x00000400 +#define IXGBE_FCTRL_PMCF 0x00001000 +#define IXGBE_FCTRL_DPF 0x00002000 +#define IXGBE_FCTRL_RPFCE 0x00004000 +#define IXGBE_FCTRL_RFCE 0x00008000 +#define IXGBE_VLNCTRL_VET 0x0000FFFF +#define IXGBE_VLNCTRL_CFI 0x10000000 +#define IXGBE_VLNCTRL_CFIEN 0x20000000 +#define IXGBE_VLNCTRL_VFE 0x40000000 +#define IXGBE_VLNCTRL_VME 0x80000000 +#define IXGBE_LINKS_UP 0x40000000 +#define IXGBE_LINKS_SPEED 0x20000000 +#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F +#define IXGBE_HLREG0_TXCRCEN 0x00000001 +#define IXGBE_HLREG0_RXCRCSTRP 0x00000002 +#define IXGBE_HLREG0_JUMBOEN 0x00000004 +#define IXGBE_HLREG0_TXPADEN 0x00000400 +#define IXGBE_HLREG0_LPBK 0x00008000 +#define IXGBE_RMCS_TFCE_802_3X 0x00000008 +#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 +#define IXGBE_FCCFG_TFCE_802_3X 0x00000008 +#define IXGBE_FCCFG_TFCE_PRIORITY 0x00000010 +#define IXGBE_MFLCN_PMCF 0x00000001 /* Pass MAC Control Frames */ +#define IXGBE_MFLCN_DPF 0x00000002 /* Discard Pause Frame */ +#define IXGBE_MFLCN_RPFCE 0x00000004 /* Receive Priority FC Enable */ +#define IXGBE_MFLCN_RFCE 0x00000008 /* Receive FC Enable */ + +/* Device IDs */ +#define IXGBE_DEV_ID_82598 0x10B6 +#define IXGBE_DEV_ID_82598_BX 0x1508 +#define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6 +#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7 +#define IXGBE_DEV_ID_82598EB_SFP_LOM 0x10DB +#define IXGBE_DEV_ID_82598AT 0x10C8 +#define IXGBE_DEV_ID_82598AT2 0x150B +#define IXGBE_DEV_ID_82598EB_CX4 0x10DD +#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC +#define IXGBE_DEV_ID_82598_DA_DUAL_PORT 0x10F1 +#define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1 +#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4 +#define IXGBE_DEV_ID_82599_KX4 0x10F7 +#define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514 +#define IXGBE_DEV_ID_82599_KR 0x1517 +#define IXGBE_DEV_ID_82599_T3_LOM 0x151C +#define IXGBE_DEV_ID_82599_CX4 0x10F9 +#define IXGBE_DEV_ID_82599_SFP 0x10FB +#define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152a +#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529 +#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 +#define IXGBE_DEV_ID_82599_SFP_EM 0x1507 +#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D +#define IXGBE_DEV_ID_82599EN_SFP 0x1557 +#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC +#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 +#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C +#define IXGBE_DEV_ID_82599_LS 0x154F +#define IXGBE_DEV_ID_X540T 0x1528 +#define IXGBE_DEV_ID_82599_SFP_SF_QP 0x154A +#define IXGBE_DEV_ID_82599_QSFP_SF_QP 0x1558 +#define IXGBE_DEV_ID_X540T1 0x1560 + +#define IXGBE_DEV_ID_X550T 0x1563 +#define IXGBE_DEV_ID_X550T1 0x15D1 +#define IXGBE_DEV_ID_X550EM_X_KX4 0x15AA +#define IXGBE_DEV_ID_X550EM_X_KR 0x15AB +#define IXGBE_DEV_ID_X550EM_X_SFP 0x15AC +#define IXGBE_DEV_ID_X550EM_X_10G_T 0x15AD +#define IXGBE_DEV_ID_X550EM_X_1G_T 0x15AE +#define IXGBE_DEV_ID_X550EM_A_KR 0x15C2 +#define IXGBE_DEV_ID_X550EM_A_KR_L 0x15C3 +#define IXGBE_DEV_ID_X550EM_A_SFP_N 0x15C4 +#define IXGBE_DEV_ID_X550EM_A_SGMII 0x15C6 +#define IXGBE_DEV_ID_X550EM_A_SGMII_L 0x15C7 +#define IXGBE_DEV_ID_X550EM_A_SFP 0x15CE + +/* + * Enumerated types specific to the ixgbe hardware + * Media Access Controlers + */ +enum ixgbe_mac_type { + ixgbe_mac_unknown = 0, + ixgbe_mac_82598EB, + ixgbe_mac_82599EB, + ixgbe_mac_X540, + ixgbe_mac_x550, + ixgbe_mac_x550em_x, + ixgbe_mac_x550em_a, + ixgbe_num_macs +}; + +static enum ixgbe_mac_type +ixgbe_get_mac_type(u16 device_id) +{ + enum ixgbe_mac_type mac_type = ixgbe_mac_unknown; + + switch (device_id) { + case IXGBE_DEV_ID_82598: + case IXGBE_DEV_ID_82598_BX: + case IXGBE_DEV_ID_82598AF_DUAL_PORT: + case IXGBE_DEV_ID_82598AF_SINGLE_PORT: + case IXGBE_DEV_ID_82598EB_SFP_LOM: + case IXGBE_DEV_ID_82598AT: + case IXGBE_DEV_ID_82598AT2: + case IXGBE_DEV_ID_82598EB_CX4: + case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: + case IXGBE_DEV_ID_82598_DA_DUAL_PORT: + case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: + case IXGBE_DEV_ID_82598EB_XF_LR: + mac_type = ixgbe_mac_82598EB; + break; + case IXGBE_DEV_ID_82599_KX4: + case IXGBE_DEV_ID_82599_KX4_MEZZ: + case IXGBE_DEV_ID_82599_KR: + case IXGBE_DEV_ID_82599_T3_LOM: + case IXGBE_DEV_ID_82599_CX4: + case IXGBE_DEV_ID_82599_SFP: + case IXGBE_DEV_ID_82599_BACKPLANE_FCOE: + case IXGBE_DEV_ID_82599_SFP_FCOE: + case IXGBE_SUBDEV_ID_82599_SFP: + case IXGBE_DEV_ID_82599_SFP_EM: + case IXGBE_DEV_ID_82599_SFP_SF2: + case IXGBE_DEV_ID_82599EN_SFP: + case IXGBE_DEV_ID_82599_XAUI_LOM: + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: + case IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ: + case IXGBE_DEV_ID_82599_LS: + case IXGBE_DEV_ID_82599_SFP_SF_QP: + case IXGBE_DEV_ID_82599_QSFP_SF_QP: + mac_type = ixgbe_mac_82599EB; + break; + case IXGBE_DEV_ID_X540T: + case IXGBE_DEV_ID_X540T1: + mac_type = ixgbe_mac_X540; + break; + case IXGBE_DEV_ID_X550T: + case IXGBE_DEV_ID_X550T1: + mac_type = ixgbe_mac_x550; + break; + case IXGBE_DEV_ID_X550EM_X_KX4: + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X_SFP: + case IXGBE_DEV_ID_X550EM_X_10G_T: + case IXGBE_DEV_ID_X550EM_X_1G_T: + mac_type = ixgbe_mac_x550em_x; + break; + case IXGBE_DEV_ID_X550EM_A_KR: + case IXGBE_DEV_ID_X550EM_A_KR_L: + case IXGBE_DEV_ID_X550EM_A_SFP_N: + case IXGBE_DEV_ID_X550EM_A_SGMII: + case IXGBE_DEV_ID_X550EM_A_SGMII_L: + case IXGBE_DEV_ID_X550EM_A_SFP: + mac_type = ixgbe_mac_x550em_a; + break; + default: + mac_type = ixgbe_mac_82598EB; + break; + } + + return mac_type; +} + +int +ixgbe_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *regs_buff = (u32 *)regs->data; + u32 regs_buff_len = regs->len / sizeof(*regs_buff); + u32 reg; + u32 offset; + u16 hw_device_id = (u16) regs->version; + u8 version = (u8)(regs->version >> 24); + u8 i; + enum ixgbe_mac_type mac_type; + + if (version == 0) + return -1; + + /* The current driver reports the MAC type, but older versions + * only report the device ID so we have to infer the MAC type. + */ + mac_type = version > 1 ? version : ixgbe_get_mac_type(hw_device_id); + + reg = regs_buff[1065]; + fprintf(stdout, + "0x042A4: LINKS (Link Status register) 0x%08X\n" + " Link Status: %s\n" + " Link Speed: %s\n", + reg, + reg & IXGBE_LINKS_UP ? "up" : "down", + reg & IXGBE_LINKS_SPEED ? "10G" : "1G"); + + reg = regs_buff[515]; + fprintf(stdout, + "0x05080: FCTRL (Filter Control register) 0x%08X\n" + " Broadcast Accept: %s\n" + " Unicast Promiscuous: %s\n" + " Multicast Promiscuous: %s\n" + " Store Bad Packets: %s\n", + reg, + reg & IXGBE_FCTRL_BAM ? "enabled" : "disabled", + reg & IXGBE_FCTRL_UPE ? "enabled" : "disabled", + reg & IXGBE_FCTRL_MPE ? "enabled" : "disabled", + reg & IXGBE_FCTRL_SBP ? "enabled" : "disabled"); + + /* Some FCTRL bits are valid only on 82598 */ + if (mac_type == ixgbe_mac_82598EB) { + fprintf(stdout, + " Receive Flow Control Packets: %s\n" + " Receive Priority Flow Control Packets: %s\n" + " Discard Pause Frames: %s\n" + " Pass MAC Control Frames: %s\n", + reg & IXGBE_FCTRL_RFCE ? "enabled" : "disabled", + reg & IXGBE_FCTRL_RPFCE ? "enabled" : "disabled", + reg & IXGBE_FCTRL_DPF ? "enabled" : "disabled", + reg & IXGBE_FCTRL_PMCF ? "enabled" : "disabled"); + } + + reg = regs_buff[1128]; + if (mac_type >= ixgbe_mac_82599EB) { + fprintf(stdout, + "0x04294: MFLCN (TabMAC Flow Control register) 0x%08X\n" + " Receive Flow Control Packets: %s\n" + " Discard Pause Frames: %s\n" + " Pass MAC Control Frames: %s\n" + " Receive Priority Flow Control Packets: %s\n", + reg, + reg & IXGBE_MFLCN_RFCE ? "enabled" : "disabled", + reg & IXGBE_MFLCN_DPF ? "enabled" : "disabled", + reg & IXGBE_MFLCN_PMCF ? "enabled" : "disabled", + reg & IXGBE_MFLCN_RPFCE ? "enabled" : "disabled"); + } + + reg = regs_buff[516]; + fprintf(stdout, + "0x05088: VLNCTRL (VLAN Control register) 0x%08X\n" + " VLAN Mode: %s\n" + " VLAN Filter: %s\n", + reg, + reg & IXGBE_VLNCTRL_VME ? "enabled" : "disabled", + reg & IXGBE_VLNCTRL_VFE ? "enabled" : "disabled"); + + reg = regs_buff[437]; + fprintf(stdout, + "0x02100: SRRCTL0 (Split and Replic Rx Control 0) 0x%08X\n" + " Receive Buffer Size: %uKB\n", + reg, + (reg & IXGBE_SRRCTL_BSIZEPKT_MASK) <= 0x10 ? (reg & IXGBE_SRRCTL_BSIZEPKT_MASK) : 0x10); + + reg = regs_buff[829]; + if (mac_type == ixgbe_mac_82598EB) { + fprintf(stdout, + "0x03D00: RMCS (Receive Music Control register) 0x%08X\n" + " Transmit Flow Control: %s\n" + " Priority Flow Control: %s\n", + reg, + reg & IXGBE_RMCS_TFCE_802_3X ? "enabled" : "disabled", + reg & IXGBE_RMCS_TFCE_PRIORITY ? "enabled" : "disabled"); + } else if (mac_type >= ixgbe_mac_82599EB) { + fprintf(stdout, + "0x03D00: FCCFG (Flow Control Configuration) 0x%08X\n" + " Transmit Flow Control: %s\n" + " Priority Flow Control: %s\n", + reg, + reg & IXGBE_FCCFG_TFCE_802_3X ? "enabled" : "disabled", + reg & IXGBE_FCCFG_TFCE_PRIORITY ? "enabled" : "disabled"); + } + + reg = regs_buff[1047]; + fprintf(stdout, + "0x04240: HLREG0 (Highlander Control 0 register) 0x%08X\n" + " Transmit CRC: %s\n" + " Receive CRC Strip: %s\n" + " Jumbo Frames: %s\n" + " Pad Short Frames: %s\n" + " Loopback: %s\n", + reg, + reg & IXGBE_HLREG0_TXCRCEN ? "enabled" : "disabled", + reg & IXGBE_HLREG0_RXCRCSTRP ? "enabled" : "disabled", + reg & IXGBE_HLREG0_JUMBOEN ? "enabled" : "disabled", + reg & IXGBE_HLREG0_TXPADEN ? "enabled" : "disabled", + reg & IXGBE_HLREG0_LPBK ? "enabled" : "disabled"); + + /* General Registers */ + fprintf(stdout, + "0x00000: CTRL (Device Control) 0x%08X\n", + regs_buff[0]); + + fprintf(stdout, + "0x00008: STATUS (Device Status) 0x%08X\n", + regs_buff[1]); + + fprintf(stdout, + "0x00018: CTRL_EXT (Extended Device Control) 0x%08X\n", + regs_buff[2]); + + fprintf(stdout, + "0x00020: ESDP (Extended SDP Control) 0x%08X\n", + regs_buff[3]); + + fprintf(stdout, + "0x00028: EODSDP (Extended OD SDP Control) 0x%08X\n", + regs_buff[4]); + + fprintf(stdout, + "0x00200: LEDCTL (LED Control) 0x%08X\n", + regs_buff[5]); + + fprintf(stdout, + "0x00048: FRTIMER (Free Running Timer) 0x%08X\n", + regs_buff[6]); + + fprintf(stdout, + "0x0004C: TCPTIMER (TCP Timer) 0x%08X\n", + regs_buff[7]); + + /* NVM Register */ + offset = mac_type == ixgbe_mac_x550em_a ? 0x15FF8 : 0x10010; + fprintf(stdout, + "0x%05X: EEC (EEPROM/Flash Control) 0x%08X\n", + offset, regs_buff[8]); + + fprintf(stdout, + "0x10014: EERD (EEPROM Read) 0x%08X\n", + regs_buff[9]); + + offset = mac_type == ixgbe_mac_x550em_a ? 0x15F6C : 0x1001C; + fprintf(stdout, + "0x%05X: FLA (Flash Access) 0x%08X\n", + offset, regs_buff[10]); + + fprintf(stdout, + "0x10110: EEMNGCTL (Manageability EEPROM Control) 0x%08X\n", + regs_buff[11]); + + fprintf(stdout, + "0x10114: EEMNGDATA (Manageability EEPROM R/W Data) 0x%08X\n", + regs_buff[12]); + + fprintf(stdout, + "0x10118: FLMNGCTL (Manageability Flash Control) 0x%08X\n", + regs_buff[13]); + + fprintf(stdout, + "0x1011C: FLMNGDATA (Manageability Flash Read Data) 0x%08X\n", + regs_buff[14]); + + fprintf(stdout, + "0x10120: FLMNGCNT (Manageability Flash Read Count) 0x%08X\n", + regs_buff[15]); + + fprintf(stdout, + "0x1013C: FLOP (Flash Opcode) 0x%08X\n", + regs_buff[16]); + + offset = mac_type == ixgbe_mac_x550em_a ? 0x15F64 : 0x10200; + fprintf(stdout, + "0x%05X: GRC (General Receive Control) 0x%08X\n", + offset, regs_buff[17]); + + /* Interrupt */ + fprintf(stdout, + "0x00800: EICR (Extended Interrupt Cause) 0x%08X\n", + regs_buff[18]); + + fprintf(stdout, + "0x00808: EICS (Extended Interrupt Cause Set) 0x%08X\n", + regs_buff[19]); + + fprintf(stdout, + "0x00880: EIMS (Extended Interr. Mask Set/Read) 0x%08X\n", + regs_buff[20]); + + fprintf(stdout, + "0x00888: EIMC (Extended Interrupt Mask Clear) 0x%08X\n", + regs_buff[21]); + + fprintf(stdout, + "0x00810: EIAC (Extended Interrupt Auto Clear) 0x%08X\n", + regs_buff[22]); + + fprintf(stdout, + "0x00890: EIAM (Extended Interr. Auto Mask EN) 0x%08X\n", + regs_buff[23]); + + fprintf(stdout, + "0x00820: EITR0 (Extended Interrupt Throttle 0) 0x%08X\n", + regs_buff[24]); + + fprintf(stdout, + "0x00900: IVAR0 (Interrupt Vector Allocation 0) 0x%08X\n", + regs_buff[25]); + + fprintf(stdout, + "0x00000: MSIXT (MSI-X Table) 0x%08X\n", + regs_buff[26]); + + if (mac_type == ixgbe_mac_82598EB) + fprintf(stdout, + "0x02000: MSIXPBA (MSI-X Pending Bit Array) 0x%08X\n", + regs_buff[27]); + + fprintf(stdout, + "0x11068: PBACL (MSI-X PBA Clear) 0x%08X\n", + regs_buff[28]); + + fprintf(stdout, + "0x00898: GPIE (General Purpose Interrupt EN) 0x%08X\n", + regs_buff[29]); + + /* Flow Control */ + fprintf(stdout, + "0x03008: PFCTOP (Priority Flow Ctrl Type Opcode) 0x%08X\n", + regs_buff[30]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x%05X: FCCTV%d (Flow Ctrl Tx Timer Value %d) 0x%08X\n", + 0x03200 + (4 * i), i, i, regs_buff[31 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: FCRTL%d (Flow Ctrl Rx Threshold low %d) 0x%08X\n", + 0x3220 + (8 * i), i, i, regs_buff[35 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: FCRTH%d (Flow Ctrl Rx Threshold High %d) 0x%08X\n", + 0x3260 + (8 * i), i, i, regs_buff[43 + i]); + + fprintf(stdout, + "0x032A0: FCRTV (Flow Control Refresh Threshold) 0x%08X\n", + regs_buff[51]); + + fprintf(stdout, + "0x0CE00: TFCS (Transmit Flow Control Status) 0x%08X\n", + regs_buff[52]); + + /* Receive DMA */ + for (i = 0; i < 64; i++) + fprintf(stdout, + "0x%05X: RDBAL%02d (Rx Desc Base Addr Low %02d) 0x%08X\n", + 0x01000 + (0x40 * i), i, i, regs_buff[53 + i]); + + for (i = 0; i < 64; i++) + fprintf(stdout, + "0x%05X: RDBAH%02d (Rx Desc Base Addr High %02d) 0x%08X\n", + 0x01004 + (0x40 * i), i, i, regs_buff[117 + i]); + + for (i = 0; i < 64; i++) + fprintf(stdout, + "0x%05X: RDLEN%02d (Receive Descriptor Length %02d) 0x%08X\n", + 0x01008 + (0x40 * i), i, i, regs_buff[181 + i]); + + for (i = 0; i < 64; i++) + fprintf(stdout, + "0x%05X: RDH%02d (Receive Descriptor Head %02d) 0x%08X\n", + 0x01010 + (0x40 * i), i, i, regs_buff[245 + i]); + + for (i = 0; i < 64; i++) + fprintf(stdout, + "0x%05X: RDT%02d (Receive Descriptor Tail %02d) 0x%08X\n", + 0x01018 + (0x40 * i), i, i, regs_buff[309 + i]); + + for (i = 0; i < 64; i++) + fprintf(stdout, + "0x%05X: RXDCTL%02d (Receive Descriptor Control %02d) 0x%08X\n", + 0x01028 + (0x40 * i), i, i, regs_buff[373 + i]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x%05X: SRRCTL%02d (Split and Replic Rx Control %02d) 0x%08X\n", + 0x02100 + (4 * i), i, i, regs_buff[437 + i]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x%05X: DCA_RXCTRL%02d (Rx DCA Control %02d) 0x%08X\n", + 0x02200 + (4 * i), i, i, regs_buff[453 + i]); + + fprintf(stdout, + "0x02F00: RDRXCTL (Receive DMA Control) 0x%08X\n", + regs_buff[469]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RXPBSIZE%d (Receive Packet Buffer Size %d) 0x%08X\n", + 0x3C00 + (4 * i), i, i, regs_buff[470 + i]); + + fprintf(stdout, + "0x03000: RXCTRL (Receive Control) 0x%08X\n", + regs_buff[478]); + + if (mac_type == ixgbe_mac_82598EB) + fprintf(stdout, + "0x03D04: DROPEN (Drop Enable Control) 0x%08X\n", + regs_buff[479]); + + /* Receive */ + fprintf(stdout, + "0x05000: RXCSUM (Receive Checksum Control) 0x%08X\n", + regs_buff[480]); + + fprintf(stdout, + "0x05008: RFCTL (Receive Filter Control) 0x%08X\n", + regs_buff[481]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x%05X: RAL%02d (Receive Address Low%02d) 0x%08X\n", + 0x05400 + (8 * i), i, i, regs_buff[482 + i]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x%05X: RAH%02d (Receive Address High %02d) 0x%08X\n", + 0x05404 + (8 * i), i, i, regs_buff[498 + i]); + + fprintf(stdout, + "0x05480: PSRTYPE (Packet Split Receive Type) 0x%08X\n", + regs_buff[514]); + + fprintf(stdout, + "0x05090: MCSTCTRL (Multicast Control) 0x%08X\n", + regs_buff[517]); + + fprintf(stdout, + "0x05818: MRQC (Multiple Rx Queues Command) 0x%08X\n", + regs_buff[518]); + + fprintf(stdout, + "0x0581C: VMD_CTL (VMDq Control) 0x%08X\n", + regs_buff[519]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: IMIR%d (Immediate Interrupt Rx %d) 0x%08X\n", + 0x05A80 + (4 * i), i, i, regs_buff[520 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: IMIREXT%d (Immed. Interr. Rx Extended %d) 0x%08X\n", + 0x05AA0 + (4 * i), i, i, regs_buff[528 + i]); + + fprintf(stdout, + "0x05AC0: IMIRVP (Immed. Interr. Rx VLAN Prior.) 0x%08X\n", + regs_buff[536]); + + /* Transmit */ + for (i = 0; i < 32; i++) + fprintf(stdout, + "0x%05X: TDBAL%02d (Tx Desc Base Addr Low %02d) 0x%08X\n", + 0x06000 + (0x40 * i), i, i, regs_buff[537 + i]); + + for (i = 0; i < 32; i++) + fprintf(stdout, + "0x%05X: TDBAH%02d (Tx Desc Base Addr High %02d) 0x%08X\n", + 0x06004 + (0x40 * i), i, i, regs_buff[569 + i]); + + for (i = 0; i < 32; i++) + fprintf(stdout, + "0x%05X: TDLEN%02d (Tx Descriptor Length %02d) 0x%08X\n", + 0x06008 + (0x40 * i), i, i, regs_buff[601 + i]); + + for (i = 0; i < 32; i++) + fprintf(stdout, + "0x%05X: TDH%02d (Transmit Descriptor Head %02d) 0x%08X\n", + 0x06010 + (0x40 * i), i, i, regs_buff[633 + i]); + + for (i = 0; i < 32; i++) + fprintf(stdout, + "0x%05X: TDT%02d (Transmit Descriptor Tail %02d) 0x%08X\n", + 0x06018 + (0x40 * i), i, i, regs_buff[665 + i]); + + for (i = 0; i < 32; i++) + fprintf(stdout, + "0x%05X: TXDCTL%02d (Tx Descriptor Control %02d) 0x%08X\n", + 0x06028 + (0x40 * i), i, i, regs_buff[697 + i]); + + for (i = 0; i < 32; i++) + fprintf(stdout, + "0x%05X: TDWBAL%02d (Tx Desc Compl. WB Addr low %02d) 0x%08X\n", + 0x06038 + (0x40 * i), i, i, regs_buff[729 + i]); + + for (i = 0; i < 32; i++) + fprintf(stdout, + "0x%05X: TDWBAH%02d (Tx Desc Compl. WB Addr High %02d) 0x%08X\n", + 0x0603C + (0x40 * i), i, i, regs_buff[761 + i]); + + fprintf(stdout, + "0x07E00: DTXCTL (DMA Tx Control) 0x%08X\n", + regs_buff[793]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x%05X: DCA_TXCTRL%02d (Tx DCA Control %02d) 0x%08X\n", + 0x07200 + (4 * i), i, i, regs_buff[794 + i]); + + if (mac_type == ixgbe_mac_82598EB) + fprintf(stdout, + "0x0CB00: TIPG (Transmit IPG Control) 0x%08X\n", + regs_buff[810]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: TXPBSIZE%d (Transmit Packet Buffer Size %d) 0x%08X\n", + 0x0CC00 + (4 * i), i, i, regs_buff[811 + i]); + + fprintf(stdout, + "0x0CD10: MNGTXMAP (Manageability Tx TC Mapping) 0x%08X\n", + regs_buff[819]); + + /* Wake Up */ + fprintf(stdout, + "0x05800: WUC (Wake up Control) 0x%08X\n", + regs_buff[820]); + + fprintf(stdout, + "0x05808: WUFC (Wake Up Filter Control) 0x%08X\n", + regs_buff[821]); + + fprintf(stdout, + "0x05810: WUS (Wake Up Status) 0x%08X\n", + regs_buff[822]); + + fprintf(stdout, + "0x05838: IPAV (IP Address Valid) 0x%08X\n", + regs_buff[823]); + + fprintf(stdout, + "0x05840: IP4AT (IPv4 Address Table) 0x%08X\n", + regs_buff[824]); + + fprintf(stdout, + "0x05880: IP6AT (IPv6 Address Table) 0x%08X\n", + regs_buff[825]); + + fprintf(stdout, + "0x05900: WUPL (Wake Up Packet Length) 0x%08X\n", + regs_buff[826]); + + fprintf(stdout, + "0x05A00: WUPM (Wake Up Packet Memory) 0x%08X\n", + regs_buff[827]); + + fprintf(stdout, + "0x09000: FHFT (Flexible Host Filter Table) 0x%08X\n", + regs_buff[828]); + + /* DCB */ + if (mac_type == ixgbe_mac_82598EB) { + fprintf(stdout, + "0x07F40: DPMCS (Desc. Plan Music Ctrl Status) 0x%08X\n", + regs_buff[830]); + + fprintf(stdout, + "0x0CD00: PDPMCS (Pkt Data Plan Music ctrl Stat) 0x%08X\n", + regs_buff[831]); + + fprintf(stdout, + "0x050A0: RUPPBMR (Rx User Prior to Pkt Buff Map) 0x%08X\n", + regs_buff[832]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RT2CR%d (Receive T2 Configure %d) 0x%08X\n", + 0x03C20 + (4 * i), i, i, regs_buff[833 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RT2SR%d (Receive T2 Status %d) 0x%08X\n", + 0x03C40 + (4 * i), i, i, regs_buff[841 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: TDTQ2TCCR%d (Tx Desc TQ2 TC Config %d) 0x%08X\n", + 0x0602C + (0x40 * i), i, i, regs_buff[849 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: TDTQ2TCSR%d (Tx Desc TQ2 TC Status %d) 0x%08X\n", + 0x0622C + (0x40 * i), i, i, regs_buff[857 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: TDPT2TCCR%d (Tx Data Plane T2 TC Config %d) 0x%08X\n", + 0x0CD20 + (4 * i), i, i, regs_buff[865 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: TDPT2TCSR%d (Tx Data Plane T2 TC Status %d) 0x%08X\n", + 0x0CD40 + (4 * i), i, i, regs_buff[873 + i]); + } else if (mac_type >= ixgbe_mac_82599EB && mac_type <= ixgbe_mac_x550) { + fprintf(stdout, + "0x04900: RTTDCS (Tx Descr Plane Ctrl&Status) 0x%08X\n", + regs_buff[830]); + + fprintf(stdout, + "0x0CD00: RTTPCS (Tx Pkt Plane Ctrl&Status) 0x%08X\n", + regs_buff[831]); + + fprintf(stdout, + "0x02430: RTRPCS (Rx Packet Plane Ctrl&Status) 0x%08X\n", + regs_buff[832]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RTRPT4C%d (Rx Packet Plane T4 Config %d) 0x%08X\n", + 0x02140 + (4 * i), i, i, regs_buff[833 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RTRPT4S%d (Rx Packet Plane T4 Status %d) 0x%08X\n", + 0x02160 + (4 * i), i, i, regs_buff[841 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RTTDT2C%d (Tx Descr Plane T2 Config %d) 0x%08X\n", + 0x04910 + (4 * i), i, i, regs_buff[849 + i]); + + if (mac_type < ixgbe_mac_x550) + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RTTDT2S%d (Tx Descr Plane T2 Status %d) 0x%08X\n", + 0x04930 + (4 * i), i, i, regs_buff[857 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RTTPT2C%d (Tx Packet Plane T2 Config %d) 0x%08X\n", + 0x0CD20 + (4 * i), i, i, regs_buff[865]); + + if (mac_type < ixgbe_mac_x550) + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RTTPT2S%d (Tx Packet Plane T2 Status %d) 0x%08X\n", + 0x0CD40 + (4 * i), i, i, regs_buff[873 + i]); + } + + if (regs_buff_len > 1129 && mac_type != ixgbe_mac_82598EB) { + fprintf(stdout, + "0x03020: RTRUP2TC (Rx User Prio to Traffic Classes)0x%08X\n", + regs_buff[1129]); + + fprintf(stdout, + "0x0C800: RTTUP2TC (Tx User Prio to Traffic Classes)0x%08X\n", + regs_buff[1130]); + + if (mac_type <= ixgbe_mac_x550) + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x%05X: TXLLQ%d (Strict Low Lat Tx Queues %d) 0x%08X\n", + 0x082E0 + (4 * i), i, i, regs_buff[1131 + i]); + + if (mac_type == ixgbe_mac_82599EB) { + fprintf(stdout, + "0x04980: RTTBCNRM (DCB TX Rate Sched MMW) 0x%08X\n", + regs_buff[1135]); + + fprintf(stdout, + "0x0498C: RTTBCNRD (DCB TX Rate-Scheduler Drift) 0x%08X\n", + regs_buff[1136]); + } else if (mac_type <= ixgbe_mac_x550) { + fprintf(stdout, + "0x04980: RTTQCNRM (DCB TX QCN Rate Sched MMW) 0x%08X\n", + regs_buff[1135]); + + fprintf(stdout, + "0x0498C: RTTQCNRR (DCB TX QCN Rate Reset) 0x%08X\n", + regs_buff[1136]); + + if (mac_type < ixgbe_mac_x550) + fprintf(stdout, + "0x08B00: RTTQCNCR (DCB TX QCN Control) 0x%08X\n", + regs_buff[1137]); + + fprintf(stdout, + "0x04A90: RTTQCNTG (DCB TX QCN Tagging) 0x%08X\n", + regs_buff[1138]); + } + } + + /* Statistics */ + fprintf(stdout, + "0x04000: crcerrs (CRC Error Count) 0x%08X\n", + regs_buff[881]); + + fprintf(stdout, + "0x04004: illerrc (Illegal Byte Error Count) 0x%08X\n", + regs_buff[882]); + + fprintf(stdout, + "0x04008: errbc (Error Byte Count) 0x%08X\n", + regs_buff[883]); + + fprintf(stdout, + "0x04010: mspdc (MAC Short Packet Discard Count) 0x%08X\n", + regs_buff[884]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: mpc%d (Missed Packets Count %d) 0x%08X\n", + 0x03FA0 + (4 * i), i, i, regs_buff[885 + i]); + + fprintf(stdout, + "0x04034: mlfc (MAC Local Fault Count) 0x%08X\n", + regs_buff[893]); + + fprintf(stdout, + "0x04038: mrfc (MAC Remote Fault Count) 0x%08X\n", + regs_buff[894]); + + fprintf(stdout, + "0x04040: rlec (Receive Length Error Count) 0x%08X\n", + regs_buff[895]); + + fprintf(stdout, + "0x03F60: lxontxc (Link XON Transmitted Count) 0x%08X\n", + regs_buff[896]); + + fprintf(stdout, + "0x0CF60: lxonrxc (Link XON Received Count) 0x%08X\n", + regs_buff[897]); + + fprintf(stdout, + "0x03F68: lxofftxc (Link XOFF Transmitted Count) 0x%08X\n", + regs_buff[898]); + + fprintf(stdout, + "0x0CF68: lxoffrxc (Link XOFF Received Count) 0x%08X\n", + regs_buff[899]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: pxontxc%d (Priority XON Tx Count %d) 0x%08X\n", + 0x03F00 + (4 * i), i, i, regs_buff[900 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: pxonrxc%d (Priority XON Received Count %d) 0x%08X\n", + 0x0CF00 + (4 * i), i, i, regs_buff[908 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: pxofftxc%d (Priority XOFF Tx Count %d) 0x%08X\n", + 0x03F20 + (4 * i), i, i, regs_buff[916 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: pxoffrxc%d (Priority XOFF Received Count %d) 0x%08X\n", + 0x0CF20 + (4 * i), i, i, regs_buff[924 + i]); + + fprintf(stdout, + "0x0405C: prc64 (Packets Received (64B) Count) 0x%08X\n", + regs_buff[932]); + + fprintf(stdout, + "0x04060: prc127 (Packets Rx (65-127B) Count) 0x%08X\n", + regs_buff[933]); + + fprintf(stdout, + "0x04064: prc255 (Packets Rx (128-255B) Count) 0x%08X\n", + regs_buff[934]); + + fprintf(stdout, + "0x04068: prc511 (Packets Rx (256-511B) Count) 0x%08X\n", + regs_buff[935]); + + fprintf(stdout, + "0x0406C: prc1023 (Packets Rx (512-1023B) Count) 0x%08X\n", + regs_buff[936]); + + fprintf(stdout, + "0x04070: prc1522 (Packets Rx (1024-Max) Count) 0x%08X\n", + regs_buff[937]); + + fprintf(stdout, + "0x04074: gprc (Good Packets Received Count) 0x%08X\n", + regs_buff[938]); + + fprintf(stdout, + "0x04078: bprc (Broadcast Packets Rx Count) 0x%08X\n", + regs_buff[939]); + + fprintf(stdout, + "0x0407C: mprc (Multicast Packets Rx Count) 0x%08X\n", + regs_buff[940]); + + fprintf(stdout, + "0x04080: gptc (Good Packets Transmitted Count) 0x%08X\n", + regs_buff[941]); + + fprintf(stdout, + "0x04088: gorcl (Good Octets Rx Count Low) 0x%08X\n", + regs_buff[942]); + + fprintf(stdout, + "0x0408C: gorch (Good Octets Rx Count High) 0x%08X\n", + regs_buff[943]); + + fprintf(stdout, + "0x04090: gotcl (Good Octets Tx Count Low) 0x%08X\n", + regs_buff[944]); + + fprintf(stdout, + "0x04094: gotch (Good Octets Tx Count High) 0x%08X\n", + regs_buff[945]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: rnbc%d (Receive No Buffers Count %d) 0x%08X\n", + 0x03FC0 + (4 * i), i, i, regs_buff[946 + i]); + + fprintf(stdout, + "0x040A4: ruc (Receive Undersize count) 0x%08X\n", + regs_buff[954]); + + fprintf(stdout, + "0x040A8: rfc (Receive Fragment Count) 0x%08X\n", + regs_buff[955]); + + fprintf(stdout, + "0x040AC: roc (Receive Oversize Count) 0x%08X\n", + regs_buff[956]); + + fprintf(stdout, + "0x040B0: rjc (Receive Jabber Count) 0x%08X\n", + regs_buff[957]); + + fprintf(stdout, + "0x040B4: mngprc (Management Packets Rx Count) 0x%08X\n", + regs_buff[958]); + + fprintf(stdout, + "0x040B8: mngpdc (Management Pkts Dropped Count) 0x%08X\n", + regs_buff[959]); + + fprintf(stdout, + "0x0CF90: mngptc (Management Packets Tx Count) 0x%08X\n", + regs_buff[960]); + + fprintf(stdout, + "0x040C0: torl (Total Octets Rx Count Low) 0x%08X\n", + regs_buff[961]); + + fprintf(stdout, + "0x040C4: torh (Total Octets Rx Count High) 0x%08X\n", + regs_buff[962]); + + fprintf(stdout, + "0x040D0: tpr (Total Packets Received) 0x%08X\n", + regs_buff[963]); + + fprintf(stdout, + "0x040D4: tpt (Total Packets Transmitted) 0x%08X\n", + regs_buff[964]); + + fprintf(stdout, + "0x040D8: ptc64 (Packets Tx (64B) Count) 0x%08X\n", + regs_buff[965]); + + fprintf(stdout, + "0x040DC: ptc127 (Packets Tx (65-127B) Count) 0x%08X\n", + regs_buff[966]); + + fprintf(stdout, + "0x040E0: ptc255 (Packets Tx (128-255B) Count) 0x%08X\n", + regs_buff[967]); + + fprintf(stdout, + "0x040E4: ptc511 (Packets Tx (256-511B) Count) 0x%08X\n", + regs_buff[968]); + + fprintf(stdout, + "0x040E8: ptc1023 (Packets Tx (512-1023B) Count) 0x%08X\n", + regs_buff[969]); + + fprintf(stdout, + "0x040EC: ptc1522 (Packets Tx (1024-Max) Count) 0x%08X\n", + regs_buff[970]); + + fprintf(stdout, + "0x040F0: mptc (Multicast Packets Tx Count) 0x%08X\n", + regs_buff[971]); + + fprintf(stdout, + "0x040F4: bptc (Broadcast Packets Tx Count) 0x%08X\n", + regs_buff[972]); + + fprintf(stdout, + "0x04120: xec (XSUM Error Count) 0x%08X\n", + regs_buff[973]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x%05X: qprc%02d (Queue Packets Rx Count %02d) 0x%08X\n", + 0x01030 + (0x40 * i), i, i, regs_buff[974 + i]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x%05X: qptc%02d (Queue Packets Tx Count %02d) 0x%08X\n", + 0x06030 + (0x40 * i), i, i, regs_buff[990 + i]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x%05X: qbrc%02d (Queue Bytes Rx Count %02d) 0x%08X\n", + 0x01034 + (0x40 * i), i, i, regs_buff[1006 + i]); + + for (i = 0; i < 16; i++) + fprintf(stdout, + "0x%05X: qbtc%02d (Queue Bytes Tx Count %02d) 0x%08X\n", + 0x06034 + (0x40 * i), i, i, regs_buff[1022 + i]); + + /* MAC */ + if (mac_type < ixgbe_mac_X540) { + fprintf(stdout, + "0x04200: PCS1GCFIG (PCS_1G Gloabal Config 1) 0x%08X\n", + regs_buff[1038]); + + fprintf(stdout, + "0x04208: PCS1GLCTL (PCS_1G Link Control) 0x%08X\n", + regs_buff[1039]); + + fprintf(stdout, + "0x0420C: PCS1GLSTA (PCS_1G Link Status) 0x%08X\n", + regs_buff[1040]); + + fprintf(stdout, + "0x04210: PCS1GDBG0 (PCS_1G Debug 0) 0x%08X\n", + regs_buff[1041]); + + fprintf(stdout, + "0x04214: PCS1GDBG1 (PCS_1G Debug 1) 0x%08X\n", + regs_buff[1042]); + + fprintf(stdout, + "0x04218: PCS1GANA (PCS-1G Auto Neg. Adv.) 0x%08X\n", + regs_buff[1043]); + + fprintf(stdout, + "0x0421C: PCS1GANLP (PCS-1G AN LP Ability) 0x%08X\n", + regs_buff[1044]); + + fprintf(stdout, + "0x04220: PCS1GANNP (PCS_1G Auto Neg Next Page Tx) 0x%08X\n", + regs_buff[1045]); + + fprintf(stdout, + "0x04224: PCS1GANLPNP (PCS_1G Auto Neg LPs Next Page) 0x%08X\n", + regs_buff[1046]); + } + + fprintf(stdout, + "0x04244: HLREG1 (Highlander Status 1) 0x%08X\n", + regs_buff[1048]); + + fprintf(stdout, + "0x04248: PAP (Pause and Pace) 0x%08X\n", + regs_buff[1049]); + + fprintf(stdout, + "0x0424C: MACA (MDI Auto-Scan Command and Addr) 0x%08X\n", + regs_buff[1050]); + + fprintf(stdout, + "0x04250: APAE (Auto-Scan PHY Address Enable) 0x%08X\n", + regs_buff[1051]); + + fprintf(stdout, + "0x04254: ARD (Auto-Scan Read Data) 0x%08X\n", + regs_buff[1052]); + + fprintf(stdout, + "0x04258: AIS (Auto-Scan Interrupt Status) 0x%08X\n", + regs_buff[1053]); + + fprintf(stdout, + "0x0425C: MSCA (MDI Single Command and Addr) 0x%08X\n", + regs_buff[1054]); + + fprintf(stdout, + "0x04260: MSRWD (MDI Single Read and Write Data) 0x%08X\n", + regs_buff[1055]); + + fprintf(stdout, + "0x04264: MLADD (MAC Address Low) 0x%08X\n", + regs_buff[1056]); + + fprintf(stdout, + "0x04268: MHADD (MAC Addr High/Max Frame size) 0x%08X\n", + regs_buff[1057]); + + fprintf(stdout, + "0x0426C: TREG (Test Register) 0x%08X\n", + regs_buff[1058]); + + if (mac_type < ixgbe_mac_X540) { + fprintf(stdout, + "0x04288: PCSS1 (XGXS Status 1) 0x%08X\n", + regs_buff[1059]); + + fprintf(stdout, + "0x0428C: PCSS2 (XGXS Status 2) 0x%08X\n", + regs_buff[1060]); + + fprintf(stdout, + "0x04290: XPCSS (10GBASE-X PCS Status) 0x%08X\n", + regs_buff[1061]); + + fprintf(stdout, + "0x04298: SERDESC (SERDES Interface Control) 0x%08X\n", + regs_buff[1062]); + + fprintf(stdout, + "0x0429C: MACS (FIFO Status/CNTL Report) 0x%08X\n", + regs_buff[1063]); + + fprintf(stdout, + "0x042A0: AUTOC (Auto Negotiation Control) 0x%08X\n", + regs_buff[1064]); + + fprintf(stdout, + "0x042A8: AUTOC2 (Auto Negotiation Control 2) 0x%08X\n", + regs_buff[1066]); + + fprintf(stdout, + "0x042AC: AUTOC3 (Auto Negotiation Control 3) 0x%08X\n", + regs_buff[1067]); + + fprintf(stdout, + "0x042B0: ANLP1 (Auto Neg Lnk Part. Ctrl Word 1) 0x%08X\n", + regs_buff[1068]); + + fprintf(stdout, + "0x042B4: ANLP2 (Auto Neg Lnk Part. Ctrl Word 2) 0x%08X\n", + regs_buff[1069]); + } + + if (mac_type == ixgbe_mac_82598EB) { + fprintf(stdout, + "0x04800: ATLASCTL (Atlas Analog Configuration) 0x%08X\n", + regs_buff[1070]); + + /* Diagnostic */ + fprintf(stdout, + "0x02C20: RDSTATCTL (Rx DMA Statistic Control) 0x%08X\n", + regs_buff[1071]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: RDSTAT%d (Rx DMA Statistics %d) 0x%08X\n", + 0x02C00 + (4 * i), i, i, regs_buff[1072 + i]); + + fprintf(stdout, + "0x02F08: RDHMPN (Rx Desc Handler Mem Page num) 0x%08X\n", + regs_buff[1080]); + + fprintf(stdout, + "0x02F10: RIC_DW0 (Rx Desc Hand. Mem Read Data 0) 0x%08X\n", + regs_buff[1081]); + + fprintf(stdout, + "0x02F14: RIC_DW1 (Rx Desc Hand. Mem Read Data 1) 0x%08X\n", + regs_buff[1082]); + + fprintf(stdout, + "0x02F18: RIC_DW2 (Rx Desc Hand. Mem Read Data 2) 0x%08X\n", + regs_buff[1083]); + + fprintf(stdout, + "0x02F1C: RIC_DW3 (Rx Desc Hand. Mem Read Data 3) 0x%08X\n", + regs_buff[1084]); + } + + if (mac_type < ixgbe_mac_X540) + fprintf(stdout, + "0x02F20: RDPROBE (Rx Probe Mode Status) 0x%08X\n", + regs_buff[1085]); + + fprintf(stdout, + "0x07C20: TDSTATCTL (Tx DMA Statistic Control) 0x%08X\n", + regs_buff[1086]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: TDSTAT%d (Tx DMA Statistics %d) 0x%08X\n", + 0x07C00 + (4 * i), i, i, regs_buff[1087 + i]); + + fprintf(stdout, + "0x07F08: TDHMPN (Tx Desc Handler Mem Page Num) 0x%08X\n", + regs_buff[1095]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x%05X: TIC_DW%d (Tx Desc Hand. Mem Read Data %d) 0x%08X\n", + 0x07F10 + (4 * i), i, i, regs_buff[1096 + i]); + + fprintf(stdout, + "0x07F20: TDPROBE (Tx Probe Mode Status) 0x%08X\n", + regs_buff[1100]); + + fprintf(stdout, + "0x0C600: TXBUFCTRL (TX Buffer Access Control) 0x%08X\n", + regs_buff[1101]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x%05X: TXBUFDATA%d (TX Buffer DATA %d) 0x%08X\n", + 0x0C610 + (4 * i), i, i, regs_buff[1102 + i]); + + fprintf(stdout, + "0x03600: RXBUFCTRL (RX Buffer Access Control) 0x%08X\n", + regs_buff[1106]); + + for (i = 0; i < 4; i++) + fprintf(stdout, + "0x%05X: RXBUFDATA%d (RX Buffer DATA %d) 0x%08X\n", + 0x03610 + (4 * i), i, i, regs_buff[1107 + i]); + + for (i = 0; i < 8; i++) + fprintf(stdout, + "0x%05X: PCIE_DIAG%d (PCIe Diagnostic %d) 0x%08X\n", + 0x11090 + (4 * i), i, i, regs_buff[1111 + i]); + + fprintf(stdout, + "0x050A4: RFVAL (Receive Filter Validation) 0x%08X\n", + regs_buff[1119]); + + if (mac_type < ixgbe_mac_X540) { + fprintf(stdout, + "0x042B8: MDFTC1 (MAC DFT Control 1) 0x%08X\n", + regs_buff[1120]); + + fprintf(stdout, + "0x042C0: MDFTC2 (MAC DFT Control 2) 0x%08X\n", + regs_buff[1121]); + + fprintf(stdout, + "0x042C4: MDFTFIFO1 (MAC DFT FIFO 1) 0x%08X\n", + regs_buff[1122]); + + fprintf(stdout, + "0x042C8: MDFTFIFO2 (MAC DFT FIFO 2) 0x%08X\n", + regs_buff[1123]); + + fprintf(stdout, + "0x042CC: MDFTS (MAC DFT Status) 0x%08X\n", + regs_buff[1124]); + } + + if (mac_type == ixgbe_mac_82598EB) { + fprintf(stdout, + "0x1106C: PCIEECCCTL (PCIe ECC Control) 0x%08X\n", + regs_buff[1125]); + + fprintf(stdout, + "0x0C300: PBTXECC (Packet Buffer Tx ECC) 0x%08X\n", + regs_buff[1126]); + + fprintf(stdout, + "0x03300: PBRXECC (Packet Buffer Rx ECC) 0x%08X\n", + regs_buff[1127]); + } + + if (regs_buff_len > 1139 && mac_type != ixgbe_mac_82598EB) { + fprintf(stdout, + "0x08800: SECTXCTRL (Security Tx Control) 0x%08X\n", + regs_buff[1139]); + + fprintf(stdout, + "0x08804: SECTXSTAT (Security Tx Status) 0x%08X\n", + regs_buff[1140]); + + fprintf(stdout, + "0x08808: SECTXBUFFAF (Security Tx Buffer Almost Full) 0x%08X\n", + regs_buff[1141]); + + fprintf(stdout, + "0x08800: SECTXMINIFG (Security Tx Buffer Minimum IFG) 0x%08X\n", + regs_buff[1142]); + + fprintf(stdout, + "0x08800: SECRXCTRL (Security Rx Control) 0x%08X\n", + regs_buff[1143]); + + fprintf(stdout, + "0x08800: SECRXSTAT (Security Rx Status) 0x%08X\n", + regs_buff[1144]); + } + + return 0; +} diff --git a/ixgbevf.c b/ixgbevf.c new file mode 100644 index 0000000..91c2b2c --- /dev/null +++ b/ixgbevf.c @@ -0,0 +1,181 @@ +/* Copyright (c) 2013 Intel Corporation */ +#include +#include "internal.h" + +int +ixgbevf_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *regs_buff = (u32 *)regs->data; + u8 version = (u8)(regs->version >> 24); + u8 i; + + if (version == 0) + return -1; + + fprintf(stdout, + "0x00000: VFCTRL (VF Control Register) (Write Only) N/A\n"); + + fprintf(stdout, + "0x00008: VFSTATUS (VF Status Register) 0x%08X\n", + regs_buff[1]); + + fprintf(stdout, + "0x00010: VFLINKS (VF Link Status Register) 0x%08X\n", + regs_buff[2]); + + fprintf(stdout, + "0x03190: VFRXMEMWRAP (Rx Packet Buffer Flush Detect) 0x%08X\n", + regs_buff[3]); + + fprintf(stdout, + "0x00048: VFFRTIMER (VF Free Running Timer) 0x%08X\n", + regs_buff[4]); + + fprintf(stdout, + "0x00100: VFEICR (VF Extended Interrupt Cause) 0x%08X\n", + regs_buff[5]); + + fprintf(stdout, + "0x00104: VFEICS (VF Extended Interrupt Cause Set) 0x%08X\n", + regs_buff[6]); + + fprintf(stdout, + "0x00108: VFEIMS (VF Extended Interrupt Mask Set) 0x%08X\n", + regs_buff[7]); + + fprintf(stdout, + "0x0010C: VFEIMC (VF Extended Interrupt Mask Clear) 0x%08X\n", + regs_buff[8]); + + fprintf(stdout, + "0x00110: VFEIAC (VF Extended Interrupt Auto Clear) 0x%08X\n", + regs_buff[9]); + + fprintf(stdout, + "0x00114: VFEIAM (VF Extended Interrupt Auto Mask) 0x%08X\n", + regs_buff[10]); + + fprintf(stdout, + "0x00820: VFEITR(0) (VF Extended Interrupt Throttle) 0x%08X\n", + regs_buff[11]); + + fprintf(stdout, + "0x00120: VFIVAR(0) (VF Interrupt Vector Allocation) 0x%08X\n", + regs_buff[12]); + + fprintf(stdout, + "0x00140: VFIVAR_MISC (VF Interrupt Vector Misc) 0x%08X\n", + regs_buff[13]); + + fprintf(stdout, + "0x00104: VFPSRTYPE (VF Replication Packet Split Type) 0x%08X\n", + regs_buff[28]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFRDBAL(%d) (VF Rx Desc. Base Addr Low %d) 0x%08X\n", + 0x1000 + 0x40*i, + i, i, + regs_buff[14+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFRDBAH(%d) (VF Rx Desc. Base Addr High %d) 0x%08X\n", + 0x1004 + 0x40*i, + i, i, + regs_buff[16+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFRDLEN(%d) (VF Rx Desc. Length %d) 0x%08X\n", + 0x1008 + 0x40*i, + i, i, + regs_buff[18+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFRDH(%d) (VF Rx Desc. Head %d) 0x%08X\n", + 0x1010 + 0x40*i, + i, i, + regs_buff[20+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFRDT(%d) (VF Rx Desc. Tail %d) 0x%08X\n", + 0x1018 + 0x40*i, + i, i, + regs_buff[22+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFRDT(%d) (VF Rx Desc. Control %d), 0x%08X\n", + 0x1028 + 0x40*i, + i, i, + regs_buff[24+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFSRRCTL(%d) (VF Split Rx Control %d) 0x%08X\n", + 0x1014 + 0x40*i, + i, i, + regs_buff[26+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFTDBAL(%d) (VF Tx Desc. Base Addr Low %d) 0x%08X\n", + 0x2000 + 0x40*i, + i, i, + regs_buff[29+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFTDBAH(%d) (VF Tx Desc. Base Addr High %d) 0x%08X\n", + 0x2004 + 0x40*i, + i, i, + regs_buff[31+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFTDLEN(%d) (VF Tx Desc. Length %d) 0x%08X\n", + 0x2008 + 0x40*i, + i, i, + regs_buff[33+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFTDH(%d) (VF Tx Desc. Head %d) 0x%08X\n", + 0x2010 + 0x40*i, + i, i, + regs_buff[35+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFTDT(%d) (VF Tx Desc. Tail %d) 0x%08X\n", + 0x2018 + 0x40*i, + i, i, + regs_buff[37+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFTDT(%d) (VF Tx Desc. Control %d) 0x%08X\n", + 0x2028 + 0x40*i, + i, i, + regs_buff[39+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFTDWBAL(%d) (VF Tx Desc. Write Back Addr Lo %d) 0x%08X\n", + 0x2038 + 0x40*i, + i, i, + regs_buff[41+i]); + + for (i = 0; i < 2; i++) + fprintf(stdout, + "0x%05x: VFTDWBAH(%d) (VF Tx Desc. Write Back Addr Hi %d) 0x%08X\n", + 0x203C + 0x40*i, + i, i, + regs_buff[43+i]); + + return 0; +} diff --git a/json_print.c b/json_print.c new file mode 100644 index 0000000..4f62767 --- /dev/null +++ b/json_print.c @@ -0,0 +1,228 @@ +/* + * json_print.c "print regular or json output, based on json_writer". + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Julien Fortin, + */ + +#include +#include +#include +#include + +#include "json_print.h" + +#define SPRINT_BSIZE 64 +#define SPRINT_BUF(x) char x[SPRINT_BSIZE] + +static json_writer_t *_jw; + +#define _IS_JSON_CONTEXT(type) ((type & PRINT_JSON || type & PRINT_ANY) && _jw) +#define _IS_FP_CONTEXT(type) (!_jw && (type & PRINT_FP || type & PRINT_ANY)) + +void new_json_obj(int json) +{ + if (json) { + _jw = jsonw_new(stdout); + if (!_jw) { + perror("json object"); + exit(1); + } + jsonw_pretty(_jw, true); + jsonw_start_array(_jw); + } +} + +void delete_json_obj(void) +{ + if (_jw) { + jsonw_end_array(_jw); + jsonw_destroy(&_jw); + } +} + +bool is_json_context(void) +{ + return _jw != NULL; +} + +json_writer_t *get_json_writer(void) +{ + return _jw; +} + +void open_json_object(const char *str) +{ + if (_IS_JSON_CONTEXT(PRINT_JSON)) { + if (str) + jsonw_name(_jw, str); + jsonw_start_object(_jw); + } +} + +void close_json_object(void) +{ + if (_IS_JSON_CONTEXT(PRINT_JSON)) + jsonw_end_object(_jw); +} + +/* + * Start json array or string array using + * the provided string as json key (if not null) + * or array delimiter in non-json context. + */ +void open_json_array(const char *key, const char *str) +{ + if (is_json_context()) { + if (key) + jsonw_name(_jw, key); + jsonw_start_array(_jw); + } else { + printf("%s", str); + } +} + +/* + * End json array or string array + */ +void close_json_array(const char *delim) +{ + if (is_json_context()) + jsonw_end_array(_jw); + else + printf("%s", delim); +} + +/* + * pre-processor directive to generate similar + * functions handling different types + */ +#define _PRINT_FUNC(type_name, type) \ + __attribute__((format(printf, 3, 0))) \ + void print_##type_name(enum output_type t, \ + const char *key, \ + const char *fmt, \ + type value) \ + { \ + if (_IS_JSON_CONTEXT(t)) { \ + if (!key) \ + jsonw_##type_name(_jw, value); \ + else \ + jsonw_##type_name##_field(_jw, key, value); \ + } else if (_IS_FP_CONTEXT(t)) { \ + fprintf(stdout, fmt, value); \ + } \ + } +_PRINT_FUNC(int, int); +_PRINT_FUNC(s64, int64_t); +_PRINT_FUNC(hhu, unsigned char); +_PRINT_FUNC(hu, unsigned short); +_PRINT_FUNC(uint, unsigned int); +_PRINT_FUNC(u64, uint64_t); +_PRINT_FUNC(luint, unsigned long); +_PRINT_FUNC(lluint, unsigned long long); +_PRINT_FUNC(float, double); +#undef _PRINT_FUNC + +void print_string(enum output_type type, + const char *key, + const char *fmt, + const char *value) +{ + if (_IS_JSON_CONTEXT(type)) { + if (key && !value) + jsonw_name(_jw, key); + else if (!key && value) + jsonw_string(_jw, value); + else + jsonw_string_field(_jw, key, value); + } else if (_IS_FP_CONTEXT(type)) { + fprintf(stdout, fmt, value); + } +} + +/* + * value's type is bool. When using this function in FP context you can't pass + * a value to it, you will need to use "is_json_context()" to have different + * branch for json and regular output. grep -r "print_bool" for example + */ +void print_bool(enum output_type type, + const char *key, + const char *fmt, + bool value) +{ + if (_IS_JSON_CONTEXT(type)) { + if (key) + jsonw_bool_field(_jw, key, value); + else + jsonw_bool(_jw, value); + } else if (_IS_FP_CONTEXT(type)) { + fprintf(stdout, fmt, value ? "true" : "false"); + } +} + +/* + * In JSON context uses hardcode %#x format: 42 -> 0x2a + */ +void print_0xhex(enum output_type type, + const char *key, + const char *fmt, + unsigned long long hex) +{ + if (_IS_JSON_CONTEXT(type)) { + SPRINT_BUF(b1); + + snprintf(b1, sizeof(b1), "%#llx", hex); + print_string(PRINT_JSON, key, NULL, b1); + } else if (_IS_FP_CONTEXT(type)) { + fprintf(stdout, fmt, hex); + } +} + +void print_hex(enum output_type type, + const char *key, + const char *fmt, + unsigned int hex) +{ + if (_IS_JSON_CONTEXT(type)) { + SPRINT_BUF(b1); + + snprintf(b1, sizeof(b1), "%x", hex); + if (key) + jsonw_string_field(_jw, key, b1); + else + jsonw_string(_jw, b1); + } else if (_IS_FP_CONTEXT(type)) { + fprintf(stdout, fmt, hex); + } +} + +/* + * In JSON context we don't use the argument "value" we simply call jsonw_null + * whereas FP context can use "value" to output anything + */ +void print_null(enum output_type type, + const char *key, + const char *fmt, + const char *value) +{ + if (_IS_JSON_CONTEXT(type)) { + if (key) + jsonw_null_field(_jw, key); + else + jsonw_null(_jw); + } else if (_IS_FP_CONTEXT(type)) { + fprintf(stdout, fmt, value); + } +} + +/* Print line separator (if not in JSON mode) */ +void print_nl(void) +{ + if (!_jw) + printf("%s", "\n"); +} diff --git a/json_print.h b/json_print.h new file mode 100644 index 0000000..df15314 --- /dev/null +++ b/json_print.h @@ -0,0 +1,67 @@ +/* + * json_print.h "print regular or json output, based on json_writer". + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Julien Fortin, + */ + +#ifndef _JSON_PRINT_H_ +#define _JSON_PRINT_H_ + +#include "json_writer.h" + +json_writer_t *get_json_writer(void); + +/* + * use: + * - PRINT_ANY for context based output + * - PRINT_FP for non json specific output + * - PRINT_JSON for json specific output + */ +enum output_type { + PRINT_FP = 1, + PRINT_JSON = 2, + PRINT_ANY = 4, +}; + +void new_json_obj(int json); +void delete_json_obj(void); + +bool is_json_context(void); + +void fflush_fp(void); + +void open_json_object(const char *str); +void close_json_object(void); +void open_json_array(const char *key, const char *str); +void close_json_array(const char *delim); + +void print_nl(void); + +#define _PRINT_FUNC(type_name, type) \ + void print_##type_name(enum output_type t, \ + const char *key, \ + const char *fmt, \ + type value) \ + +_PRINT_FUNC(int, int); +_PRINT_FUNC(s64, int64_t); +_PRINT_FUNC(bool, bool); +_PRINT_FUNC(null, const char*); +_PRINT_FUNC(string, const char*); +_PRINT_FUNC(uint, unsigned int); +_PRINT_FUNC(u64, uint64_t); +_PRINT_FUNC(hhu, unsigned char); +_PRINT_FUNC(hu, unsigned short); +_PRINT_FUNC(hex, unsigned int); +_PRINT_FUNC(0xhex, unsigned long long); +_PRINT_FUNC(luint, unsigned long); +_PRINT_FUNC(lluint, unsigned long long); +_PRINT_FUNC(float, double); +#undef _PRINT_FUNC + +#endif /* _JSON_PRINT_H_ */ diff --git a/json_writer.c b/json_writer.c new file mode 100644 index 0000000..e8b3926 --- /dev/null +++ b/json_writer.c @@ -0,0 +1,391 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) // +/* + * Simple streaming JSON writer + * + * This takes care of the annoying bits of JSON syntax like the commas + * after elements + * + * Authors: Stephen Hemminger + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "json_writer.h" + +struct json_writer { + FILE *out; /* output file */ + unsigned int depth; /* nesting */ + bool pretty; /* optional whitepace */ + char sep; /* either nul or comma */ +}; + +/* indentation for pretty print */ +static void jsonw_indent(json_writer_t *self) +{ + unsigned int i; + + for (i = 0; i < self->depth; ++i) + fputs(" ", self->out); +} + +/* end current line and indent if pretty printing */ +static void jsonw_eol(json_writer_t *self) +{ + if (!self->pretty) + return; + + putc('\n', self->out); + jsonw_indent(self); +} + +/* If current object is not empty print a comma */ +static void jsonw_eor(json_writer_t *self) +{ + if (self->sep != '\0') + putc(self->sep, self->out); + self->sep = ','; +} + + +/* Output JSON encoded string */ +/* Handles C escapes, does not do Unicode */ +static void jsonw_puts(json_writer_t *self, const char *str) +{ + putc('"', self->out); + for (; *str; ++str) + switch (*str) { + case '\t': + fputs("\\t", self->out); + break; + case '\n': + fputs("\\n", self->out); + break; + case '\r': + fputs("\\r", self->out); + break; + case '\f': + fputs("\\f", self->out); + break; + case '\b': + fputs("\\b", self->out); + break; + case '\\': + fputs("\\\\", self->out); + break; + case '"': + fputs("\\\"", self->out); + break; + case '\'': + fputs("\\\'", self->out); + break; + default: + putc(*str, self->out); + } + putc('"', self->out); +} + +/* Create a new JSON stream */ +json_writer_t *jsonw_new(FILE *f) +{ + json_writer_t *self = malloc(sizeof(*self)); + + if (self) { + self->out = f; + self->depth = 0; + self->pretty = false; + self->sep = '\0'; + } + return self; +} + +/* End output to JSON stream */ +void jsonw_destroy(json_writer_t **self_p) +{ + json_writer_t *self = *self_p; + + assert(self->depth == 0); + fputs("\n", self->out); + fflush(self->out); + free(self); + *self_p = NULL; +} + +void jsonw_pretty(json_writer_t *self, bool on) +{ + self->pretty = on; +} + +/* Basic blocks */ +static void jsonw_begin(json_writer_t *self, int c) +{ + jsonw_eor(self); + putc(c, self->out); + ++self->depth; + self->sep = '\0'; +} + +static void jsonw_end(json_writer_t *self, int c) +{ + assert(self->depth > 0); + + --self->depth; + if (self->sep != '\0') + jsonw_eol(self); + putc(c, self->out); + self->sep = ','; +} + + +/* Add a JSON property name */ +void jsonw_name(json_writer_t *self, const char *name) +{ + jsonw_eor(self); + jsonw_eol(self); + self->sep = '\0'; + jsonw_puts(self, name); + putc(':', self->out); + if (self->pretty) + putc(' ', self->out); +} + +__attribute__((format(printf, 2, 3))) +void jsonw_printf(json_writer_t *self, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + jsonw_eor(self); + vfprintf(self->out, fmt, ap); + va_end(ap); +} + +/* Collections */ +void jsonw_start_object(json_writer_t *self) +{ + jsonw_begin(self, '{'); +} + +void jsonw_end_object(json_writer_t *self) +{ + jsonw_end(self, '}'); +} + +void jsonw_start_array(json_writer_t *self) +{ + jsonw_begin(self, '['); + if (self->pretty) + putc(' ', self->out); +} + +void jsonw_end_array(json_writer_t *self) +{ + if (self->pretty && self->sep) + putc(' ', self->out); + self->sep = '\0'; + jsonw_end(self, ']'); +} + +/* JSON value types */ +void jsonw_string(json_writer_t *self, const char *value) +{ + jsonw_eor(self); + jsonw_puts(self, value); +} + +void jsonw_bool(json_writer_t *self, bool val) +{ + jsonw_printf(self, "%s", val ? "true" : "false"); +} + +void jsonw_null(json_writer_t *self) +{ + jsonw_printf(self, "null"); +} + +void jsonw_float(json_writer_t *self, double num) +{ + jsonw_printf(self, "%g", num); +} + +void jsonw_hhu(json_writer_t *self, unsigned char num) +{ + jsonw_printf(self, "%hhu", num); +} + +void jsonw_hu(json_writer_t *self, unsigned short num) +{ + jsonw_printf(self, "%hu", num); +} + +void jsonw_uint(json_writer_t *self, unsigned int num) +{ + jsonw_printf(self, "%u", num); +} + +void jsonw_u64(json_writer_t *self, uint64_t num) +{ + jsonw_printf(self, "%"PRIu64, num); +} + +void jsonw_xint(json_writer_t *self, uint64_t num) +{ + jsonw_printf(self, "%"PRIx64, num); +} + +void jsonw_luint(json_writer_t *self, unsigned long num) +{ + jsonw_printf(self, "%lu", num); +} + +void jsonw_lluint(json_writer_t *self, unsigned long long num) +{ + jsonw_printf(self, "%llu", num); +} + +void jsonw_int(json_writer_t *self, int num) +{ + jsonw_printf(self, "%d", num); +} + +void jsonw_s64(json_writer_t *self, int64_t num) +{ + jsonw_printf(self, "%"PRId64, num); +} + +/* Basic name/value objects */ +void jsonw_string_field(json_writer_t *self, const char *prop, const char *val) +{ + jsonw_name(self, prop); + jsonw_string(self, val); +} + +void jsonw_bool_field(json_writer_t *self, const char *prop, bool val) +{ + jsonw_name(self, prop); + jsonw_bool(self, val); +} + +void jsonw_float_field(json_writer_t *self, const char *prop, double val) +{ + jsonw_name(self, prop); + jsonw_float(self, val); +} + +void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num) +{ + jsonw_name(self, prop); + jsonw_uint(self, num); +} + +void jsonw_u64_field(json_writer_t *self, const char *prop, uint64_t num) +{ + jsonw_name(self, prop); + jsonw_u64(self, num); +} + +void jsonw_xint_field(json_writer_t *self, const char *prop, uint64_t num) +{ + jsonw_name(self, prop); + jsonw_xint(self, num); +} + +void jsonw_hhu_field(json_writer_t *self, const char *prop, unsigned char num) +{ + jsonw_name(self, prop); + jsonw_hhu(self, num); +} + +void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num) +{ + jsonw_name(self, prop); + jsonw_hu(self, num); +} + +void jsonw_luint_field(json_writer_t *self, + const char *prop, + unsigned long num) +{ + jsonw_name(self, prop); + jsonw_luint(self, num); +} + +void jsonw_lluint_field(json_writer_t *self, + const char *prop, + unsigned long long num) +{ + jsonw_name(self, prop); + jsonw_lluint(self, num); +} + +void jsonw_int_field(json_writer_t *self, const char *prop, int num) +{ + jsonw_name(self, prop); + jsonw_int(self, num); +} + +void jsonw_s64_field(json_writer_t *self, const char *prop, int64_t num) +{ + jsonw_name(self, prop); + jsonw_s64(self, num); +} + +void jsonw_null_field(json_writer_t *self, const char *prop) +{ + jsonw_name(self, prop); + jsonw_null(self); +} + +#ifdef TEST +int main(int argc, char **argv) +{ + json_writer_t *wr = jsonw_new(stdout); + + jsonw_start_object(wr); + jsonw_pretty(wr, true); + jsonw_name(wr, "Vyatta"); + jsonw_start_object(wr); + jsonw_string_field(wr, "url", "http://vyatta.com"); + jsonw_uint_field(wr, "downloads", 2000000ul); + jsonw_float_field(wr, "stock", 8.16); + + jsonw_name(wr, "ARGV"); + jsonw_start_array(wr); + while (--argc) + jsonw_string(wr, *++argv); + jsonw_end_array(wr); + + jsonw_name(wr, "empty"); + jsonw_start_array(wr); + jsonw_end_array(wr); + + jsonw_name(wr, "NIL"); + jsonw_start_object(wr); + jsonw_end_object(wr); + + jsonw_null_field(wr, "my_null"); + + jsonw_name(wr, "special chars"); + jsonw_start_array(wr); + jsonw_string_field(wr, "slash", "/"); + jsonw_string_field(wr, "newline", "\n"); + jsonw_string_field(wr, "tab", "\t"); + jsonw_string_field(wr, "ff", "\f"); + jsonw_string_field(wr, "quote", "\""); + jsonw_string_field(wr, "tick", "\'"); + jsonw_string_field(wr, "backslash", "\\"); + jsonw_end_array(wr); + + jsonw_end_object(wr); + + jsonw_end_object(wr); + jsonw_destroy(&wr); + return 0; +} + +#endif diff --git a/json_writer.h b/json_writer.h new file mode 100644 index 0000000..b52dc2d --- /dev/null +++ b/json_writer.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) */ +/* + * Simple streaming JSON writer + * + * This takes care of the annoying bits of JSON syntax like the commas + * after elements + * + * Authors: Stephen Hemminger + */ + +#ifndef _JSON_WRITER_H_ +#define _JSON_WRITER_H_ + +#include +#include + +/* Opaque class structure */ +typedef struct json_writer json_writer_t; + +/* Create a new JSON stream */ +json_writer_t *jsonw_new(FILE *f); +/* End output to JSON stream */ +void jsonw_destroy(json_writer_t **self_p); + +/* Cause output to have pretty whitespace */ +void jsonw_pretty(json_writer_t *self, bool on); + +/* Add property name */ +void jsonw_name(json_writer_t *self, const char *name); + +/* Add value */ +__attribute__((format(printf, 2, 3))) +void jsonw_printf(json_writer_t *self, const char *fmt, ...); +void jsonw_string(json_writer_t *self, const char *value); +void jsonw_bool(json_writer_t *self, bool value); +void jsonw_float(json_writer_t *self, double number); +void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num); +void jsonw_uint(json_writer_t *self, unsigned int number); +void jsonw_u64(json_writer_t *self, uint64_t number); +void jsonw_xint(json_writer_t *self, uint64_t number); +void jsonw_hhu(json_writer_t *self, unsigned char num); +void jsonw_hu(json_writer_t *self, unsigned short number); +void jsonw_int(json_writer_t *self, int number); +void jsonw_s64(json_writer_t *self, int64_t number); +void jsonw_null(json_writer_t *self); +void jsonw_luint(json_writer_t *self, unsigned long num); +void jsonw_lluint(json_writer_t *self, unsigned long long num); + +/* Useful Combinations of name and value */ +void jsonw_string_field(json_writer_t *self, const char *prop, const char *val); +void jsonw_bool_field(json_writer_t *self, const char *prop, bool value); +void jsonw_float_field(json_writer_t *self, const char *prop, double num); +void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num); +void jsonw_u64_field(json_writer_t *self, const char *prop, uint64_t num); +void jsonw_xint_field(json_writer_t *self, const char *prop, uint64_t num); +void jsonw_hhu_field(json_writer_t *self, const char *prop, unsigned char num); +void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num); +void jsonw_int_field(json_writer_t *self, const char *prop, int num); +void jsonw_s64_field(json_writer_t *self, const char *prop, int64_t num); +void jsonw_null_field(json_writer_t *self, const char *prop); +void jsonw_luint_field(json_writer_t *self, const char *prop, + unsigned long num); +void jsonw_lluint_field(json_writer_t *self, const char *prop, + unsigned long long num); + +/* Collections */ +void jsonw_start_object(json_writer_t *self); +void jsonw_end_object(json_writer_t *self); + +void jsonw_start_array(json_writer_t *self); +void jsonw_end_array(json_writer_t *self); + +/* Override default exception handling */ +typedef void (jsonw_err_handler_fn)(const char *); + +#endif /* _JSON_WRITER_H_ */ diff --git a/lan743x.c b/lan743x.c new file mode 100644 index 0000000..f430ee8 --- /dev/null +++ b/lan743x.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries. */ + +#include +#include +#include "internal.h" + +#define LAN743X_ETH_REG_VERSION 1 + +enum { + ETH_PRIV_FLAGS, + ETH_ID_REV, + ETH_FPGA_REV, + ETH_STRAP_READ, + ETH_INT_STS, + ETH_HW_CFG, + ETH_PMT_CTL, + ETH_E2P_CMD, + ETH_E2P_DATA, + ETH_MAC_CR, + ETH_MAC_RX, + ETH_MAC_TX, + ETH_FLOW, + ETH_MII_ACC, + ETH_MII_DATA, + ETH_EEE_TX_LPI_REQ_DLY, + ETH_WUCSR, + ETH_WK_SRC, + + /* Add new registers above */ + MAX_LAN743X_ETH_REGS +}; + +void lan743x_comm_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *lan743x_reg = (u32 *)regs->data; + + fprintf(stdout, "LAN743x Registers:\n"); + fprintf(stdout, "------------------\n"); + fprintf(stdout, "CHIP_ID_REV = 0x%08X\n", lan743x_reg[ETH_ID_REV]); + fprintf(stdout, "FPGA_REV = 0x%08X\n", lan743x_reg[ETH_FPGA_REV]); + fprintf(stdout, "STRAP_READ = 0x%08X\n", lan743x_reg[ETH_STRAP_READ]); + fprintf(stdout, "INT_STS = 0x%08X\n", lan743x_reg[ETH_INT_STS]); + fprintf(stdout, "HW_CFG = 0x%08X\n", lan743x_reg[ETH_HW_CFG]); + fprintf(stdout, "PMT_CTRL = 0x%08X\n", lan743x_reg[ETH_PMT_CTL]); + fprintf(stdout, "E2P_CMD = 0x%08X\n", lan743x_reg[ETH_E2P_CMD]); + fprintf(stdout, "E2P_DATA = 0x%08X\n", lan743x_reg[ETH_E2P_DATA]); + fprintf(stdout, "\n"); + + fprintf(stdout, "MAC Registers:\n"); + fprintf(stdout, "--------------\n"); + fprintf(stdout, "MAC_CR = 0x%08X\n", lan743x_reg[ETH_MAC_CR]); + fprintf(stdout, "MAC_RX = 0x%08X\n", lan743x_reg[ETH_MAC_RX]); + fprintf(stdout, "MAC_TX = 0x%08X\n", lan743x_reg[ETH_MAC_TX]); + fprintf(stdout, "FLOW = 0x%08X\n", lan743x_reg[ETH_FLOW]); + fprintf(stdout, "MII_ACC = 0x%08X\n", lan743x_reg[ETH_MII_ACC]); + fprintf(stdout, "MII_DATA = 0x%08X\n", lan743x_reg[ETH_MII_DATA]); + fprintf(stdout, "WUCSR = 0x%08X\n", lan743x_reg[ETH_WUCSR]); + fprintf(stdout, "WK_SRC = 0x%08X\n", lan743x_reg[ETH_WK_SRC]); + fprintf(stdout, "EEE_TX_LPI_REQ_DLY = 0x%08X\n", + lan743x_reg[ETH_EEE_TX_LPI_REQ_DLY]); + fprintf(stdout, "\n"); +} + +int lan743x_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + + lan743x_comm_dump_regs(info, regs); + + return 0; +} diff --git a/lan78xx.c b/lan78xx.c new file mode 100644 index 0000000..75ee048 --- /dev/null +++ b/lan78xx.c @@ -0,0 +1,88 @@ +#include +#include +#include "internal.h" + +int lan78xx_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + unsigned int *lan78xx_reg = (unsigned int *)regs->data; + + fprintf(stdout, "LAN78xx Registers:\n"); + fprintf(stdout, "------------------\n"); + fprintf(stdout, "ID_REV = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "INT_STS = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "HW_CFG = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "PMT_CTRL = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "E2P_CMD = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "E2P_DATA = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "USB_STATUS = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "VLAN_TYPE = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "\n"); + + fprintf(stdout, "MAC Registers:\n"); + fprintf(stdout, "--------------\n"); + fprintf(stdout, "MAC_CR = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "MAC_RX = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "MAC_TX = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "FLOW = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "ERR_STS = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "MII_ACC = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "MII_DATA = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "EEE_TX_LPI_REQ_DLY = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "EEE_TW_TX_SYS = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "EEE_TX_LPI_REM_DLY = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "WUCSR = 0x%08X\n", *lan78xx_reg++); + fprintf(stdout, "\n"); + + fprintf(stdout, "PHY Registers:\n"); + fprintf(stdout, "--------------\n"); + fprintf(stdout, "Mode Control = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Mode Status = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Device identifier1 = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Device identifier2 = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Advertisement = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Link Partner Ability = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Expansion = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Next Page TX = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Auto-Neg Link Partner Next Page RX = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "1000BASE-T Control = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "1000BASE-T Status = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Reserved = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Reserved = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "MMD Access Control = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "MMD Access Address/Data = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "1000BASE-T Status Extension1 = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "1000BASE-TX Status Extension = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "1000BASE-T Status Extension2 = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "Bypass Control = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, + "100BASE-TX/1000BASE-T Rx Error Counter = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, + "100BASE-TX/1000BASE-T FC Err Counter = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, + "10BASE-T/100BASE-TX/1000BASE-T LD Counter = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "Extended 10BASE-T Control and Status = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "Extended PHY Control1 = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Extended PHY Control2 = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Interrupt Mask = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Interrupt Status = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Reserved = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Auxiliary Control and Status = 0x%04X\n", + *lan78xx_reg++); + fprintf(stdout, "LED Mode Select = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "LED Behavior = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "Extended Page Access = 0x%04X\n", *lan78xx_reg++); + fprintf(stdout, "\n"); + + return 0; +} diff --git a/list.h b/list.h new file mode 100644 index 0000000..aa97fdd --- /dev/null +++ b/list.h @@ -0,0 +1,34 @@ +#ifndef ETHTOOL_LIST_H__ +#define ETHTOOL_LIST_H__ + +#include + +/* Generic list utilities */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +static inline void list_add(struct list_head *new, struct list_head *head) +{ + head->next->prev = new; + new->next = head->next; + new->prev = head; + head->next = new; +} + +static inline void list_del(struct list_head *entry) +{ + entry->next->prev = entry->prev; + entry->prev->next = entry->next; + entry->next = NULL; + entry->prev = NULL; +} + +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +#endif diff --git a/marvell.c b/marvell.c new file mode 100644 index 0000000..d3d570e --- /dev/null +++ b/marvell.c @@ -0,0 +1,455 @@ +/* + * Code to dump Marvell SysKonnect registers for skge and sky2 drivers. + * + * Copyright (C) 2004, 2006 + * Stephen Hemminger + */ + +#include + +#include "internal.h" + +static void dump_addr(int n, const u8 *a) +{ + int i; + + printf("Addr %d ", n); + for (i = 0; i < 6; i++) + printf("%02X%c", a[i], i == 5 ? '\n' : ' '); +} + +static void dump_timer(const char *name, const void *p) +{ + const u8 *a = p; + const u32 *r = p; + + printf("%s\n", name); + printf("\tInit 0x%08X Value 0x%08X\n", r[0], r[1]); + printf("\tTest 0x%02X Control 0x%02X\n", a[8], a[9]); +} + +static void dump_queue(const char *name, const void *a, int rx) +{ + struct desc { + u_int32_t ctl; + u_int32_t next; + u_int32_t data_lo; + u_int32_t data_hi; + u_int32_t status; + u_int32_t timestamp; + u_int16_t csum2; + u_int16_t csum1; + u_int16_t csum2_start; + u_int16_t csum1_start; + u_int32_t addr_lo; + u_int32_t addr_hi; + u_int32_t count_lo; + u_int32_t count_hi; + u_int32_t byte_count; + u_int32_t csr; + u_int32_t flag; + }; + const struct desc *d = a; + + /* is reset bit set? */ + if (!(d->ctl & 2)) { + printf("\n%s (disabled)\n", name); + return; + } + + printf("\n%s\n", name); + printf("---------------\n"); + printf("Descriptor Address 0x%08X%08X\n", + d->addr_hi, d->addr_lo); + printf("Address Counter 0x%08X%08X\n", + d->count_hi, d->count_lo); + printf("Current Byte Counter %d\n", d->byte_count); + printf("BMU Control/Status 0x%08X\n", d->csr); + printf("Flag & FIFO Address 0x%08X\n", d->flag); + printf("\n"); + printf("Control 0x%08X\n", d->ctl); + printf("Next 0x%08X\n", d->next); + printf("Data 0x%08X%08X\n", + d->data_hi, d->data_lo); + printf("Status 0x%08X\n", d->status); + printf("Timestamp 0x%08X\n", d->timestamp); + if (rx) { + printf("Csum1 Offset %4d Position %d\n", + d->csum1, d->csum1_start); + printf("Csum2 Offset %4d Position %d\n", + d->csum2, d->csum2_start); + } else + printf("Csum Start 0x%04X Pos %4d Write %d\n", + d->csum1, d->csum2_start, d->csum1_start); + +} + +static void dump_ram(const char *name, const void *p) +{ + const u32 *r = p; + + if (!(r[10] & 2)) { + printf("\n%s (disabled)\n", name); + return; + } + + printf("\n%s\n", name); + printf("---------------\n"); + printf("Start Address 0x%08X\n", r[0]); + printf("End Address 0x%08X\n", r[1]); + printf("Write Pointer 0x%08X\n", r[2]); + printf("Read Pointer 0x%08X\n", r[3]); + + if (*name == 'R') { /* Receive only */ + printf("Upper Threshold/Pause Packets 0x%08X\n", r[4]); + printf("Lower Threshold/Pause Packets 0x%08X\n", r[5]); + printf("Upper Threshold/High Priority 0x%08X\n", r[6]); + printf("Lower Threshold/High Priority 0x%08X\n", r[7]); + } + printf("Packet Counter 0x%08X\n", r[8]); + printf("Level 0x%08X\n", r[9]); + printf("Control 0x%08X\n", r[10]); +} + +static void dump_fifo(const char *name, const void *p) +{ + const u32 *r = p; + + printf("\n%s\n", name); + printf("---------------\n"); + printf("End Address 0x%08X\n", r[0]); + printf("Write Pointer 0x%08X\n", r[1]); + printf("Read Pointer 0x%08X\n", r[2]); + printf("Packet Counter 0x%08X\n", r[3]); + printf("Level 0x%08X\n", r[4]); + printf("Control 0x%08X\n", r[5]); + printf("Control/Test 0x%08X\n", r[6]); + dump_timer("LED", r + 8); +} + +static void dump_gmac_fifo(const char *name, const void *p) +{ + const u32 *r = p; + unsigned int i; + static const char *regs[] = { + "End Address", + "Almost Full Thresh", + "Control/Test", + "FIFO Flush Mask", + "FIFO Flush Threshold", + "Truncation Threshold", + "Upper Pause Threshold", + "Lower Pause Threshold", + "VLAN Tag", + "FIFO Write Pointer", + "FIFO Write Level", + "FIFO Read Pointer", + "FIFO Read Level", + }; + + printf("\n%s\n", name); + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); ++i) + printf("%-32s 0x%08X\n", regs[i], r[i]); + +} + +static void dump_mac(const u8 *r) +{ + u8 id; + + printf("\nMAC Addresses\n"); + printf("---------------\n"); + dump_addr(1, r + 0x100); + dump_addr(2, r + 0x108); + dump_addr(3, r + 0x110); + printf("\n"); + + printf("Connector type 0x%02X (%c)\n", + r[0x118], (char)r[0x118]); + printf("PMD type 0x%02X (%c)\n", + r[0x119], (char)r[0x119]); + printf("PHY type 0x%02X\n", r[0x11d]); + + id = r[0x11b]; + printf("Chip Id 0x%02X ", id); + + switch (id) { + case 0x0a: printf("Genesis"); break; + case 0xb0: printf("Yukon"); break; + case 0xb1: printf("Yukon-Lite"); break; + case 0xb2: printf("Yukon-LP"); break; + case 0xb3: printf("Yukon-2 XL"); break; + case 0xb5: printf("Yukon Extreme"); break; + case 0xb4: printf("Yukon-2 EC Ultra"); break; + case 0xb6: printf("Yukon-2 EC"); break; + case 0xb7: printf("Yukon-2 FE"); break; + case 0xb8: printf("Yukon-2 FE Plus"); break; + case 0xb9: printf("Yukon Supreme"); break; + case 0xba: printf("Yukon Ultra 2"); break; + case 0xbc: printf("Yukon Optima"); break; + default: printf("(Unknown)"); break; + } + + printf(" (rev %d)\n", (r[0x11a] & 0xf0) >> 4); + + printf("Ram Buffer 0x%02X\n", r[0x11c]); + +} + +static void dump_gma(const char *name, const u8 *r) +{ + int i; + + printf("%12s address: ", name); + for (i = 0; i < 3; i++) { + u16 a = *(u16 *)(r + i * 4); + printf(" %02X %02X", a & 0xff, (a >> 8) & 0xff); + } + printf("\n"); +} + +static void dump_gmac(const char *name, const u8 *data) +{ + printf("\n%s\n", name); + + printf("Status 0x%04X\n", *(u16 *) data); + printf("Control 0x%04X\n", *(u16 *) (data + 4)); + printf("Transmit 0x%04X\n", *(u16 *) (data + 8)); + printf("Receive 0x%04X\n", *(u16 *) (data + 0xc)); + printf("Transmit flow control 0x%04X\n", *(u16 *) (data + 0x10)); + printf("Transmit parameter 0x%04X\n", *(u16 *) (data + 0x14)); + printf("Serial mode 0x%04X\n", *(u16 *) (data + 0x18)); + + dump_gma("Source", data + 0x1c); + dump_gma("Physical", data + 0x28); +} + +static void dump_pci(const u8 *cfg) +{ + int i; + + printf("\nPCI config\n----------\n"); + for(i = 0; i < 0x80; i++) { + if (!(i & 15)) + printf("%02x:", i); + printf(" %02x", cfg[i]); + if ((i & 15) == 15) + putchar('\n'); + } + putchar('\n'); +} + +static void dump_control(u8 *r) +{ + printf("Control Registers\n"); + printf("-----------------\n"); + + printf("Register Access Port 0x%02X\n", *r); + printf("LED Control/Status 0x%08X\n", *(u32 *) (r + 4)); + + printf("Interrupt Source 0x%08X\n", *(u32 *) (r + 8)); + printf("Interrupt Mask 0x%08X\n", *(u32 *) (r + 0xc)); + printf("Interrupt Hardware Error Source 0x%08X\n", *(u32 *) (r + 0x10)); + printf("Interrupt Hardware Error Mask 0x%08X\n", *(u32 *) (r + 0x14)); + printf("Interrupt Control 0x%08X\n", *(u32 *) (r + 0x2c)); + printf("Interrupt Moderation Mask 0x%08X\n", *(u32 *) (r + 0x14c)); + printf("Hardware Moderation Mask 0x%08X\n", *(u32 *) (r + 0x150)); + dump_timer("Moderation Timer", r + 0x140); + + printf("General Purpose I/O 0x%08X\n", *(u32 *) (r + 0x15c)); +} + +int skge_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + const u32 *r = (const u32 *) regs->data; + int dual = !(regs->data[0x11a] & 1); + + dump_pci(regs->data + 0x380); + + dump_control(regs->data); + + printf("\nBus Management Unit\n"); + printf("-------------------\n"); + printf("CSR Receive Queue 1 0x%08X\n", r[24]); + printf("CSR Sync Queue 1 0x%08X\n", r[26]); + printf("CSR Async Queue 1 0x%08X\n", r[27]); + if (dual) { + printf("CSR Receive Queue 2 0x%08X\n", r[25]); + printf("CSR Async Queue 2 0x%08X\n", r[29]); + printf("CSR Sync Queue 2 0x%08X\n", r[28]); + } + + dump_mac(regs->data); + dump_gmac("GMAC 1", regs->data + 0x2800); + + dump_timer("Timer", regs->data + 0x130); + dump_timer("Blink Source", regs->data +0x170); + + dump_queue("Receive Queue 1", regs->data +0x400, 1); + dump_queue("Sync Transmit Queue 1", regs->data +0x600, 0); + dump_queue("Async Transmit Queue 1", regs->data +0x680, 0); + + dump_ram("Receive RAMbuffer 1", regs->data+0x800); + dump_ram("Sync Transmit RAMbuffer 1", regs->data+0xa00); + dump_ram("Async Transmit RAMbuffer 1", regs->data+0xa80); + + dump_fifo("Receive MAC FIFO 1", regs->data+0xc00); + dump_fifo("Transmit MAC FIFO 1", regs->data+0xd00); + if (dual) { + dump_gmac("GMAC 1", regs->data + 0x2800); + + dump_queue("Receive Queue 2", regs->data +0x480, 1); + dump_queue("Async Transmit Queue 2", regs->data +0x780, 0); + dump_queue("Sync Transmit Queue 2", regs->data +0x700, 0); + + dump_ram("Receive RAMbuffer 2", regs->data+0x880); + dump_ram("Sync Transmit RAMbuffer 2", regs->data+0xb00); + dump_ram("Async Transmit RAMbuffer 21", regs->data+0xb80); + + dump_fifo("Receive MAC FIFO 2", regs->data+0xc80); + dump_fifo("Transmit MAC FIFO 2", regs->data+0xd80); + } + + dump_timer("Descriptor Poll", regs->data+0xe00); + return 0; + +} + +static void dump_queue2(const char *name, void *a, int rx) +{ + struct sky2_queue { + u16 buf_control; + u16 byte_count; + u32 rss; + u32 addr_lo, addr_hi; + u32 status; + u32 timestamp; + u16 csum1, csum2; + u16 csum1_start, csum2_start; + u16 length; + u16 vlan; + u16 rsvd1; + u16 done; + u32 req_lo, req_hi; + u16 rsvd2; + u16 req_count; + u32 csr; + } *d = a; + + printf("\n%s\n", name); + printf("---------------\n"); + + printf("Buffer control 0x%04X\n", d->buf_control); + + printf("Byte Counter %d\n", d->byte_count); + printf("Descriptor Address 0x%08X%08X\n", + d->addr_hi, d->addr_lo); + printf("Status 0x%08X\n", d->status); + printf("Timestamp 0x%08X\n", d->timestamp); + printf("BMU Control/Status 0x%08X\n", d->csr); + printf("Done 0x%04X\n", d->done); + printf("Request 0x%08X%08X\n", + d->req_hi, d->req_lo); + if (rx) { + printf("Csum1 Offset %4d Position %d\n", + d->csum1, d->csum1_start); + printf("Csum2 Offset %4d Position %d\n", + d->csum2, d->csum2_start); + } else + printf("Csum Start 0x%04X Pos %4d Write %d\n", + d->csum1, d->csum2_start, d->csum1_start); +} + +static void dump_prefetch(const char *name, const void *r) +{ + const u32 *reg = r; + + printf("\n%s Prefetch\n", name); + printf("Control 0x%08X\n", reg[0]); + printf("Last Index %u\n", reg[1]); + printf("Start Address 0x%08x%08x\n", reg[3], reg[2]); + if (*name == 'S') { /* Status unit */ + printf("TX1 report %u\n", reg[4]); + printf("TX2 report %u\n", reg[5]); + printf("TX threshold %u\n", reg[6]); + printf("Put Index %u\n", reg[7]); + } else { + printf("Get Index %u\n", reg[4]); + printf("Put Index %u\n", reg[5]); + } +} + +int sky2_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + const u16 *r16 = (const u16 *) regs->data; + const u32 *r32 = (const u32 *) regs->data; + int dual; + + dump_pci(regs->data + 0x1c00); + + dump_control(regs->data); + + printf("\nBus Management Unit\n"); + printf("-------------------\n"); + printf("CSR Receive Queue 1 0x%08X\n", r32[24]); + printf("CSR Sync Queue 1 0x%08X\n", r32[26]); + printf("CSR Async Queue 1 0x%08X\n", r32[27]); + + dual = (regs->data[0x11e] & 2) != 0; + if (dual) { + printf("CSR Receive Queue 2 0x%08X\n", r32[25]); + printf("CSR Async Queue 2 0x%08X\n", r32[29]); + printf("CSR Sync Queue 2 0x%08X\n", r32[28]); + } + + dump_mac(regs->data); + + dump_prefetch("Status", regs->data + 0xe80); + dump_prefetch("Receive 1", regs->data + 0x450); + dump_prefetch("Transmit 1", regs->data + 0x450 + 0x280); + + if (dual) { + dump_prefetch("Receive 2", regs->data + 0x450 + 0x80); + dump_prefetch("Transmit 2", regs->data + 0x450 + 0x380); + } + + printf("\nStatus FIFO\n"); + printf("\tWrite Pointer 0x%02X\n", regs->data[0xea0]); + printf("\tRead Pointer 0x%02X\n", regs->data[0xea4]); + printf("\tLevel 0x%02X\n", regs->data[0xea8]); + printf("\tWatermark 0x%02X\n", regs->data[0xeac]); + printf("\tISR Watermark 0x%02X\n", regs->data[0xead]); + + dump_timer("Status level", regs->data + 0xeb0); + dump_timer("TX status", regs->data + 0xec0); + dump_timer("ISR", regs->data + 0xed0); + + printf("\nGMAC control 0x%04X\n", r32[0xf00 >> 2]); + printf("GPHY control 0x%04X\n", r32[0xf04 >> 2]); + printf("LINK control 0x%02hX\n", r16[0xf10 >> 1]); + + dump_gmac("GMAC 1", regs->data + 0x2800); + dump_gmac_fifo("Rx GMAC 1", regs->data + 0xc40); + dump_gmac_fifo("Tx GMAC 1", regs->data + 0xd40); + + dump_queue2("Receive Queue 1", regs->data +0x400, 1); + dump_queue("Sync Transmit Queue 1", regs->data +0x600, 0); + dump_queue2("Async Transmit Queue 1", regs->data +0x680, 0); + + dump_ram("Receive RAMbuffer 1", regs->data+0x800); + dump_ram("Sync Transmit RAMbuffer 1", regs->data+0xa00); + dump_ram("Async Transmit RAMbuffer 1", regs->data+0xa80); + + if (dual) { + dump_ram("Receive RAMbuffer 2", regs->data+0x880); + dump_ram("Sync Transmit RAMbuffer 2", regs->data+0xb00); + dump_ram("Async Transmit RAMbuffer 21", regs->data+0xb80); + dump_gmac("GMAC 2", regs->data + 0x3800); + dump_gmac_fifo("Rx GMAC 2", regs->data + 0xc40 + 128); + dump_gmac_fifo("Tx GMAC 2", regs->data + 0xd40 + 128); + } + + return 0; +} diff --git a/missing b/missing new file mode 100755 index 0000000..c6e3795 --- /dev/null +++ b/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2016-01-11.22; # UTC + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/natsemi.c b/natsemi.c new file mode 100644 index 0000000..4d9fc09 --- /dev/null +++ b/natsemi.c @@ -0,0 +1,987 @@ +/* Copyright 2001 Sun Microsystems (thockin@sun.com) */ +#include +#include "internal.h" + +#define PCI_VENDOR_NATSEMI 0x100b +#define PCI_DEVICE_DP83815 0x0020 +#define NATSEMI_MAGIC (PCI_VENDOR_NATSEMI | \ + (PCI_DEVICE_DP83815<<16)) + +/* register indices in the ethtool_regs->data */ +#define REG_CR 0 +#define BIT_CR_TXE (1<<0) +#define BIT_CR_RXE (1<<2) +#define BIT_CR_RST (1<<8) +#define REG_CFG 1 +#define BIT_CFG_BEM (1<<0) +#define BIT_CFG_BROM_DIS (1<<2) +#define BIT_CFG_PHY_DIS (1<<9) +#define BIT_CFG_PHY_RST (1<<10) +#define BIT_CFG_EXT_PHY (1<<12) +#define BIT_CFG_ANEG_EN (1<<13) +#define BIT_CFG_ANEG_100 (1<<14) +#define BIT_CFG_ANEG_FDUP (1<<15) +#define BIT_CFG_PINT_ACEN (1<<17) +#define BIT_CFG_PHY_CFG (0x3f<<18) +#define BIT_CFG_ANEG_DN (1<<27) +#define BIT_CFG_POL (1<<28) +#define BIT_CFG_FDUP (1<<29) +#define BIT_CFG_SPEED100 (1<<30) +#define BIT_CFG_LNKSTS (1<<31) + +#define REG_MEAR 2 +#define REG_PTSCR 3 +#define BIT_PTSCR_EEBIST_FAIL (1<<0) +#define BIT_PTSCR_EELOAD_EN (1<<2) +#define BIT_PTSCR_RBIST_RXFFAIL (1<<3) +#define BIT_PTSCR_RBIST_TXFAIL (1<<4) +#define BIT_PTSCR_RBIST_RXFAIL (1<<5) +#define REG_ISR 4 +#define REG_IMR 5 +#define BIT_INTR_RXOK (1<<0) +#define NAME_INTR_RXOK "Rx Complete" +#define BIT_INTR_RXDESC (1<<1) +#define NAME_INTR_RXDESC "Rx Descriptor" +#define BIT_INTR_RXERR (1<<2) +#define NAME_INTR_RXERR "Rx Packet Error" +#define BIT_INTR_RXEARLY (1<<3) +#define NAME_INTR_RXEARLY "Rx Early Threshold" +#define BIT_INTR_RXIDLE (1<<4) +#define NAME_INTR_RXIDLE "Rx Idle" +#define BIT_INTR_RXORN (1<<5) +#define NAME_INTR_RXORN "Rx Overrun" +#define BIT_INTR_TXOK (1<<6) +#define NAME_INTR_TXOK "Tx Packet OK" +#define BIT_INTR_TXDESC (1<<7) +#define NAME_INTR_TXDESC "Tx Descriptor" +#define BIT_INTR_TXERR (1<<8) +#define NAME_INTR_TXERR "Tx Packet Error" +#define BIT_INTR_TXIDLE (1<<9) +#define NAME_INTR_TXIDLE "Tx Idle" +#define BIT_INTR_TXURN (1<<10) +#define NAME_INTR_TXURN "Tx Underrun" +#define BIT_INTR_MIB (1<<11) +#define NAME_INTR_MIB "MIB Service" +#define BIT_INTR_SWI (1<<12) +#define NAME_INTR_SWI "Software" +#define BIT_INTR_PME (1<<13) +#define NAME_INTR_PME "Power Management Event" +#define BIT_INTR_PHY (1<<14) +#define NAME_INTR_PHY "Phy" +#define BIT_INTR_HIBERR (1<<15) +#define NAME_INTR_HIBERR "High Bits Error" +#define BIT_INTR_RXSOVR (1<<16) +#define NAME_INTR_RXSOVR "Rx Status FIFO Overrun" +#define BIT_INTR_RTABT (1<<20) +#define NAME_INTR_RTABT "Received Target Abort" +#define BIT_INTR_RMABT (1<<20) +#define NAME_INTR_RMABT "Received Master Abort" +#define BIT_INTR_SSERR (1<<20) +#define NAME_INTR_SSERR "Signaled System Error" +#define BIT_INTR_DPERR (1<<20) +#define NAME_INTR_DPERR "Detected Parity Error" +#define BIT_INTR_RXRCMP (1<<20) +#define NAME_INTR_RXRCMP "Rx Reset Complete" +#define BIT_INTR_TXRCMP (1<<20) +#define NAME_INTR_TXRCMP "Tx Reset Complete" +#define REG_IER 6 +#define BIT_IER_IE (1<<0) +#define REG_TXDP 8 +#define REG_TXCFG 9 +#define BIT_TXCFG_DRTH (0x3f<<0) +#define BIT_TXCFG_FLTH (0x3f<<8) +#define BIT_TXCFG_MXDMA (0x7<<20) +#define BIT_TXCFG_ATP (1<<28) +#define BIT_TXCFG_MLB (1<<29) +#define BIT_TXCFG_HBI (1<<30) +#define BIT_TXCFG_CSI (1<<31) +#define REG_RXDP 12 +#define REG_RXCFG 13 +#define BIT_RXCFG_DRTH (0x1f<<1) +#define BIT_RXCFG_MXDMA (0x7<<20) +#define BIT_RXCFG_ALP (1<<27) +#define BIT_RXCFG_ATX (1<<28) +#define BIT_RXCFG_ARP (1<<30) +#define BIT_RXCFG_AEP (1<<31) +#define REG_CCSR 15 +#define BIT_CCSR_CLKRUN_EN (1<<0) +#define BIT_CCSR_PMEEN (1<<8) +#define BIT_CCSR_PMESTS (1<<15) +#define REG_WCSR 16 +#define BIT_WCSR_WKPHY (1<<0) +#define BIT_WCSR_WKUCP (1<<1) +#define BIT_WCSR_WKMCP (1<<2) +#define BIT_WCSR_WKBCP (1<<3) +#define BIT_WCSR_WKARP (1<<4) +#define BIT_WCSR_WKPAT0 (1<<5) +#define BIT_WCSR_WKPAT1 (1<<6) +#define BIT_WCSR_WKPAT2 (1<<7) +#define BIT_WCSR_WKPAT3 (1<<8) +#define BIT_WCSR_WKMAG (1<<9) +#define BIT_WCSR_MPSOE (1<<10) +#define BIT_WCSR_SOHACK (1<<20) +#define BIT_WCSR_PHYINT (1<<22) +#define BIT_WCSR_UCASTR (1<<23) +#define BIT_WCSR_MCASTR (1<<24) +#define BIT_WCSR_BCASTR (1<<25) +#define BIT_WCSR_ARPR (1<<26) +#define BIT_WCSR_PATM0 (1<<27) +#define BIT_WCSR_PATM1 (1<<28) +#define BIT_WCSR_PATM2 (1<<29) +#define BIT_WCSR_PATM3 (1<<30) +#define BIT_WCSR_MPR (1<<31) +#define REG_PCR 17 +#define BIT_PCR_PAUSE_CNT (0xffff<<0) +#define BIT_PCR_PSNEG (1<<21) +#define BIT_PCR_PS_RCVD (1<<22) +#define BIT_PCR_PS_DA (1<<29) +#define BIT_PCR_PSMCAST (1<<30) +#define BIT_PCR_PSEN (1<<31) +#define REG_RFCR 18 +#define BIT_RFCR_UHEN (1<<20) +#define BIT_RFCR_MHEN (1<<21) +#define BIT_RFCR_AARP (1<<22) +#define BIT_RFCR_APAT0 (1<<23) +#define BIT_RFCR_APAT1 (1<<24) +#define BIT_RFCR_APAT2 (1<<25) +#define BIT_RFCR_APAT3 (1<<26) +#define BIT_RFCR_APM (1<<27) +#define BIT_RFCR_AAU (1<<28) +#define BIT_RFCR_AAM (1<<29) +#define BIT_RFCR_AAB (1<<30) +#define BIT_RFCR_RFEN (1<<31) +#define REG_RFDR 19 +#define REG_BRAR 20 +#define BIT_BRAR_AUTOINC (1<<31) +#define REG_BRDR 21 +#define REG_SRR 22 +#define REG_MIBC 23 +#define BIT_MIBC_WRN (1<<0) +#define BIT_MIBC_FRZ (1<<1) +#define REG_MIB0 24 +#define REG_MIB1 25 +#define REG_MIB2 26 +#define REG_MIB3 27 +#define REG_MIB4 28 +#define REG_MIB5 29 +#define REG_MIB6 30 +#define REG_BMCR 32 +#define BIT_BMCR_FDUP (1<<8) +#define BIT_BMCR_ANRST (1<<9) +#define BIT_BMCR_ISOL (1<<10) +#define BIT_BMCR_PDOWN (1<<11) +#define BIT_BMCR_ANEN (1<<12) +#define BIT_BMCR_SPEED (1<<13) +#define BIT_BMCR_LOOP (1<<14) +#define BIT_BMCR_RST (1<<15) +#define REG_BMSR 33 +#define BIT_BMSR_JABBER (1<<1) +#define BIT_BMSR_LNK (1<<2) +#define BIT_BMSR_ANCAP (1<<3) +#define BIT_BMSR_RFAULT (1<<4) +#define BIT_BMSR_ANDONE (1<<5) +#define BIT_BMSR_PREAMBLE (1<<6) +#define BIT_BMSR_10HCAP (1<<11) +#define BIT_BMSR_10FCAP (1<<12) +#define BIT_BMSR_100HCAP (1<<13) +#define BIT_BMSR_100FCAP (1<<14) +#define BIT_BMSR_100T4CAP (1<<15) +#define REG_PHYIDR1 34 +#define REG_PHYIDR2 35 +#define BIT_PHYIDR2_OUILSB (0x3f<<10) +#define BIT_PHYIDR2_MODEL (0x3f<<4) +#define BIT_PHYIDR2_REV (0xf) +#define REG_ANAR 36 +#define BIT_ANAR_PROTO (0x1f<<0) +#define BIT_ANAR_10 (1<<5) +#define BIT_ANAR_10_FD (1<<6) +#define BIT_ANAR_TX (1<<7) +#define BIT_ANAR_TXFD (1<<8) +#define BIT_ANAR_T4 (1<<9) +#define BIT_ANAR_PAUSE (1<<10) +#define BIT_ANAR_RF (1<<13) +#define BIT_ANAR_NP (1<<15) +#define REG_ANLPAR 37 +#define BIT_ANLPAR_PROTO (0x1f<<0) +#define BIT_ANLPAR_10 (1<<5) +#define BIT_ANLPAR_10_FD (1<<6) +#define BIT_ANLPAR_TX (1<<7) +#define BIT_ANLPAR_TXFD (1<<8) +#define BIT_ANLPAR_T4 (1<<9) +#define BIT_ANLPAR_PAUSE (1<<10) +#define BIT_ANLPAR_RF (1<<13) +#define BIT_ANLPAR_ACK (1<<14) +#define BIT_ANLPAR_NP (1<<15) +#define REG_ANER 38 +#define BIT_ANER_LP_AN_ENABLE (1<<0) +#define BIT_ANER_PAGE_RX (1<<1) +#define BIT_ANER_NP_ABLE (1<<2) +#define BIT_ANER_LP_NP_ABLE (1<<3) +#define BIT_ANER_PDF (1<<4) +#define REG_ANNPTR 39 +#define REG_PHYSTS 48 +#define BIT_PHYSTS_LNK (1<<0) +#define BIT_PHYSTS_SPD10 (1<<1) +#define BIT_PHYSTS_FDUP (1<<2) +#define BIT_PHYSTS_LOOP (1<<3) +#define BIT_PHYSTS_ANDONE (1<<4) +#define BIT_PHYSTS_JABBER (1<<5) +#define BIT_PHYSTS_RF (1<<6) +#define BIT_PHYSTS_MINT (1<<7) +#define BIT_PHYSTS_FC (1<<11) +#define BIT_PHYSTS_POL (1<<12) +#define BIT_PHYSTS_RXERR (1<<13) +#define REG_MICR 49 +#define BIT_MICR_INTEN (1<<1) +#define REG_MISR 50 +#define BIT_MISR_MSK_RHF (1<<9) +#define BIT_MISR_MSK_FHF (1<<10) +#define BIT_MISR_MSK_ANC (1<<11) +#define BIT_MISR_MSK_RF (1<<12) +#define BIT_MISR_MSK_JAB (1<<13) +#define BIT_MISR_MSK_LNK (1<<14) +#define BIT_MISR_MINT (1<<15) +#define REG_PGSEL 51 +#define REG_FCSCR 52 +#define REG_RECR 53 +#define REG_PCSR 54 +#define BIT_PCSR_NRZI (1<<2) +#define BIT_PCSR_FORCE_100 (1<<5) +#define BIT_PCSR_SDOPT (1<<8) +#define BIT_PCSR_SDFORCE (1<<9) +#define BIT_PCSR_TQM (1<<10) +#define BIT_PCSR_CLK (1<<11) +#define BIT_PCSR_4B5B (1<<12) +#define REG_PHYCR 57 +#define BIT_PHYCR_PHYADDR (0x1f<<0) +#define BIT_PHYCR_PAUSE_STS (1<<7) +#define BIT_PHYCR_STRETCH (1<<8) +#define BIT_PHYCR_BIST (1<<9) +#define BIT_PHYCR_BIST_STAT (1<<10) +#define BIT_PHYCR_PSR15 (1<<11) +#define REG_TBTSCR 58 +#define BIT_TBTSCR_JAB (1<<0) +#define BIT_TBTSCR_BEAT (1<<1) +#define BIT_TBTSCR_AUTOPOL (1<<3) +#define BIT_TBTSCR_POL (1<<4) +#define BIT_TBTSCR_FPOL (1<<5) +#define BIT_TBTSCR_FORCE_10 (1<<6) +#define BIT_TBTSCR_PULSE (1<<7) +#define BIT_TBTSCR_LOOP (1<<8) +#define REG_PMDCSR 64 +#define REG_TSTDAT 65 +#define REG_DSPCFG 66 +#define REG_SDCFG 67 +#define REG_PMATCH0 68 +#define REG_PMATCH1 69 +#define REG_PMATCH2 70 +#define REG_PCOUNT0 71 +#define REG_PCOUNT1 72 +#define REG_SOPASS0 73 +#define REG_SOPASS1 74 +#define REG_SOPASS2 75 + +static void __print_intr(int d, int intr, const char *name, + const char *s1, const char *s2) +{ + if ((d) & intr) + fprintf(stdout, " %s Interrupt: %s\n", name, s1); + else if (s2) + fprintf(stdout, " %s Interrupt: %s\n", name, s2); +} + +#define PRINT_INTR(d, i, s1, s2) do { \ + int intr = BIT_INTR_ ## i; \ + const char *name = NAME_INTR_ ## i; \ + __print_intr(d, intr, name, s1, s2); \ +} while (0) + +#define PRINT_INTRS(d, s1, s2) do { \ + PRINT_INTR((d), RXOK, s1, s2); \ + PRINT_INTR((d), RXDESC, s1, s2); \ + PRINT_INTR((d), RXERR, s1, s2); \ + PRINT_INTR((d), RXEARLY, s1, s2); \ + PRINT_INTR((d), RXIDLE, s1, s2); \ + PRINT_INTR((d), RXORN, s1, s2); \ + PRINT_INTR((d), TXOK, s1, s2); \ + PRINT_INTR((d), TXDESC, s1, s2); \ + PRINT_INTR((d), TXERR, s1, s2); \ + PRINT_INTR((d), TXIDLE, s1, s2); \ + PRINT_INTR((d), TXURN, s1, s2); \ + PRINT_INTR((d), MIB, s1, s2); \ + PRINT_INTR((d), SWI, s1, s2); \ + PRINT_INTR((d), PME, s1, s2); \ + PRINT_INTR((d), PHY, s1, s2); \ + PRINT_INTR((d), HIBERR, s1, s2); \ + PRINT_INTR((d), RXSOVR, s1, s2); \ + PRINT_INTR((d), RTABT, s1, s2); \ + PRINT_INTR((d), RMABT, s1, s2); \ + PRINT_INTR((d), SSERR, s1, s2); \ + PRINT_INTR((d), DPERR, s1, s2); \ + PRINT_INTR((d), RXRCMP, s1, s2); \ + PRINT_INTR((d), TXRCMP, s1, s2); \ +} while (0) + +int +natsemi_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *data = (u32 *)regs->data; + u32 tmp; + + fprintf(stdout, "Mac/BIU Registers\n"); + fprintf(stdout, "-----------------\n"); + + /* command register */ + fprintf(stdout, + "0x00: CR (Command): 0x%08x\n", + data[REG_CR]); + fprintf(stdout, + " Transmit %s\n" + " Receive %s\n", + data[REG_CR] & BIT_CR_TXE ? "Active" : "Idle", + data[REG_CR] & BIT_CR_RXE ? "Active" : "Idle"); + if (data[REG_CR] & BIT_CR_RST) fprintf(stdout, + " Reset In Progress\n"); + + /* configuration register */ + fprintf(stdout, + "0x04: CFG (Configuration): 0x%08x\n", + data[REG_CFG]); + fprintf(stdout, + " %s Endian\n" + " Boot ROM %s\n" + " Internal Phy %s\n" + " Phy Reset %s\n" + " External Phy %s\n" + " Default Auto-Negotiation %s, %s %s Mb %s Duplex\n" + " Phy Interrupt %sAuto-Cleared\n" + " Phy Configuration = 0x%02x\n" + " Auto-Negotiation %s\n" + " %s Polarity\n" + " %s Duplex\n" + " %d Mb/s\n" + " Link %s\n", + data[REG_CFG] & BIT_CFG_BEM ? "Big" : "Little", + data[REG_CFG] & BIT_CFG_BROM_DIS ? "Disabled" : "Enabled", + data[REG_CFG] & BIT_CFG_PHY_DIS ? "Disabled" : "Enabled", + data[REG_CFG] & BIT_CFG_PHY_RST ? "In Progress" : "Idle", + data[REG_CFG] & BIT_CFG_EXT_PHY ? "Enabled" : "Disabled", + data[REG_CFG] & BIT_CFG_ANEG_EN ? "Enabled" : "Disabled", + data[REG_CFG] & BIT_CFG_ANEG_EN ? "Advertise" : "Force", + data[REG_CFG] & BIT_CFG_ANEG_100 ? + (data[REG_CFG] & BIT_CFG_ANEG_EN ? "10/100" : "100") + : "10", + data[REG_CFG] & BIT_CFG_ANEG_FDUP ? + (data[REG_CFG] & BIT_CFG_ANEG_EN ? "Half/Full" : "Full") + : "Half", + data[REG_CFG] & BIT_CFG_PINT_ACEN ? "" : "Not ", + data[REG_CFG] & BIT_CFG_PHY_CFG >> 18, + data[REG_CFG] & BIT_CFG_ANEG_DN ? "Done" : "Not Done", + data[REG_CFG] & BIT_CFG_POL ? "Reversed" : "Normal", + data[REG_CFG] & BIT_CFG_FDUP ? "Full" : "Half", + data[REG_CFG] & BIT_CFG_SPEED100 ? 100 : 10, + data[REG_CFG] & BIT_CFG_LNKSTS ? "Up" : "Down"); + + /* EEPROM access register */ + fprintf(stdout, + "0x08: MEAR (EEPROM Access): 0x%08x\n", + data[REG_MEAR]); + + /* PCI test control register */ + fprintf(stdout, + "0x0c: PTSCR (PCI Test Control): 0x%08x\n", + data[REG_PTSCR]); + fprintf(stdout, + " EEPROM Self Test %s\n" + " Rx Filter Self Test %s\n" + " Tx FIFO Self Test %s\n" + " Rx FIFO Self Test %s\n", + data[REG_PTSCR] & BIT_PTSCR_EEBIST_FAIL ? "Failed" : "Passed", + data[REG_PTSCR] & BIT_PTSCR_RBIST_RXFFAIL ? "Failed" : "Passed", + data[REG_PTSCR] & BIT_PTSCR_RBIST_TXFAIL ? "Failed" : "Passed", + data[REG_PTSCR] & BIT_PTSCR_RBIST_RXFAIL ? "Failed" : "Passed"); + if (data[REG_PTSCR] & BIT_PTSCR_EELOAD_EN) fprintf(stdout, + " EEPROM Reload In Progress\n"); + + /* Interrupt status register */ + fprintf(stdout, + "0x10: ISR (Interrupt Status): 0x%08x\n", + data[REG_ISR]); + if (data[REG_ISR]) + PRINT_INTRS(data[REG_ISR], "Active", (char *)NULL); + else + fprintf(stdout, " No Interrupts Active\n"); + + /* Interrupt mask register */ + fprintf(stdout, + "0x14: IMR (Interrupt Mask): 0x%08x\n", + data[REG_IMR]); + PRINT_INTRS(data[REG_IMR], "Enabled", "Masked"); + + /* Interrupt enable register */ + fprintf(stdout, + "0x18: IER (Interrupt Enable): 0x%08x\n", + data[REG_IER]); + fprintf(stdout, + " Interrupts %s\n", + data[REG_IER] & BIT_IER_IE ? "Enabled" : "Disabled"); + + /* Tx descriptor pointer register */ + fprintf(stdout, + "0x20: TXDP (Tx Descriptor Pointer): 0x%08x\n", + data[REG_TXDP]); + + /* Tx configuration register */ + fprintf(stdout, + "0x24: TXCFG (Tx Config): 0x%08x\n", + data[REG_TXCFG]); + tmp = (data[REG_TXCFG] & BIT_TXCFG_MXDMA)>>20; + fprintf(stdout, + " Drain Threshold = %d bytes (%d)\n" + " Fill Threshold = %d bytes (%d)\n" + " Max DMA Burst per Tx = %d bytes\n" + " Automatic Tx Padding %s\n" + " Mac Loopback %s\n" + " Heartbeat Ignore %s\n" + " Carrier Sense Ignore %s\n", + (data[REG_TXCFG] & BIT_TXCFG_DRTH) * 32, + data[REG_TXCFG] & BIT_TXCFG_DRTH, + ((data[REG_TXCFG] & BIT_TXCFG_FLTH)>>8) * 32, + data[REG_TXCFG] & BIT_TXCFG_FLTH, + tmp ? (1<<(tmp-1))*4 : 512, + data[REG_TXCFG] & BIT_TXCFG_ATP ? "Enabled" : "Disabled", + data[REG_TXCFG] & BIT_TXCFG_MLB ? "Enabled" : "Disabled", + data[REG_TXCFG] & BIT_TXCFG_HBI ? "Enabled" : "Disabled", + data[REG_TXCFG] & BIT_TXCFG_CSI ? "Enabled" : "Disabled"); + + + /* Rx descriptor pointer register */ + fprintf(stdout, + "0x30: RXDP (Rx Descriptor Pointer): 0x%08x\n", + data[REG_RXDP]); + + /* Rx configuration register */ + fprintf(stdout, + "0x34: RXCFG (Rx Config): 0x%08x\n", + data[REG_RXCFG]); + tmp = (data[REG_RXCFG] & BIT_RXCFG_MXDMA)>>20; + fprintf(stdout, + " Drain Threshold = %d bytes (%d)\n" + " Max DMA Burst per Rx = %d bytes\n" + " Long Packets %s\n" + " Tx Packets %s\n" + " Runt Packets %s\n" + " Error Packets %s\n", + ((data[REG_RXCFG] & BIT_RXCFG_DRTH) >> 1) * 8, + (data[REG_RXCFG] & BIT_RXCFG_DRTH) >> 1, + tmp ? (1<<(tmp-1))*4 : 512, + data[REG_RXCFG] & BIT_RXCFG_ALP ? "Accepted" : "Rejected", + data[REG_RXCFG] & BIT_RXCFG_ATX ? "Accepted" : "Rejected", + data[REG_RXCFG] & BIT_RXCFG_ARP ? "Accepted" : "Rejected", + data[REG_RXCFG] & BIT_RXCFG_AEP ? "Accepted" : "Rejected"); + + /* CLKRUN control/status register */ + fprintf(stdout, + "0x3c: CCSR (CLKRUN Control/Status): 0x%08x\n", + data[REG_CCSR]); + fprintf(stdout, + " CLKRUNN %s\n" + " Power Management %s\n", + data[REG_CCSR] & BIT_CCSR_CLKRUN_EN ? "Enabled" : "Disabled", + data[REG_CCSR] & BIT_CCSR_PMEEN ? "Enabled" : "Disabled"); + if (data[REG_CCSR] & BIT_CCSR_PMESTS) fprintf(stdout, + " Power Management Event Pending\n"); + + /* WoL control/status register */ + fprintf(stdout, + "0x40: WCSR (Wake-on-LAN Control/Status): 0x%08x\n", + data[REG_WCSR]); + if (data[REG_WCSR] & BIT_WCSR_WKPHY) fprintf(stdout, + " Wake on Phy Interrupt Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_WKUCP) fprintf(stdout, + " Wake on Unicast Packet Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_WKMCP) fprintf(stdout, + " Wake on Multicast Packet Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_WKBCP) fprintf(stdout, + " Wake on Broadcast Packet Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_WKARP) fprintf(stdout, + " Wake on Arp Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_WKPAT0) fprintf(stdout, + " Wake on Pattern 0 Match Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_WKPAT1) fprintf(stdout, + " Wake on Pattern 1 Match Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_WKPAT2) fprintf(stdout, + " Wake on Pattern 2 Match Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_WKPAT3) fprintf(stdout, + " Wake on Pattern 3 Match Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_WKMAG) fprintf(stdout, + " Wake on Magic Packet Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_MPSOE) fprintf(stdout, + " Magic Packet SecureOn Enabled\n"); + if (data[REG_WCSR] & BIT_WCSR_SOHACK) fprintf(stdout, + " SecureOn Hack Detected\n"); + if (data[REG_WCSR] & BIT_WCSR_PHYINT) fprintf(stdout, + " Phy Interrupt Received\n"); + if (data[REG_WCSR] & BIT_WCSR_UCASTR) fprintf(stdout, + " Unicast Packet Received\n"); + if (data[REG_WCSR] & BIT_WCSR_MCASTR) fprintf(stdout, + " Multicast Packet Received\n"); + if (data[REG_WCSR] & BIT_WCSR_BCASTR) fprintf(stdout, + " Broadcast Packet Received\n"); + if (data[REG_WCSR] & BIT_WCSR_ARPR) fprintf(stdout, + " Arp Received\n"); + if (data[REG_WCSR] & BIT_WCSR_PATM0) fprintf(stdout, + " Pattern 0 Received\n"); + if (data[REG_WCSR] & BIT_WCSR_PATM1) fprintf(stdout, + " Pattern 1 Received\n"); + if (data[REG_WCSR] & BIT_WCSR_PATM2) fprintf(stdout, + " Pattern 2 Received\n"); + if (data[REG_WCSR] & BIT_WCSR_PATM3) fprintf(stdout, + " Pattern 3 Received\n"); + if (data[REG_WCSR] & BIT_WCSR_MPR) fprintf(stdout, + " Magic Packet Received\n"); + + /* Pause control/status register */ + fprintf(stdout, + "0x44: PCR (Pause Control/Status): 0x%08x\n", + data[REG_PCR]); + fprintf(stdout, + " Pause Counter = %d\n" + " Pause %sNegotiated\n" + " Pause on DA %s\n" + " Pause on Mulitcast %s\n" + " Pause %s\n", + data[REG_PCR] & BIT_PCR_PAUSE_CNT, + data[REG_PCR] & BIT_PCR_PSNEG ? "" : "Not ", + data[REG_PCR] & BIT_PCR_PS_DA ? "Enabled" : "Disabled", + data[REG_PCR] & BIT_PCR_PSMCAST ? "Enabled" : "Disabled", + data[REG_PCR] & BIT_PCR_PSEN ? "Enabled" : "Disabled"); + if (data[REG_PCR] & BIT_PCR_PS_RCVD) fprintf(stdout, + " PS_RCVD: Pause Frame Received\n"); + + /* Rx Filter Control */ + fprintf(stdout, + "0x48: RFCR (Rx Filter Control): 0x%08x\n", + data[REG_RFCR]); + fprintf(stdout, + " Unicast Hash %s\n" + " Multicast Hash %s\n" + " Arp %s\n" + " Pattern 0 Match %s\n" + " Pattern 1 Match %s\n" + " Pattern 2 Match %s\n" + " Pattern 3 Match %s\n" + " Perfect Match %s\n" + " All Unicast %s\n" + " All Multicast %s\n" + " All Broadcast %s\n" + " Rx Filter %s\n", + data[REG_RFCR] & BIT_RFCR_UHEN ? "Enabled" : "Disabled", + data[REG_RFCR] & BIT_RFCR_MHEN ? "Enabled" : "Disabled", + data[REG_RFCR] & BIT_RFCR_AARP ? "Accepted" : "Rejected", + data[REG_RFCR] & BIT_RFCR_APAT0 ? "Accepted" : "Rejected", + data[REG_RFCR] & BIT_RFCR_APAT1 ? "Accepted" : "Rejected", + data[REG_RFCR] & BIT_RFCR_APAT2 ? "Accepted" : "Rejected", + data[REG_RFCR] & BIT_RFCR_APAT3 ? "Accepted" : "Rejected", + data[REG_RFCR] & BIT_RFCR_APM ? "Accepted" : "Rejected", + data[REG_RFCR] & BIT_RFCR_AAU ? "Accepted" : "Rejected", + data[REG_RFCR] & BIT_RFCR_AAM ? "Accepted" : "Rejected", + data[REG_RFCR] & BIT_RFCR_AAB ? "Accepted" : "Rejected", + data[REG_RFCR] & BIT_RFCR_RFEN ? "Enabled" : "Disabled"); + + /* Rx filter data register */ + fprintf(stdout, + "0x4c: RFDR (Rx Filter Data): 0x%08x\n", + data[REG_RFDR]); + if (regs->version >= 1) fprintf(stdout, + " PMATCH 1-0 = 0x%08x\n" + " PMATCH 3-2 = 0x%08x\n" + " PMATCH 5-4 = 0x%08x\n" + " PCOUNT 1-0 = 0x%08x\n" + " PCOUNT 3-2 = 0x%08x\n" + " SOPASS 1-0 = 0x%08x\n" + " SOPASS 3-2 = 0x%08x\n" + " SOPASS 5-4 = 0x%08x\n", + data[REG_PMATCH0], data[REG_PMATCH1], data[REG_PMATCH2], + data[REG_PCOUNT0], data[REG_PCOUNT1], + data[REG_SOPASS0], data[REG_SOPASS1], data[REG_SOPASS2]); + + + /* Boot ROM address register */ + fprintf(stdout, + "0x50: BRAR (Boot ROM Address): 0x%08x\n", + data[REG_BRAR]); + if (data[REG_BRAR] & BIT_BRAR_AUTOINC) fprintf(stdout, + " Automatically Increment Address\n"); + + /* Boot ROM data register */ + fprintf(stdout, + "0x54: BRDR (Boot ROM Data): 0x%08x\n", + data[REG_BRDR]); + + /* Silicon revison register */ + fprintf(stdout, + "0x58: SRR (Silicon Revision): 0x%08x\n", + data[REG_SRR]); + + /* Management information base control register */ + fprintf(stdout, + "0x5c: MIBC (Mgmt Info Base Control): 0x%08x\n", + data[REG_MIBC]); + if (data[REG_MIBC] & BIT_MIBC_WRN) fprintf(stdout, + " Counter Overflow Warning\n"); + if (data[REG_MIBC] & BIT_MIBC_FRZ) fprintf(stdout, + " Counters Frozen\n"); + + /* MIB registers */ + fprintf(stdout, + "0x60: MIB[0] (Rx Errored Packets): 0x%04x\n", + data[REG_MIB0]); + fprintf(stdout, " Value = %d\n", data[REG_MIB0]); + fprintf(stdout, + "0x64: MIB[1] (Rx Frame Sequence Errors): 0x%02x\n", + data[REG_MIB1]); + fprintf(stdout, " Value = %d\n", data[REG_MIB1]); + fprintf(stdout, + "0x68: MIB[2] (Rx Missed Packets): 0x%02x\n", + data[REG_MIB2]); + fprintf(stdout, " Value = %d\n", data[REG_MIB2]); + fprintf(stdout, + "0x6c: MIB[3] (Rx Alignment Errors): 0x%02x\n", + data[REG_MIB3]); + fprintf(stdout, " Value = %d\n", data[REG_MIB3]); + fprintf(stdout, + "0x70: MIB[4] (Rx Symbol Errors): 0x%02x\n", + data[REG_MIB4]); + fprintf(stdout, " Value = %d\n", data[REG_MIB4]); + fprintf(stdout, + "0x74: MIB[5] (Rx Long Frame Errors): 0x%02x\n", + data[REG_MIB5]); + fprintf(stdout, " Value = %d\n", data[REG_MIB5]); + fprintf(stdout, + "0x78: MIB[6] (Tx Heartbeat Errors): 0x%02x\n", + data[REG_MIB6]); + fprintf(stdout, " Value = %d\n", data[REG_MIB6]); + + fprintf(stdout, "\n"); + fprintf(stdout, "Internal Phy Registers\n"); + fprintf(stdout, "----------------------\n"); + + /* Basic mode control register */ + fprintf(stdout, + "0x80: BMCR (Basic Mode Control): 0x%04x\n", + data[REG_BMCR]); + fprintf(stdout, + " %s Duplex\n" + " Port is Powered %s\n" + " Auto-Negotiation %s\n" + " %d Mb/s\n", + data[REG_BMCR] & BIT_BMCR_FDUP ? "Full" : "Half", + data[REG_BMCR] & BIT_BMCR_PDOWN ? "Down" : "Up", + data[REG_BMCR] & BIT_BMCR_ANEN ? "Enabled" : "Disabled", + data[REG_BMCR] & BIT_BMCR_SPEED ? 100 : 10); + if (data[REG_BMCR] & BIT_BMCR_ANRST) fprintf(stdout, + " Auto-Negotiation Restarting\n"); + if (data[REG_BMCR] & BIT_BMCR_ISOL) fprintf(stdout, + " Port Isolated\n"); + if (data[REG_BMCR] & BIT_BMCR_LOOP) fprintf(stdout, + " Loopback Enabled\n"); + if (data[REG_BMCR] & BIT_BMCR_RST) fprintf(stdout, + " Reset In Progress\n"); + + /* Basic mode status register */ + fprintf(stdout, + "0x84: BMSR (Basic Mode Status): 0x%04x\n", + data[REG_BMSR]); + fprintf(stdout, + " Link %s\n" + " %sCapable of Auto-Negotiation\n" + " Auto-Negotiation %sComplete\n" + " %sCapable of Preamble Suppression\n" + " %sCapable of 10Base-T Half Duplex\n" + " %sCapable of 10Base-T Full Duplex\n" + " %sCapable of 100Base-TX Half Duplex\n" + " %sCapable of 100Base-TX Full Duplex\n" + " %sCapable of 100Base-T4\n", + data[REG_BMSR] & BIT_BMSR_LNK ? "Up" : "Down", + data[REG_BMSR] & BIT_BMSR_ANCAP ? "" : "Not ", + data[REG_BMSR] & BIT_BMSR_ANDONE ? "" : "Not ", + data[REG_BMSR] & BIT_BMSR_PREAMBLE ? "" : "Not ", + data[REG_BMSR] & BIT_BMSR_10HCAP ? "" : "Not ", + data[REG_BMSR] & BIT_BMSR_10FCAP ? "" : "Not ", + data[REG_BMSR] & BIT_BMSR_100HCAP ? "" : "Not ", + data[REG_BMSR] & BIT_BMSR_100FCAP ? "" : "Not ", + data[REG_BMSR] & BIT_BMSR_100T4CAP ? "" : "Not "); + if (data[REG_BMSR] & BIT_BMSR_JABBER) fprintf(stdout, + " Jabber Condition Detected\n"); + if (data[REG_BMSR] & BIT_BMSR_RFAULT) fprintf(stdout, + " Remote Fault Detected\n"); + + /* PHY identification registers */ + fprintf(stdout, + "0x88: PHYIDR1 (PHY ID #1): 0x%04x\n", + data[REG_PHYIDR1]); + fprintf(stdout, + "0x8c: PHYIDR2 (PHY ID #2): 0x%04x\n", + data[REG_PHYIDR2]); + fprintf(stdout, + " OUI = 0x%06x\n" + " Model = 0x%02x (%d)\n" + " Revision = 0x%01x (%d)\n", + (data[REG_PHYIDR1] << 6) | (data[REG_PHYIDR2] >> 10), + (data[REG_PHYIDR2] & BIT_PHYIDR2_MODEL) >> 4 & 0x3f, + (data[REG_PHYIDR2] & BIT_PHYIDR2_MODEL) >> 4 & 0x3f, + data[REG_PHYIDR2] & BIT_PHYIDR2_REV, + data[REG_PHYIDR2] & BIT_PHYIDR2_REV); + + /* autonegotiation advertising register */ + fprintf(stdout, + "0x90: ANAR (Autoneg Advertising): 0x%04x\n", + data[REG_ANAR]); + fprintf(stdout, + " Protocol Selector = 0x%02x (%d)\n", + data[REG_ANAR] & BIT_ANAR_PROTO, + data[REG_ANAR] & BIT_ANAR_PROTO); + if (data[REG_ANAR] & BIT_ANAR_10) fprintf(stdout, + " Advertising 10Base-T Half Duplex\n"); + if (data[REG_ANAR] & BIT_ANAR_10_FD) fprintf(stdout, + " Advertising 10Base-T Full Duplex\n"); + if (data[REG_ANAR] & BIT_ANAR_TX) fprintf(stdout, + " Advertising 100Base-TX Half Duplex\n"); + if (data[REG_ANAR] & BIT_ANAR_TXFD) fprintf(stdout, + " Advertising 100Base-TX Full Duplex\n"); + if (data[REG_ANAR] & BIT_ANAR_T4) fprintf(stdout, + " Advertising 100Base-T4\n"); + if (data[REG_ANAR] & BIT_ANAR_PAUSE) fprintf(stdout, + " Advertising Pause\n"); + if (data[REG_ANAR] & BIT_ANAR_RF) fprintf(stdout, + " Indicating Remote Fault\n"); + if (data[REG_ANAR] & BIT_ANAR_NP) fprintf(stdout, + " Next Page Desired\n"); + + /* Autonegotiation link partner ability register */ + fprintf(stdout, + "0x94: ANLPAR (Autoneg Partner): 0x%04x\n", + data[REG_ANLPAR]); + fprintf(stdout, + " Protocol Selector = 0x%02x (%d)\n", + data[REG_ANLPAR] & BIT_ANLPAR_PROTO, + data[REG_ANLPAR] & BIT_ANLPAR_PROTO); + if (data[REG_ANLPAR] & BIT_ANLPAR_10) fprintf(stdout, + " Supports 10Base-T Half Duplex\n"); + if (data[REG_ANLPAR] & BIT_ANLPAR_10_FD) fprintf(stdout, + " Supports 10Base-T Full Duplex\n"); + if (data[REG_ANLPAR] & BIT_ANLPAR_TX) fprintf(stdout, + " Supports 100Base-TX Half Duplex\n"); + if (data[REG_ANLPAR] & BIT_ANLPAR_TXFD) fprintf(stdout, + " Supports 100Base-TX Full Duplex\n"); + if (data[REG_ANLPAR] & BIT_ANLPAR_T4) fprintf(stdout, + " Supports 100Base-T4\n"); + if (data[REG_ANLPAR] & BIT_ANLPAR_PAUSE) fprintf(stdout, + " Supports Pause\n"); + if (data[REG_ANLPAR] & BIT_ANLPAR_RF) fprintf(stdout, + " Indicates Remote Fault\n"); + if (data[REG_ANLPAR] & BIT_ANLPAR_ACK) fprintf(stdout, + " Indicates Acknowledgement\n"); + if (data[REG_ANLPAR] & BIT_ANLPAR_NP) fprintf(stdout, + " Next Page Desired\n"); + + /* Autonegotiation expansion register */ + fprintf(stdout, + "0x98: ANER (Autoneg Expansion): 0x%04x\n", + data[REG_ANER]); + fprintf(stdout, + " Link Partner Can %sAuto-Negotiate\n" + " Link Code Word %sReceived\n" + " Next Page %sSupported\n" + " Link Partner Next Page %sSupported\n", + data[REG_ANER] & BIT_ANER_LP_AN_ENABLE ? "" : "Not ", + data[REG_ANER] & BIT_ANER_PAGE_RX ? "" : "Not ", + data[REG_ANER] & BIT_ANER_NP_ABLE ? "" : "Not ", + data[REG_ANER] & BIT_ANER_LP_NP_ABLE ? "" : "Not "); + if (data[REG_ANER] & BIT_ANER_PDF) fprintf(stdout, + " Parallel Detection Fault\n"); + + /* Autonegotiation next-page tx register */ + fprintf(stdout, + "0x9c: ANNPTR (Autoneg Next Page Tx): 0x%04x\n", + data[REG_ANNPTR]); + + /* Phy status register */ + fprintf(stdout, + "0xc0: PHYSTS (Phy Status): 0x%04x\n", + data[REG_PHYSTS]); + fprintf(stdout, + " Link %s\n" + " %d Mb/s\n" + " %s Duplex\n" + " Auto-Negotiation %sComplete\n" + " %s Polarity\n", + data[REG_PHYSTS] & BIT_PHYSTS_LNK ? "Up" : "Down", + data[REG_PHYSTS] & BIT_PHYSTS_SPD10 ? 10 : 100, + data[REG_PHYSTS] & BIT_PHYSTS_FDUP ? "Full" : "Half", + data[REG_PHYSTS] & BIT_PHYSTS_ANDONE ? "" : "Not ", + data[REG_PHYSTS] & BIT_PHYSTS_POL ? "Reverse" : "Normal"); + if (data[REG_PHYSTS] & BIT_PHYSTS_LOOP) fprintf(stdout, + " Loopback Enabled\n"); + if (data[REG_PHYSTS] & BIT_PHYSTS_JABBER) fprintf(stdout, + " Jabber Condition Detected\n"); + if (data[REG_PHYSTS] & BIT_PHYSTS_RF) fprintf(stdout, + " Remote Fault Detected\n"); + if (data[REG_PHYSTS] & BIT_PHYSTS_MINT) fprintf(stdout, + " MII Interrupt Detected\n"); + if (data[REG_PHYSTS] & BIT_PHYSTS_FC) fprintf(stdout, + " False Carrier Detected\n"); + if (data[REG_PHYSTS] & BIT_PHYSTS_RXERR) fprintf(stdout, + " Rx Error Detected\n"); + + fprintf(stdout, + "0xc4: MICR (MII Interrupt Control): 0x%04x\n", + data[REG_MICR]); + fprintf(stdout, + " MII Interrupts %s\n", + data[REG_MICR] & BIT_MICR_INTEN ? "Enabled" : "Disabled"); + + fprintf(stdout, + "0xc8: MISR (MII Interrupt Status): 0x%04x\n", + data[REG_MISR]); + fprintf(stdout, + " Rx Error Counter Half-Full Interrupt %s\n" + " False Carrier Counter Half-Full Interrupt %s\n" + " Auto-Negotiation Complete Interrupt %s\n" + " Remote Fault Interrupt %s\n" + " Jabber Interrupt %s\n" + " Link Change Interrupt %s\n", + data[REG_MISR] & BIT_MISR_MSK_RHF ? "Masked" : "Enabled", + data[REG_MISR] & BIT_MISR_MSK_FHF ? "Masked" : "Enabled", + data[REG_MISR] & BIT_MISR_MSK_ANC ? "Masked" : "Enabled", + data[REG_MISR] & BIT_MISR_MSK_RF ? "Masked" : "Enabled", + data[REG_MISR] & BIT_MISR_MSK_JAB ? "Masked" : "Enabled", + data[REG_MISR] & BIT_MISR_MSK_LNK ? "Masked" : "Enabled"); + if (data[REG_MISR] & BIT_MISR_MINT) fprintf(stdout, + " MII Interrupt Pending\n"); + + /* Page select register (from section of spec on 'suggested values') */ + fprintf(stdout, + "0xcc: PGSEL (Phy Register Page Select): 0x%04x\n", + data[REG_PGSEL]); + + /* counters */ + fprintf(stdout, + "0xd0: FCSCR (False Carrier Counter): 0x%04x\n", + data[REG_FCSCR]); + fprintf(stdout, + " Value = %d\n", data[REG_FCSCR] & 0xff); + fprintf(stdout, + "0xd4: RECR (Rx Error Counter): 0x%04x\n", + data[REG_RECR]); + fprintf(stdout, + " Value = %d\n", data[REG_RECR] & 0xff); + + /* 100 Mbit configuration register */ + fprintf(stdout, + "0xd8: PCSR (100Mb/s PCS Config/Status): 0x%04x\n", + data[REG_PCSR]); + fprintf(stdout, + " NRZI Bypass %s\n" + " %s Signal Detect Algorithm\n" + " %s Signal Detect Operation\n" + " True Quiet Mode %s\n" + " Rx Clock is %s\n" + " 4B/5B Operation %s\n", + data[REG_PCSR] & BIT_PCSR_NRZI ? "Enabled" : "Disabled", + data[REG_PCSR] & BIT_PCSR_SDOPT ? "Enhanced" : "Reduced", + data[REG_PCSR] & BIT_PCSR_SDFORCE ? "Forced" : "Normal", + data[REG_PCSR] & BIT_PCSR_TQM ? "Enabled" : "Disabled", + data[REG_PCSR] & BIT_PCSR_CLK ? + "Free-Running" : "Phase-Adjusted", + data[REG_PCSR] & BIT_PCSR_4B5B ? "Bypassed" : "Normal"); + if (data[REG_PCSR] & BIT_PCSR_FORCE_100) fprintf(stdout, + " Forced 100 Mb/s Good Link\n"); + + /* Phy control register */ + fprintf(stdout, + "0xe4: PHYCR (Phy Control): 0x%04x\n", + data[REG_PHYCR]); + fprintf(stdout, + " Phy Address = 0x%x (%d)\n" + " %sPause Compatible with Link Partner\n" + " LED Stretching %s\n" + " Phy Self Test %s\n" + " Self Test Sequence = PSR%d\n", + data[REG_PHYCR] & BIT_PHYCR_PHYADDR, + data[REG_PHYCR] & BIT_PHYCR_PHYADDR, + data[REG_PHYCR] & BIT_PHYCR_PAUSE_STS ? "" : "Not ", + data[REG_PHYCR] & BIT_PHYCR_STRETCH ? "Bypassed" : "Enabled", + data[REG_PHYCR] & BIT_PHYCR_BIST ? "In Progress" : + data[REG_PHYCR] & BIT_PHYCR_BIST_STAT ? + "Passed" : "Failed or Not Run", + data[REG_PHYCR] & BIT_PHYCR_PSR15 ? 15 : 9); + + + /* 10 Mbit control and status register */ + fprintf(stdout, + "0xe8: TBTSCR (10Base-T Status/Control): 0x%04x\n", + data[REG_TBTSCR]); + fprintf(stdout, + " Jabber %s\n" + " Heartbeat %s\n" + " Polarity Auto-Sense/Correct %s\n" + " %s Polarity %s\n" + " Normal Link Pulse %s\n" + " 10 Mb/s Loopback %s\n", + data[REG_TBTSCR] & BIT_TBTSCR_JAB ? "Disabled" : "Enabled", + data[REG_TBTSCR] & BIT_TBTSCR_BEAT ? "Disabled" : "Enabled", + data[REG_TBTSCR] & BIT_TBTSCR_AUTOPOL ? "Disabled" : "Enabled", + data[REG_TBTSCR] & BIT_TBTSCR_AUTOPOL ? + data[REG_TBTSCR]&BIT_TBTSCR_FPOL ? "Reverse":"Normal" : + data[REG_TBTSCR]&BIT_TBTSCR_POL ? "Reverse":"Normal", + data[REG_TBTSCR] & BIT_TBTSCR_AUTOPOL ? "Forced" : "Detected", + data[REG_TBTSCR] & BIT_TBTSCR_PULSE ? "Disabled" : "Enabled", + data[REG_TBTSCR] & BIT_TBTSCR_LOOP ? "Enabled" : "Disabled"); + if (data[REG_TBTSCR] & BIT_TBTSCR_FORCE_10) fprintf(stdout, + " Forced 10 Mb/s Good Link\n"); + + /* the spec says to set these */ + fprintf(stdout, "\n"); + fprintf(stdout, "'Magic' Phy Registers\n"); + fprintf(stdout, "---------------------\n"); + fprintf(stdout, + "0xe4: PMDCSR: 0x%04x\n", + data[REG_PMDCSR]); + fprintf(stdout, + "0xf4: DSPCFG: 0x%04x\n", + data[REG_DSPCFG]); + fprintf(stdout, + "0xf8: SDCFG: 0x%04x\n", + data[REG_SDCFG]); + fprintf(stdout, + "0xfc: TSTDAT: 0x%04x\n", + data[REG_TSTDAT]); + + return 0; +} + +int +natsemi_dump_eeprom(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_eeprom *ee) +{ + u16 *eebuf = (u16 *)ee->data; + unsigned int i; + + if (ee->magic != NATSEMI_MAGIC) { + fprintf(stderr, "Magic number 0x%08x does not match 0x%08x\n", + ee->magic, NATSEMI_MAGIC); + return -1; + } + + fprintf(stdout, "Address\tData\n"); + fprintf(stdout, "-------\t------\n"); + for (i = 0; i < ee->len/2; i++) { + fprintf(stdout, "0x%02x \t0x%04x\n", i + ee->offset, eebuf[i]); + } + + return 0; +} + diff --git a/netlink/bitset.c b/netlink/bitset.c new file mode 100644 index 0000000..10ce8e9 --- /dev/null +++ b/netlink/bitset.c @@ -0,0 +1,259 @@ +/* + * bitset.h - netlink bitset helpers + * + * Functions for easier handling of ethtool netlink bitset attributes. + */ + +#include +#include + +#include "../common.h" +#include "netlink.h" +#include "bitset.h" + +uint32_t bitset_get_count(const struct nlattr *bitset, int *retptr) +{ + const struct nlattr *attr; + + mnl_attr_for_each_nested(attr, bitset) { + if (mnl_attr_get_type(attr) != ETHTOOL_A_BITSET_SIZE) + continue; + *retptr = 0; + return mnl_attr_get_u32(attr); + } + + *retptr = -EFAULT; + return 0; +} + +bool bitset_is_compact(const struct nlattr *bitset) +{ + const struct nlattr *attr; + + mnl_attr_for_each_nested(attr, bitset) { + switch(mnl_attr_get_type(attr)) { + case ETHTOOL_A_BITSET_BITS: + return 0; + case ETHTOOL_A_BITSET_VALUE: + case ETHTOOL_A_BITSET_MASK: + return 1; + } + } + + return false; +} + +bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx, + int *retptr) +{ + const struct nlattr *bitset_tb[ETHTOOL_A_BITSET_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(bitset_tb); + const struct nlattr *bits; + const struct nlattr *bit; + bool nomask; + int ret; + + *retptr = 0; + ret = mnl_attr_parse_nested(bitset, attr_cb, &bitset_tb_info); + if (ret < 0) + goto err; + + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK]; + if (mask && nomask) { + /* Trying to determine if a bit is set in the mask of a "no + * mask" bitset doesn't make sense. + */ + ret = -EFAULT; + goto err; + } + + bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] : + bitset_tb[ETHTOOL_A_BITSET_VALUE]; + if (bits) { + const uint32_t *bitmap = + (const uint32_t *)mnl_attr_get_payload(bits); + + if (idx >= 8 * mnl_attr_get_payload_len(bits)) + return false; + return bitmap[idx / 32] & (1U << (idx % 32)); + } + + bits = bitset_tb[ETHTOOL_A_BITSET_BITS]; + if (!bits) + goto err; + mnl_attr_for_each_nested(bit, bits) { + const struct nlattr *tb[ETHTOOL_A_BITSET_BIT_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + unsigned int my_idx; + + if (mnl_attr_get_type(bit) != ETHTOOL_A_BITSET_BITS_BIT) + continue; + ret = mnl_attr_parse_nested(bit, attr_cb, &tb_info); + if (ret < 0) + goto err; + ret = -EFAULT; + if (!tb[ETHTOOL_A_BITSET_BIT_INDEX]) + goto err; + + my_idx = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]); + if (my_idx == idx) + return mask || nomask || tb[ETHTOOL_A_BITSET_BIT_VALUE]; + } + + return false; +err: + fprintf(stderr, "malformed netlink message (bitset)\n"); + *retptr = ret; + return false; +} + +bool bitset_is_empty(const struct nlattr *bitset, bool mask, int *retptr) +{ + const struct nlattr *bitset_tb[ETHTOOL_A_BITSET_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(bitset_tb); + const struct nlattr *bits; + const struct nlattr *bit; + int ret; + + *retptr = 0; + ret = mnl_attr_parse_nested(bitset, attr_cb, &bitset_tb_info); + if (ret < 0) + goto err; + + bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] : + bitset_tb[ETHTOOL_A_BITSET_VALUE]; + if (bits) { + const uint32_t *bitmap = + (const uint32_t *)mnl_attr_get_payload(bits); + unsigned int n = mnl_attr_get_payload_len(bits); + unsigned int i; + + ret = -EFAULT; + if (n % 4) + goto err; + for (i = 0; i < n / 4; i++) + if (bitmap[i]) + return false; + return true; + } + + bits = bitset_tb[ETHTOOL_A_BITSET_BITS]; + if (!bits) + goto err; + mnl_attr_for_each_nested(bit, bits) { + const struct nlattr *tb[ETHTOOL_A_BITSET_BIT_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + + if (mnl_attr_get_type(bit) != ETHTOOL_A_BITSET_BITS_BIT) + continue; + if (mask || bitset_tb[ETHTOOL_A_BITSET_NOMASK]) + return false; + + ret = mnl_attr_parse_nested(bit, attr_cb, &tb_info); + if (ret < 0) + goto err; + if (tb[ETHTOOL_A_BITSET_BIT_VALUE]) + return false; + } + + return true; +err: + fprintf(stderr, "malformed netlink message (bitset)\n"); + *retptr = ret; + return true; +} + +static uint32_t *get_compact_bitset_attr(const struct nlattr *bitset, + uint16_t type) +{ + const struct nlattr *tb[ETHTOOL_A_BITSET_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + unsigned int count; + int ret; + + ret = mnl_attr_parse_nested(bitset, attr_cb, &tb_info); + if (ret < 0) + return NULL; + if (!tb[ETHTOOL_A_BITSET_SIZE] || !tb[ETHTOOL_A_BITSET_VALUE] || + !tb[type]) + return NULL; + count = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_SIZE]); + if (8 * mnl_attr_get_payload_len(tb[type]) < count) + return NULL; + + return mnl_attr_get_payload(tb[type]); +} + +uint32_t *get_compact_bitset_value(const struct nlattr *bitset) +{ + return get_compact_bitset_attr(bitset, ETHTOOL_A_BITSET_VALUE); +} + +uint32_t *get_compact_bitset_mask(const struct nlattr *bitset) +{ + return get_compact_bitset_attr(bitset, ETHTOOL_A_BITSET_MASK); +} + +int walk_bitset(const struct nlattr *bitset, const struct stringset *labels, + bitset_walk_callback cb, void *data) +{ + const struct nlattr *bitset_tb[ETHTOOL_A_BITSET_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(bitset_tb); + const struct nlattr *bits; + const struct nlattr *bit; + bool is_list; + int ret; + + ret = mnl_attr_parse_nested(bitset, attr_cb, &bitset_tb_info); + if (ret < 0) + return ret; + is_list = bitset_tb[ETHTOOL_A_BITSET_NOMASK]; + + bits = bitset_tb[ETHTOOL_A_BITSET_VALUE]; + if (bits) { + const struct nlattr *mask = bitset_tb[ETHTOOL_A_BITSET_MASK]; + unsigned int count, nwords, idx; + uint32_t *val_bm; + uint32_t *mask_bm; + + if (!bitset_tb[ETHTOOL_A_BITSET_SIZE]) + return -EFAULT; + count = mnl_attr_get_u32(bitset_tb[ETHTOOL_A_BITSET_SIZE]); + nwords = (count + 31) / 32; + if ((mnl_attr_get_payload_len(bits) / 4 < nwords) || + (mask && mnl_attr_get_payload_len(mask) / 4 < nwords)) + return -EFAULT; + + val_bm = mnl_attr_get_payload(bits); + mask_bm = mask ? mnl_attr_get_payload(mask) : NULL; + for (idx = 0; idx < count; idx++) + if (!mask_bm || (mask_bm[idx / 32] & (1 << (idx % 32)))) + cb(idx, get_string(labels, idx), + val_bm[idx / 32] & (1 << (idx % 32)), data); + return 0; + } + + bits = bitset_tb[ETHTOOL_A_BITSET_BITS]; + if (!bits) + return -EFAULT; + mnl_attr_for_each_nested(bit, bits) { + const struct nlattr *tb[ETHTOOL_A_BITSET_BIT_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + const char *name; + unsigned int idx; + + if (mnl_attr_get_type(bit) != ETHTOOL_A_BITSET_BITS_BIT) + continue; + + ret = mnl_attr_parse_nested(bit, attr_cb, &tb_info); + if (ret < 0 || !tb[ETHTOOL_A_BITSET_BIT_INDEX] || + !tb[ETHTOOL_A_BITSET_BIT_NAME]) + return -EFAULT; + + idx = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]); + name = mnl_attr_get_str(tb[ETHTOOL_A_BITSET_BIT_NAME]); + cb(idx, name, is_list || tb[ETHTOOL_A_BITSET_BIT_VALUE], data); + } + + return 0; +} diff --git a/netlink/bitset.h b/netlink/bitset.h new file mode 100644 index 0000000..4c9cdac --- /dev/null +++ b/netlink/bitset.h @@ -0,0 +1,28 @@ +/* + * bitset.h - netlink bitset helpers + * + * Declarations of helpers for handling ethtool netlink bitsets. + */ + +#ifndef ETHTOOL_NETLINK_BITSET_H__ +#define ETHTOOL_NETLINK_BITSET_H__ + +#include +#include +#include +#include +#include "strset.h" + +typedef void (*bitset_walk_callback)(unsigned int, const char *, bool, void *); + +uint32_t bitset_get_count(const struct nlattr *bitset, int *retptr); +bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx, + int *retptr); +bool bitset_is_compact(const struct nlattr *bitset); +bool bitset_is_empty(const struct nlattr *bitset, bool mask, int *retptr); +uint32_t *get_compact_bitset_value(const struct nlattr *bitset); +uint32_t *get_compact_bitset_mask(const struct nlattr *bitset); +int walk_bitset(const struct nlattr *bitset, const struct stringset *labels, + bitset_walk_callback cb, void *data); + +#endif /* ETHTOOL_NETLINK_BITSET_H__ */ diff --git a/netlink/cable_test.c b/netlink/cable_test.c new file mode 100644 index 0000000..9305a47 --- /dev/null +++ b/netlink/cable_test.c @@ -0,0 +1,595 @@ +/* + * cable_test.c - netlink implementation of cable test command + * + * Implementation of ethtool --cable-test + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "parser.h" + +struct cable_test_context { + bool breakout; +}; + +static int nl_get_cable_test_result(const struct nlattr *nest, uint8_t *pair, + uint16_t *code) +{ + const struct nlattr *tb[ETHTOOL_A_CABLE_RESULT_MAX+1] = {}; + DECLARE_ATTR_TB_INFO(tb); + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0 || + !tb[ETHTOOL_A_CABLE_RESULT_PAIR] || + !tb[ETHTOOL_A_CABLE_RESULT_CODE]) + return -EFAULT; + + *pair = mnl_attr_get_u8(tb[ETHTOOL_A_CABLE_RESULT_PAIR]); + *code = mnl_attr_get_u8(tb[ETHTOOL_A_CABLE_RESULT_CODE]); + + return 0; +} + +static int nl_get_cable_test_fault_length(const struct nlattr *nest, + uint8_t *pair, unsigned int *cm) +{ + const struct nlattr *tb[ETHTOOL_A_CABLE_FAULT_LENGTH_MAX+1] = {}; + DECLARE_ATTR_TB_INFO(tb); + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0 || + !tb[ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR] || + !tb[ETHTOOL_A_CABLE_FAULT_LENGTH_CM]) + return -EFAULT; + + *pair = mnl_attr_get_u8(tb[ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR]); + *cm = mnl_attr_get_u32(tb[ETHTOOL_A_CABLE_FAULT_LENGTH_CM]); + + return 0; +} + +static char *nl_code2txt(uint16_t code) +{ + switch (code) { + case ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC: + default: + return "Unknown"; + case ETHTOOL_A_CABLE_RESULT_CODE_OK: + return "OK"; + case ETHTOOL_A_CABLE_RESULT_CODE_OPEN: + return "Open Circuit"; + case ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT: + return "Short within Pair"; + case ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT: + return "Short to another pair"; + } +} + +static char *nl_pair2txt(uint8_t pair) +{ + switch (pair) { + case ETHTOOL_A_CABLE_PAIR_A: + return "Pair A"; + case ETHTOOL_A_CABLE_PAIR_B: + return "Pair B"; + case ETHTOOL_A_CABLE_PAIR_C: + return "Pair C"; + case ETHTOOL_A_CABLE_PAIR_D: + return "Pair D"; + default: + return "Unexpected pair"; + } +} + +static int nl_cable_test_ntf_attr(struct nlattr *evattr) +{ + unsigned int cm; + uint16_t code; + uint8_t pair; + int ret; + + switch (mnl_attr_get_type(evattr)) { + case ETHTOOL_A_CABLE_NEST_RESULT: + ret = nl_get_cable_test_result(evattr, &pair, &code); + if (ret < 0) + return ret; + + open_json_object(NULL); + print_string(PRINT_ANY, "pair", "%s ", nl_pair2txt(pair)); + print_string(PRINT_ANY, "code", "code %s\n", nl_code2txt(code)); + close_json_object(); + break; + + case ETHTOOL_A_CABLE_NEST_FAULT_LENGTH: + ret = nl_get_cable_test_fault_length(evattr, &pair, &cm); + if (ret < 0) + return ret; + open_json_object(NULL); + print_string(PRINT_ANY, "pair", "%s, ", nl_pair2txt(pair)); + print_float(PRINT_ANY, "length", "fault length: %0.2fm\n", + (float)cm / 100); + close_json_object(); + break; + } + return 0; +} + +static void cable_test_ntf_nest(const struct nlattr *nest) +{ + struct nlattr *pos; + int ret; + + mnl_attr_for_each_nested(pos, nest) { + ret = nl_cable_test_ntf_attr(pos); + if (ret < 0) + return; + } +} + +/* Returns MNL_CB_STOP when the test is complete. Used when executing + * a test, but not suitable for monitor. + */ +static int cable_test_ntf_stop_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_CABLE_TEST_NTF_MAX + 1] = {}; + u8 status = ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC; + struct cable_test_context *ctctx; + struct nl_context *nlctx = data; + DECLARE_ATTR_TB_INFO(tb); + bool silent; + int err_ret; + int ret; + + ctctx = nlctx->cmd_private; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + + nlctx->devname = get_dev_name(tb[ETHTOOL_A_CABLE_TEST_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (tb[ETHTOOL_A_CABLE_TEST_NTF_STATUS]) + status = mnl_attr_get_u8(tb[ETHTOOL_A_CABLE_TEST_NTF_STATUS]); + + switch (status) { + case ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED: + print_string(PRINT_FP, "status", + "Cable test started for device %s.\n", + nlctx->devname); + break; + case ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED: + print_string(PRINT_FP, "status", + "Cable test completed for device %s.\n", + nlctx->devname); + break; + default: + break; + } + + if (tb[ETHTOOL_A_CABLE_TEST_NTF_NEST]) + cable_test_ntf_nest(tb[ETHTOOL_A_CABLE_TEST_NTF_NEST]); + + if (status == ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED) { + if (ctctx) + ctctx->breakout = true; + return MNL_CB_STOP; + } + + return MNL_CB_OK; +} + +/* Wrapper around cable_test_ntf_stop_cb() which does not return STOP, + * used for monitor + */ +int cable_test_ntf_cb(const struct nlmsghdr *nlhdr, void *data) +{ + int status = cable_test_ntf_stop_cb(nlhdr, data); + + if (status == MNL_CB_STOP) + status = MNL_CB_OK; + + return status; +} + +static int nl_cable_test_results_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct genlmsghdr *ghdr = (const struct genlmsghdr *)(nlhdr + 1); + + if (ghdr->cmd != ETHTOOL_MSG_CABLE_TEST_NTF) + return MNL_CB_OK; + + return cable_test_ntf_stop_cb(nlhdr, data); +} + +/* Receive the broadcasted messages until we get the cable test + * results + */ +static int nl_cable_test_process_results(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + struct cable_test_context ctctx; + int err; + + nlctx->is_monitor = true; + nlsk->port = 0; + nlsk->seq = 0; + nlctx->filter_devname = ctx->devname; + + ctctx.breakout = false; + nlctx->cmd_private = &ctctx; + + while (!ctctx.breakout) { + err = nlsock_process_reply(nlsk, nl_cable_test_results_cb, + nlctx); + if (err) + return err; + } + + return err; +} + +int nl_cable_test(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + uint32_t grpid = nlctx->ethnl_mongrp; + int ret; + + /* Join the multicast group so we can receive the results in a + * race free way. + */ + if (!grpid) { + fprintf(stderr, "multicast group 'monitor' not found\n"); + return -EOPNOTSUPP; + } + + ret = mnl_socket_setsockopt(nlsk->sk, NETLINK_ADD_MEMBERSHIP, + &grpid, sizeof(grpid)); + if (ret < 0) + return ret; + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_CABLE_TEST_ACT, + ETHTOOL_A_CABLE_TEST_HEADER, 0); + if (ret < 0) + return ret; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + fprintf(stderr, "Cannot start cable test\n"); + else { + new_json_obj(ctx->json); + + ret = nl_cable_test_process_results(ctx); + + delete_json_obj(); + } + + return ret; +} + +static int nl_get_cable_test_tdr_amplitude(const struct nlattr *nest, + uint8_t *pair, int16_t *mV) +{ + const struct nlattr *tb[ETHTOOL_A_CABLE_AMPLITUDE_MAX+1] = {}; + DECLARE_ATTR_TB_INFO(tb); + uint16_t mV_unsigned; + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0 || + !tb[ETHTOOL_A_CABLE_AMPLITUDE_PAIR] || + !tb[ETHTOOL_A_CABLE_AMPLITUDE_mV]) + return -EFAULT; + + *pair = mnl_attr_get_u8(tb[ETHTOOL_A_CABLE_AMPLITUDE_PAIR]); + mV_unsigned = mnl_attr_get_u16(tb[ETHTOOL_A_CABLE_AMPLITUDE_mV]); + *mV = (int16_t)(mV_unsigned); + + return 0; +} + +static int nl_get_cable_test_tdr_pulse(const struct nlattr *nest, uint16_t *mV) +{ + const struct nlattr *tb[ETHTOOL_A_CABLE_PULSE_MAX+1] = {}; + DECLARE_ATTR_TB_INFO(tb); + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0 || + !tb[ETHTOOL_A_CABLE_PULSE_mV]) + return -EFAULT; + + *mV = mnl_attr_get_u16(tb[ETHTOOL_A_CABLE_PULSE_mV]); + + return 0; +} + +static int nl_get_cable_test_tdr_step(const struct nlattr *nest, + uint32_t *first, uint32_t *last, + uint32_t *step) +{ + const struct nlattr *tb[ETHTOOL_A_CABLE_STEP_MAX+1] = {}; + DECLARE_ATTR_TB_INFO(tb); + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0 || + !tb[ETHTOOL_A_CABLE_STEP_FIRST_DISTANCE] || + !tb[ETHTOOL_A_CABLE_STEP_LAST_DISTANCE] || + !tb[ETHTOOL_A_CABLE_STEP_STEP_DISTANCE]) + return -EFAULT; + + *first = mnl_attr_get_u32(tb[ETHTOOL_A_CABLE_STEP_FIRST_DISTANCE]); + *last = mnl_attr_get_u32(tb[ETHTOOL_A_CABLE_STEP_LAST_DISTANCE]); + *step = mnl_attr_get_u32(tb[ETHTOOL_A_CABLE_STEP_STEP_DISTANCE]); + + return 0; +} + +static int nl_cable_test_tdr_ntf_attr(struct nlattr *evattr) +{ + uint32_t first, last, step; + uint8_t pair; + int ret; + + switch (mnl_attr_get_type(evattr)) { + case ETHTOOL_A_CABLE_TDR_NEST_AMPLITUDE: { + int16_t mV; + + ret = nl_get_cable_test_tdr_amplitude( + evattr, &pair, &mV); + if (ret < 0) + return ret; + + open_json_object(NULL); + print_string(PRINT_ANY, "pair", "%s ", nl_pair2txt(pair)); + print_int(PRINT_ANY, "amplitude", "Amplitude %4d\n", mV); + close_json_object(); + break; + } + case ETHTOOL_A_CABLE_TDR_NEST_PULSE: { + uint16_t mV; + + ret = nl_get_cable_test_tdr_pulse(evattr, &mV); + if (ret < 0) + return ret; + + open_json_object(NULL); + print_uint(PRINT_ANY, "pulse", "TDR Pulse %dmV\n", mV); + close_json_object(); + break; + } + case ETHTOOL_A_CABLE_TDR_NEST_STEP: + ret = nl_get_cable_test_tdr_step(evattr, &first, &last, &step); + if (ret < 0) + return ret; + + open_json_object(NULL); + print_float(PRINT_ANY, "first", "Step configuration: %.2f-", + (float)first / 100); + print_float(PRINT_ANY, "last", "%.2f meters ", + (float)last / 100); + print_float(PRINT_ANY, "step", "in %.2fm steps\n", + (float)step / 100); + close_json_object(); + break; + } + return 0; +} + +static void cable_test_tdr_ntf_nest(const struct nlattr *nest) +{ + struct nlattr *pos; + int ret; + + mnl_attr_for_each_nested(pos, nest) { + ret = nl_cable_test_tdr_ntf_attr(pos); + if (ret < 0) + return; + } +} + +/* Returns MNL_CB_STOP when the test is complete. Used when executing + * a test, but not suitable for monitor. + */ +int cable_test_tdr_ntf_stop_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX + 1] = {}; + u8 status = ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC; + struct cable_test_context *ctctx; + struct nl_context *nlctx = data; + + DECLARE_ATTR_TB_INFO(tb); + bool silent; + int err_ret; + int ret; + + ctctx = nlctx->cmd_private; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + + nlctx->devname = get_dev_name(tb[ETHTOOL_A_CABLE_TEST_TDR_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (tb[ETHTOOL_A_CABLE_TEST_NTF_STATUS]) + status = mnl_attr_get_u8(tb[ETHTOOL_A_CABLE_TEST_NTF_STATUS]); + + switch (status) { + case ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED: + print_string(PRINT_FP, "status", + "Cable test TDR started for device %s.\n", + nlctx->devname); + break; + case ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED: + print_string(PRINT_FP, "status", + "Cable test TDR completed for device %s.\n", + nlctx->devname); + break; + default: + break; + } + + if (tb[ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST]) + cable_test_tdr_ntf_nest(tb[ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST]); + + if (status == ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED) { + if (ctctx) + ctctx->breakout = true; + return MNL_CB_STOP; + } + + return MNL_CB_OK; +} + +/* Wrapper around cable_test_tdr_ntf_stop_cb() which does not return + * STOP, used for monitor + */ +int cable_test_tdr_ntf_cb(const struct nlmsghdr *nlhdr, void *data) +{ + int status = cable_test_tdr_ntf_stop_cb(nlhdr, data); + + if (status == MNL_CB_STOP) + status = MNL_CB_OK; + + return status; +} + +static int nl_cable_test_tdr_results_cb(const struct nlmsghdr *nlhdr, + void *data) +{ + const struct genlmsghdr *ghdr = (const struct genlmsghdr *)(nlhdr + 1); + + if (ghdr->cmd != ETHTOOL_MSG_CABLE_TEST_TDR_NTF) + return MNL_CB_OK; + + cable_test_tdr_ntf_cb(nlhdr, data); + + return MNL_CB_STOP; +} + +/* Receive the broadcasted messages until we get the cable test + * results + */ +static int nl_cable_test_tdr_process_results(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + struct cable_test_context ctctx; + int err; + + nlctx->is_monitor = true; + nlsk->port = 0; + nlsk->seq = 0; + nlctx->filter_devname = ctx->devname; + + ctctx.breakout = false; + nlctx->cmd_private = &ctctx; + + while (!ctctx.breakout) { + err = nlsock_process_reply(nlsk, nl_cable_test_tdr_results_cb, + nlctx); + if (err) + return err; + } + + return err; +} + +static const struct param_parser tdr_params[] = { + { + .arg = "first", + .type = ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST, + .group = ETHTOOL_A_CABLE_TEST_TDR_CFG, + .handler = nl_parse_direct_m2cm, + }, + { + .arg = "last", + .type = ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST, + .group = ETHTOOL_A_CABLE_TEST_TDR_CFG, + .handler = nl_parse_direct_m2cm, + }, + { + .arg = "step", + .type = ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP, + .group = ETHTOOL_A_CABLE_TEST_TDR_CFG, + .handler = nl_parse_direct_m2cm, + }, + { + .arg = "pair", + .type = ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR, + .group = ETHTOOL_A_CABLE_TEST_TDR_CFG, + .handler = nl_parse_direct_u8, + }, + {} +}; + +int nl_cable_test_tdr(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + uint32_t grpid = nlctx->ethnl_mongrp; + struct nl_msg_buff *msgbuff; + int ret; + + nlctx->cmd = "--cable-test-tdr"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + msgbuff = &nlsk->msgbuff; + + /* Join the multicast group so we can receive the results in a + * race free way. + */ + if (!grpid) { + fprintf(stderr, "multicast group 'monitor' not found\n"); + return -EOPNOTSUPP; + } + + ret = mnl_socket_setsockopt(nlsk->sk, NETLINK_ADD_MEMBERSHIP, + &grpid, sizeof(grpid)); + if (ret < 0) + return ret; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_CABLE_TEST_TDR_ACT, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + + if (ethnla_fill_header(msgbuff, ETHTOOL_A_CABLE_TEST_TDR_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, tdr_params, NULL, PARSER_GROUP_NEST, NULL); + if (ret < 0) + return ret; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + fprintf(stderr, "Cannot start cable test TDR\n"); + else { + new_json_obj(ctx->json); + + ret = nl_cable_test_tdr_process_results(ctx); + + delete_json_obj(); + } + + return ret; +} diff --git a/netlink/channels.c b/netlink/channels.c new file mode 100644 index 0000000..894c74b --- /dev/null +++ b/netlink/channels.c @@ -0,0 +1,141 @@ +/* + * channels.c - netlink implementation of channel commands + * + * Implementation of "ethtool -l " and "ethtool -L ..." + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "parser.h" + +/* CHANNELS_GET */ + +int channels_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_CHANNELS_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_CHANNELS_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + putchar('\n'); + printf("Channel parameters for %s:\n", nlctx->devname); + printf("Pre-set maximums:\n"); + show_u32(tb[ETHTOOL_A_CHANNELS_RX_MAX], "RX:\t\t"); + show_u32(tb[ETHTOOL_A_CHANNELS_TX_MAX], "TX:\t\t"); + show_u32(tb[ETHTOOL_A_CHANNELS_OTHER_MAX], "Other:\t\t"); + show_u32(tb[ETHTOOL_A_CHANNELS_COMBINED_MAX], "Combined:\t"); + printf("Current hardware settings:\n"); + show_u32(tb[ETHTOOL_A_CHANNELS_RX_COUNT], "RX:\t\t"); + show_u32(tb[ETHTOOL_A_CHANNELS_TX_COUNT], "TX:\t\t"); + show_u32(tb[ETHTOOL_A_CHANNELS_OTHER_COUNT], "Other:\t\t"); + show_u32(tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT], "Combined:\t"); + + return MNL_CB_OK; +} + +int nl_gchannels(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_CHANNELS_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_CHANNELS_GET, + ETHTOOL_A_CHANNELS_HEADER, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, channels_reply_cb); +} + +/* CHANNELS_SET */ + +static const struct param_parser schannels_params[] = { + { + .arg = "rx", + .type = ETHTOOL_A_CHANNELS_RX_COUNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx", + .type = ETHTOOL_A_CHANNELS_TX_COUNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "other", + .type = ETHTOOL_A_CHANNELS_OTHER_COUNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "combined", + .type = ETHTOOL_A_CHANNELS_COMBINED_COUNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + {} +}; + +int nl_schannels(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_CHANNELS_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "-L"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_CHANNELS_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_CHANNELS_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, schannels_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 1; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 1; +} diff --git a/netlink/coalesce.c b/netlink/coalesce.c new file mode 100644 index 0000000..15037c2 --- /dev/null +++ b/netlink/coalesce.c @@ -0,0 +1,285 @@ +/* + * coalesce.c - netlink implementation of coalescing commands + * + * Implementation of "ethtool -c " and "ethtool -C ..." + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "parser.h" + +/* COALESCE_GET */ + +int coalesce_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_COALESCE_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_COALESCE_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + putchar('\n'); + printf("Coalesce parameters for %s:\n", nlctx->devname); + show_bool("rx", "Adaptive RX: %s ", + tb[ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX]); + show_bool("tx", "TX: %s\n", tb[ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX]); + show_u32(tb[ETHTOOL_A_COALESCE_STATS_BLOCK_USECS], + "stats-block-usecs: "); + show_u32(tb[ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL], + "sample-interval: "); + show_u32(tb[ETHTOOL_A_COALESCE_PKT_RATE_LOW], "pkt-rate-low: "); + show_u32(tb[ETHTOOL_A_COALESCE_PKT_RATE_HIGH], "pkt-rate-high: "); + putchar('\n'); + show_u32(tb[ETHTOOL_A_COALESCE_RX_USECS], "rx-usecs: "); + show_u32(tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES], "rx-frames: "); + show_u32(tb[ETHTOOL_A_COALESCE_RX_USECS_IRQ], "rx-usecs-irq: "); + show_u32(tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ], "rx-frames-irq: "); + putchar('\n'); + show_u32(tb[ETHTOOL_A_COALESCE_TX_USECS], "tx-usecs: "); + show_u32(tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES], "tx-frames: "); + show_u32(tb[ETHTOOL_A_COALESCE_TX_USECS_IRQ], "tx-usecs-irq: "); + show_u32(tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ], "tx-frames-irq: "); + putchar('\n'); + show_u32(tb[ETHTOOL_A_COALESCE_RX_USECS_LOW], "rx-usecs-low: "); + show_u32(tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW], "rx-frame-low: "); + show_u32(tb[ETHTOOL_A_COALESCE_TX_USECS_LOW], "tx-usecs-low: "); + show_u32(tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW], "tx-frame-low: "); + putchar('\n'); + show_u32(tb[ETHTOOL_A_COALESCE_RX_USECS_HIGH], "rx-usecs-high: "); + show_u32(tb[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH], "rx-frame-high: "); + show_u32(tb[ETHTOOL_A_COALESCE_TX_USECS_HIGH], "tx-usecs-high: "); + show_u32(tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH], "tx-frame-high: "); + putchar('\n'); + show_bool("rx", "CQE mode RX: %s ", + tb[ETHTOOL_A_COALESCE_USE_CQE_MODE_RX]); + show_bool("tx", "TX: %s\n", tb[ETHTOOL_A_COALESCE_USE_CQE_MODE_TX]); + putchar('\n'); + + return MNL_CB_OK; +} + +int nl_gcoalesce(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_COALESCE_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_COALESCE_GET, + ETHTOOL_A_COALESCE_HEADER, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, coalesce_reply_cb); +} + +/* COALESCE_SET */ + +static const struct param_parser scoalesce_params[] = { + { + .arg = "adaptive-rx", + .type = ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "adaptive-tx", + .type = ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "sample-interval", + .type = ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "stats-block-usecs", + .type = ETHTOOL_A_COALESCE_STATS_BLOCK_USECS, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "pkt-rate-low", + .type = ETHTOOL_A_COALESCE_PKT_RATE_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "pkt-rate-high", + .type = ETHTOOL_A_COALESCE_PKT_RATE_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-usecs", + .type = ETHTOOL_A_COALESCE_RX_USECS, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-frames", + .type = ETHTOOL_A_COALESCE_RX_MAX_FRAMES, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-usecs-irq", + .type = ETHTOOL_A_COALESCE_RX_USECS_IRQ, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-frames-irq", + .type = ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-usecs", + .type = ETHTOOL_A_COALESCE_TX_USECS, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-frames", + .type = ETHTOOL_A_COALESCE_TX_MAX_FRAMES, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-usecs-irq", + .type = ETHTOOL_A_COALESCE_TX_USECS_IRQ, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-frames-irq", + .type = ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-usecs-low", + .type = ETHTOOL_A_COALESCE_RX_USECS_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-frames-low", + .type = ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-usecs-low", + .type = ETHTOOL_A_COALESCE_TX_USECS_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-frames-low", + .type = ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-usecs-high", + .type = ETHTOOL_A_COALESCE_RX_USECS_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-frames-high", + .type = ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-usecs-high", + .type = ETHTOOL_A_COALESCE_TX_USECS_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-frames-high", + .type = ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "cqe-mode-rx", + .type = ETHTOOL_A_COALESCE_USE_CQE_MODE_RX, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "cqe-mode-tx", + .type = ETHTOOL_A_COALESCE_USE_CQE_MODE_TX, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + {} +}; + +int nl_scoalesce(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_COALESCE_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "-C"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_COALESCE_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_COALESCE_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, scoalesce_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 1; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 1; +} diff --git a/netlink/desc-ethtool.c b/netlink/desc-ethtool.c new file mode 100644 index 0000000..b3ac64d --- /dev/null +++ b/netlink/desc-ethtool.c @@ -0,0 +1,529 @@ +/* + * desc-ethtool.c - ethtool netlink format descriptions + * + * Descriptions of ethtool netlink messages and attributes for pretty print. + */ + +#include "../internal.h" +#include + +#include "prettymsg.h" + +static const struct pretty_nla_desc __header_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_HEADER_UNSPEC), + NLATTR_DESC_U32(ETHTOOL_A_HEADER_DEV_INDEX), + NLATTR_DESC_STRING(ETHTOOL_A_HEADER_DEV_NAME), + NLATTR_DESC_X32(ETHTOOL_A_HEADER_FLAGS), +}; + +static const struct pretty_nla_desc __bitset_bit_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_BITSET_BIT_UNSPEC), + NLATTR_DESC_U32(ETHTOOL_A_BITSET_BIT_INDEX), + NLATTR_DESC_STRING(ETHTOOL_A_BITSET_BIT_NAME), + NLATTR_DESC_FLAG(ETHTOOL_A_BITSET_BIT_VALUE), +}; + +static const struct pretty_nla_desc __bitset_bits_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_BITSET_BITS_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_BITSET_BITS_BIT, bitset_bit), +}; + +static const struct pretty_nla_desc __bitset_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_BITSET_UNSPEC), + NLATTR_DESC_FLAG(ETHTOOL_A_BITSET_NOMASK), + NLATTR_DESC_U32(ETHTOOL_A_BITSET_SIZE), + NLATTR_DESC_NESTED(ETHTOOL_A_BITSET_BITS, bitset_bits), + NLATTR_DESC_BINARY(ETHTOOL_A_BITSET_VALUE), + NLATTR_DESC_BINARY(ETHTOOL_A_BITSET_MASK), +}; + +static const struct pretty_nla_desc __string_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_STRING_UNSPEC), + NLATTR_DESC_U32(ETHTOOL_A_STRING_INDEX), + NLATTR_DESC_STRING(ETHTOOL_A_STRING_VALUE), +}; + +static const struct pretty_nla_desc __strings_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_STRINGS_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_STRINGS_STRING, string), +}; + +static const struct pretty_nla_desc __stringset_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_STRINGSET_UNSPEC), + NLATTR_DESC_U32(ETHTOOL_A_STRINGSET_ID), + NLATTR_DESC_U32(ETHTOOL_A_STRINGSET_COUNT), + NLATTR_DESC_NESTED(ETHTOOL_A_STRINGSET_STRINGS, strings), +}; + +static const struct pretty_nla_desc __stringsets_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_STRINGSETS_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_STRINGSETS_STRINGSET, stringset), +}; + +static const struct pretty_nla_desc __strset_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_STRSET_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_STRSET_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_STRSET_STRINGSETS, stringsets), + NLATTR_DESC_FLAG(ETHTOOL_A_STRSET_COUNTS_ONLY), +}; + +static const struct pretty_nla_desc __linkinfo_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_LINKINFO_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_LINKINFO_HEADER, header), + NLATTR_DESC_U8(ETHTOOL_A_LINKINFO_PORT), + NLATTR_DESC_U8(ETHTOOL_A_LINKINFO_PHYADDR), + NLATTR_DESC_U8(ETHTOOL_A_LINKINFO_TP_MDIX), + NLATTR_DESC_U8(ETHTOOL_A_LINKINFO_TP_MDIX_CTRL), + NLATTR_DESC_U8(ETHTOOL_A_LINKINFO_TRANSCEIVER), +}; + +static const char *__linkmodes_rate_matching_names[] = { + [RATE_MATCH_NONE] = "RATE_MATCH_NONE", + [RATE_MATCH_PAUSE] = "RATE_MATCH_PAUSE", + [RATE_MATCH_CRS] = "RATE_MATCH_CRS", + [RATE_MATCH_OPEN_LOOP] = "RATE_MATCH_OPEN_LOOP", +}; + +static const struct pretty_nla_desc __linkmodes_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_LINKMODES_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_LINKMODES_HEADER, header), + NLATTR_DESC_BOOL(ETHTOOL_A_LINKMODES_AUTONEG), + NLATTR_DESC_NESTED(ETHTOOL_A_LINKMODES_OURS, bitset), + NLATTR_DESC_NESTED(ETHTOOL_A_LINKMODES_PEER, bitset), + NLATTR_DESC_U32(ETHTOOL_A_LINKMODES_SPEED), + NLATTR_DESC_U8(ETHTOOL_A_LINKMODES_DUPLEX), + NLATTR_DESC_U8(ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG), + NLATTR_DESC_U8(ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE), + NLATTR_DESC_U32(ETHTOOL_A_LINKMODES_LANES), + NLATTR_DESC_U8_ENUM(ETHTOOL_A_LINKMODES_RATE_MATCHING, + linkmodes_rate_matching), +}; + +static const struct pretty_nla_desc __linkstate_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_LINKSTATE_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_LINKSTATE_HEADER, header), + NLATTR_DESC_BOOL(ETHTOOL_A_LINKSTATE_LINK), + NLATTR_DESC_U32(ETHTOOL_A_LINKSTATE_SQI), + NLATTR_DESC_U32(ETHTOOL_A_LINKSTATE_SQI_MAX), + NLATTR_DESC_U8(ETHTOOL_A_LINKSTATE_EXT_STATE), + NLATTR_DESC_U8(ETHTOOL_A_LINKSTATE_EXT_SUBSTATE), +}; + +static const struct pretty_nla_desc __debug_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_DEBUG_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_DEBUG_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_DEBUG_MSGMASK, bitset), +}; + +static const struct pretty_nla_desc __wol_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_WOL_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_WOL_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_WOL_MODES, bitset), + NLATTR_DESC_BINARY(ETHTOOL_A_WOL_SOPASS), +}; + +static const struct pretty_nla_desc __features_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_FEATURES_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_FEATURES_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_FEATURES_HW, bitset), + NLATTR_DESC_NESTED(ETHTOOL_A_FEATURES_WANTED, bitset), + NLATTR_DESC_NESTED(ETHTOOL_A_FEATURES_ACTIVE, bitset), + NLATTR_DESC_NESTED(ETHTOOL_A_FEATURES_NOCHANGE, bitset), +}; + +static const struct pretty_nla_desc __privflags_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_PRIVFLAGS_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_PRIVFLAGS_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_PRIVFLAGS_FLAGS, bitset), +}; + +static const char *__rings_tcp_data_split_names[] = { + [ETHTOOL_TCP_DATA_SPLIT_UNKNOWN] = "ETHTOOL_TCP_DATA_SPLIT_UNKNOWN", + [ETHTOOL_TCP_DATA_SPLIT_DISABLED] = "ETHTOOL_TCP_DATA_SPLIT_DISABLED", + [ETHTOOL_TCP_DATA_SPLIT_ENABLED] = "ETHTOOL_TCP_DATA_SPLIT_ENABLED", +}; + +static const struct pretty_nla_desc __rings_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_RINGS_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_RINGS_HEADER, header), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_RX_MAX), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_RX_MINI_MAX), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_RX_JUMBO_MAX), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_TX_MAX), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_RX), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_RX_MINI), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_RX_JUMBO), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_TX), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_RX_BUF_LEN), + NLATTR_DESC_U8_ENUM(ETHTOOL_A_RINGS_TCP_DATA_SPLIT, rings_tcp_data_split), + NLATTR_DESC_U32(ETHTOOL_A_RINGS_CQE_SIZE), + NLATTR_DESC_BOOL(ETHTOOL_A_RINGS_TX_PUSH), +}; + +static const struct pretty_nla_desc __channels_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CHANNELS_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_CHANNELS_HEADER, header), + NLATTR_DESC_U32(ETHTOOL_A_CHANNELS_RX_MAX), + NLATTR_DESC_U32(ETHTOOL_A_CHANNELS_TX_MAX), + NLATTR_DESC_U32(ETHTOOL_A_CHANNELS_OTHER_MAX), + NLATTR_DESC_U32(ETHTOOL_A_CHANNELS_COMBINED_MAX), + NLATTR_DESC_U32(ETHTOOL_A_CHANNELS_RX_COUNT), + NLATTR_DESC_U32(ETHTOOL_A_CHANNELS_TX_COUNT), + NLATTR_DESC_U32(ETHTOOL_A_CHANNELS_OTHER_COUNT), + NLATTR_DESC_U32(ETHTOOL_A_CHANNELS_COMBINED_COUNT), +}; + +static const struct pretty_nla_desc __coalesce_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_COALESCE_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_COALESCE_HEADER, header), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RX_USECS), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RX_MAX_FRAMES), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RX_USECS_IRQ), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_USECS), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_MAX_FRAMES), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_USECS_IRQ), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_STATS_BLOCK_USECS), + NLATTR_DESC_BOOL(ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX), + NLATTR_DESC_BOOL(ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_PKT_RATE_LOW), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RX_USECS_LOW), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_USECS_LOW), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_PKT_RATE_HIGH), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RX_USECS_HIGH), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_USECS_HIGH), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH), + NLATTR_DESC_U32(ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL), + NLATTR_DESC_BOOL(ETHTOOL_A_COALESCE_USE_CQE_MODE_TX), + NLATTR_DESC_BOOL(ETHTOOL_A_COALESCE_USE_CQE_MODE_RX), +}; + +static const struct pretty_nla_desc __pause_stats_desc[] = { + NLATTR_DESC_BINARY(ETHTOOL_A_PAUSE_STAT_PAD), + NLATTR_DESC_U64(ETHTOOL_A_PAUSE_STAT_TX_FRAMES), + NLATTR_DESC_U64(ETHTOOL_A_PAUSE_STAT_RX_FRAMES), +}; + +static const struct pretty_nla_desc __pause_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_PAUSE_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_PAUSE_HEADER, header), + NLATTR_DESC_BOOL(ETHTOOL_A_PAUSE_AUTONEG), + NLATTR_DESC_BOOL(ETHTOOL_A_PAUSE_RX), + NLATTR_DESC_BOOL(ETHTOOL_A_PAUSE_TX), + NLATTR_DESC_NESTED(ETHTOOL_A_PAUSE_STATS, pause_stats), +}; + +static const struct pretty_nla_desc __eee_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_EEE_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_EEE_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_EEE_MODES_OURS, bitset), + NLATTR_DESC_NESTED(ETHTOOL_A_EEE_MODES_PEER, bitset), + NLATTR_DESC_BOOL(ETHTOOL_A_EEE_ACTIVE), + NLATTR_DESC_BOOL(ETHTOOL_A_EEE_ENABLED), + NLATTR_DESC_BOOL(ETHTOOL_A_EEE_TX_LPI_ENABLED), + NLATTR_DESC_U32(ETHTOOL_A_EEE_TX_LPI_TIMER), +}; + +static const struct pretty_nla_desc __tsinfo_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_TSINFO_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_TSINFO_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_TSINFO_TIMESTAMPING, bitset), + NLATTR_DESC_NESTED(ETHTOOL_A_TSINFO_TX_TYPES, bitset), + NLATTR_DESC_NESTED(ETHTOOL_A_TSINFO_RX_FILTERS, bitset), + NLATTR_DESC_U32(ETHTOOL_A_TSINFO_PHC_INDEX), +}; + +static const struct pretty_nla_desc __cable_test_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_TEST_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TEST_HEADER, header), +}; + +static const struct pretty_nla_desc __cable_test_result_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_RESULT_UNSPEC), + NLATTR_DESC_U8(ETHTOOL_A_CABLE_RESULT_PAIR), + NLATTR_DESC_U8(ETHTOOL_A_CABLE_RESULT_CODE), +}; + +static const struct pretty_nla_desc __cable_test_flength_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC), + NLATTR_DESC_U8(ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR), + NLATTR_DESC_U32(ETHTOOL_A_CABLE_FAULT_LENGTH_CM), +}; + +static const struct pretty_nla_desc __cable_nest_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_NEST_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_NEST_RESULT, cable_test_result), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_NEST_FAULT_LENGTH, + cable_test_flength), +}; + +static const struct pretty_nla_desc __cable_test_ntf_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_TEST_NTF_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TEST_NTF_HEADER, header), + NLATTR_DESC_U8(ETHTOOL_A_CABLE_TEST_NTF_STATUS), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TEST_NTF_NEST, cable_nest), +}; + +static const struct pretty_nla_desc __cable_test_tdr_cfg_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_TEST_TDR_CFG_UNSPEC), + NLATTR_DESC_U32(ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST), + NLATTR_DESC_U32(ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST), + NLATTR_DESC_U32(ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP), + NLATTR_DESC_U8(ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR), +}; + +static const struct pretty_nla_desc __cable_test_tdr_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_TEST_TDR_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TEST_TDR_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TEST_TDR_CFG, cable_test_tdr_cfg), +}; + +static const struct pretty_nla_desc __cable_step_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_STEP_UNSPEC), + NLATTR_DESC_U32(ETHTOOL_A_CABLE_STEP_FIRST_DISTANCE), + NLATTR_DESC_U32(ETHTOOL_A_CABLE_STEP_LAST_DISTANCE), + NLATTR_DESC_U32(ETHTOOL_A_CABLE_STEP_STEP_DISTANCE), +}; + +static const struct pretty_nla_desc __cable_amplitude_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_AMPLITUDE_UNSPEC), + NLATTR_DESC_U8(ETHTOOL_A_CABLE_AMPLITUDE_PAIR), + NLATTR_DESC_S16(ETHTOOL_A_CABLE_AMPLITUDE_mV), +}; + +static const struct pretty_nla_desc __cable_pulse_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_PULSE_UNSPEC), + NLATTR_DESC_S16(ETHTOOL_A_CABLE_PULSE_mV), +}; + +static const struct pretty_nla_desc __cable_test_tdr_nest_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_TDR_NEST_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TDR_NEST_STEP, cable_step), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TDR_NEST_AMPLITUDE, cable_amplitude), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TDR_NEST_PULSE, cable_pulse), +}; + +static const struct pretty_nla_desc __cable_test_tdr_ntf_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_CABLE_TEST_TDR_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER, header), + NLATTR_DESC_U8(ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS), + NLATTR_DESC_NESTED(ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST, + cable_test_tdr_nest), +}; + +const struct pretty_nla_desc __tunnel_udp_entry_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_TUNNEL_UDP_ENTRY_UNSPEC), + NLATTR_DESC_U16(ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT), + NLATTR_DESC_U32(ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE), +}; + +const struct pretty_nla_desc __tunnel_udp_table_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_TUNNEL_UDP_TABLE_UNSPEC), + NLATTR_DESC_U32(ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE), + NLATTR_DESC_NESTED(ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES, bitset), + NLATTR_DESC_NESTED(ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY, tunnel_udp_entry), +}; + +const struct pretty_nla_desc __tunnel_udp_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_TUNNEL_UDP_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_TUNNEL_UDP_TABLE, tunnel_udp_table), +}; + +const struct pretty_nla_desc __tunnel_info_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_TUNNEL_INFO_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_TUNNEL_INFO_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_TUNNEL_INFO_UDP_PORTS, tunnel_udp), +}; + +const struct pretty_nla_desc __fec_stats_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_FEC_STAT_UNSPEC), + NLATTR_DESC_BINARY(ETHTOOL_A_FEC_STAT_PAD), + NLATTR_DESC_U64(ETHTOOL_A_FEC_STAT_CORRECTED), + NLATTR_DESC_U64(ETHTOOL_A_FEC_STAT_UNCORR), + NLATTR_DESC_U64(ETHTOOL_A_FEC_STAT_CORR_BITS), +}; + +static const struct pretty_nla_desc __fec_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_FEC_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_FEC_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_FEC_MODES, bitset), + NLATTR_DESC_BOOL(ETHTOOL_A_FEC_AUTO), + NLATTR_DESC_U32(ETHTOOL_A_FEC_ACTIVE), + NLATTR_DESC_NESTED(ETHTOOL_A_FEC_STATS, fec_stats), +}; + +const struct pretty_nla_desc __module_eeprom_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_MODULE_EEPROM_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_MODULE_EEPROM_HEADER, header), + NLATTR_DESC_U32(ETHTOOL_A_MODULE_EEPROM_OFFSET), + NLATTR_DESC_U32(ETHTOOL_A_MODULE_EEPROM_LENGTH), + NLATTR_DESC_U8(ETHTOOL_A_MODULE_EEPROM_PAGE), + NLATTR_DESC_U8(ETHTOOL_A_MODULE_EEPROM_BANK), + NLATTR_DESC_U8(ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS), + NLATTR_DESC_BINARY(ETHTOOL_A_MODULE_EEPROM_DATA) +}; + +static const struct pretty_nla_desc __stats_grp_stat_desc[] = { + NLATTR_DESC_U64(0), NLATTR_DESC_U64(1), NLATTR_DESC_U64(2), + NLATTR_DESC_U64(3), NLATTR_DESC_U64(4), NLATTR_DESC_U64(5), + NLATTR_DESC_U64(6), NLATTR_DESC_U64(7), NLATTR_DESC_U64(8), + NLATTR_DESC_U64(9), NLATTR_DESC_U64(10), NLATTR_DESC_U64(11), + NLATTR_DESC_U64(12), NLATTR_DESC_U64(13), NLATTR_DESC_U64(14), + NLATTR_DESC_U64(15), NLATTR_DESC_U64(16), NLATTR_DESC_U64(17), + NLATTR_DESC_U64(18), NLATTR_DESC_U64(19), NLATTR_DESC_U64(20), + NLATTR_DESC_U64(21), NLATTR_DESC_U64(22), NLATTR_DESC_U64(23), + NLATTR_DESC_U64(24), NLATTR_DESC_U64(25), NLATTR_DESC_U64(26), + NLATTR_DESC_U64(27), NLATTR_DESC_U64(28), NLATTR_DESC_U64(29), +}; + +static const struct pretty_nla_desc __stats_grp_hist_desc[] = { + NLATTR_DESC_U32(ETHTOOL_A_STATS_GRP_HIST_BKT_LOW), + NLATTR_DESC_U32(ETHTOOL_A_STATS_GRP_HIST_BKT_HI), + NLATTR_DESC_U64(ETHTOOL_A_STATS_GRP_HIST_VAL), +}; + +static const struct pretty_nla_desc __stats_grp_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_STATS_GRP_UNSPEC), + NLATTR_DESC_INVALID(ETHTOOL_A_STATS_GRP_PAD), + NLATTR_DESC_U32(ETHTOOL_A_STATS_GRP_ID), + NLATTR_DESC_U32(ETHTOOL_A_STATS_GRP_SS_ID), + NLATTR_DESC_NESTED(ETHTOOL_A_STATS_GRP_STAT, stats_grp_stat), + NLATTR_DESC_NESTED(ETHTOOL_A_STATS_GRP_HIST_RX, stats_grp_hist), + NLATTR_DESC_NESTED(ETHTOOL_A_STATS_GRP_HIST_TX, stats_grp_hist), +}; + +static const struct pretty_nla_desc __stats_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_STATS_UNSPEC), + NLATTR_DESC_INVALID(ETHTOOL_A_STATS_PAD), + NLATTR_DESC_NESTED(ETHTOOL_A_STATS_HEADER, header), + NLATTR_DESC_NESTED(ETHTOOL_A_STATS_GROUPS, bitset), + NLATTR_DESC_NESTED(ETHTOOL_A_STATS_GRP, stats_grp), +}; + +static const struct pretty_nla_desc __phc_vclocks_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_PHC_VCLOCKS_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_PHC_VCLOCKS_HEADER, header), + NLATTR_DESC_U32(ETHTOOL_A_PHC_VCLOCKS_NUM), + NLATTR_DESC_BINARY(ETHTOOL_A_PHC_VCLOCKS_INDEX), +}; + +static const struct pretty_nla_desc __module_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_MODULE_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_MODULE_HEADER, header), + NLATTR_DESC_U8(ETHTOOL_A_MODULE_POWER_MODE_POLICY), + NLATTR_DESC_U8(ETHTOOL_A_MODULE_POWER_MODE), +}; + +static const char *__pse_admin_state_names[] = { + [ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN] = "ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN", + [ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED] = "ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED", + [ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED] = "ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED", +}; + +static const char *__pse_pw_d_status_names[] = { + [ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN] = "ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN", + [ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED] = "ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED", + [ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING] = "ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING", + [ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING] = "ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING", + [ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP] = "ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP", + [ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE] = "ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE", + [ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR] = "ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR", +}; + +static const struct pretty_nla_desc __pse_desc[] = { + NLATTR_DESC_INVALID(ETHTOOL_A_PSE_UNSPEC), + NLATTR_DESC_NESTED(ETHTOOL_A_PSE_HEADER, header), + NLATTR_DESC_U32_ENUM(ETHTOOL_A_PODL_PSE_ADMIN_STATE, pse_admin_state), + NLATTR_DESC_U32_ENUM(ETHTOOL_A_PODL_PSE_ADMIN_CONTROL, pse_admin_state), + NLATTR_DESC_U32_ENUM(ETHTOOL_A_PODL_PSE_PW_D_STATUS, pse_pw_d_status), +}; + +const struct pretty_nlmsg_desc ethnl_umsg_desc[] = { + NLMSG_DESC_INVALID(ETHTOOL_MSG_USER_NONE), + NLMSG_DESC(ETHTOOL_MSG_STRSET_GET, strset), + NLMSG_DESC(ETHTOOL_MSG_LINKINFO_GET, linkinfo), + NLMSG_DESC(ETHTOOL_MSG_LINKINFO_SET, linkinfo), + NLMSG_DESC(ETHTOOL_MSG_LINKMODES_GET, linkmodes), + NLMSG_DESC(ETHTOOL_MSG_LINKMODES_SET, linkmodes), + NLMSG_DESC(ETHTOOL_MSG_LINKSTATE_GET, linkstate), + NLMSG_DESC(ETHTOOL_MSG_DEBUG_GET, debug), + NLMSG_DESC(ETHTOOL_MSG_DEBUG_SET, debug), + NLMSG_DESC(ETHTOOL_MSG_WOL_GET, wol), + NLMSG_DESC(ETHTOOL_MSG_WOL_SET, wol), + NLMSG_DESC(ETHTOOL_MSG_FEATURES_GET, features), + NLMSG_DESC(ETHTOOL_MSG_FEATURES_SET, features), + NLMSG_DESC(ETHTOOL_MSG_PRIVFLAGS_GET, privflags), + NLMSG_DESC(ETHTOOL_MSG_PRIVFLAGS_SET, privflags), + NLMSG_DESC(ETHTOOL_MSG_RINGS_GET, rings), + NLMSG_DESC(ETHTOOL_MSG_RINGS_SET, rings), + NLMSG_DESC(ETHTOOL_MSG_CHANNELS_GET, channels), + NLMSG_DESC(ETHTOOL_MSG_CHANNELS_SET, channels), + NLMSG_DESC(ETHTOOL_MSG_COALESCE_GET, coalesce), + NLMSG_DESC(ETHTOOL_MSG_COALESCE_SET, coalesce), + NLMSG_DESC(ETHTOOL_MSG_PAUSE_GET, pause), + NLMSG_DESC(ETHTOOL_MSG_PAUSE_SET, pause), + NLMSG_DESC(ETHTOOL_MSG_EEE_GET, eee), + NLMSG_DESC(ETHTOOL_MSG_EEE_SET, eee), + NLMSG_DESC(ETHTOOL_MSG_TSINFO_GET, tsinfo), + NLMSG_DESC(ETHTOOL_MSG_CABLE_TEST_ACT, cable_test), + NLMSG_DESC(ETHTOOL_MSG_CABLE_TEST_TDR_ACT, cable_test_tdr), + NLMSG_DESC(ETHTOOL_MSG_TUNNEL_INFO_GET, tunnel_info), + NLMSG_DESC(ETHTOOL_MSG_FEC_GET, fec), + NLMSG_DESC(ETHTOOL_MSG_FEC_SET, fec), + NLMSG_DESC(ETHTOOL_MSG_MODULE_EEPROM_GET, module_eeprom), + NLMSG_DESC(ETHTOOL_MSG_STATS_GET, stats), + NLMSG_DESC(ETHTOOL_MSG_PHC_VCLOCKS_GET, phc_vclocks), + NLMSG_DESC(ETHTOOL_MSG_MODULE_GET, module), + NLMSG_DESC(ETHTOOL_MSG_MODULE_SET, module), + NLMSG_DESC(ETHTOOL_MSG_PSE_GET, pse), + NLMSG_DESC(ETHTOOL_MSG_PSE_SET, pse), +}; + +const unsigned int ethnl_umsg_n_desc = ARRAY_SIZE(ethnl_umsg_desc); + +const struct pretty_nlmsg_desc ethnl_kmsg_desc[] = { + NLMSG_DESC_INVALID(ETHTOOL_MSG_KERNEL_NONE), + NLMSG_DESC(ETHTOOL_MSG_STRSET_GET_REPLY, strset), + NLMSG_DESC(ETHTOOL_MSG_LINKINFO_GET_REPLY, linkinfo), + NLMSG_DESC(ETHTOOL_MSG_LINKINFO_NTF, linkinfo), + NLMSG_DESC(ETHTOOL_MSG_LINKMODES_GET_REPLY, linkmodes), + NLMSG_DESC(ETHTOOL_MSG_LINKMODES_NTF, linkmodes), + NLMSG_DESC(ETHTOOL_MSG_LINKSTATE_GET_REPLY, linkstate), + NLMSG_DESC(ETHTOOL_MSG_DEBUG_GET_REPLY, debug), + NLMSG_DESC(ETHTOOL_MSG_DEBUG_NTF, debug), + NLMSG_DESC(ETHTOOL_MSG_WOL_GET_REPLY, wol), + NLMSG_DESC(ETHTOOL_MSG_WOL_NTF, wol), + NLMSG_DESC(ETHTOOL_MSG_FEATURES_GET_REPLY, features), + NLMSG_DESC(ETHTOOL_MSG_FEATURES_SET_REPLY, features), + NLMSG_DESC(ETHTOOL_MSG_FEATURES_NTF, features), + NLMSG_DESC(ETHTOOL_MSG_PRIVFLAGS_GET_REPLY, privflags), + NLMSG_DESC(ETHTOOL_MSG_PRIVFLAGS_NTF, privflags), + NLMSG_DESC(ETHTOOL_MSG_RINGS_GET_REPLY, rings), + NLMSG_DESC(ETHTOOL_MSG_RINGS_NTF, rings), + NLMSG_DESC(ETHTOOL_MSG_CHANNELS_GET_REPLY, channels), + NLMSG_DESC(ETHTOOL_MSG_CHANNELS_NTF, channels), + NLMSG_DESC(ETHTOOL_MSG_COALESCE_GET_REPLY, coalesce), + NLMSG_DESC(ETHTOOL_MSG_COALESCE_NTF, coalesce), + NLMSG_DESC(ETHTOOL_MSG_PAUSE_GET_REPLY, pause), + NLMSG_DESC(ETHTOOL_MSG_PAUSE_NTF, pause), + NLMSG_DESC(ETHTOOL_MSG_EEE_GET_REPLY, eee), + NLMSG_DESC(ETHTOOL_MSG_EEE_NTF, eee), + NLMSG_DESC(ETHTOOL_MSG_TSINFO_GET_REPLY, tsinfo), + NLMSG_DESC(ETHTOOL_MSG_CABLE_TEST_NTF, cable_test_ntf), + NLMSG_DESC(ETHTOOL_MSG_CABLE_TEST_TDR_NTF, cable_test_tdr_ntf), + NLMSG_DESC(ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY, tunnel_info), + NLMSG_DESC(ETHTOOL_MSG_FEC_GET_REPLY, fec), + NLMSG_DESC(ETHTOOL_MSG_FEC_NTF, fec), + NLMSG_DESC(ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY, module_eeprom), + NLMSG_DESC(ETHTOOL_MSG_STATS_GET_REPLY, stats), + NLMSG_DESC(ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY, phc_vclocks), + NLMSG_DESC(ETHTOOL_MSG_MODULE_GET_REPLY, module), + NLMSG_DESC(ETHTOOL_MSG_MODULE_NTF, module), + NLMSG_DESC(ETHTOOL_MSG_PSE_GET_REPLY, pse), +}; + +const unsigned int ethnl_kmsg_n_desc = ARRAY_SIZE(ethnl_kmsg_desc); diff --git a/netlink/desc-genlctrl.c b/netlink/desc-genlctrl.c new file mode 100644 index 0000000..43b41ab --- /dev/null +++ b/netlink/desc-genlctrl.c @@ -0,0 +1,113 @@ +/* + * desc-genlctrl.c - genetlink control format descriptions + * + * Descriptions of genetlink control messages and attributes for pretty print. + */ + +#include + +#include "../internal.h" +#include "prettymsg.h" + +static const struct pretty_nla_desc __attrop_desc[] = { + NLATTR_DESC_INVALID(CTRL_ATTR_OP_UNSPEC), + NLATTR_DESC_U32(CTRL_ATTR_OP_ID), + NLATTR_DESC_X32(CTRL_ATTR_OP_FLAGS), +}; + +static const struct pretty_nla_desc __attrops_desc[] = { + NLATTR_DESC_NESTED(0, attrop), +}; + +static const struct pretty_nla_desc __mcgrp_desc[] = { + NLATTR_DESC_INVALID(CTRL_ATTR_MCAST_GRP_UNSPEC), + NLATTR_DESC_STRING(CTRL_ATTR_MCAST_GRP_NAME), + NLATTR_DESC_U32(CTRL_ATTR_MCAST_GRP_ID), +}; + +static const struct pretty_nla_desc __mcgrps_desc[] = { + NLATTR_DESC_NESTED(0, mcgrp), +}; + +static const char *__policy_attr_type_names[] = { + [NL_ATTR_TYPE_INVALID] = "NL_ATTR_TYPE_INVALID", + [NL_ATTR_TYPE_FLAG] = "NL_ATTR_TYPE_FLAG", + [NL_ATTR_TYPE_U8] = "NL_ATTR_TYPE_U8", + [NL_ATTR_TYPE_U16] = "NL_ATTR_TYPE_U16", + [NL_ATTR_TYPE_U32] = "NL_ATTR_TYPE_U32", + [NL_ATTR_TYPE_U64] = "NL_ATTR_TYPE_U64", + [NL_ATTR_TYPE_S8] = "NL_ATTR_TYPE_S8", + [NL_ATTR_TYPE_S16] = "NL_ATTR_TYPE_S16", + [NL_ATTR_TYPE_S32] = "NL_ATTR_TYPE_S32", + [NL_ATTR_TYPE_S64] = "NL_ATTR_TYPE_S64", + [NL_ATTR_TYPE_BINARY] = "NL_ATTR_TYPE_BINARY", + [NL_ATTR_TYPE_STRING] = "NL_ATTR_TYPE_STRING", + [NL_ATTR_TYPE_NUL_STRING] = "NL_ATTR_TYPE_NUL_STRING", + [NL_ATTR_TYPE_NESTED] = "NL_ATTR_TYPE_NESTED", + [NL_ATTR_TYPE_NESTED_ARRAY] = "NL_ATTR_TYPE_NESTED_ARRAY", + [NL_ATTR_TYPE_BITFIELD32] = "NL_ATTR_TYPE_BITFIELD32", +}; + +static const struct pretty_nla_desc __policy_attr_desc[] = { + NLATTR_DESC_INVALID(NL_POLICY_TYPE_ATTR_UNSPEC), + NLATTR_DESC_U32_ENUM(NL_POLICY_TYPE_ATTR_TYPE, policy_attr_type), + NLATTR_DESC_S64(NL_POLICY_TYPE_ATTR_MIN_VALUE_S), + NLATTR_DESC_S64(NL_POLICY_TYPE_ATTR_MAX_VALUE_S), + NLATTR_DESC_U64(NL_POLICY_TYPE_ATTR_MIN_VALUE_U), + NLATTR_DESC_U64(NL_POLICY_TYPE_ATTR_MAX_VALUE_U), + NLATTR_DESC_U32(NL_POLICY_TYPE_ATTR_MIN_LENGTH), + NLATTR_DESC_U32(NL_POLICY_TYPE_ATTR_MAX_LENGTH), + NLATTR_DESC_U32(NL_POLICY_TYPE_ATTR_POLICY_IDX), + NLATTR_DESC_U32(NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE), + NLATTR_DESC_X32(NL_POLICY_TYPE_ATTR_BITFIELD32_MASK), + NLATTR_DESC_X64(NL_POLICY_TYPE_ATTR_PAD), + NLATTR_DESC_BINARY(NL_POLICY_TYPE_ATTR_MASK), +}; + +static const struct pretty_nla_desc __policy_attrs_desc[] = { + NLATTR_DESC_NESTED(0, policy_attr), +}; + +static const struct pretty_nla_desc __policies_desc[] = { + NLATTR_DESC_ARRAY(0, policy_attrs), +}; + +static const struct pretty_nla_desc __op_policy_desc[] = { + NLATTR_DESC_INVALID(CTRL_ATTR_POLICY_UNSPEC), + NLATTR_DESC_U32(CTRL_ATTR_POLICY_DO), + NLATTR_DESC_U32(CTRL_ATTR_POLICY_DUMP), +}; + +static const struct pretty_nla_desc __op_policies_desc[] = { + NLATTR_DESC_NESTED(0, op_policy), +}; + +static const struct pretty_nla_desc __attr_desc[] = { + NLATTR_DESC_INVALID(CTRL_ATTR_UNSPEC), + NLATTR_DESC_U16(CTRL_ATTR_FAMILY_ID), + NLATTR_DESC_STRING(CTRL_ATTR_FAMILY_NAME), + NLATTR_DESC_U32(CTRL_ATTR_VERSION), + NLATTR_DESC_U32(CTRL_ATTR_HDRSIZE), + NLATTR_DESC_U32(CTRL_ATTR_MAXATTR), + NLATTR_DESC_ARRAY(CTRL_ATTR_OPS, attrops), + NLATTR_DESC_ARRAY(CTRL_ATTR_MCAST_GROUPS, mcgrps), + NLATTR_DESC_ARRAY(CTRL_ATTR_POLICY, policies), + NLATTR_DESC_ARRAY(CTRL_ATTR_OP_POLICY, op_policies), + NLATTR_DESC_U32(CTRL_ATTR_OP), +}; + +const struct pretty_nlmsg_desc genlctrl_msg_desc[] = { + NLMSG_DESC_INVALID(CTRL_CMD_UNSPEC), + NLMSG_DESC(CTRL_CMD_NEWFAMILY, attr), + NLMSG_DESC(CTRL_CMD_DELFAMILY, attr), + NLMSG_DESC(CTRL_CMD_GETFAMILY, attr), + NLMSG_DESC(CTRL_CMD_NEWOPS, attr), + NLMSG_DESC(CTRL_CMD_DELOPS, attr), + NLMSG_DESC(CTRL_CMD_GETOPS, attr), + NLMSG_DESC(CTRL_CMD_NEWMCAST_GRP, attr), + NLMSG_DESC(CTRL_CMD_DELMCAST_GRP, attr), + NLMSG_DESC(CTRL_CMD_GETMCAST_GRP, attr), + NLMSG_DESC(CTRL_CMD_GETPOLICY, attr), +}; + +const unsigned int genlctrl_msg_n_desc = ARRAY_SIZE(genlctrl_msg_desc); diff --git a/netlink/desc-rtnl.c b/netlink/desc-rtnl.c new file mode 100644 index 0000000..e15e6f0 --- /dev/null +++ b/netlink/desc-rtnl.c @@ -0,0 +1,96 @@ +/* + * desc-rtnl.c - rtnetlink message descriptions + * + * Descriptions of rtnetlink messages and attributes for pretty print. + */ + +#include + +#include "../internal.h" +#include "prettymsg.h" + +static const struct pretty_nla_desc __link_desc[] = { + NLATTR_DESC_INVALID(IFLA_UNSPEC), + NLATTR_DESC_BINARY(IFLA_ADDRESS), + NLATTR_DESC_BINARY(IFLA_BROADCAST), + NLATTR_DESC_STRING(IFLA_IFNAME), + NLATTR_DESC_U32(IFLA_MTU), + NLATTR_DESC_U32(IFLA_LINK), + NLATTR_DESC_STRING(IFLA_QDISC), + NLATTR_DESC_BINARY(IFLA_STATS), + NLATTR_DESC_INVALID(IFLA_COST), + NLATTR_DESC_INVALID(IFLA_PRIORITY), + NLATTR_DESC_U32(IFLA_MASTER), + NLATTR_DESC_BINARY(IFLA_WIRELESS), + NLATTR_DESC_NESTED_NODESC(IFLA_PROTINFO), + NLATTR_DESC_U32(IFLA_TXQLEN), + NLATTR_DESC_BINARY(IFLA_MAP), + NLATTR_DESC_U32(IFLA_WEIGHT), + NLATTR_DESC_U8(IFLA_OPERSTATE), + NLATTR_DESC_U8(IFLA_LINKMODE), + NLATTR_DESC_NESTED_NODESC(IFLA_LINKINFO), + NLATTR_DESC_U32(IFLA_NET_NS_PID), + NLATTR_DESC_STRING(IFLA_IFALIAS), + NLATTR_DESC_U32(IFLA_NUM_VF), + NLATTR_DESC_NESTED_NODESC(IFLA_VFINFO_LIST), + NLATTR_DESC_BINARY(IFLA_STATS64), + NLATTR_DESC_NESTED_NODESC(IFLA_VF_PORTS), + NLATTR_DESC_NESTED_NODESC(IFLA_PORT_SELF), + NLATTR_DESC_NESTED_NODESC(IFLA_AF_SPEC), + NLATTR_DESC_U32(IFLA_GROUP), + NLATTR_DESC_U32(IFLA_NET_NS_FD), + NLATTR_DESC_U32(IFLA_EXT_MASK), + NLATTR_DESC_U32(IFLA_PROMISCUITY), + NLATTR_DESC_U32(IFLA_NUM_TX_QUEUES), + NLATTR_DESC_U32(IFLA_NUM_RX_QUEUES), + NLATTR_DESC_U8(IFLA_CARRIER), + NLATTR_DESC_BINARY(IFLA_PHYS_PORT_ID), + NLATTR_DESC_U32(IFLA_CARRIER_CHANGES), + NLATTR_DESC_BINARY(IFLA_PHYS_SWITCH_ID), + NLATTR_DESC_S32(IFLA_LINK_NETNSID), + NLATTR_DESC_STRING(IFLA_PHYS_PORT_NAME), + NLATTR_DESC_U8(IFLA_PROTO_DOWN), + NLATTR_DESC_U32(IFLA_GSO_MAX_SEGS), + NLATTR_DESC_U32(IFLA_GSO_MAX_SIZE), + NLATTR_DESC_BINARY(IFLA_PAD), + NLATTR_DESC_U32(IFLA_XDP), + NLATTR_DESC_U32(IFLA_EVENT), + NLATTR_DESC_S32(IFLA_NEW_NETNSID), + NLATTR_DESC_S32(IFLA_IF_NETNSID), + NLATTR_DESC_U32(IFLA_CARRIER_UP_COUNT), + NLATTR_DESC_U32(IFLA_CARRIER_DOWN_COUNT), + NLATTR_DESC_S32(IFLA_NEW_IFINDEX), + NLATTR_DESC_U32(IFLA_MIN_MTU), + NLATTR_DESC_U32(IFLA_MAX_MTU), + NLATTR_DESC_NESTED_NODESC(IFLA_PROP_LIST), + NLATTR_DESC_STRING(IFLA_ALT_IFNAME), + NLATTR_DESC_BINARY(IFLA_PERM_ADDRESS), +}; + +const struct pretty_nlmsg_desc rtnl_msg_desc[] = { + NLMSG_DESC(RTM_NEWLINK, link), + NLMSG_DESC(RTM_DELLINK, link), + NLMSG_DESC(RTM_GETLINK, link), + NLMSG_DESC(RTM_SETLINK, link), +}; + +const unsigned int rtnl_msg_n_desc = ARRAY_SIZE(rtnl_msg_desc); + +#define RTNL_MSGHDR_LEN(_name, _struct) \ + [((RTM_ ## _name) - RTM_BASE) / 4] = sizeof(struct _struct) +#define RTNL_MSGHDR_NOLEN(_name) \ + [((RTM_ ## _name) - RTM_BASE) / 4] = USHRT_MAX + +const unsigned short rtnl_msghdr_lengths[] = { + RTNL_MSGHDR_LEN(NEWLINK, ifinfomsg), + RTNL_MSGHDR_LEN(NEWADDR, ifaddrmsg), + RTNL_MSGHDR_LEN(NEWROUTE, rtmsg), + RTNL_MSGHDR_LEN(NEWNEIGH, ndmsg), + RTNL_MSGHDR_LEN(NEWRULE, rtmsg), + RTNL_MSGHDR_LEN(NEWQDISC, tcmsg), + RTNL_MSGHDR_LEN(NEWTCLASS, tcmsg), + RTNL_MSGHDR_LEN(NEWTFILTER, tcmsg), + RTNL_MSGHDR_LEN(NEWACTION, tcamsg), +}; + +const unsigned int rtnl_msghdr_n_len = ARRAY_SIZE(rtnl_msghdr_lengths); diff --git a/netlink/eee.c b/netlink/eee.c new file mode 100644 index 0000000..04d8f0b --- /dev/null +++ b/netlink/eee.c @@ -0,0 +1,189 @@ +/* + * eee.c - netlink implementation of eee commands + * + * Implementation of "ethtool --show-eee " and + * "ethtool --set-eee ..." + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "bitset.h" +#include "parser.h" + +/* EEE_GET */ + +int eee_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_EEE_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + bool enabled, active, tx_lpi_enabled; + struct nl_context *nlctx = data; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_EEE_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (!tb[ETHTOOL_A_EEE_MODES_OURS] || + !tb[ETHTOOL_A_EEE_ACTIVE] || !tb[ETHTOOL_A_EEE_ENABLED] || + !tb[ETHTOOL_A_EEE_TX_LPI_ENABLED] || + !tb[ETHTOOL_A_EEE_TX_LPI_TIMER]) { + fprintf(stderr, "Malformed response from kernel\n"); + return err_ret; + } + active = mnl_attr_get_u8(tb[ETHTOOL_A_EEE_ACTIVE]); + enabled = mnl_attr_get_u8(tb[ETHTOOL_A_EEE_ENABLED]); + tx_lpi_enabled = mnl_attr_get_u8(tb[ETHTOOL_A_EEE_TX_LPI_ENABLED]); + + if (silent) + putchar('\n'); + printf("EEE settings for %s:\n", nlctx->devname); + printf("\tEEE status: "); + if (bitset_is_empty(tb[ETHTOOL_A_EEE_MODES_OURS], true, &ret)) { + printf("not supported\n"); + return MNL_CB_OK; + } + if (!enabled) + printf("disabled\n"); + else + printf("enabled - %s\n", active ? "active" : "inactive"); + printf("\tTx LPI: "); + if (tx_lpi_enabled) + printf("%u (us)\n", + mnl_attr_get_u32(tb[ETHTOOL_A_EEE_TX_LPI_TIMER])); + else + printf("disabled\n"); + + ret = dump_link_modes(nlctx, tb[ETHTOOL_A_EEE_MODES_OURS], true, + LM_CLASS_REAL, + "Supported EEE link modes: ", NULL, "\n", + "Not reported"); + if (ret < 0) + return err_ret; + ret = dump_link_modes(nlctx, tb[ETHTOOL_A_EEE_MODES_OURS], false, + LM_CLASS_REAL, + "Advertised EEE link modes: ", NULL, "\n", + "Not reported"); + if (ret < 0) + return err_ret; + ret = dump_link_modes(nlctx, tb[ETHTOOL_A_EEE_MODES_PEER], false, + LM_CLASS_REAL, + "Link partner advertised EEE link modes: ", NULL, + "\n", "Not reported"); + if (ret < 0) + return err_ret; + + return MNL_CB_OK; +} + +int nl_geee(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_EEE_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_EEE_GET, + ETHTOOL_A_EEE_HEADER, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, eee_reply_cb); +} + +/* EEE_SET */ + +static const struct bitset_parser_data advertise_parser_data = { + .no_mask = false, + .force_hex = true, +}; + +static const struct param_parser seee_params[] = { + { + .arg = "advertise", + .type = ETHTOOL_A_EEE_MODES_OURS, + .handler = nl_parse_bitset, + .handler_data = &advertise_parser_data, + .min_argc = 1, + }, + { + .arg = "tx-lpi", + .type = ETHTOOL_A_EEE_TX_LPI_ENABLED, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "tx-timer", + .type = ETHTOOL_A_EEE_TX_LPI_TIMER, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "eee", + .type = ETHTOOL_A_EEE_ENABLED, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + {} +}; + +int nl_seee(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_EEE_SET, false)) + return -EOPNOTSUPP; + if (!ctx->argc) { + fprintf(stderr, "ethtool (--set-eee): parameters missing\n"); + return 1; + } + + nlctx->cmd = "--set-eee"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_EEE_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_EEE_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, seee_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 76; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 76; +} diff --git a/netlink/extapi.h b/netlink/extapi.h new file mode 100644 index 0000000..1bb580a --- /dev/null +++ b/netlink/extapi.h @@ -0,0 +1,120 @@ +/* + * extapi.h - external interface of netlink code + * + * Declarations needed by non-netlink code (mostly ethtool.c). + */ + +#ifndef ETHTOOL_EXTAPI_H__ +#define ETHTOOL_EXTAPI_H__ + +struct cmd_context; +struct nl_context; + +typedef int (*nl_func_t)(struct cmd_context *); +typedef bool (*nl_chk_t)(struct cmd_context *); + +#ifdef ETHTOOL_ENABLE_NETLINK + +void netlink_run_handler(struct cmd_context *ctx, nl_chk_t nlchk, + nl_func_t nlfunc, bool no_fallback); + +int nl_gset(struct cmd_context *ctx); +int nl_sset(struct cmd_context *ctx); +int nl_permaddr(struct cmd_context *ctx); +int nl_gfeatures(struct cmd_context *ctx); +int nl_sfeatures(struct cmd_context *ctx); +int nl_gprivflags(struct cmd_context *ctx); +int nl_sprivflags(struct cmd_context *ctx); +int nl_gring(struct cmd_context *ctx); +int nl_sring(struct cmd_context *ctx); +int nl_gchannels(struct cmd_context *ctx); +int nl_schannels(struct cmd_context *ctx); +int nl_gcoalesce(struct cmd_context *ctx); +int nl_scoalesce(struct cmd_context *ctx); +int nl_gpause(struct cmd_context *ctx); +int nl_spause(struct cmd_context *ctx); +int nl_geee(struct cmd_context *ctx); +int nl_seee(struct cmd_context *ctx); +int nl_tsinfo(struct cmd_context *ctx); +int nl_cable_test(struct cmd_context *ctx); +int nl_cable_test_tdr(struct cmd_context *ctx); +int nl_gtunnels(struct cmd_context *ctx); +int nl_gfec(struct cmd_context *ctx); +int nl_sfec(struct cmd_context *ctx); +bool nl_gstats_chk(struct cmd_context *ctx); +int nl_gstats(struct cmd_context *ctx); +int nl_gmodule(struct cmd_context *ctx); +int nl_smodule(struct cmd_context *ctx); +int nl_monitor(struct cmd_context *ctx); +int nl_getmodule(struct cmd_context *ctx); + +void nl_monitor_usage(void); + +int nl_get_eeprom_page(struct cmd_context *ctx, + struct ethtool_module_eeprom *request); + +#else /* ETHTOOL_ENABLE_NETLINK */ + +static inline void netlink_run_handler(struct cmd_context *ctx __maybe_unused, + nl_chk_t nlchk __maybe_unused, + nl_func_t nlfunc __maybe_unused, + bool no_fallback) +{ + if (no_fallback) { + fprintf(stderr, + "Command requires kernel netlink support which is not " + "enabled in this ethtool binary\n"); + exit(1); + } +} + +static inline int nl_monitor(struct cmd_context *ctx __maybe_unused) +{ + fprintf(stderr, "Netlink not supported by ethtool, option --monitor unsupported.\n"); + return -EOPNOTSUPP; +} + +static inline void nl_monitor_usage(void) +{ +} + +static inline int +nl_get_eeprom_page(struct cmd_context *ctx __maybe_unused, + struct ethtool_module_eeprom *request __maybe_unused) +{ + fprintf(stderr, "Netlink not supported by ethtool.\n"); + return -EOPNOTSUPP; +} + +#define nl_gset NULL +#define nl_sset NULL +#define nl_permaddr NULL +#define nl_gfeatures NULL +#define nl_sfeatures NULL +#define nl_gprivflags NULL +#define nl_sprivflags NULL +#define nl_gring NULL +#define nl_sring NULL +#define nl_gchannels NULL +#define nl_schannels NULL +#define nl_gcoalesce NULL +#define nl_scoalesce NULL +#define nl_gpause NULL +#define nl_spause NULL +#define nl_geee NULL +#define nl_seee NULL +#define nl_tsinfo NULL +#define nl_cable_test NULL +#define nl_cable_test_tdr NULL +#define nl_gtunnels NULL +#define nl_gfec NULL +#define nl_sfec NULL +#define nl_gstats_chk NULL +#define nl_gstats NULL +#define nl_getmodule NULL +#define nl_gmodule NULL +#define nl_smodule NULL + +#endif /* ETHTOOL_ENABLE_NETLINK */ + +#endif /* ETHTOOL_EXTAPI_H__ */ diff --git a/netlink/features.c b/netlink/features.c new file mode 100644 index 0000000..a4dae8f --- /dev/null +++ b/netlink/features.c @@ -0,0 +1,557 @@ +/* + * features.c - netlink implementation of netdev features commands + * + * Implementation of "ethtool -k ". + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "strset.h" +#include "bitset.h" + +/* FEATURES_GET */ + +struct feature_results { + uint32_t *hw; + uint32_t *wanted; + uint32_t *active; + uint32_t *nochange; + unsigned int count; + unsigned int words; +}; + +static int prepare_feature_results(const struct nlattr *const *tb, + struct feature_results *dest) +{ + unsigned int count; + int ret; + + memset(dest, '\0', sizeof(*dest)); + if (!tb[ETHTOOL_A_FEATURES_HW] || !tb[ETHTOOL_A_FEATURES_WANTED] || + !tb[ETHTOOL_A_FEATURES_ACTIVE] || !tb[ETHTOOL_A_FEATURES_NOCHANGE]) + return -EFAULT; + count = bitset_get_count(tb[ETHTOOL_A_FEATURES_HW], &ret); + if (ret < 0) + return -EFAULT; + if ((bitset_get_count(tb[ETHTOOL_A_FEATURES_WANTED], &ret) != count) || + (bitset_get_count(tb[ETHTOOL_A_FEATURES_ACTIVE], &ret) != count) || + (bitset_get_count(tb[ETHTOOL_A_FEATURES_NOCHANGE], &ret) != count)) + return -EFAULT; + dest->hw = get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_HW]); + dest->wanted = get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_WANTED]); + dest->active = get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_ACTIVE]); + dest->nochange = + get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_NOCHANGE]); + if (!dest->hw || !dest->wanted || !dest->active || !dest->nochange) + return -EFAULT; + dest->count = count; + dest->words = (count + 31) / 32; + + return 0; +} + +static bool feature_on(const uint32_t *bitmap, unsigned int idx) +{ + return bitmap[idx / 32] & (1 << (idx % 32)); +} + +static void dump_feature(const struct feature_results *results, + const uint32_t *ref, const uint32_t *ref_mask, + unsigned int idx, const char *name, const char *prefix) +{ + const char *suffix = ""; + + if (!name || !*name) + return; + if (ref) { + if (ref_mask && !feature_on(ref_mask, idx)) + return; + if ((!ref_mask || feature_on(ref_mask, idx)) && + (feature_on(results->active, idx) == feature_on(ref, idx))) + return; + } + + if (!feature_on(results->hw, idx) || feature_on(results->nochange, idx)) + suffix = " [fixed]"; + else if (feature_on(results->active, idx) != + feature_on(results->wanted, idx)) + suffix = feature_on(results->wanted, idx) ? + " [requested on]" : " [requested off]"; + if (is_json_context()) { + open_json_object(name); + print_bool(PRINT_JSON, "active", NULL, feature_on(results->active, idx)); + print_bool(PRINT_JSON, "fixed", NULL, + (!feature_on(results->hw, idx) || feature_on(results->nochange, idx))); + print_bool(PRINT_JSON, "requested", NULL, feature_on(results->wanted, idx)); + close_json_object(); + } else { + printf("%s%s: %s%s\n", prefix, name, + feature_on(results->active, idx) ? "on" : "off", suffix); + } +} + +/* this assumes pattern contains no more than one asterisk */ +static bool flag_pattern_match(const char *name, const char *pattern) +{ + const char *p_ast = strchr(pattern, '*'); + + if (p_ast) { + size_t name_len = strlen(name); + size_t pattern_len = strlen(pattern); + + if (name_len + 1 < pattern_len) + return false; + if (strncmp(name, pattern, p_ast - pattern)) + return false; + pattern_len -= (p_ast - pattern) + 1; + name += name_len - pattern_len; + pattern = p_ast + 1; + } + return !strcmp(name, pattern); +} + +int dump_features(const struct nlattr *const *tb, + const struct stringset *feature_names) +{ + unsigned int *feature_flags = NULL; + struct feature_results results; + unsigned int i, j; + int ret; + + ret = prepare_feature_results(tb, &results); + if (ret < 0) + return -EFAULT; + feature_flags = calloc(results.count, sizeof(feature_flags[0])); + if (!feature_flags) + return -ENOMEM; + + /* map netdev features to legacy flags */ + for (i = 0; i < results.count; i++) { + const char *name = get_string(feature_names, i); + feature_flags[i] = UINT_MAX; + + if (!name || !*name) + continue; + for (j = 0; j < OFF_FLAG_DEF_SIZE; j++) { + const char *flag_name = off_flag_def[j].kernel_name; + + if (flag_pattern_match(name, flag_name)) { + feature_flags[i] = j; + break; + } + } + } + /* show legacy flags and their matching features first */ + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { + unsigned int n_match = 0; + bool flag_value = false; + + /* no kernel with netlink interface supports UFO */ + if (off_flag_def[i].value == ETH_FLAG_UFO) + continue; + + for (j = 0; j < results.count; j++) { + if (feature_flags[j] == i) { + n_match++; + flag_value = flag_value || + feature_on(results.active, j); + } + } + if (n_match != 1) { + if (is_json_context()) { + open_json_object(off_flag_def[i].long_name); + print_bool(PRINT_JSON, "active", NULL, flag_value); + print_null(PRINT_JSON, "fixed", NULL, NULL); + print_null(PRINT_JSON, "requested", NULL, NULL); + close_json_object(); + } else { + printf("%s: %s\n", off_flag_def[i].long_name, + flag_value ? "on" : "off"); + } + } + if (n_match == 0) + continue; + for (j = 0; j < results.count; j++) { + const char *name = get_string(feature_names, j); + + if (feature_flags[j] != i) + continue; + if (n_match == 1) + dump_feature(&results, NULL, NULL, j, + off_flag_def[i].long_name, ""); + else + dump_feature(&results, NULL, NULL, j, name, + "\t"); + } + } + /* and, finally, remaining netdev_features not matching legacy flags */ + for (i = 0; i < results.count; i++) { + const char *name = get_string(feature_names, i); + + if (!name || !*name || feature_flags[i] != UINT_MAX) + continue; + dump_feature(&results, NULL, NULL, i, name, ""); + } + + free(feature_flags); + return 0; +} + +int features_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + const struct stringset *feature_names; + struct nl_context *nlctx = data; + bool silent; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + if (!nlctx->is_monitor) { + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + return MNL_CB_ERROR; + } + feature_names = global_stringset(ETH_SS_FEATURES, nlctx->ethnl2_socket); + + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return silent ? MNL_CB_OK : MNL_CB_ERROR; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_FEATURES_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + if (silent) + putchar('\n'); + open_json_object(NULL); + print_string(PRINT_ANY, "ifname", "Features for %s:\n", nlctx->devname); + ret = dump_features(tb, feature_names); + close_json_object(); + return (silent || !ret) ? MNL_CB_OK : MNL_CB_ERROR; +} + +int nl_gfeatures(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_FEATURES_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_FEATURES_GET, + ETHTOOL_A_FEATURES_HEADER, + ETHTOOL_FLAG_COMPACT_BITSETS); + if (ret < 0) + return ret; + + new_json_obj(ctx->json); + ret = nlsock_send_get_request(nlsk, features_reply_cb); + delete_json_obj(); + + return ret; +} + +/* FEATURES_SET */ + +struct sfeatures_context { + bool nothing_changed; + uint32_t req_mask[0]; +}; + +static int find_feature(const char *name, + const struct stringset *feature_names) +{ + const unsigned int count = get_count(feature_names); + unsigned int i; + + for (i = 0; i < count; i++) + if (!strcmp(name, get_string(feature_names, i))) + return i; + + return -1; +} + +static int fill_feature(struct nl_msg_buff *msgbuff, const char *name, bool val) +{ + struct nlattr *bit_attr; + + bit_attr = ethnla_nest_start(msgbuff, ETHTOOL_A_BITSET_BITS_BIT); + if (!bit_attr) + return -EMSGSIZE; + if (ethnla_put_strz(msgbuff, ETHTOOL_A_BITSET_BIT_NAME, name)) + return -EMSGSIZE; + if (ethnla_put_flag(msgbuff, ETHTOOL_A_BITSET_BIT_VALUE, val)) + return -EMSGSIZE; + mnl_attr_nest_end(msgbuff->nlhdr, bit_attr); + + return 0; +} + +static void set_sf_req_mask(struct nl_context *nlctx, unsigned int idx) +{ + struct sfeatures_context *sfctx = nlctx->cmd_private; + + sfctx->req_mask[idx / 32] |= (1 << (idx % 32)); +} + +static int fill_legacy_flag(struct nl_context *nlctx, const char *flag_name, + const struct stringset *feature_names, bool val) +{ + struct nl_msg_buff *msgbuff = &nlctx->ethnl_socket->msgbuff; + const unsigned int count = get_count(feature_names); + unsigned int i, j; + int ret; + + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { + const char *pattern; + + if (strcmp(flag_name, off_flag_def[i].short_name) && + strcmp(flag_name, off_flag_def[i].long_name)) + continue; + pattern = off_flag_def[i].kernel_name; + + for (j = 0; j < count; j++) { + const char *name = get_string(feature_names, j); + + if (flag_pattern_match(name, pattern)) { + ret = fill_feature(msgbuff, name, val); + if (ret < 0) + return ret; + set_sf_req_mask(nlctx, j); + } + } + + return 0; + } + + return 1; +} + +int fill_sfeatures_bitmap(struct nl_context *nlctx, + const struct stringset *feature_names) +{ + struct nl_msg_buff *msgbuff = &nlctx->ethnl_socket->msgbuff; + struct nlattr *bitset_attr; + struct nlattr *bits_attr; + int ret; + + ret = -EMSGSIZE; + bitset_attr = ethnla_nest_start(msgbuff, ETHTOOL_A_FEATURES_WANTED); + if (!bitset_attr) + return ret; + bits_attr = ethnla_nest_start(msgbuff, ETHTOOL_A_BITSET_BITS); + if (!bits_attr) + goto err; + + while (nlctx->argc > 0) { + bool val; + + if (!strcmp(*nlctx->argp, "--")) { + nlctx->argp++; + nlctx->argc--; + break; + } + ret = -EINVAL; + if (nlctx->argc < 2 || + (strcmp(nlctx->argp[1], "on") && + strcmp(nlctx->argp[1], "off"))) { + fprintf(stderr, + "ethtool (%s): flag '%s' for parameter '%s' is" + " not followed by 'on' or 'off'\n", + nlctx->cmd, nlctx->argp[1], nlctx->param); + goto err; + } + + val = !strcmp(nlctx->argp[1], "on"); + ret = fill_legacy_flag(nlctx, nlctx->argp[0], feature_names, + val); + if (ret > 0) { + ret = fill_feature(msgbuff, nlctx->argp[0], val); + if (ret == 0) { + int idx = find_feature(nlctx->argp[0], + feature_names); + + if (idx >= 0) + set_sf_req_mask(nlctx, idx); + } + } + if (ret < 0) + goto err; + + nlctx->argp += 2; + nlctx->argc -= 2; + } + + ethnla_nest_end(msgbuff, bits_attr); + ethnla_nest_end(msgbuff, bitset_attr); + return 0; +err: + ethnla_nest_cancel(msgbuff, bitset_attr); + return ret; +} + +static void show_feature_changes(struct nl_context *nlctx, + const struct nlattr *const *tb) +{ + struct sfeatures_context *sfctx = nlctx->cmd_private; + const struct stringset *feature_names; + const uint32_t *wanted_mask; + const uint32_t *active_mask; + const uint32_t *wanted_val; + const uint32_t *active_val; + unsigned int count, words; + unsigned int i; + bool diff; + int ret; + + feature_names = global_stringset(ETH_SS_FEATURES, nlctx->ethnl_socket); + count = get_count(feature_names); + words = DIV_ROUND_UP(count, 32); + + if (!tb[ETHTOOL_A_FEATURES_WANTED] || !tb[ETHTOOL_A_FEATURES_ACTIVE]) + goto err; + if (bitset_get_count(tb[ETHTOOL_A_FEATURES_WANTED], &ret) != count || + ret < 0) + goto err; + if (bitset_get_count(tb[ETHTOOL_A_FEATURES_ACTIVE], &ret) != count || + ret < 0) + goto err; + wanted_val = get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_WANTED]); + wanted_mask = get_compact_bitset_mask(tb[ETHTOOL_A_FEATURES_WANTED]); + active_val = get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_ACTIVE]); + active_mask = get_compact_bitset_mask(tb[ETHTOOL_A_FEATURES_ACTIVE]); + if (!wanted_val || !wanted_mask || !active_val || !active_mask) + goto err; + + sfctx->nothing_changed = true; + diff = false; + for (i = 0; i < words; i++) { + if (wanted_mask[i] != sfctx->req_mask[i]) + sfctx->nothing_changed = false; + if (wanted_mask[i] || (active_mask[i] & ~sfctx->req_mask[i])) + diff = true; + } + if (!diff) + return; + + /* result is not exactly as requested, show differences */ + printf("Actual changes:\n"); + for (i = 0; i < count; i++) { + const char *name = get_string(feature_names, i); + + if (!name) + continue; + if (!feature_on(wanted_mask, i) && !feature_on(active_mask, i)) + continue; + printf("%s: ", name); + if (feature_on(wanted_mask, i)) + /* we requested a value but result is different */ + printf("%s [requested %s]", + feature_on(wanted_val, i) ? "off" : "on", + feature_on(wanted_val, i) ? "on" : "off"); + else if (!feature_on(sfctx->req_mask, i)) + /* not requested but changed anyway */ + printf("%s [not requested]", + feature_on(active_val, i) ? "on" : "off"); + else + printf("%s", feature_on(active_val, i) ? "on" : "off"); + fputc('\n', stdout); + } + + return; +err: + fprintf(stderr, "malformed diff info from kernel\n"); +} + +int sfeatures_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct genlmsghdr *ghdr = (const struct genlmsghdr *)(nlhdr + 1); + const struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + const char *devname; + int ret; + + if (ghdr->cmd != ETHTOOL_MSG_FEATURES_SET_REPLY) { + fprintf(stderr, "warning: unexpected reply message type %u\n", + ghdr->cmd); + return MNL_CB_OK; + } + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + devname = get_dev_name(tb[ETHTOOL_A_FEATURES_HEADER]); + if (strcmp(devname, nlctx->devname)) { + fprintf(stderr, "warning: unexpected message for device %s\n", + devname); + return MNL_CB_OK; + } + + show_feature_changes(nlctx, tb); + return MNL_CB_OK; +} + +int nl_sfeatures(struct cmd_context *ctx) +{ + const struct stringset *feature_names; + struct nl_context *nlctx = ctx->nlctx; + struct sfeatures_context *sfctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + unsigned int words; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_FEATURES_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "-K"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->cmd_private = &sfctx; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + feature_names = global_stringset(ETH_SS_FEATURES, nlctx->ethnl_socket); + words = (get_count(feature_names) + 31) / 32; + sfctx = malloc(sizeof(*sfctx) + words * sizeof(sfctx->req_mask[0])); + if (!sfctx) + return -ENOMEM; + memset(sfctx, '\0', + sizeof(*sfctx) + words * sizeof(sfctx->req_mask[0])); + nlctx->cmd_private = sfctx; + + nlctx->devname = ctx->devname; + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_FEATURES_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_FEATURES_HEADER, ctx->devname, + ETHTOOL_FLAG_COMPACT_BITSETS)) + return -EMSGSIZE; + ret = fill_sfeatures_bitmap(nlctx, feature_names); + if (ret < 0) + return ret; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 92; + ret = nlsock_process_reply(nlsk, sfeatures_reply_cb, nlctx); + if (sfctx->nothing_changed) { + fprintf(stderr, "Could not change any device features\n"); + return nlctx->exit_code ?: 1; + } + if (ret == 0) + return 0; + return nlctx->exit_code ?: 92; +} diff --git a/netlink/fec.c b/netlink/fec.c new file mode 100644 index 0000000..6027dc0 --- /dev/null +++ b/netlink/fec.c @@ -0,0 +1,360 @@ +/* + * fec.c - netlink implementation of FEC commands + * + * Implementation of "ethtool --show-fec " and + * "ethtool --set-fec ..." + */ + +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "bitset.h" +#include "parser.h" + +/* FEC_GET */ + +static void +fec_mode_walk(unsigned int idx, const char *name, bool val, void *data) +{ + bool *empty = data; + + if (!val) + return; + if (empty) + *empty = false; + + /* Rename None to Off - in legacy ioctl None means "not supported" + * rather than supported but disabled. + */ + if (idx == ETHTOOL_LINK_MODE_FEC_NONE_BIT) + name = "Off"; + /* Rename to match the ioctl letter case */ + else if (idx == ETHTOOL_LINK_MODE_FEC_BASER_BIT) + name = "BaseR"; + + print_string(PRINT_ANY, NULL, " %s", name); +} + +static int fec_show_stats(const struct nlattr *nest) +{ + const struct nlattr *tb[ETHTOOL_A_FEC_STAT_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + static const struct { + unsigned int attr; + char *name; + } stats[] = { + { ETHTOOL_A_FEC_STAT_CORRECTED, "corrected_blocks" }, + { ETHTOOL_A_FEC_STAT_UNCORR, "uncorrectable_blocks" }, + { ETHTOOL_A_FEC_STAT_CORR_BITS, "corrected_bits" }, + }; + bool header = false; + unsigned int i; + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0) + return ret; + + open_json_object("statistics"); + for (i = 0; i < ARRAY_SIZE(stats); i++) { + uint64_t *vals; + int lanes, l; + + if (!tb[stats[i].attr] || + !mnl_attr_get_payload_len(tb[stats[i].attr])) + continue; + + if (!header && !is_json_context()) { + printf("Statistics:\n"); + header = true; + } + + if (mnl_attr_get_payload_len(tb[stats[i].attr]) % 8) { + fprintf(stderr, "malformed netlink message (statistic)\n"); + goto err_close_stats; + } + + vals = mnl_attr_get_payload(tb[stats[i].attr]); + lanes = mnl_attr_get_payload_len(tb[stats[i].attr]) / 8 - 1; + + if (!is_json_context()) { + fprintf(stdout, " %s: %" PRIu64 "\n", + stats[i].name, *vals++); + } else { + open_json_object(stats[i].name); + print_u64(PRINT_JSON, "total", NULL, *vals++); + } + + if (lanes) + open_json_array("lanes", ""); + for (l = 0; l < lanes; l++) { + if (!is_json_context()) + fprintf(stdout, " Lane %d: %" PRIu64 "\n", + l, *vals++); + else + print_u64(PRINT_JSON, NULL, NULL, *vals++); + } + if (lanes) + close_json_array(""); + + close_json_object(); + } + close_json_object(); + + return 0; + +err_close_stats: + close_json_object(); + return -1; +} + +int fec_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_FEC_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + const struct stringset *lm_strings; + const char *name; + bool fa, empty; + bool silent; + int err_ret; + u32 active; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_FEC_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + return err_ret; + lm_strings = global_stringset(ETH_SS_LINK_MODES, nlctx->ethnl2_socket); + + active = 0; + if (tb[ETHTOOL_A_FEC_ACTIVE]) + active = mnl_attr_get_u32(tb[ETHTOOL_A_FEC_ACTIVE]); + + if (silent) + print_nl(); + + open_json_object(NULL); + + print_string(PRINT_ANY, "ifname", "FEC parameters for %s:\n", + nlctx->devname); + + open_json_array("config", "Supported/Configured FEC encodings:"); + fa = tb[ETHTOOL_A_FEC_AUTO] && mnl_attr_get_u8(tb[ETHTOOL_A_FEC_AUTO]); + if (fa) + print_string(PRINT_ANY, NULL, " %s", "Auto"); + empty = !fa; + + ret = walk_bitset(tb[ETHTOOL_A_FEC_MODES], lm_strings, fec_mode_walk, + &empty); + if (ret < 0) + goto err_close_dev; + if (empty) + print_string(PRINT_ANY, NULL, " %s", "None"); + close_json_array("\n"); + + open_json_array("active", "Active FEC encoding:"); + if (active) { + name = get_string(lm_strings, active); + if (name) + /* Take care of renames */ + fec_mode_walk(active, name, true, NULL); + else + print_uint(PRINT_ANY, NULL, " BIT%u", active); + } else { + print_string(PRINT_ANY, NULL, " %s", "None"); + } + close_json_array("\n"); + + if (tb[ETHTOOL_A_FEC_STATS]) { + ret = fec_show_stats(tb[ETHTOOL_A_FEC_STATS]); + if (ret < 0) + goto err_close_dev; + } + + close_json_object(); + + return MNL_CB_OK; + +err_close_dev: + close_json_object(); + return err_ret; +} + +int nl_gfec(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + u32 flags; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_FEC_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + flags = get_stats_flag(nlctx, ETHTOOL_MSG_FEC_GET, + ETHTOOL_A_FEC_HEADER); + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_FEC_GET, + ETHTOOL_A_FEC_HEADER, flags); + if (ret < 0) + return ret; + + new_json_obj(ctx->json); + ret = nlsock_send_get_request(nlsk, fec_reply_cb); + delete_json_obj(); + return ret; +} + +/* FEC_SET */ + +static void strupc(char *dst, const char *src) +{ + while (*src) + *dst++ = toupper(*src++); + *dst = '\0'; +} + +static int fec_parse_bitset(struct nl_context *nlctx, uint16_t type, + const void *data __maybe_unused, + struct nl_msg_buff *msgbuff, void *dest) +{ + struct nlattr *bitset_attr; + struct nlattr *bits_attr; + struct nlattr *bit_attr; + char upper[ETH_GSTRING_LEN]; + bool fec_auto = false; + int ret; + + if (!type || dest) { + fprintf(stderr, "ethtool (%s): internal error parsing '%s'\n", + nlctx->cmd, nlctx->param); + return -EFAULT; + } + + bitset_attr = ethnla_nest_start(msgbuff, type); + if (!bitset_attr) + return -EMSGSIZE; + ret = -EMSGSIZE; + if (ethnla_put_flag(msgbuff, ETHTOOL_A_BITSET_NOMASK, true)) + goto err; + bits_attr = ethnla_nest_start(msgbuff, ETHTOOL_A_BITSET_BITS); + if (!bits_attr) + goto err; + + while (nlctx->argc > 0) { + const char *name = *nlctx->argp; + + if (!strcmp(name, "--")) { + nlctx->argp++; + nlctx->argc--; + break; + } + + if (!strcasecmp(name, "auto")) { + fec_auto = true; + goto next; + } + if (!strcasecmp(name, "off")) { + name = "None"; + } else { + strupc(upper, name); + name = upper; + } + + ret = -EMSGSIZE; + bit_attr = ethnla_nest_start(msgbuff, + ETHTOOL_A_BITSET_BITS_BIT); + if (!bit_attr) + goto err; + if (ethnla_put_strz(msgbuff, ETHTOOL_A_BITSET_BIT_NAME, name)) + goto err; + ethnla_nest_end(msgbuff, bit_attr); + +next: + nlctx->argp++; + nlctx->argc--; + } + + ethnla_nest_end(msgbuff, bits_attr); + ethnla_nest_end(msgbuff, bitset_attr); + + if (ethnla_put_u8(msgbuff, ETHTOOL_A_FEC_AUTO, fec_auto)) + goto err; + + return 0; +err: + ethnla_nest_cancel(msgbuff, bitset_attr); + return ret; +} + +static const struct param_parser sfec_params[] = { + { + .arg = "encoding", + .type = ETHTOOL_A_FEC_MODES, + .handler = fec_parse_bitset, + .min_argc = 1, + }, + {} +}; + +int nl_sfec(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_FEC_SET, false)) + return -EOPNOTSUPP; + if (!ctx->argc) { + fprintf(stderr, "ethtool (--set-fec): parameters missing\n"); + return 1; + } + + nlctx->cmd = "--set-fec"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_FEC_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_FEC_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, sfec_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 83; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 83; +} diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c new file mode 100644 index 0000000..49833a2 --- /dev/null +++ b/netlink/module-eeprom.c @@ -0,0 +1,305 @@ +/* + * module-eeprom.c - netlink implementation of module eeprom get command + * + * ethtool -m + */ + +#include +#include +#include +#include + +#include "../sff-common.h" +#include "../qsfp.h" +#include "../cmis.h" +#include "../internal.h" +#include "../common.h" +#include "../list.h" +#include "netlink.h" +#include "parser.h" + +#define ETH_I2C_ADDRESS_LOW 0x50 +#define ETH_I2C_MAX_ADDRESS 0x7F + +struct cmd_params { + u8 dump_hex; + u8 dump_raw; + u32 offset; + u32 length; + u32 page; + u32 bank; + u32 i2c_address; +}; + +static const struct param_parser getmodule_params[] = { + { + .arg = "hex", + .handler = nl_parse_u8bool, + .dest_offset = offsetof(struct cmd_params, dump_hex), + .min_argc = 1, + }, + { + .arg = "raw", + .handler = nl_parse_u8bool, + .dest_offset = offsetof(struct cmd_params, dump_raw), + .min_argc = 1, + }, + { + .arg = "offset", + .handler = nl_parse_direct_u32, + .dest_offset = offsetof(struct cmd_params, offset), + .min_argc = 1, + }, + { + .arg = "length", + .handler = nl_parse_direct_u32, + .dest_offset = offsetof(struct cmd_params, length), + .min_argc = 1, + }, + { + .arg = "page", + .handler = nl_parse_direct_u32, + .dest_offset = offsetof(struct cmd_params, page), + .min_argc = 1, + }, + { + .arg = "bank", + .handler = nl_parse_direct_u32, + .dest_offset = offsetof(struct cmd_params, bank), + .min_argc = 1, + }, + { + .arg = "i2c", + .handler = nl_parse_direct_u32, + .dest_offset = offsetof(struct cmd_params, i2c_address), + .min_argc = 1, + }, + {} +}; + +static struct list_head eeprom_page_list = LIST_HEAD_INIT(eeprom_page_list); + +struct eeprom_page_entry { + struct list_head list; /* Member of eeprom_page_list */ + void *data; +}; + +static int eeprom_page_list_add(void *data) +{ + struct eeprom_page_entry *entry; + + entry = malloc(sizeof(*entry)); + if (!entry) + return -ENOMEM; + + entry->data = data; + list_add(&entry->list, &eeprom_page_list); + + return 0; +} + +static void eeprom_page_list_flush(void) +{ + struct eeprom_page_entry *entry; + struct list_head *head, *next; + + list_for_each_safe(head, next, &eeprom_page_list) { + entry = (struct eeprom_page_entry *) head; + free(entry->data); + list_del(head); + free(entry); + } +} + +static int get_eeprom_page_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_MODULE_EEPROM_DATA + 1] = {}; + struct ethtool_module_eeprom *request = data; + DECLARE_ATTR_TB_INFO(tb); + u8 *eeprom_data; + int ret; + + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + + if (!tb[ETHTOOL_A_MODULE_EEPROM_DATA]) + return MNL_CB_ERROR; + + eeprom_data = mnl_attr_get_payload(tb[ETHTOOL_A_MODULE_EEPROM_DATA]); + request->data = malloc(request->length); + if (!request->data) + return MNL_CB_ERROR; + memcpy(request->data, eeprom_data, request->length); + + ret = eeprom_page_list_add(request->data); + if (ret < 0) + goto err_list_add; + + return MNL_CB_OK; + +err_list_add: + free(request->data); + return MNL_CB_ERROR; +} + +int nl_get_eeprom_page(struct cmd_context *ctx, + struct ethtool_module_eeprom *request) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsock; + struct nl_msg_buff *msg; + int ret; + + if (!request || request->i2c_address > ETH_I2C_MAX_ADDRESS) + return -EINVAL; + + nlsock = nlctx->ethnl_socket; + msg = &nlsock->msgbuff; + + ret = nlsock_prep_get_request(nlsock, ETHTOOL_MSG_MODULE_EEPROM_GET, + ETHTOOL_A_MODULE_EEPROM_HEADER, 0); + if (ret < 0) + return ret; + + if (ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_LENGTH, + request->length) || + ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_OFFSET, + request->offset) || + ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_PAGE, + request->page) || + ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_BANK, + request->bank) || + ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS, + request->i2c_address)) + return -EMSGSIZE; + + ret = nlsock_sendmsg(nlsock, NULL); + if (ret < 0) + return ret; + return nlsock_process_reply(nlsock, get_eeprom_page_reply_cb, + (void *)request); +} + +static int eeprom_dump_hex(struct cmd_context *ctx) +{ + struct ethtool_module_eeprom request = { + .length = 128, + .i2c_address = ETH_I2C_ADDRESS_LOW, + }; + int ret; + + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + + dump_hex(stdout, request.data, request.length, request.offset); + + return 0; +} + +static int eeprom_parse(struct cmd_context *ctx) +{ + struct ethtool_module_eeprom request = { + .length = 1, + .i2c_address = ETH_I2C_ADDRESS_LOW, + }; + int ret; + + /* Fetch the SFF-8024 Identifier Value. For all supported standards, it + * is located at I2C address 0x50, byte 0. See section 4.1 in SFF-8024, + * revision 4.9. + */ + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + + switch (request.data[0]) { +#ifdef ETHTOOL_ENABLE_PRETTY_DUMP + case SFF8024_ID_SFP: + return sff8079_show_all_nl(ctx); + case SFF8024_ID_QSFP: + case SFF8024_ID_QSFP28: + case SFF8024_ID_QSFP_PLUS: + return sff8636_show_all_nl(ctx); + case SFF8024_ID_QSFP_DD: + case SFF8024_ID_OSFP: + case SFF8024_ID_DSFP: + return cmis_show_all_nl(ctx); +#endif + default: + /* If we cannot recognize the memory map, default to dumping + * the first 128 bytes in hex. + */ + return eeprom_dump_hex(ctx); + } +} + +int nl_getmodule(struct cmd_context *ctx) +{ + struct cmd_params getmodule_cmd_params = {}; + struct ethtool_module_eeprom request = {0}; + struct nl_context *nlctx = ctx->nlctx; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_MODULE_EEPROM_GET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "-m"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + ret = nl_parser(nlctx, getmodule_params, &getmodule_cmd_params, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return ret; + + if (getmodule_cmd_params.dump_hex && getmodule_cmd_params.dump_raw) { + fprintf(stderr, "Hex and raw dump cannot be specified together\n"); + return -EINVAL; + } + + /* When complete hex/raw dump of the EEPROM is requested, fallback to + * ioctl. Netlink can only request specific pages. + */ + if ((getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) && + !getmodule_cmd_params.page && !getmodule_cmd_params.bank && + !getmodule_cmd_params.i2c_address) { + nlctx->ioctl_fallback = true; + return -EOPNOTSUPP; + } + +#ifdef ETHTOOL_ENABLE_PRETTY_DUMP + if (getmodule_cmd_params.page || getmodule_cmd_params.bank || + getmodule_cmd_params.offset || getmodule_cmd_params.length) +#endif + getmodule_cmd_params.dump_hex = true; + + request.offset = getmodule_cmd_params.offset; + request.length = getmodule_cmd_params.length ?: 128; + request.page = getmodule_cmd_params.page; + request.bank = getmodule_cmd_params.bank; + request.i2c_address = getmodule_cmd_params.i2c_address ?: ETH_I2C_ADDRESS_LOW; + + if (request.page && !request.offset) + request.offset = 128; + + if (getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) { + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + goto cleanup; + + if (getmodule_cmd_params.dump_raw) + fwrite(request.data, 1, request.length, stdout); + else + dump_hex(stdout, request.data, request.length, + request.offset); + } else { + ret = eeprom_parse(ctx); + if (ret < 0) + goto cleanup; + } + +cleanup: + eeprom_page_list_flush(); + return ret; +} diff --git a/netlink/module.c b/netlink/module.c new file mode 100644 index 0000000..54aa6d0 --- /dev/null +++ b/netlink/module.c @@ -0,0 +1,179 @@ +/* + * module.c - netlink implementation of module commands + * + * Implementation of "ethtool --show-module " and + * "ethtool --set-module ..." + */ + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "parser.h" + +/* MODULE_GET */ + +static const char *module_power_mode_policy_name(u8 val) +{ + switch (val) { + case ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH: + return "high"; + case ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO: + return "auto"; + default: + return "unknown"; + } +} + +static const char *module_power_mode_name(u8 val) +{ + switch (val) { + case ETHTOOL_MODULE_POWER_MODE_LOW: + return "low"; + case ETHTOOL_MODULE_POWER_MODE_HIGH: + return "high"; + default: + return "unknown"; + } +} + +int module_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_MODULE_MAX + 1] = {}; + struct nl_context *nlctx = data; + DECLARE_ATTR_TB_INFO(tb); + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_MODULE_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + print_nl(); + + open_json_object(NULL); + + print_string(PRINT_ANY, "ifname", "Module parameters for %s:\n", + nlctx->devname); + + if (tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]) { + u8 val; + + val = mnl_attr_get_u8(tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]); + print_string(PRINT_ANY, "power-mode-policy", + "power-mode-policy: %s\n", + module_power_mode_policy_name(val)); + } + + if (tb[ETHTOOL_A_MODULE_POWER_MODE]) { + u8 val; + + val = mnl_attr_get_u8(tb[ETHTOOL_A_MODULE_POWER_MODE]); + print_string(PRINT_ANY, "power-mode", + "power-mode: %s\n", module_power_mode_name(val)); + } + + close_json_object(); + + return MNL_CB_OK; +} + +int nl_gmodule(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_MODULE_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + nlsk = nlctx->ethnl_socket; + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_MODULE_GET, + ETHTOOL_A_MODULE_HEADER, 0); + if (ret < 0) + return ret; + + new_json_obj(ctx->json); + ret = nlsock_send_get_request(nlsk, module_reply_cb); + delete_json_obj(); + return ret; +} + +/* MODULE_SET */ + +static const struct lookup_entry_u8 power_mode_policy_values[] = { + { .arg = "high", .val = ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH }, + { .arg = "auto", .val = ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO }, + {} +}; + +static const struct param_parser smodule_params[] = { + { + .arg = "power-mode-policy", + .type = ETHTOOL_A_MODULE_POWER_MODE_POLICY, + .handler = nl_parse_lookup_u8, + .handler_data = power_mode_policy_values, + .min_argc = 1, + }, + {} +}; + +int nl_smodule(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_MODULE_SET, false)) + return -EOPNOTSUPP; + if (!ctx->argc) { + fprintf(stderr, "ethtool (--set-module): parameters missing\n"); + return 1; + } + + nlctx->cmd = "--set-module"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_MODULE_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_MODULE_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, smodule_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 83; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 83; +} diff --git a/netlink/monitor.c b/netlink/monitor.c new file mode 100644 index 0000000..ace9b25 --- /dev/null +++ b/netlink/monitor.c @@ -0,0 +1,324 @@ +/* + * monitor.c - netlink notification monitor + * + * Implementation of "ethtool --monitor" for watching netlink notifications. + */ + +#include + +#include "../internal.h" +#include "netlink.h" +#include "nlsock.h" +#include "strset.h" + +static struct { + uint8_t cmd; + mnl_cb_t cb; +} monitor_callbacks[] = { + { + .cmd = ETHTOOL_MSG_LINKMODES_NTF, + .cb = linkmodes_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_LINKINFO_NTF, + .cb = linkinfo_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_WOL_NTF, + .cb = wol_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_DEBUG_NTF, + .cb = debug_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_FEATURES_NTF, + .cb = features_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_PRIVFLAGS_NTF, + .cb = privflags_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_RINGS_NTF, + .cb = rings_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_CHANNELS_NTF, + .cb = channels_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_COALESCE_NTF, + .cb = coalesce_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_PAUSE_NTF, + .cb = pause_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_EEE_NTF, + .cb = eee_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_CABLE_TEST_NTF, + .cb = cable_test_ntf_cb, + }, + { + .cmd = ETHTOOL_MSG_CABLE_TEST_TDR_NTF, + .cb = cable_test_tdr_ntf_cb, + }, + { + .cmd = ETHTOOL_MSG_FEC_NTF, + .cb = fec_reply_cb, + }, + { + .cmd = ETHTOOL_MSG_MODULE_NTF, + .cb = module_reply_cb, + }, +}; + +static void clear_filter(struct nl_context *nlctx) +{ + unsigned int i; + + for (i = 0; i < CMDMASK_WORDS; i++) + nlctx->filter_cmds[i] = 0; +} + +static bool test_filter_cmd(const struct nl_context *nlctx, unsigned int cmd) +{ + return nlctx->filter_cmds[cmd / 32] & (1U << (cmd % 32)); +} + +static void set_filter_cmd(struct nl_context *nlctx, unsigned int cmd) +{ + nlctx->filter_cmds[cmd / 32] |= (1U << (cmd % 32)); +} + +static void set_filter_all(struct nl_context *nlctx) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(monitor_callbacks); i++) + set_filter_cmd(nlctx, monitor_callbacks[i].cmd); +} + +static int monitor_any_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct genlmsghdr *ghdr = (const struct genlmsghdr *)(nlhdr + 1); + struct nl_context *nlctx = data; + unsigned int i; + + if (!test_filter_cmd(nlctx, ghdr->cmd)) + return MNL_CB_OK; + + for (i = 0; i < MNL_ARRAY_SIZE(monitor_callbacks); i++) + if (monitor_callbacks[i].cmd == ghdr->cmd) + return monitor_callbacks[i].cb(nlhdr, data); + + return MNL_CB_OK; +} + +struct monitor_option { + const char *pattern; + uint8_t cmd; + uint32_t info_mask; +}; + +static struct monitor_option monitor_opts[] = { + { + .pattern = "|--all", + .cmd = 0, + }, + { + .pattern = "-s|--change", + .cmd = ETHTOOL_MSG_LINKINFO_NTF, + }, + { + .pattern = "-s|--change", + .cmd = ETHTOOL_MSG_LINKMODES_NTF, + }, + { + .pattern = "-s|--change", + .cmd = ETHTOOL_MSG_WOL_NTF, + }, + { + .pattern = "-s|--change", + .cmd = ETHTOOL_MSG_DEBUG_NTF, + }, + { + .pattern = "-k|--show-features|--show-offload|-K|--features|--offload", + .cmd = ETHTOOL_MSG_FEATURES_NTF, + }, + { + .pattern = "--show-priv-flags|--set-priv-flags", + .cmd = ETHTOOL_MSG_PRIVFLAGS_NTF, + }, + { + .pattern = "-g|--show-ring|-G|--set-ring", + .cmd = ETHTOOL_MSG_RINGS_NTF, + }, + { + .pattern = "-l|--show-channels|-L|--set-channels", + .cmd = ETHTOOL_MSG_CHANNELS_NTF, + }, + { + .pattern = "-c|--show-coalesce|-C|--coalesce", + .cmd = ETHTOOL_MSG_COALESCE_NTF, + }, + { + .pattern = "-a|--show-pause|-A|--pause", + .cmd = ETHTOOL_MSG_PAUSE_NTF, + }, + { + .pattern = "--show-eee|--set-eee", + .cmd = ETHTOOL_MSG_EEE_NTF, + }, + { + .pattern = "--cable-test", + .cmd = ETHTOOL_MSG_CABLE_TEST_NTF, + }, + { + .pattern = "--cable-test-tdr", + .cmd = ETHTOOL_MSG_CABLE_TEST_TDR_NTF, + }, + { + .pattern = "--show-module|--set-module", + .cmd = ETHTOOL_MSG_MODULE_NTF, + }, +}; + +static bool pattern_match(const char *s, const char *pattern) +{ + const char *opt = pattern; + const char *next; + int slen = strlen(s); + int optlen; + + do { + next = opt; + while (*next && *next != '|') + next++; + optlen = next - opt; + if (slen == optlen && !strncmp(s, opt, optlen)) + return true; + + opt = next; + if (*opt == '|') + opt++; + } while (*opt); + + return false; +} + +static int parse_monitor(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + char **argp = ctx->argp; + int argc = ctx->argc; + const char *opt = ""; + bool opt_found; + unsigned int i; + + if (*argp && argp[0][0] == '-') { + opt = *argp; + argp++; + argc--; + } + opt_found = false; + clear_filter(nlctx); + for (i = 0; i < MNL_ARRAY_SIZE(monitor_opts); i++) { + if (pattern_match(opt, monitor_opts[i].pattern)) { + unsigned int cmd = monitor_opts[i].cmd; + + if (!cmd) + set_filter_all(nlctx); + else + set_filter_cmd(nlctx, cmd); + opt_found = true; + } + } + if (!opt_found) { + fprintf(stderr, "monitoring for option '%s' not supported\n", + *argp); + return -1; + } + + if (*argp && strcmp(*argp, WILDCARD_DEVNAME)) + ctx->devname = *argp; + return 0; +} + +int nl_monitor(struct cmd_context *ctx) +{ + struct nl_context *nlctx; + struct nl_socket *nlsk; + uint32_t grpid; + bool is_dev; + int ret; + + ret = netlink_init(ctx); + if (ret < 0) { + fprintf(stderr, "Netlink interface initialization failed, option --monitor not supported.\n"); + return ret; + } + nlctx = ctx->nlctx; + nlsk = nlctx->ethnl_socket; + grpid = nlctx->ethnl_mongrp; + if (!grpid) { + fprintf(stderr, "multicast group 'monitor' not found\n"); + return -EOPNOTSUPP; + } + + if (parse_monitor(ctx) < 0) + return 1; + is_dev = ctx->devname && strcmp(ctx->devname, WILDCARD_DEVNAME); + + ret = preload_global_strings(nlsk); + if (ret < 0) + return ret; + ret = mnl_socket_setsockopt(nlsk->sk, NETLINK_ADD_MEMBERSHIP, + &grpid, sizeof(grpid)); + if (ret < 0) + return ret; + if (is_dev) { + ret = preload_perdev_strings(nlsk, ctx->devname); + if (ret < 0) + goto out_strings; + } + + nlctx->filter_devname = ctx->devname; + nlctx->is_monitor = true; + nlsk->port = 0; + nlsk->seq = 0; + + fputs("listening...\n", stdout); + fflush(stdout); + ret = nlsock_process_reply(nlsk, monitor_any_cb, nlctx); + +out_strings: + cleanup_all_strings(); + return ret; +} + +void nl_monitor_usage(void) +{ + unsigned int i; + const char *p; + + fputs(" ethtool --monitor Show kernel notifications\n", + stdout); + fputs(" ( [ --all ]", stdout); + for (i = 1; i < MNL_ARRAY_SIZE(monitor_opts); i++) { + if (!strcmp(monitor_opts[i].pattern, monitor_opts[i - 1].pattern)) + continue; + fputs("\n | ", stdout); + for (p = monitor_opts[i].pattern; *p; p++) + if (*p == '|') + fputs(" | ", stdout); + else + fputc(*p, stdout); + } + fputs(" )\n", stdout); + fputs(" [ DEVNAME | * ]\n", stdout); +} diff --git a/netlink/msgbuff.c b/netlink/msgbuff.c new file mode 100644 index 0000000..216f5b9 --- /dev/null +++ b/netlink/msgbuff.c @@ -0,0 +1,256 @@ +/* + * msgbuff.c - netlink message buffer + * + * Data structures and code for flexible message buffer abstraction. + */ + +#include +#include +#include +#include + +#include "../internal.h" +#include "netlink.h" +#include "msgbuff.h" + +#define MAX_MSG_SIZE (4 << 20) /* 4 MB */ + +/** + * msgbuff_realloc() - reallocate buffer if needed + * @msgbuff: message buffer + * @new_size: requested minimum size (add MNL_SOCKET_BUFFER_SIZE if zero) + * + * Make sure allocated buffer has size at least @new_size. If @new_size is + * shorter than current size, do nothing. If @new_size is 0, grow buffer by + * MNL_SOCKET_BUFFER_SIZE. Fail if new size would exceed MAX_MSG_SIZE. + * + * Return: 0 on success or negative error code + */ +int msgbuff_realloc(struct nl_msg_buff *msgbuff, unsigned int new_size) +{ + unsigned int nlhdr_off, genlhdr_off, payload_off; + unsigned int old_size = msgbuff->size; + char *nbuff; + + nlhdr_off = (char *)msgbuff->nlhdr - msgbuff->buff; + genlhdr_off = (char *)msgbuff->genlhdr - msgbuff->buff; + payload_off = (char *)msgbuff->payload - msgbuff->buff; + + if (!new_size) + new_size = old_size + MNL_SOCKET_BUFFER_SIZE; + if (new_size <= old_size) + return 0; + if (new_size > MAX_MSG_SIZE) + return -EMSGSIZE; + nbuff = realloc(msgbuff->buff, new_size); + if (!nbuff) { + msgbuff->buff = NULL; + msgbuff->size = 0; + msgbuff->left = 0; + return -ENOMEM; + } + if (nbuff != msgbuff->buff) { + if (new_size > old_size) + memset(nbuff + old_size, '\0', new_size - old_size); + msgbuff->nlhdr = (struct nlmsghdr *)(nbuff + nlhdr_off); + msgbuff->genlhdr = (struct genlmsghdr *)(nbuff + genlhdr_off); + msgbuff->payload = nbuff + payload_off; + msgbuff->buff = nbuff; + } + msgbuff->size = new_size; + msgbuff->left += (new_size - old_size); + + return 0; +} + +/** + * msgbuff_append() - add contents of another message buffer + * @dest: target message buffer + * @src: source message buffer + * + * Append contents of @src at the end of @dest. Fail if target buffer cannot + * be reallocated to sufficient size. + * + * Return: 0 on success or negative error code. + */ +int msgbuff_append(struct nl_msg_buff *dest, struct nl_msg_buff *src) +{ + unsigned int src_len = mnl_nlmsg_get_payload_len(src->nlhdr); + unsigned int dest_len = MNL_ALIGN(msgbuff_len(dest)); + int ret; + + src_len -= GENL_HDRLEN; + ret = msgbuff_realloc(dest, dest_len + src_len); + if (ret < 0) + return ret; + memcpy(mnl_nlmsg_get_payload_tail(dest->nlhdr), src->payload, src_len); + msgbuff_reset(dest, dest_len + src_len); + + return 0; +} + +/** + * ethnla_put - write a netlink attribute to message buffer + * @msgbuff: message buffer + * @type: attribute type + * @len: attribute payload length + * @data: attribute payload + * + * Appends a netlink attribute with header to message buffer, reallocates + * if needed. This is mostly used via specific ethnla_put_* wrappers for + * basic data types. + * + * Return: false on success, true on error (reallocation failed) + */ +bool ethnla_put(struct nl_msg_buff *msgbuff, uint16_t type, size_t len, + const void *data) +{ + struct nlmsghdr *nlhdr = msgbuff->nlhdr; + + while (!mnl_attr_put_check(nlhdr, msgbuff->left, type, len, data)) { + int ret = msgbuff_realloc(msgbuff, 0); + + if (ret < 0) + return true; + } + + return false; +} + +/** + * ethnla_nest_start - start a nested attribute + * @msgbuff: message buffer + * @type: nested attribute type (NLA_F_NESTED is added automatically) + * + * Return: pointer to the nest attribute or null of error + */ +struct nlattr *ethnla_nest_start(struct nl_msg_buff *msgbuff, uint16_t type) +{ + struct nlmsghdr *nlhdr = msgbuff->nlhdr; + struct nlattr *attr; + + do { + attr = mnl_attr_nest_start_check(nlhdr, msgbuff->left, type); + if (attr) + return attr; + } while (msgbuff_realloc(msgbuff, 0) == 0); + + return NULL; +} + +/** + * ethnla_fill_header() - write standard ethtool request header to message + * @msgbuff: message buffer + * @type: attribute type for header nest + * @devname: device name (NULL to omit) + * @flags: request flags (omitted if 0) + * + * Return: pointer to the nest attribute or null of error + */ +bool ethnla_fill_header(struct nl_msg_buff *msgbuff, uint16_t type, + const char *devname, uint32_t flags) +{ + struct nlattr *nest; + + nest = ethnla_nest_start(msgbuff, type); + if (!nest) + return true; + + if ((devname && + ethnla_put_strz(msgbuff, ETHTOOL_A_HEADER_DEV_NAME, devname)) || + (flags && + ethnla_put_u32(msgbuff, ETHTOOL_A_HEADER_FLAGS, flags))) + goto err; + + ethnla_nest_end(msgbuff, nest); + return false; + +err: + ethnla_nest_cancel(msgbuff, nest); + return true; +} + +/** + * __msg_init() - init a genetlink message, fill netlink and genetlink header + * @msgbuff: message buffer + * @family: genetlink family + * @cmd: genetlink command (genlmsghdr::cmd) + * @flags: netlink flags (nlmsghdr::nlmsg_flags) + * @version: genetlink family version (genlmsghdr::version) + * + * Initialize a new genetlink message, fill netlink and genetlink header and + * set pointers in struct nl_msg_buff. + * + * Return: 0 on success or negative error code. + */ +int __msg_init(struct nl_msg_buff *msgbuff, int family, int cmd, + unsigned int flags, int version) +{ + struct nlmsghdr *nlhdr; + struct genlmsghdr *genlhdr; + int ret; + + ret = msgbuff_realloc(msgbuff, MNL_SOCKET_BUFFER_SIZE); + if (ret < 0) + return ret; + memset(msgbuff->buff, '\0', NLMSG_HDRLEN + GENL_HDRLEN); + + nlhdr = mnl_nlmsg_put_header(msgbuff->buff); + nlhdr->nlmsg_type = family; + nlhdr->nlmsg_flags = flags; + msgbuff->nlhdr = nlhdr; + + genlhdr = mnl_nlmsg_put_extra_header(nlhdr, sizeof(*genlhdr)); + genlhdr->cmd = cmd; + genlhdr->version = version; + msgbuff->genlhdr = genlhdr; + + msgbuff->payload = mnl_nlmsg_get_payload_offset(nlhdr, GENL_HDRLEN); + + return 0; +} + +/** + * msg_init() - init an ethtool netlink message + * @msgbuff: message buffer + * @cmd: genetlink command (genlmsghdr::cmd) + * @flags: netlink flags (nlmsghdr::nlmsg_flags) + * + * Initialize a new ethtool netlink message, fill netlink and genetlink header + * and set pointers in struct nl_msg_buff. + * + * Return: 0 on success or negative error code. + */ +int msg_init(struct nl_context *nlctx, struct nl_msg_buff *msgbuff, int cmd, + unsigned int flags) +{ + return __msg_init(msgbuff, nlctx->ethnl_fam, cmd, flags, + ETHTOOL_GENL_VERSION); +} + +/** + * msgbuff_init() - initialize a message buffer + * @msgbuff: message buffer + * + * Initialize a message buffer structure before first use. Buffer length is + * set to zero and the buffer is not allocated until the first call to + * msgbuff_reallocate(). + */ +void msgbuff_init(struct nl_msg_buff *msgbuff) +{ + memset(msgbuff, '\0', sizeof(*msgbuff)); +} + +/** + * msg_done() - destroy a message buffer + * @msgbuff: message buffer + * + * Free the buffer and reset size and remaining size. + */ +void msgbuff_done(struct nl_msg_buff *msgbuff) +{ + free(msgbuff->buff); + msgbuff->buff = NULL; + msgbuff->size = 0; + msgbuff->left = 0; +} diff --git a/netlink/msgbuff.h b/netlink/msgbuff.h new file mode 100644 index 0000000..7d6731f --- /dev/null +++ b/netlink/msgbuff.h @@ -0,0 +1,123 @@ +/* + * msgbuff.h - netlink message buffer + * + * Declarations of netlink message buffer and related functions. + */ + +#ifndef ETHTOOL_NETLINK_MSGBUFF_H__ +#define ETHTOOL_NETLINK_MSGBUFF_H__ + +#include +#include +#include +#include + +struct nl_context; + +/** + * struct nl_msg_buff - message buffer abstraction + * @buff: pointer to buffer + * @size: total size of allocated buffer + * @left: remaining length current message end to end of buffer + * @nlhdr: pointer to netlink header of current message + * @genlhdr: pointer to genetlink header of current message + * @payload: pointer to message payload (after genetlink header) + */ +struct nl_msg_buff { + char *buff; + unsigned int size; + unsigned int left; + struct nlmsghdr *nlhdr; + struct genlmsghdr *genlhdr; + void *payload; +}; + +void msgbuff_init(struct nl_msg_buff *msgbuff); +void msgbuff_done(struct nl_msg_buff *msgbuff); +int msgbuff_realloc(struct nl_msg_buff *msgbuff, unsigned int new_size); +int msgbuff_append(struct nl_msg_buff *dest, struct nl_msg_buff *src); + +int __msg_init(struct nl_msg_buff *msgbuff, int family, int cmd, + unsigned int flags, int version); +int msg_init(struct nl_context *nlctx, struct nl_msg_buff *msgbuff, int cmd, + unsigned int flags); + +bool ethnla_put(struct nl_msg_buff *msgbuff, uint16_t type, size_t len, + const void *data); +struct nlattr *ethnla_nest_start(struct nl_msg_buff *msgbuff, uint16_t type); +bool ethnla_fill_header(struct nl_msg_buff *msgbuff, uint16_t type, + const char *devname, uint32_t flags); + +/* length of current message */ +static inline unsigned int msgbuff_len(const struct nl_msg_buff *msgbuff) +{ + return msgbuff->nlhdr->nlmsg_len; +} + +/* reset message length to position returned by msgbuff_len() */ +static inline void msgbuff_reset(const struct nl_msg_buff *msgbuff, + unsigned int len) +{ + msgbuff->nlhdr->nlmsg_len = len; +} + +/* put data wrappers */ + +static inline void ethnla_nest_end(struct nl_msg_buff *msgbuff, + struct nlattr *nest) +{ + mnl_attr_nest_end(msgbuff->nlhdr, nest); +} + +static inline void ethnla_nest_cancel(struct nl_msg_buff *msgbuff, + struct nlattr *nest) +{ + mnl_attr_nest_cancel(msgbuff->nlhdr, nest); +} + +static inline bool ethnla_put_u32(struct nl_msg_buff *msgbuff, uint16_t type, + uint32_t data) +{ + return ethnla_put(msgbuff, type, sizeof(uint32_t), &data); +} + +static inline bool ethnla_put_u16(struct nl_msg_buff *msgbuff, uint16_t type, + uint16_t data) +{ + return ethnla_put(msgbuff, type, sizeof(uint16_t), &data); +} + +static inline bool ethnla_put_u8(struct nl_msg_buff *msgbuff, uint16_t type, + uint8_t data) +{ + return ethnla_put(msgbuff, type, sizeof(uint8_t), &data); +} + +static inline bool ethnla_put_flag(struct nl_msg_buff *msgbuff, uint16_t type, + bool val) +{ + if (val) + return ethnla_put(msgbuff, type, 0, &val); + else + return false; +} + +static inline bool ethnla_put_bitfield32(struct nl_msg_buff *msgbuff, + uint16_t type, uint32_t value, + uint32_t selector) +{ + struct nla_bitfield32 val = { + .value = value, + .selector = selector, + }; + + return ethnla_put(msgbuff, type, sizeof(val), &val); +} + +static inline bool ethnla_put_strz(struct nl_msg_buff *msgbuff, uint16_t type, + const char *data) +{ + return ethnla_put(msgbuff, type, strlen(data) + 1, data); +} + +#endif /* ETHTOOL_NETLINK_MSGBUFF_H__ */ diff --git a/netlink/netlink.c b/netlink/netlink.c new file mode 100644 index 0000000..ef0d825 --- /dev/null +++ b/netlink/netlink.c @@ -0,0 +1,527 @@ +/* + * netlink.c - basic infrastructure for netlink code + * + * Heart of the netlink interface implementation. + */ + +#include + +#include "../internal.h" +#include "netlink.h" +#include "extapi.h" +#include "msgbuff.h" +#include "nlsock.h" +#include "strset.h" + +/* Used as reply callback for requests where no reply is expected (e.g. most + * "set" type commands) + */ +int nomsg_reply_cb(const struct nlmsghdr *nlhdr, void *data __maybe_unused) +{ + const struct genlmsghdr *ghdr = (const struct genlmsghdr *)(nlhdr + 1); + + fprintf(stderr, "received unexpected message: len=%u type=%u cmd=%u\n", + nlhdr->nlmsg_len, nlhdr->nlmsg_type, ghdr->cmd); + return MNL_CB_OK; +} + +/* standard attribute parser callback; it fills provided array with pointers + * to attributes like kernel nla_parse(). We must expect to run on top of + * a newer kernel which may send attributes that we do not know (yet). Rather + * than treating them as an error, just ignore them. + */ +int attr_cb(const struct nlattr *attr, void *data) +{ + const struct attr_tb_info *tb_info = data; + uint16_t type = mnl_attr_get_type(attr); + + if (type <= tb_info->max_type) + tb_info->tb[type] = attr; + + return MNL_CB_OK; +} + +/* misc helpers */ + +const char *get_dev_name(const struct nlattr *nest) +{ + const struct nlattr *tb[ETHTOOL_A_HEADER_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + int ret; + + if (!nest) + return NULL; + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0 || !tb[ETHTOOL_A_HEADER_DEV_NAME]) + return "(none)"; + return mnl_attr_get_str(tb[ETHTOOL_A_HEADER_DEV_NAME]); +} + +int get_dev_info(const struct nlattr *nest, int *ifindex, char *ifname) +{ + const struct nlattr *tb[ETHTOOL_A_HEADER_MAX + 1] = {}; + const struct nlattr *index_attr; + const struct nlattr *name_attr; + DECLARE_ATTR_TB_INFO(tb); + int ret; + + if (ifindex) + *ifindex = 0; + if (ifname) + memset(ifname, '\0', ALTIFNAMSIZ); + + if (!nest) + return -EFAULT; + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + index_attr = tb[ETHTOOL_A_HEADER_DEV_INDEX]; + name_attr = tb[ETHTOOL_A_HEADER_DEV_NAME]; + if (ret < 0 || (ifindex && !index_attr) || (ifname && !name_attr)) + return -EFAULT; + + if (ifindex) + *ifindex = mnl_attr_get_u32(index_attr); + if (ifname) { + strncpy(ifname, mnl_attr_get_str(name_attr), ALTIFNAMSIZ); + if (ifname[ALTIFNAMSIZ - 1]) { + ifname[ALTIFNAMSIZ - 1] = '\0'; + fprintf(stderr, "kernel device name too long: '%s'\n", + mnl_attr_get_str(name_attr)); + return -EFAULT; + } + } + return 0; +} + +/** + * netlink_cmd_check() - check support for netlink command + * @ctx: ethtool command context + * @cmd: netlink command id + * @devname: device name from user + * @allow_wildcard: wildcard dumps supported + * + * Check if command @cmd is known to be unsupported based on ops information + * from genetlink family id request. Set nlctx->ioctl_fallback if ethtool + * should fall back to ioctl, i.e. when we do not know in advance that + * netlink request is supported. Set nlctx->wildcard_unsupported if "*" was + * used as device name but the request does not support wildcards (on either + * side). + * + * Return: true if we know the netlink request is not supported and should + * fail (and possibly fall back) without actually sending it to kernel. + */ +bool netlink_cmd_check(struct cmd_context *ctx, unsigned int cmd, + bool allow_wildcard) +{ + bool is_dump = !strcmp(ctx->devname, WILDCARD_DEVNAME); + uint32_t cap = is_dump ? GENL_CMD_CAP_DUMP : GENL_CMD_CAP_DO; + struct nl_context *nlctx = ctx->nlctx; + + if (is_dump && !allow_wildcard) { + nlctx->wildcard_unsupported = true; + return true; + } + if (!nlctx->ops_info) { + nlctx->ioctl_fallback = true; + return false; + } + if (cmd > ETHTOOL_MSG_USER_MAX || !nlctx->ops_info[cmd].op_flags) { + nlctx->ioctl_fallback = true; + return true; + } + + if (is_dump && !(nlctx->ops_info[cmd].op_flags & GENL_CMD_CAP_DUMP)) + nlctx->wildcard_unsupported = true; + + return !(nlctx->ops_info[cmd].op_flags & cap); +} + +struct ethtool_op_policy_query_ctx { + struct nl_context *nlctx; + unsigned int op; + unsigned int op_hdr_attr; + + bool op_policy_found; + bool hdr_policy_found; + unsigned int op_policy_idx; + unsigned int hdr_policy_idx; + uint64_t flag_mask; +}; + +static int family_policy_find_op(struct ethtool_op_policy_query_ctx *policy_ctx, + const struct nlattr *op_policy) +{ + const struct nlattr *attr; + unsigned int type; + int ret; + + type = policy_ctx->nlctx->is_dump ? + CTRL_ATTR_POLICY_DUMP : CTRL_ATTR_POLICY_DO; + + mnl_attr_for_each_nested(attr, op_policy) { + const struct nlattr *tb[CTRL_ATTR_POLICY_DUMP_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + + if (mnl_attr_get_type(attr) != policy_ctx->op) + continue; + + ret = mnl_attr_parse_nested(attr, attr_cb, &tb_info); + if (ret < 0) + return ret; + + if (!tb[type]) + continue; + + policy_ctx->op_policy_found = true; + policy_ctx->op_policy_idx = mnl_attr_get_u32(tb[type]); + break; + } + + return 0; +} + +static int family_policy_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tba[NL_POLICY_TYPE_ATTR_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tba); + const struct nlattr *tb[CTRL_ATTR_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct ethtool_op_policy_query_ctx *policy_ctx = data; + const struct nlattr *policy_attr, *attr_attr, *attr; + unsigned int attr_idx, policy_idx; + int ret; + + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return MNL_CB_ERROR; + + if (!policy_ctx->op_policy_found) { + if (!tb[CTRL_ATTR_OP_POLICY]) { + fprintf(stderr, "Error: op policy map not present\n"); + return MNL_CB_ERROR; + } + ret = family_policy_find_op(policy_ctx, tb[CTRL_ATTR_OP_POLICY]); + return ret < 0 ? MNL_CB_ERROR : MNL_CB_OK; + } + + if (!tb[CTRL_ATTR_POLICY]) + return MNL_CB_OK; + + policy_attr = mnl_attr_get_payload(tb[CTRL_ATTR_POLICY]); + policy_idx = mnl_attr_get_type(policy_attr); + attr_attr = mnl_attr_get_payload(policy_attr); + attr_idx = mnl_attr_get_type(attr_attr); + + ret = mnl_attr_parse_nested(attr_attr, attr_cb, &tba_info); + if (ret < 0) + return MNL_CB_ERROR; + + if (policy_idx == policy_ctx->op_policy_idx && + attr_idx == policy_ctx->op_hdr_attr) { + attr = tba[NL_POLICY_TYPE_ATTR_POLICY_IDX]; + if (!attr) { + fprintf(stderr, "Error: no policy index in what was expected to be ethtool header attribute\n"); + return MNL_CB_ERROR; + } + policy_ctx->hdr_policy_found = true; + policy_ctx->hdr_policy_idx = mnl_attr_get_u32(attr); + } + + if (policy_ctx->hdr_policy_found && + policy_ctx->hdr_policy_idx == policy_idx && + attr_idx == ETHTOOL_A_HEADER_FLAGS) { + attr = tba[NL_POLICY_TYPE_ATTR_MASK]; + if (!attr) { + fprintf(stderr, "Error: validation mask not reported for ethtool header flags\n"); + return MNL_CB_ERROR; + } + + policy_ctx->flag_mask = mnl_attr_get_u64(attr); + } + + return MNL_CB_OK; +} + +static int read_flags_policy(struct nl_context *nlctx, struct nl_socket *nlsk, + unsigned int nlcmd, unsigned int hdrattr) +{ + struct ethtool_op_policy_query_ctx policy_ctx; + struct nl_msg_buff *msgbuff = &nlsk->msgbuff; + int ret; + + if (nlctx->ops_info[nlcmd].hdr_policy_loaded) + return 0; + + memset(&policy_ctx, 0, sizeof(policy_ctx)); + policy_ctx.nlctx = nlctx; + policy_ctx.op = nlcmd; + policy_ctx.op_hdr_attr = hdrattr; + + ret = __msg_init(msgbuff, GENL_ID_CTRL, CTRL_CMD_GETPOLICY, + NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, 1); + if (ret < 0) + return ret; + ret = -EMSGSIZE; + if (ethnla_put_u16(msgbuff, CTRL_ATTR_FAMILY_ID, nlctx->ethnl_fam)) + return ret; + if (ethnla_put_u32(msgbuff, CTRL_ATTR_OP, nlcmd)) + return ret; + + nlsock_sendmsg(nlsk, NULL); + nlsock_process_reply(nlsk, family_policy_cb, &policy_ctx); + + nlctx->ops_info[nlcmd].hdr_policy_loaded = 1; + nlctx->ops_info[nlcmd].hdr_flags = policy_ctx.flag_mask; + return 0; +} + +u32 get_stats_flag(struct nl_context *nlctx, unsigned int nlcmd, + unsigned int hdrattr) +{ + if (!nlctx->ctx->show_stats) + return 0; + if (nlcmd > ETHTOOL_MSG_USER_MAX || + !(nlctx->ops_info[nlcmd].op_flags & GENL_CMD_CAP_HASPOL)) + return 0; + + if (read_flags_policy(nlctx, nlctx->ethnl_socket, nlcmd, hdrattr) < 0) + return 0; + + return nlctx->ops_info[nlcmd].hdr_flags & ETHTOOL_FLAG_STATS; +} + +/* initialization */ + +static int genl_read_ops(struct nl_context *nlctx, + const struct nlattr *ops_attr) +{ + struct nl_op_info *ops_info; + struct nlattr *op_attr; + int ret; + + ops_info = calloc(__ETHTOOL_MSG_USER_CNT, sizeof(ops_info[0])); + if (!ops_info) + return -ENOMEM; + + mnl_attr_for_each_nested(op_attr, ops_attr) { + const struct nlattr *tb[CTRL_ATTR_OP_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + uint32_t op_id; + + ret = mnl_attr_parse_nested(op_attr, attr_cb, &tb_info); + if (ret < 0) + goto err; + + if (!tb[CTRL_ATTR_OP_ID] || !tb[CTRL_ATTR_OP_FLAGS]) + continue; + op_id = mnl_attr_get_u32(tb[CTRL_ATTR_OP_ID]); + if (op_id >= __ETHTOOL_MSG_USER_CNT) + continue; + + ops_info[op_id].op_flags = + mnl_attr_get_u32(tb[CTRL_ATTR_OP_FLAGS]); + } + + nlctx->ops_info = ops_info; + return 0; +err: + free(ops_info); + return ret; +} + +static void find_mc_group(struct nl_context *nlctx, struct nlattr *nest) +{ + const struct nlattr *grp_tb[CTRL_ATTR_MCAST_GRP_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(grp_tb); + struct nlattr *grp_attr; + int ret; + + mnl_attr_for_each_nested(grp_attr, nest) { + ret = mnl_attr_parse_nested(grp_attr, attr_cb, &grp_tb_info); + if (ret < 0) + return; + if (!grp_tb[CTRL_ATTR_MCAST_GRP_NAME] || + !grp_tb[CTRL_ATTR_MCAST_GRP_ID]) + continue; + if (strcmp(mnl_attr_get_str(grp_tb[CTRL_ATTR_MCAST_GRP_NAME]), + ETHTOOL_MCGRP_MONITOR_NAME)) + continue; + nlctx->ethnl_mongrp = + mnl_attr_get_u32(grp_tb[CTRL_ATTR_MCAST_GRP_ID]); + return; + } +} + +static int __maybe_unused family_info_cb(const struct nlmsghdr *nlhdr, + void *data) +{ + struct nl_context *nlctx = data; + struct nlattr *attr; + int ret; + + mnl_attr_for_each(attr, nlhdr, GENL_HDRLEN) { + switch (mnl_attr_get_type(attr)) { + case CTRL_ATTR_FAMILY_ID: + nlctx->ethnl_fam = mnl_attr_get_u16(attr); + break; + case CTRL_ATTR_OPS: + ret = genl_read_ops(nlctx, attr); + if (ret < 0) + return MNL_CB_ERROR; + break; + case CTRL_ATTR_MCAST_GROUPS: + find_mc_group(nlctx, attr); + break; + } + } + + return MNL_CB_OK; +} + +#ifdef TEST_ETHTOOL +static int get_genl_family(struct nl_context *nlctx __maybe_unused, + struct nl_socket *nlsk __maybe_unused) +{ + return 0; +} +#else +static int get_genl_family(struct nl_context *nlctx, struct nl_socket *nlsk) +{ + struct nl_msg_buff *msgbuff = &nlsk->msgbuff; + int ret; + + nlctx->suppress_nlerr = 2; + ret = __msg_init(msgbuff, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, + NLM_F_REQUEST | NLM_F_ACK, 1); + if (ret < 0) + goto out; + ret = -EMSGSIZE; + if (ethnla_put_strz(msgbuff, CTRL_ATTR_FAMILY_NAME, ETHTOOL_GENL_NAME)) + goto out; + + nlsock_sendmsg(nlsk, NULL); + nlsock_process_reply(nlsk, family_info_cb, nlctx); + ret = nlctx->ethnl_fam ? 0 : -EADDRNOTAVAIL; + +out: + nlctx->suppress_nlerr = 0; + return ret; +} +#endif + +int netlink_init(struct cmd_context *ctx) +{ + struct nl_context *nlctx; + int ret; + + nlctx = calloc(1, sizeof(*nlctx)); + if (!nlctx) + return -ENOMEM; + nlctx->ctx = ctx; + ret = nlsock_init(nlctx, &nlctx->ethnl_socket, NETLINK_GENERIC); + if (ret < 0) + goto out_free; + ret = get_genl_family(nlctx, nlctx->ethnl_socket); + if (ret < 0) + goto out_nlsk; + + ctx->nlctx = nlctx; + return 0; + +out_nlsk: + nlsock_done(nlctx->ethnl_socket); +out_free: + free(nlctx->ops_info); + free(nlctx); + return ret; +} + +static void netlink_done(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + + if (!nlctx) + return; + + nlsock_done(nlctx->ethnl_socket); + nlsock_done(nlctx->ethnl2_socket); + nlsock_done(nlctx->rtnl_socket); + free(nlctx->ops_info); + free(nlctx); + ctx->nlctx = NULL; + cleanup_all_strings(); +} + +/** + * netlink_run_handler() - run netlink handler for subcommand + * @ctx: command context + * @nlchk: netlink capability check + * @nlfunc: subcommand netlink handler to call + * @no_fallback: there is no ioctl fallback handler + * + * This function returns only if ioctl() handler should be run as fallback. + * Otherwise it exits with appropriate return code. + */ +void netlink_run_handler(struct cmd_context *ctx, nl_chk_t nlchk, + nl_func_t nlfunc, bool no_fallback) +{ + bool wildcard = ctx->devname && !strcmp(ctx->devname, WILDCARD_DEVNAME); + bool wildcard_unsupported, ioctl_fallback; + struct nl_context *nlctx; + const char *reason; + int ret; + + if (nlchk && !nlchk(ctx)) { + reason = "ioctl-only request"; + goto no_support; + } + if (ctx->devname && strlen(ctx->devname) >= ALTIFNAMSIZ) { + fprintf(stderr, "device name '%s' longer than %u characters\n", + ctx->devname, ALTIFNAMSIZ - 1); + exit(1); + } + + if (!nlfunc) { + reason = "ethtool netlink support for subcommand missing"; + goto no_support; + } + if (netlink_init(ctx)) { + reason = "netlink interface initialization failed"; + goto no_support; + } + nlctx = ctx->nlctx; + + ret = nlfunc(ctx); + wildcard_unsupported = nlctx->wildcard_unsupported; + ioctl_fallback = nlctx->ioctl_fallback; + netlink_done(ctx); + + if (no_fallback || ret != -EOPNOTSUPP || !ioctl_fallback) { + if (wildcard_unsupported) + fprintf(stderr, "%s\n", + "subcommand does not support wildcard dump"); + exit(ret >= 0 ? ret : 1); + } + if (wildcard_unsupported) + reason = "subcommand does not support wildcard dump"; + else + reason = "kernel netlink support for subcommand missing"; + +no_support: + if (no_fallback) { + fprintf(stderr, "%s, subcommand not supported by ioctl\n", + reason); + exit(1); + } + if (wildcard) { + fprintf(stderr, "%s, wildcard dump not supported\n", reason); + exit(1); + } + if (ctx->devname && strlen(ctx->devname) >= IFNAMSIZ) { + fprintf(stderr, + "%s, device name longer than %u not supported\n", + reason, IFNAMSIZ - 1); + exit(1); + } + + /* fallback to ioctl() */ +} diff --git a/netlink/netlink.h b/netlink/netlink.h new file mode 100644 index 0000000..f43c1bf --- /dev/null +++ b/netlink/netlink.h @@ -0,0 +1,164 @@ +/* + * netlink.h - common interface for all netlink code + * + * Declarations of data structures, global data and helpers for netlink code + */ + +#ifndef ETHTOOL_NETLINK_INT_H__ +#define ETHTOOL_NETLINK_INT_H__ + +#include +#include +#include +#include +#include "nlsock.h" + +#define WILDCARD_DEVNAME "*" +#define CMDMASK_WORDS DIV_ROUND_UP(__ETHTOOL_MSG_KERNEL_CNT, 32) + +enum link_mode_class { + LM_CLASS_UNKNOWN, + LM_CLASS_REAL, + LM_CLASS_AUTONEG, + LM_CLASS_PORT, + LM_CLASS_PAUSE, + LM_CLASS_FEC, +}; + +struct nl_op_info { + uint32_t op_flags; + uint32_t hdr_flags; + uint8_t hdr_policy_loaded:1; +}; + +struct nl_context { + struct cmd_context *ctx; + void *cmd_private; + const char *devname; + bool is_dump; + int exit_code; + unsigned int suppress_nlerr; + uint16_t ethnl_fam; + uint32_t ethnl_mongrp; + struct nl_op_info *ops_info; + struct nl_socket *ethnl_socket; + struct nl_socket *ethnl2_socket; + struct nl_socket *rtnl_socket; + bool is_monitor; + uint32_t filter_cmds[CMDMASK_WORDS]; + const char *filter_devname; + bool no_banner; + const char *cmd; + const char *param; + char **argp; + unsigned int argc; + bool ioctl_fallback; + bool wildcard_unsupported; +}; + +struct attr_tb_info { + const struct nlattr **tb; + unsigned int max_type; +}; + +#define DECLARE_ATTR_TB_INFO(tbl) \ + struct attr_tb_info tbl ## _info = { (tbl), (MNL_ARRAY_SIZE(tbl) - 1) } + +int nomsg_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int attr_cb(const struct nlattr *attr, void *data); + +int netlink_init(struct cmd_context *ctx); +bool netlink_cmd_check(struct cmd_context *ctx, unsigned int cmd, + bool allow_wildcard); +const char *get_dev_name(const struct nlattr *nest); +int get_dev_info(const struct nlattr *nest, int *ifindex, char *ifname); +u32 get_stats_flag(struct nl_context *nlctx, unsigned int nlcmd, + unsigned int hdrattr); + +int linkmodes_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int linkinfo_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int wol_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int debug_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int features_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int privflags_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int rings_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int channels_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int coalesce_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int eee_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int cable_test_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int cable_test_ntf_cb(const struct nlmsghdr *nlhdr, void *data); +int cable_test_tdr_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int cable_test_tdr_ntf_cb(const struct nlmsghdr *nlhdr, void *data); +int fec_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int module_reply_cb(const struct nlmsghdr *nlhdr, void *data); + +/* dump helpers */ + +int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset, + bool mask, unsigned int class, const char *before, + const char *between, const char *after, + const char *if_none); + +static inline void show_u32(const struct nlattr *attr, const char *label) +{ + if (attr) + printf("%s%u\n", label, mnl_attr_get_u32(attr)); + else + printf("%sn/a\n", label); +} + +static inline const char *u8_to_bool(const uint8_t *val) +{ + if (val) + return *val ? "on" : "off"; + else + return "n/a"; +} + +static inline void show_bool_val(const char *key, const char *fmt, uint8_t *val) +{ + if (is_json_context()) { + if (val) + print_bool(PRINT_JSON, key, NULL, val); + } else { + print_string(PRINT_FP, NULL, fmt, u8_to_bool(val)); + } +} + +static inline void show_bool(const char *key, const char *fmt, + const struct nlattr *attr) +{ + show_bool_val(key, fmt, attr ? mnl_attr_get_payload(attr) : NULL); +} + +/* misc */ + +static inline void copy_devname(char *dst, const char *src) +{ + strncpy(dst, src, ALTIFNAMSIZ); + dst[ALTIFNAMSIZ - 1] = '\0'; +} + +static inline bool dev_ok(const struct nl_context *nlctx) +{ + return !nlctx->filter_devname || + (nlctx->devname && + !strcmp(nlctx->devname, nlctx->filter_devname)); +} + +static inline int netlink_init_ethnl2_socket(struct nl_context *nlctx) +{ + if (nlctx->ethnl2_socket) + return 0; + return nlsock_init(nlctx, &nlctx->ethnl2_socket, NETLINK_GENERIC); +} + +static inline int netlink_init_rtnl_socket(struct nl_context *nlctx) +{ + if (nlctx->rtnl_socket) + return 0; + return nlsock_init(nlctx, &nlctx->rtnl_socket, NETLINK_ROUTE); +} + +#endif /* ETHTOOL_NETLINK_INT_H__ */ diff --git a/netlink/nlsock.c b/netlink/nlsock.c new file mode 100644 index 0000000..0ec2738 --- /dev/null +++ b/netlink/nlsock.c @@ -0,0 +1,405 @@ +/* + * nlsock.c - netlink socket + * + * Data structure and code for netlink socket abstraction. + */ + +#include +#include + +#include "../internal.h" +#include "nlsock.h" +#include "netlink.h" +#include "prettymsg.h" + +#define NLSOCK_RECV_BUFFSIZE 65536 + +static void ctrl_msg_summary(const struct nlmsghdr *nlhdr) +{ + const struct nlmsgerr *nlerr; + + switch (nlhdr->nlmsg_type) { + case NLMSG_NOOP: + printf(" noop\n"); + break; + case NLMSG_ERROR: + printf(" error"); + if (nlhdr->nlmsg_len < NLMSG_HDRLEN + sizeof(*nlerr)) { + printf(" malformed\n"); + break; + } + nlerr = mnl_nlmsg_get_payload(nlhdr); + printf(" errno=%d\n", nlerr->error); + break; + case NLMSG_DONE: + printf(" done\n"); + break; + case NLMSG_OVERRUN: + printf(" overrun\n"); + break; + default: + printf(" type %u\n", nlhdr->nlmsg_type); + break; + } +} + +static void genl_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam, + bool outgoing, bool pretty) +{ + if (nlhdr->nlmsg_type == ethnl_fam) { + const struct pretty_nlmsg_desc *msg_desc; + const struct genlmsghdr *ghdr; + unsigned int n_desc; + + printf(" ethool"); + if (nlhdr->nlmsg_len < NLMSG_HDRLEN + GENL_HDRLEN) { + printf(" malformed\n"); + return; + } + ghdr = mnl_nlmsg_get_payload(nlhdr); + + msg_desc = outgoing ? ethnl_umsg_desc : ethnl_kmsg_desc; + n_desc = outgoing ? ethnl_umsg_n_desc : ethnl_kmsg_n_desc; + if (ghdr->cmd < n_desc && msg_desc[ghdr->cmd].name) + printf(" %s", msg_desc[ghdr->cmd].name); + else + printf(" cmd %u", ghdr->cmd); + fputc('\n', stdout); + + if (pretty) + pretty_print_genlmsg(nlhdr, msg_desc, n_desc, 0); + return; + } + + if (nlhdr->nlmsg_type == GENL_ID_CTRL) { + printf(" genl-ctrl\n"); + if (pretty) + pretty_print_genlmsg(nlhdr, genlctrl_msg_desc, + genlctrl_msg_n_desc, 0); + } else { + fputc('\n', stdout); + if (pretty) + pretty_print_genlmsg(nlhdr, NULL, 0, 0); + } +} + +static void rtnl_msg_summary(const struct nlmsghdr *nlhdr, bool pretty) +{ + unsigned int type = nlhdr->nlmsg_type; + + if (type < rtnl_msg_n_desc && rtnl_msg_desc[type].name) + printf(" %s\n", rtnl_msg_desc[type].name); + else + printf(" type %u\n", type); + + if (pretty) + pretty_print_rtnlmsg(nlhdr, 0); +} + +static void debug_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam, + int nl_fam, bool outgoing, bool pretty) +{ + printf(" msg length %u", nlhdr->nlmsg_len); + + if (nlhdr->nlmsg_type < NLMSG_MIN_TYPE) { + ctrl_msg_summary(nlhdr); + return; + } + + switch(nl_fam) { + case NETLINK_GENERIC: + genl_msg_summary(nlhdr, ethnl_fam, outgoing, pretty); + break; + case NETLINK_ROUTE: + rtnl_msg_summary(nlhdr, pretty); + break; + default: + fputc('\n', stdout); + break; + } +} + +static void debug_msg(struct nl_socket *nlsk, const void *msg, unsigned int len, + bool outgoing) +{ + const char *dirlabel = outgoing ? "sending" : "received"; + uint32_t debug = nlsk->nlctx->ctx->debug; + const struct nlmsghdr *nlhdr = msg; + bool summary, dump, pretty; + const char *nl_fam_label; + int left = len; + + summary = debug_on(debug, DEBUG_NL_MSGS); + dump = debug_on(debug, + outgoing ? DEBUG_NL_DUMP_SND : DEBUG_NL_DUMP_RCV); + pretty = debug_on(debug, DEBUG_NL_PRETTY_MSG); + if (!summary && !dump) + return; + switch(nlsk->nl_fam) { + case NETLINK_GENERIC: + nl_fam_label = "genetlink"; + break; + case NETLINK_ROUTE: + nl_fam_label = "rtnetlink"; + break; + default: + nl_fam_label = "netlink"; + break; + } + printf("%s %s packet (%u bytes):\n", dirlabel, nl_fam_label, len); + + while (nlhdr && left > 0 && mnl_nlmsg_ok(nlhdr, left)) { + if (summary) + debug_msg_summary(nlhdr, nlsk->nlctx->ethnl_fam, + nlsk->nl_fam, outgoing, pretty); + if (dump) + mnl_nlmsg_fprintf(stdout, nlhdr, nlhdr->nlmsg_len, + GENL_HDRLEN); + + nlhdr = mnl_nlmsg_next(nlhdr, &left); + } +} + +/** + * nlsock_process_ack() - process NLMSG_ERROR message from kernel + * @nlhdr: pointer to netlink header + * @len: length of received data (from nlhdr to end of buffer) + * @suppress_nlerr: 0 show all errors, 1 silence -EOPNOTSUPP, 2 silence all + * + * Return: error code extracted from the message + */ +static int nlsock_process_ack(struct nlmsghdr *nlhdr, unsigned long len, + unsigned int suppress_nlerr, bool pretty) +{ + const struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + unsigned int err_offset = 0; + unsigned int tlv_offset; + struct nlmsgerr *nlerr; + bool silent; + + if ((len < NLMSG_HDRLEN + sizeof(*nlerr)) || (len < nlhdr->nlmsg_len)) + return -EFAULT; + nlerr = mnl_nlmsg_get_payload(nlhdr); + silent = suppress_nlerr >= 2 || + (suppress_nlerr && nlerr->error == -EOPNOTSUPP); + if (silent || !(nlhdr->nlmsg_flags & NLM_F_ACK_TLVS)) + goto tlv_done; + + tlv_offset = sizeof(*nlerr); + if (!(nlhdr->nlmsg_flags & NLM_F_CAPPED)) + tlv_offset += MNL_ALIGN(mnl_nlmsg_get_payload_len(&nlerr->msg)); + if (mnl_attr_parse(nlhdr, tlv_offset, attr_cb, &tb_info) < 0) + goto tlv_done; + + if (tb[NLMSGERR_ATTR_MSG]) { + const char *msg = mnl_attr_get_str(tb[NLMSGERR_ATTR_MSG]); + + fprintf(stderr, "netlink %s: %s", + nlerr->error ? "error" : "warning", msg); + if (!pretty && tb[NLMSGERR_ATTR_OFFS]) + fprintf(stderr, " (offset %u)", + mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS])); + fputc('\n', stderr); + } + if (tb[NLMSGERR_ATTR_OFFS]) + err_offset = mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]); + +tlv_done: + if (nlerr->error && !silent) { + errno = -nlerr->error; + perror("netlink error"); + } + if (pretty && !(nlhdr->nlmsg_flags & NLM_F_CAPPED) && + nlhdr->nlmsg_len >= NLMSG_HDRLEN + nlerr->msg.nlmsg_len) { + fprintf(stderr, "offending message%s:\n", + err_offset ? " and attribute" : ""); + pretty_print_genlmsg(&nlerr->msg, ethnl_umsg_desc, + ethnl_umsg_n_desc, err_offset); + } + return nlerr->error; +} + +/** + * nlsock_process_reply() - process reply packet(s) from kernel + * @nlsk: netlink socket to read from + * @reply_cb: callback to process each message + * @data: pointer passed as argument to @reply_cb callback + * + * Read packets from kernel and pass reply messages to @reply_cb callback + * until an error is encountered or NLMSG_ERR message is received. In the + * latter case, return value is the error code extracted from it. + * + * Return: 0 on success or negative error code + */ +int nlsock_process_reply(struct nl_socket *nlsk, mnl_cb_t reply_cb, void *data) +{ + struct nl_msg_buff *msgbuff = &nlsk->msgbuff; + struct nlmsghdr *nlhdr; + ssize_t len; + char *buff; + int ret; + + ret = msgbuff_realloc(msgbuff, NLSOCK_RECV_BUFFSIZE); + if (ret < 0) + return ret; + buff = msgbuff->buff; + + do { + len = mnl_socket_recvfrom(nlsk->sk, buff, msgbuff->size); + if (len <= 0) + return (len ? -EFAULT : 0); + debug_msg(nlsk, buff, len, false); + if (len < NLMSG_HDRLEN) + return -EFAULT; + + nlhdr = (struct nlmsghdr *)buff; + if (nlhdr->nlmsg_type == NLMSG_ERROR) { + unsigned int suppress = nlsk->nlctx->suppress_nlerr; + bool pretty; + + pretty = debug_on(nlsk->nlctx->ctx->debug, + DEBUG_NL_PRETTY_MSG); + return nlsock_process_ack(nlhdr, len, suppress, pretty); + } + + msgbuff->nlhdr = nlhdr; + msgbuff->genlhdr = mnl_nlmsg_get_payload(nlhdr); + msgbuff->payload = + mnl_nlmsg_get_payload_offset(nlhdr, GENL_HDRLEN); + ret = mnl_cb_run(buff, len, nlsk->seq, nlsk->port, reply_cb, + data); + } while (ret > 0); + + return ret; +} + +int nlsock_prep_get_request(struct nl_socket *nlsk, unsigned int nlcmd, + uint16_t hdr_attrtype, u32 flags) +{ + unsigned int nlm_flags = NLM_F_REQUEST | NLM_F_ACK; + struct nl_context *nlctx = nlsk->nlctx; + const char *devname = nlctx->ctx->devname; + int ret; + + if (devname && !strcmp(devname, WILDCARD_DEVNAME)) { + devname = NULL; + nlm_flags |= NLM_F_DUMP; + } + nlctx->is_dump = !devname; + + ret = msg_init(nlctx, &nlsk->msgbuff, nlcmd, nlm_flags); + if (ret < 0) + return ret; + if (ethnla_fill_header(&nlsk->msgbuff, hdr_attrtype, devname, flags)) + return -EMSGSIZE; + + return 0; +} + +#ifndef TEST_ETHTOOL +/** + * nlsock_sendmsg() - send a netlink message to kernel + * @nlsk: netlink socket + * @altbuff: alternative message buffer; if null, use buffer embedded in @nlsk + * + * Return: sent size or negative error code + */ +ssize_t nlsock_sendmsg(struct nl_socket *nlsk, struct nl_msg_buff *altbuff) +{ + struct nl_msg_buff *msgbuff = altbuff ?: &nlsk->msgbuff; + struct nlmsghdr *nlhdr = msgbuff->nlhdr; + + nlhdr->nlmsg_seq = ++nlsk->seq; + debug_msg(nlsk, msgbuff->buff, nlhdr->nlmsg_len, true); + return mnl_socket_sendto(nlsk->sk, nlhdr, nlhdr->nlmsg_len); +} +#endif + +/** + * nlsock_send_get_request() - send request and process reply + * @nlsk: netlink socket + * @cb: callback to process reply message(s) + * + * This simple helper only handles the most common case when the embedded + * message buffer is sent and @cb takes netlink context (struct nl_context) + * as last argument. + */ +int nlsock_send_get_request(struct nl_socket *nlsk, mnl_cb_t cb) +{ + int ret; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + goto err; + ret = nlsock_process_reply(nlsk, cb, nlsk->nlctx); + if (ret == 0) + return 0; +err: + return nlsk->nlctx->exit_code ?: 1; +} + +/** + * nlsock_init() - allocate and initialize netlink socket + * @nlctx: netlink context + * @__nlsk: store pointer to the allocated socket here + * @nl_fam: netlink family (e.g. NETLINK_GENERIC or NETLINK_ROUTE) + * + * Allocate and initialize netlink socket and its embedded message buffer. + * Cleans up on error, caller is responsible for destroying the socket with + * nlsock_done() on success. + * + * Return: 0 on success or negative error code + */ +int nlsock_init(struct nl_context *nlctx, struct nl_socket **__nlsk, int nl_fam) +{ + struct nl_socket *nlsk; + int val; + int ret; + + nlsk = calloc(1, sizeof(*nlsk)); + if (!nlsk) + return -ENOMEM; + nlsk->nlctx = nlctx; + msgbuff_init(&nlsk->msgbuff); + + ret = -ECONNREFUSED; + nlsk->sk = mnl_socket_open(nl_fam); + if (!nlsk->sk) + goto out_msgbuff; + val = 1; + mnl_socket_setsockopt(nlsk->sk, NETLINK_EXT_ACK, &val, sizeof(val)); + ret = mnl_socket_bind(nlsk->sk, 0, MNL_SOCKET_AUTOPID); + if (ret < 0) + goto out_close; + nlsk->port = mnl_socket_get_portid(nlsk->sk); + nlsk->nl_fam = nl_fam; + + *__nlsk = nlsk; + return 0; + +out_close: + if (nlsk->sk) + mnl_socket_close(nlsk->sk); +out_msgbuff: + msgbuff_done(&nlsk->msgbuff); + free(nlsk); + return ret; +} + +/** + * nlsock_done() - destroy a netlink socket + * @nlsk: netlink socket + * + * Close the socket and free the structure and related data. + */ +void nlsock_done(struct nl_socket *nlsk) +{ + if (!nlsk) + return; + if (nlsk->sk) + mnl_socket_close(nlsk->sk); + msgbuff_done(&nlsk->msgbuff); + memset(nlsk, '\0', sizeof(*nlsk)); + free(nlsk); +} diff --git a/netlink/nlsock.h b/netlink/nlsock.h new file mode 100644 index 0000000..b015f86 --- /dev/null +++ b/netlink/nlsock.h @@ -0,0 +1,45 @@ +/* + * nlsock.h - netlink socket + * + * Declarations of netlink socket structure and related functions. + */ + +#ifndef ETHTOOL_NETLINK_NLSOCK_H__ +#define ETHTOOL_NETLINK_NLSOCK_H__ + +#include +#include +#include +#include +#include "msgbuff.h" + +struct nl_context; + +/** + * struct nl_socket - netlink socket abstraction + * @nlctx: netlink context + * @sk: libmnl socket handle + * @msgbuff: embedded message buffer used by default + * @port: port number for netlink header + * @seq: autoincremented sequence number for netlink header + * @nl_fam: netlink family (e.g. NETLINK_GENERIC or NETLINK_ROUTE) + */ +struct nl_socket { + struct nl_context *nlctx; + struct mnl_socket *sk; + struct nl_msg_buff msgbuff; + unsigned int port; + unsigned int seq; + int nl_fam; +}; + +int nlsock_init(struct nl_context *nlctx, struct nl_socket **__nlsk, + int nl_fam); +void nlsock_done(struct nl_socket *nlsk); +int nlsock_prep_get_request(struct nl_socket *nlsk, unsigned int nlcmd, + uint16_t hdr_attrtype, u32 flags); +ssize_t nlsock_sendmsg(struct nl_socket *nlsk, struct nl_msg_buff *__msgbuff); +int nlsock_send_get_request(struct nl_socket *nlsk, mnl_cb_t cb); +int nlsock_process_reply(struct nl_socket *nlsk, mnl_cb_t reply_cb, void *data); + +#endif /* ETHTOOL_NETLINK_NLSOCK_H__ */ diff --git a/netlink/parser.c b/netlink/parser.c new file mode 100644 index 0000000..f982f22 --- /dev/null +++ b/netlink/parser.c @@ -0,0 +1,1141 @@ +/* + * parser.c - netlink command line parser + * + * Implementation of command line parser used by netlink code. + */ + +#include +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "parser.h" + +static void parser_err_unknown_param(struct nl_context *nlctx) +{ + fprintf(stderr, "ethtool (%s): unknown parameter '%s'\n", nlctx->cmd, + nlctx->param); +} + +static void parser_err_dup_param(struct nl_context *nlctx) +{ + fprintf(stderr, "ethtool (%s): duplicate parameter '%s'\n", nlctx->cmd, + nlctx->param); +} + +static void parser_err_min_argc(struct nl_context *nlctx, unsigned int min_argc) +{ + if (min_argc == 1) + fprintf(stderr, "ethtool (%s): no value for parameter '%s'\n", + nlctx->cmd, nlctx->param); + else + fprintf(stderr, + "ethtool (%s): parameter '%s' requires %u words\n", + nlctx->cmd, nlctx->param, min_argc); +} + +static void parser_err_invalid_value(struct nl_context *nlctx, const char *val) +{ + fprintf(stderr, "ethtool (%s): invalid value '%s' for parameter '%s'\n", + nlctx->cmd, val, nlctx->param); +} + +static void parser_err_invalid_flag(struct nl_context *nlctx, const char *flag) +{ + fprintf(stderr, "ethtool (%s): flag '%s' for parameter '%s' is not followed by 'on' or 'off'\n", + nlctx->cmd, flag, nlctx->param); +} + +static bool __prefix_0x(const char *p) +{ + return p[0] == '0' && (p[1] == 'x' || p[1] == 'X'); +} + +static float parse_float(const char *arg, float *result, float min, + float max) +{ + char *endptr; + float val; + + if (!arg || !arg[0]) + return -EINVAL; + val = strtof(arg, &endptr); + if (*endptr || val < min || val > max) + return -EINVAL; + + *result = val; + return 0; +} + +static int __parse_u32(const char *arg, uint32_t *result, uint32_t min, + uint32_t max, int base) +{ + unsigned long long val; + char *endptr; + + if (!arg || !arg[0]) + return -EINVAL; + val = strtoul(arg, &endptr, base); + if (*endptr || val < min || val > max) + return -EINVAL; + + *result = (uint32_t)val; + return 0; +} + +static int parse_u32d(const char *arg, uint32_t *result) +{ + return __parse_u32(arg, result, 0, 0xffffffff, 10); +} + +static int parse_x32(const char *arg, uint32_t *result) +{ + return __parse_u32(arg, result, 0, 0xffffffff, 16); +} + +int parse_u32(const char *arg, uint32_t *result) +{ + if (!arg) + return -EINVAL; + if (__prefix_0x(arg)) + return parse_x32(arg + 2, result); + else + return parse_u32d(arg, result); +} + +static int parse_u8(const char *arg, uint8_t *result) +{ + uint32_t val; + int ret = parse_u32(arg, &val); + + if (ret < 0) + return ret; + if (val > UINT8_MAX) + return -EINVAL; + + *result = (uint8_t)val; + return 0; +} + +static int lookup_u32(const char *arg, uint32_t *result, + const struct lookup_entry_u32 *tbl) +{ + if (!arg) + return -EINVAL; + while (tbl->arg) { + if (!strcmp(tbl->arg, arg)) { + *result = tbl->val; + return 0; + } + tbl++; + } + + return -EINVAL; +} + +static int lookup_u8(const char *arg, uint8_t *result, + const struct lookup_entry_u8 *tbl) +{ + if (!arg) + return -EINVAL; + while (tbl->arg) { + if (!strcmp(tbl->arg, arg)) { + *result = tbl->val; + return 0; + } + tbl++; + } + + return -EINVAL; +} + +/* Parser handler for a flag. Expects a name (with no additional argument), + * generates NLA_FLAG or sets a bool (if the name was present). + */ +int nl_parse_flag(struct nl_context *nlctx __maybe_unused, uint16_t type, + const void *data __maybe_unused, struct nl_msg_buff *msgbuff, + void *dest) +{ + if (dest) + *(bool *)dest = true; + return (type && ethnla_put_flag(msgbuff, type, true)) ? -EMSGSIZE : 0; +} + +/* Parser handler for null terminated string. Expects a string argument, + * generates NLA_NUL_STRING or fills const char * + */ +int nl_parse_string(struct nl_context *nlctx, uint16_t type, + const void *data __maybe_unused, + struct nl_msg_buff *msgbuff, void *dest) +{ + const char *arg = *nlctx->argp; + + nlctx->argp++; + nlctx->argc--; + + if (dest) + *(const char **)dest = arg; + return (type && ethnla_put_strz(msgbuff, type, arg)) ? -EMSGSIZE : 0; +} + +/* Parser handler for unsigned 32-bit integer. Expects a numeric argument + * (may use 0x prefix), generates NLA_U32 or fills an uint32_t. + */ +int nl_parse_direct_u32(struct nl_context *nlctx, uint16_t type, + const void *data __maybe_unused, + struct nl_msg_buff *msgbuff, void *dest) +{ + const char *arg = *nlctx->argp; + uint32_t val; + int ret; + + nlctx->argp++; + nlctx->argc--; + ret = parse_u32(arg, &val); + if (ret < 0) { + parser_err_invalid_value(nlctx, arg); + return ret; + } + + if (dest) + *(uint32_t *)dest = val; + return (type && ethnla_put_u32(msgbuff, type, val)) ? -EMSGSIZE : 0; +} + +/* Parser handler for unsigned 32-bit integer. Expects a numeric argument + * (may use 0x prefix), generates NLA_U32 or fills an uint32_t. + */ +int nl_parse_direct_u8(struct nl_context *nlctx, uint16_t type, + const void *data __maybe_unused, + struct nl_msg_buff *msgbuff, void *dest) +{ + const char *arg = *nlctx->argp; + uint8_t val; + int ret; + + nlctx->argp++; + nlctx->argc--; + ret = parse_u8(arg, &val); + if (ret < 0) { + parser_err_invalid_value(nlctx, arg); + return ret; + } + + if (dest) + *(uint8_t *)dest = val; + return (type && ethnla_put_u8(msgbuff, type, val)) ? -EMSGSIZE : 0; +} + +/* Parser handler for float meters and convert it to cm. Generates + * NLA_U32 or fills an uint32_t. + */ +int nl_parse_direct_m2cm(struct nl_context *nlctx, uint16_t type, + const void *data __maybe_unused, + struct nl_msg_buff *msgbuff, void *dest) +{ + const char *arg = *nlctx->argp; + float meters; + uint32_t cm; + int ret; + + nlctx->argp++; + nlctx->argc--; + ret = parse_float(arg, &meters, 0, 150); + if (ret < 0) { + parser_err_invalid_value(nlctx, arg); + return ret; + } + + cm = (uint32_t)(meters * 100 + 0.5); + if (dest) + *(uint32_t *)dest = cm; + return (type && ethnla_put_u32(msgbuff, type, cm)) ? -EMSGSIZE : 0; +} + +/* Parser handler for (tri-state) bool. Expects "name on|off", generates + * NLA_U8 which is 1 for "on" and 0 for "off". + */ +int nl_parse_u8bool(struct nl_context *nlctx, uint16_t type, + const void *data __maybe_unused, + struct nl_msg_buff *msgbuff, void *dest) +{ + const char *arg = *nlctx->argp; + int ret; + + nlctx->argp++; + nlctx->argc--; + if (!strcmp(arg, "on")) { + if (dest) + *(uint8_t *)dest = 1; + ret = type ? ethnla_put_u8(msgbuff, type, 1) : 0; + } else if (!strcmp(arg, "off")) { + if (dest) + *(uint8_t *)dest = 0; + ret = type ? ethnla_put_u8(msgbuff, type, 0) : 0; + } else { + parser_err_invalid_value(nlctx, arg); + return -EINVAL; + } + + return ret ? -EMSGSIZE : 0; +} + +/* Parser handler for 32-bit lookup value. Expects a string argument, looks it + * up in a table, generates NLA_U32 or fills uint32_t variable. The @data + * parameter is a null terminated array of struct lookup_entry_u32. + */ +int nl_parse_lookup_u32(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest) +{ + const char *arg = *nlctx->argp; + uint32_t val; + int ret; + + nlctx->argp++; + nlctx->argc--; + ret = lookup_u32(arg, &val, data); + if (ret < 0) { + parser_err_invalid_value(nlctx, arg); + return ret; + } + + if (dest) + *(uint32_t *)dest = val; + return (type && ethnla_put_u32(msgbuff, type, val)) ? -EMSGSIZE : 0; +} + +/* Parser handler for 8-bit lookup value. Expects a string argument, looks it + * up in a table, generates NLA_U8 or fills uint8_t variable. The @data + * parameter is a null terminated array of struct lookup_entry_u8. + */ +int nl_parse_lookup_u8(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest) +{ + const char *arg = *nlctx->argp; + uint8_t val; + int ret; + + nlctx->argp++; + nlctx->argc--; + ret = lookup_u8(arg, &val, data); + if (ret < 0) { + parser_err_invalid_value(nlctx, arg); + return ret; + } + + if (dest) + *(uint8_t *)dest = val; + return (type && ethnla_put_u8(msgbuff, type, val)) ? -EMSGSIZE : 0; +} + +/* number of significant bits */ +static unsigned int __nsb(uint32_t x) +{ + unsigned int ret = 0; + + if (x & 0xffff0000U) { + x >>= 16; + ret += 16; + } + if (x & 0xff00U) { + x >>= 8; + ret += 8; + } + if (x & 0xf0U) { + x >>= 4; + ret += 4; + } + if (x & 0xcU) { + x >>= 2; + ret += 2; + } + if (x & 0x2U) { + x >>= 1; + ret += 1; + } + + return ret + x; +} + +static bool __is_hex(char c) +{ + if (isdigit(c)) + return true; + else + return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + +static unsigned int __hex_val(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 0xa; + if (c >= 'A' && c <= 'F') + return c - 'A' + 0xa; + return 0; +} + +static bool __bytestr_delim(const char *p, char delim) +{ + return !*p || (delim ? (*p == delim) : !__is_hex(*p)); +} + +/* Parser handler for generic byte string in MAC-like format. Expects string + * argument in the "[[:xdigit:]]{2}(:[[:xdigit:]]{2})*" format, generates + * NLA_BINARY or fills a struct byte_str_value (if @dest is not null and the + * handler succeeds, caller is responsible for freeing the value). The @data + * parameter points to struct byte_str_parser_data. + */ +int nl_parse_byte_str(struct nl_context *nlctx, uint16_t type, const void *data, + struct nl_msg_buff *msgbuff, void *dest) +{ + const struct byte_str_parser_data *pdata = data; + struct byte_str_value *dest_value = dest; + const char *arg = *nlctx->argp; + uint8_t *val = NULL; + unsigned int len, i; + const char *p; + int ret; + + nlctx->argp++; + nlctx->argc--; + + len = 0; + p = arg; + if (!*p) + goto err; + while (true) { + len++; + if (!__bytestr_delim(p, pdata->delim)) + p++; + if (!__bytestr_delim(p, pdata->delim)) + p++; + if (!__bytestr_delim(p, pdata->delim)) + goto err; + if (!*p) + break; + p++; + if (*p && __bytestr_delim(p, pdata->delim)) + goto err; + } + if (len < pdata->min_len || (pdata->max_len && len > pdata->max_len)) + goto err; + val = malloc(len); + if (!val) + return -ENOMEM; + + p = arg; + for (i = 0; i < len; i++) { + uint8_t byte = 0; + + if (!__is_hex(*p)) + goto err; + while (__is_hex(*p)) + byte = 16 * byte + __hex_val(*p++); + if (!__bytestr_delim(p, pdata->delim)) + goto err; + val[i] = byte; + if (*p) + p++; + } + ret = type ? ethnla_put(msgbuff, type, len, val) : 0; + if (dest) { + dest_value->len = len; + dest_value->data = val; + } else { + free(val); + } + return ret; + +err: + free(val); + fprintf(stderr, "ethtool (%s): invalid value '%s' of parameter '%s'\n", + nlctx->cmd, arg, nlctx->param); + return -EINVAL; +} + +/* Parser handler for parameters recognized for backward compatibility but + * supposed to fail without passing to kernel. Does not generate any netlink + * attributes of fill any variable. The @data parameter points to struct + * error_parser_params (error message, return value and number of extra + * arguments to skip). + */ +int nl_parse_error(struct nl_context *nlctx, uint16_t type __maybe_unused, + const void *data, struct nl_msg_buff *msgbuff __maybe_unused, + void *dest __maybe_unused) +{ + const struct error_parser_data *parser_data = data; + unsigned int skip = parser_data->extra_args; + + fprintf(stderr, "ethtool (%s): ", nlctx->cmd); + fprintf(stderr, parser_data->err_msg, nlctx->param); + if (nlctx->argc < skip) { + fprintf(stderr, "ethtool (%s): too few arguments for parameter '%s' (expected %u)\n", + nlctx->cmd, nlctx->param, skip); + } else { + nlctx->argp += skip; + nlctx->argc -= skip; + } + + return parser_data->ret_val; +} + +/* bitset parser handlers */ + +/* Return true if a bitset argument should be parsed as numeric, i.e. + * (a) it starts with '0x' + * (b) it consists only of hex digits and at most one slash which can be + * optionally followed by "0x"; if no_mask is true, slash is not allowed + */ +static bool is_numeric_bitset(const char *arg, bool no_mask) +{ + const char *p = arg; + bool has_slash = false; + + if (!arg) + return false; + if (__prefix_0x(arg)) + return true; + while (*p) { + if (*p == '/') { + if (has_slash || no_mask) + return false; + has_slash = true; + p++; + if (__prefix_0x(p)) + p += 2; + continue; + } + if (!__is_hex(*p)) + return false; + p++; + } + return true; +} + +#define __MAX_U32_DIGITS 10 + +/* Parse hex string (without leading "0x") into a bitmap consisting of 32-bit + * words. Caller must make sure arg is at least len characters long and dst has + * place for at least (len + 7) / 8 32-bit words. If force_hex is false, allow + * also base 10 unsigned 32-bit value. + * + * Returns number of significant bits in the bitmap on success and negative + * value on error. + */ +static int __parse_num_string(const char *arg, unsigned int len, uint32_t *dst, + bool force_hex) +{ + char buff[__MAX_U32_DIGITS + 1] = {}; + unsigned int nbits = 0; + const char *p = arg; + + if (!len) + return -EINVAL; + if (!force_hex && len <= __MAX_U32_DIGITS) { + strncpy(buff, arg, len); + if (!buff[__MAX_U32_DIGITS]) { + u32 val; + int ret; + + ret = parse_u32d(buff, &val); + if (!ret) { + *dst = val; + return __nsb(val); + } + } + } + + dst += (len - 1) / 8; + while (len > 0) { + unsigned int chunk = (len % 8) ?: 8; + unsigned long val; + char *endp; + + memcpy(buff, p, chunk); + buff[chunk] = '\0'; + val = strtoul(buff, &endp, 16); + if (*endp) + return -EINVAL; + *dst-- = (uint32_t)val; + if (nbits) + nbits += 4 * chunk; + else + nbits = __nsb(val); + + p += chunk; + len -= chunk; + } + return nbits; +} + +/* Parse bitset provided as a base 16 numeric value (@no_mask is true) or pair + * of base 16 numeric values separated by '/' (@no_mask is false). The "0x" + * prefix is optional. Generates bitset nested attribute in compact form. + */ +static int parse_numeric_bitset(struct nl_context *nlctx, uint16_t type, + bool no_mask, bool force_hex, + struct nl_msg_buff *msgbuff) +{ + unsigned int nwords, len1, len2; + const char *arg = *nlctx->argp; + bool force_hex1 = force_hex; + bool force_hex2 = force_hex; + uint32_t *value = NULL; + uint32_t *mask = NULL; + struct nlattr *nest; + const char *maskptr; + int ret = 0; + int nbits; + + if (__prefix_0x(arg)) { + force_hex1 = true; + arg += 2; + } + + maskptr = strchr(arg, '/'); + if (maskptr && no_mask) { + parser_err_invalid_value(nlctx, arg); + return -EINVAL; + } + len1 = maskptr ? (unsigned int)(maskptr - arg) : strlen(arg); + nwords = DIV_ROUND_UP(len1, 8); + nbits = 0; + + if (maskptr) { + maskptr++; + if (__prefix_0x(maskptr)) { + maskptr += 2; + force_hex2 = true; + } + len2 = strlen(maskptr); + if (len2 > len1) + nwords = DIV_ROUND_UP(len2, 8); + mask = calloc(nwords, sizeof(uint32_t)); + if (!mask) + return -ENOMEM; + ret = __parse_num_string(maskptr, strlen(maskptr), mask, + force_hex2); + if (ret < 0) { + parser_err_invalid_value(nlctx, arg); + goto out_free; + } + nbits = ret; + } + + value = calloc(nwords, sizeof(uint32_t)); + if (!value) { + free(mask); + return -ENOMEM; + } + ret = __parse_num_string(arg, len1, value, force_hex1); + if (ret < 0) { + parser_err_invalid_value(nlctx, arg); + goto out_free; + } + nbits = (nbits < ret) ? ret : nbits; + nwords = (nbits + 31) / 32; + + ret = 0; + if (!type) + goto out_free; + ret = -EMSGSIZE; + nest = ethnla_nest_start(msgbuff, type); + if (!nest) + goto out_free; + if (ethnla_put_flag(msgbuff, ETHTOOL_A_BITSET_NOMASK, !mask) || + ethnla_put_u32(msgbuff, ETHTOOL_A_BITSET_SIZE, nbits) || + ethnla_put(msgbuff, ETHTOOL_A_BITSET_VALUE, + nwords * sizeof(uint32_t), value) || + (mask && + ethnla_put(msgbuff, ETHTOOL_A_BITSET_MASK, + nwords * sizeof(uint32_t), mask))) + goto out_free; + ethnla_nest_end(msgbuff, nest); + ret = 0; + +out_free: + free(value); + free(mask); + nlctx->argp++; + nlctx->argc--; + return ret; +} + +/* Parse bitset provided as series of "name on|off" pairs (@no_mask is false) + * or names (@no_mask is true). Generates bitset nested attribute in verbose + * form with names from command line. + */ +static int parse_name_bitset(struct nl_context *nlctx, uint16_t type, + bool no_mask, struct nl_msg_buff *msgbuff) +{ + struct nlattr *bitset_attr; + struct nlattr *bits_attr; + struct nlattr *bit_attr; + int ret; + + bitset_attr = ethnla_nest_start(msgbuff, type); + if (!bitset_attr) + return -EMSGSIZE; + ret = -EMSGSIZE; + if (no_mask && ethnla_put_flag(msgbuff, ETHTOOL_A_BITSET_NOMASK, true)) + goto err; + bits_attr = ethnla_nest_start(msgbuff, ETHTOOL_A_BITSET_BITS); + if (!bits_attr) + goto err; + + while (nlctx->argc > 0) { + bool bit_val = true; + + if (!strcmp(*nlctx->argp, "--")) { + nlctx->argp++; + nlctx->argc--; + break; + } + ret = -EINVAL; + if (!no_mask) { + if (nlctx->argc < 2 || + (strcmp(nlctx->argp[1], "on") && + strcmp(nlctx->argp[1], "off"))) { + parser_err_invalid_flag(nlctx, *nlctx->argp); + goto err; + } + bit_val = !strcmp(nlctx->argp[1], "on"); + } + + ret = -EMSGSIZE; + bit_attr = ethnla_nest_start(msgbuff, + ETHTOOL_A_BITSET_BITS_BIT); + if (!bit_attr) + goto err; + if (ethnla_put_strz(msgbuff, ETHTOOL_A_BITSET_BIT_NAME, + nlctx->argp[0])) + goto err; + if (!no_mask && + ethnla_put_flag(msgbuff, ETHTOOL_A_BITSET_BIT_VALUE, + bit_val)) + goto err; + ethnla_nest_end(msgbuff, bit_attr); + + nlctx->argp += (no_mask ? 1 : 2); + nlctx->argc -= (no_mask ? 1 : 2); + } + + ethnla_nest_end(msgbuff, bits_attr); + ethnla_nest_end(msgbuff, bitset_attr); + return 0; +err: + ethnla_nest_cancel(msgbuff, bitset_attr); + return ret; +} + +static bool is_char_bitset(const char *arg, + const struct char_bitset_parser_data *data) +{ + bool mask = (arg[0] == '+' || arg[0] == '-'); + unsigned int i; + const char *p; + + for (p = arg; *p; p++) { + if (*p == data->reset_char) + continue; + if (mask && (*p == '+' || *p == '-')) + continue; + for (i = 0; i < data->nbits; i++) + if (*p == data->bit_chars[i]) + goto found; + return false; +found: + ; + } + + return true; +} + +/* Parse bitset provided as a string consisting of characters corresponding to + * bit indices. The "reset character" resets the no-mask bitset to empty. If + * the first character is '+' or '-', generated bitset has mask and '+' and + * '-' switch between enabling and disabling the following bits (i.e. their + * value being true/false). In such case, "reset character" is not allowed. + */ +static int parse_char_bitset(struct nl_context *nlctx, uint16_t type, + const struct char_bitset_parser_data *data, + struct nl_msg_buff *msgbuff) +{ + const char *arg = *nlctx->argp; + struct nlattr *bitset_attr; + struct nlattr *saved_pos; + struct nlattr *bits_attr; + struct nlattr *bit_attr; + unsigned int idx; + bool val = true; + const char *p; + bool no_mask; + int ret; + + no_mask = data->no_mask || !(arg[0] == '+' || arg[0] == '-'); + bitset_attr = ethnla_nest_start(msgbuff, type); + if (!bitset_attr) + return -EMSGSIZE; + ret = -EMSGSIZE; + if (no_mask && ethnla_put_flag(msgbuff, ETHTOOL_A_BITSET_NOMASK, true)) + goto err; + bits_attr = ethnla_nest_start(msgbuff, ETHTOOL_A_BITSET_BITS); + if (!bits_attr) + goto err; + saved_pos = mnl_nlmsg_get_payload_tail(msgbuff->nlhdr); + + for (p = arg; *p; p++) { + if (*p == '+' || *p == '-') { + if (no_mask) { + parser_err_invalid_value(nlctx, arg); + ret = -EINVAL; + goto err; + } + val = (*p == '+'); + continue; + } + if (*p == data->reset_char) { + if (no_mask) { + mnl_attr_nest_cancel(msgbuff->nlhdr, saved_pos); + continue; + } + fprintf(stderr, "ethtool (%s): invalid char '%c' in '%s' for parameter '%s'\n", + nlctx->cmd, *p, arg, nlctx->param); + ret = -EINVAL; + goto err; + } + + for (idx = 0; idx < data->nbits; idx++) { + if (data->bit_chars[idx] == *p) + break; + } + if (idx >= data->nbits) { + fprintf(stderr, "ethtool (%s): invalid char '%c' in '%s' for parameter '%s'\n", + nlctx->cmd, *p, arg, nlctx->param); + ret = -EINVAL; + goto err; + } + bit_attr = ethnla_nest_start(msgbuff, + ETHTOOL_A_BITSET_BITS_BIT); + if (!bit_attr) + goto err; + if (ethnla_put_u32(msgbuff, ETHTOOL_A_BITSET_BIT_INDEX, idx)) + goto err; + if (!no_mask && + ethnla_put_flag(msgbuff, ETHTOOL_A_BITSET_BIT_VALUE, val)) + goto err; + ethnla_nest_end(msgbuff, bit_attr); + } + + ethnla_nest_end(msgbuff, bits_attr); + ethnla_nest_end(msgbuff, bitset_attr); + nlctx->argp++; + nlctx->argc--; + return 0; +err: + ethnla_nest_cancel(msgbuff, bitset_attr); + return ret; +} + +/* Parser handler for bitset. Expects either a numeric value (base 16 or 10 + * (unless force_hex is set)), optionally followed by '/' and another numeric + * value (mask, unless no_mask is set), or a series of "name on|off" pairs + * (no_mask not set) or names (no_mask set). In the latter case, names are + * passed on as they are and kernel performs their interpretation and + * validation. The @data parameter points to struct bitset_parser_data. + * Generates only a bitset nested attribute. Fails if @type is zero or @dest + * is not null. + */ +int nl_parse_bitset(struct nl_context *nlctx, uint16_t type, const void *data, + struct nl_msg_buff *msgbuff, void *dest) +{ + const struct bitset_parser_data *parser_data = data; + + if (!type || dest) { + fprintf(stderr, "ethtool (%s): internal error parsing '%s'\n", + nlctx->cmd, nlctx->param); + return -EFAULT; + } + if (is_numeric_bitset(*nlctx->argp, false)) + return parse_numeric_bitset(nlctx, type, parser_data->no_mask, + parser_data->force_hex, msgbuff); + else + return parse_name_bitset(nlctx, type, parser_data->no_mask, + msgbuff); +} + +/* Parser handler for bitset. Expects either a numeric value (base 10 or 16), + * optionally followed by '/' and another numeric value (mask, unless no_mask + * is set), or a string consisting of characters corresponding to bit indices. + * The @data parameter points to struct char_bitset_parser_data. Generates + * biset nested attribute. Fails if type is zero or if @dest is not null. + */ +int nl_parse_char_bitset(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest) +{ + const struct char_bitset_parser_data *parser_data = data; + + if (!type || dest) { + fprintf(stderr, "ethtool (%s): internal error parsing '%s'\n", + nlctx->cmd, nlctx->param); + return -EFAULT; + } + if (is_char_bitset(*nlctx->argp, data) || + !is_numeric_bitset(*nlctx->argp, false)) + return parse_char_bitset(nlctx, type, parser_data, msgbuff); + else + return parse_numeric_bitset(nlctx, type, parser_data->no_mask, + false, msgbuff); +} + +/* parser implementation */ + +static const struct param_parser *find_parser(const struct param_parser *params, + const char *arg) +{ + const struct param_parser *parser; + + for (parser = params; parser->arg; parser++) + if (!strcmp(arg, parser->arg)) + return parser; + return NULL; +} + +static bool __parser_bit(const uint64_t *map, unsigned int idx) +{ + return map[idx / 64] & (1 << (idx % 64)); +} + +static void __parser_set(uint64_t *map, unsigned int idx) +{ + map[idx / 64] |= (1 << (idx % 64)); +} + +static void __parser_set_group(const struct param_parser *params, + uint64_t *map, unsigned int alt_group) +{ + const struct param_parser *parser; + unsigned int idx = 0; + + for (parser = params; parser->arg; parser++, idx++) + if (parser->alt_group == alt_group) + __parser_set(map, idx); +} + +struct tmp_buff { + struct nl_msg_buff *msgbuff; + unsigned int id; + unsigned int orig_len; + struct tmp_buff *next; +}; + +static struct tmp_buff *tmp_buff_find(struct tmp_buff *head, unsigned int id) +{ + struct tmp_buff *buff; + + for (buff = head; buff; buff = buff->next) + if (buff->id == id) + break; + + return buff; +} + +static struct tmp_buff *tmp_buff_find_or_create(struct tmp_buff **phead, + unsigned int id) +{ + struct tmp_buff **pbuff; + struct tmp_buff *new_buff; + + for (pbuff = phead; *pbuff; pbuff = &(*pbuff)->next) + if ((*pbuff)->id == id) + return *pbuff; + + new_buff = malloc(sizeof(*new_buff)); + if (!new_buff) + return NULL; + new_buff->id = id; + new_buff->msgbuff = malloc(sizeof(*new_buff->msgbuff)); + if (!new_buff->msgbuff) { + free(new_buff); + return NULL; + } + msgbuff_init(new_buff->msgbuff); + new_buff->next = NULL; + *pbuff = new_buff; + + return new_buff; +} + +static void tmp_buff_destroy(struct tmp_buff *head) +{ + struct tmp_buff *buff = head; + struct tmp_buff *next; + + while (buff) { + next = buff->next; + if (buff->msgbuff) { + msgbuff_done(buff->msgbuff); + free(buff->msgbuff); + } + free(buff); + buff = next; + } +} + +/* Main entry point of parser implementation. + * @nlctx: netlink context + * @params: array of struct param_parser describing expected arguments + * and their handlers; the array must be terminated by null + * element {} + * @dest: optional destination to copy parsed data to (at + * param_parser::offset) + * @group_style: defines if identifiers in .group represent separate messages, + * nested attributes or are not allowed + * @msgbuffs: (only used for @group_style = PARSER_GROUP_MSG) array to store + * pointers to composed messages; caller must make sure this + * array is sufficient, i.e. that it has at least as many entries + * as the number of different .group values in params array; + * entries are filled from the start, remaining entries are not + * modified; caller should zero initialize the array before + * calling nl_parser() + */ +int nl_parser(struct nl_context *nlctx, const struct param_parser *params, + void *dest, enum parser_group_style group_style, + struct nl_msg_buff **msgbuffs) +{ + struct nl_socket *nlsk = nlctx->ethnl_socket; + const struct param_parser *parser; + struct tmp_buff *buffs = NULL; + unsigned int n_msgbuffs = 0; + struct tmp_buff *buff; + unsigned int n_params; + uint64_t *params_seen; + int ret; + + n_params = 0; + for (parser = params; parser->arg; parser++) { + struct nl_msg_buff *msgbuff; + struct nlattr *nest; + + n_params++; + if (group_style == PARSER_GROUP_NONE || !parser->group) + continue; + ret = -ENOMEM; + buff = tmp_buff_find_or_create(&buffs, parser->group); + if (!buff) + goto out_free_buffs; + msgbuff = buff->msgbuff; + ret = msg_init(nlctx, msgbuff, parser->group, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + goto out_free_buffs; + + switch (group_style) { + case PARSER_GROUP_NEST: + ret = -EMSGSIZE; + nest = ethnla_nest_start(buff->msgbuff, parser->group); + if (!nest) + goto out_free_buffs; + break; + case PARSER_GROUP_MSG: + if (ethnla_fill_header(msgbuff, + ETHTOOL_A_LINKINFO_HEADER, + nlctx->devname, 0)) + goto out_free_buffs; + break; + default: + break; + } + + buff->orig_len = msgbuff_len(msgbuff); + } + ret = -ENOMEM; + params_seen = calloc(DIV_ROUND_UP(n_params, 64), sizeof(uint64_t)); + if (!params_seen) + goto out_free_buffs; + + while (nlctx->argc > 0) { + struct nl_msg_buff *msgbuff; + void *param_dest; + + nlctx->param = *nlctx->argp; + ret = -EINVAL; + parser = find_parser(params, nlctx->param); + if (!parser) { + parser_err_unknown_param(nlctx); + goto out_free; + } + + /* check duplicates and minimum number of arguments */ + if (__parser_bit(params_seen, parser - params)) { + parser_err_dup_param(nlctx); + goto out_free; + } + nlctx->argc--; + nlctx->argp++; + if (nlctx->argc < parser->min_argc) { + parser_err_min_argc(nlctx, parser->min_argc); + goto out_free; + } + if (parser->alt_group) + __parser_set_group(params, params_seen, + parser->alt_group); + else + __parser_set(params_seen, parser - params); + + buff = NULL; + if (parser->group) + buff = tmp_buff_find(buffs, parser->group); + msgbuff = buff ? buff->msgbuff : &nlsk->msgbuff; + + param_dest = dest ? ((char *)dest + parser->dest_offset) : NULL; + ret = parser->handler(nlctx, parser->type, parser->handler_data, + msgbuff, param_dest); + if (ret < 0) + goto out_free; + } + + if (group_style == PARSER_GROUP_MSG) { + ret = -EOPNOTSUPP; + for (buff = buffs; buff; buff = buff->next) + if (msgbuff_len(buff->msgbuff) > buff->orig_len && + netlink_cmd_check(nlctx->ctx, buff->id, false)) + goto out_free; + } + for (buff = buffs; buff; buff = buff->next) { + struct nl_msg_buff *msgbuff = buff->msgbuff; + + if (group_style == PARSER_GROUP_NONE || + msgbuff_len(msgbuff) == buff->orig_len) + continue; + switch (group_style) { + case PARSER_GROUP_NEST: + ethnla_nest_end(msgbuff, msgbuff->payload); + ret = msgbuff_append(&nlsk->msgbuff, msgbuff); + if (ret < 0) + goto out_free; + break; + case PARSER_GROUP_MSG: + msgbuffs[n_msgbuffs++] = msgbuff; + buff->msgbuff = NULL; + break; + default: + break; + } + } + + ret = 0; +out_free: + free(params_seen); +out_free_buffs: + tmp_buff_destroy(buffs); + return ret; +} diff --git a/netlink/parser.h b/netlink/parser.h new file mode 100644 index 0000000..8a4e8af --- /dev/null +++ b/netlink/parser.h @@ -0,0 +1,153 @@ +/* + * parser.h - netlink command line parser + * + * Interface for command line parser used by netlink code. + */ + +#ifndef ETHTOOL_NETLINK_PARSER_H__ +#define ETHTOOL_NETLINK_PARSER_H__ + +#include + +#include "netlink.h" + +/* Some commands need to generate multiple netlink messages or multiple nested + * attributes from one set of command line parameters. Argument @group_style + * of nl_parser() takes one of three values: + * + * PARSER_GROUP_NONE - no grouping, flat series of attributes (default) + * PARSER_GROUP_NEST - one nest for each @group value (@group is nest type) + * PARSER_GROUP_MSG - one message for each @group value (@group is command) + */ +enum parser_group_style { + PARSER_GROUP_NONE = 0, + PARSER_GROUP_NEST, + PARSER_GROUP_MSG, +}; + +typedef int (*param_parser_cb_t)(struct nl_context *, uint16_t, const void *, + struct nl_msg_buff *, void *); + +struct param_parser { + /* command line parameter handled by this entry */ + const char *arg; + /* group id (see enum parser_group_style above) */ + unsigned int group; + /* netlink attribute type */ + uint16_t type; /* netlink attribute type */ + /* function called to parse parameter and its value */ + param_parser_cb_t handler; + /* pointer passed as @data argument of the handler */ + const void *handler_data; + /* minimum number of extra arguments after this parameter */ + unsigned int min_argc; + /* if @dest is passed to nl_parser(), offset to store value */ + unsigned int dest_offset; + /* parameter alternative group - only one parameter from a group + * can be specified, 0 means no group + */ + unsigned int alt_group; +}; + +/* data structures used for handler data */ + +/* used by nl_parse_lookup_u32() */ +struct lookup_entry_u32 { + const char *arg; + uint32_t val; +}; + +/* used by nl_parse_lookup_u8() */ +struct lookup_entry_u8 { + const char *arg; + uint8_t val; +}; + +/* used by nl_parse_byte_str() */ +struct byte_str_parser_data { + unsigned int min_len; + unsigned int max_len; + char delim; +}; + +/* used for value stored by nl_parse_byte_str() */ +struct byte_str_value { + unsigned int len; + u8 *data; +}; + +/* used by nl_parse_error() */ +struct error_parser_data { + const char *err_msg; + int ret_val; + unsigned int extra_args; +}; + +/* used by nl_parse_bitset() */ +struct bitset_parser_data { + bool force_hex; + bool no_mask; +}; + +/* used by nl_parse_char_bitset() */ +struct char_bitset_parser_data { + const char *bit_chars; + unsigned int nbits; + char reset_char; + bool no_mask; +}; + +int parse_u32(const char *arg, uint32_t *result); + +/* parser handlers to use as param_parser::handler */ + +/* NLA_FLAG represented by on | off */ +int nl_parse_flag(struct nl_context *nlctx, uint16_t type, const void *data, + struct nl_msg_buff *msgbuff, void *dest); +/* NLA_NUL_STRING represented by a string argument */ +int nl_parse_string(struct nl_context *nlctx, uint16_t type, const void *data, + struct nl_msg_buff *msgbuff, void *dest); +/* NLA_U32 represented as numeric argument */ +int nl_parse_direct_u32(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest); +/* NLA_U8 represented as numeric argument */ +int nl_parse_direct_u8(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest); +/* NLA_U32 represented as float number of meters, converted to cm. */ +int nl_parse_direct_m2cm(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest); +/* NLA_U8 represented as on | off */ +int nl_parse_u8bool(struct nl_context *nlctx, uint16_t type, const void *data, + struct nl_msg_buff *msgbuff, void *dest); +/* NLA_U32 represented by a string argument (lookup table) */ +int nl_parse_lookup_u32(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest); +/* NLA_U8 represented by a string argument (lookup table) */ +int nl_parse_lookup_u8(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest); +/* always fail (for deprecated parameters) */ +int nl_parse_error(struct nl_context *nlctx, uint16_t type, const void *data, + struct nl_msg_buff *msgbuff, void *dest); +/* NLA_BINARY represented by %x:%x:...%x (e.g. a MAC address) */ +int nl_parse_byte_str(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest); +/* bitset represented by %x[/%x] or name on|off ... [--] */ +int nl_parse_bitset(struct nl_context *nlctx, uint16_t type, const void *data, + struct nl_msg_buff *msgbuff, void *dest); +/* bitset represented by %u[/%u] or string (characters for bits) */ +int nl_parse_char_bitset(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest); + +/* main entry point called to parse the command line */ +int nl_parser(struct nl_context *nlctx, const struct param_parser *params, + void *dest, enum parser_group_style group_style, + struct nl_msg_buff **msgbuffs); + +#endif /* ETHTOOL_NETLINK_PARSER_H__ */ diff --git a/netlink/pause.c b/netlink/pause.c new file mode 100644 index 0000000..867d0da --- /dev/null +++ b/netlink/pause.c @@ -0,0 +1,308 @@ +/* + * pause.c - netlink implementation of pause commands + * + * Implementation of "ethtool -a " and "ethtool -A ..." + */ + +#include +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "bitset.h" +#include "parser.h" + +/* PAUSE_GET */ + +struct pause_autoneg_status { + bool pause; + bool asym_pause; +}; + +static void pause_autoneg_walker(unsigned int idx, + const char *name __maybe_unused, bool val, + void *data) +{ + struct pause_autoneg_status *status = data; + + if (idx == ETHTOOL_LINK_MODE_Pause_BIT) + status->pause = val; + if (idx == ETHTOOL_LINK_MODE_Asym_Pause_BIT) + status->asym_pause = val; +} + +static int pause_autoneg_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_LINKMODES_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct pause_autoneg_status ours = {}; + struct pause_autoneg_status peer = {}; + struct nl_context *nlctx = data; + uint8_t rx_status = false; + uint8_t tx_status = false; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + + if (!tb[ETHTOOL_A_LINKMODES_OURS] || !tb[ETHTOOL_A_LINKMODES_PEER]) + return MNL_CB_OK; + ret = walk_bitset(tb[ETHTOOL_A_LINKMODES_OURS], NULL, + pause_autoneg_walker, &ours); + if (ret < 0) + return err_ret; + ret = walk_bitset(tb[ETHTOOL_A_LINKMODES_PEER], NULL, + pause_autoneg_walker, &peer); + if (ret < 0) + return err_ret; + + if (ours.pause && peer.pause) { + rx_status = true; + tx_status = true; + } else if (ours.asym_pause && peer.asym_pause) { + if (ours.pause) + rx_status = true; + else if (peer.pause) + tx_status = true; + } + + open_json_object("negotiated"); + show_bool_val("rx", "RX negotiated: %s\n", &rx_status); + show_bool_val("tx", "TX negotiated: %s\n", &tx_status); + close_json_object(); + + return MNL_CB_OK; +} + +static int show_pause_autoneg_status(struct nl_context *nlctx) +{ + const char *saved_devname; + int ret; + + saved_devname = nlctx->ctx->devname; + nlctx->ctx->devname = nlctx->devname; + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + goto out; + + ret = nlsock_prep_get_request(nlctx->ethnl2_socket, + ETHTOOL_MSG_LINKMODES_GET, + ETHTOOL_A_LINKMODES_HEADER, + ETHTOOL_FLAG_COMPACT_BITSETS); + if (ret < 0) + goto out; + ret = nlsock_send_get_request(nlctx->ethnl2_socket, pause_autoneg_cb); + +out: + nlctx->ctx->devname = saved_devname; + return ret; +} + +static int show_pause_stats(const struct nlattr *nest) +{ + const struct nlattr *tb[ETHTOOL_A_PAUSE_STAT_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + static const struct { + unsigned int attr; + char *name; + } stats[] = { + { ETHTOOL_A_PAUSE_STAT_TX_FRAMES, "tx_pause_frames" }, + { ETHTOOL_A_PAUSE_STAT_RX_FRAMES, "rx_pause_frames" }, + }; + bool header = false; + unsigned int i; + size_t n; + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0) + return ret; + + open_json_object("statistics"); + for (i = 0; i < ARRAY_SIZE(stats); i++) { + char fmt[32]; + + if (!tb[stats[i].attr]) + continue; + + if (!header && !is_json_context()) { + printf("Statistics:\n"); + header = true; + } + + if (mnl_attr_validate(tb[stats[i].attr], MNL_TYPE_U64)) { + fprintf(stderr, "malformed netlink message (statistic)\n"); + goto err_close_stats; + } + + n = snprintf(fmt, sizeof(fmt), " %s: %%" PRIu64 "\n", + stats[i].name); + if (n >= sizeof(fmt)) { + fprintf(stderr, "internal error - malformed label\n"); + goto err_close_stats; + } + + print_u64(PRINT_ANY, stats[i].name, fmt, + mnl_attr_get_u64(tb[stats[i].attr])); + } + close_json_object(); + + return 0; + +err_close_stats: + close_json_object(); + return -1; +} + +int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_PAUSE_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_PAUSE_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + print_nl(); + + open_json_object(NULL); + + print_string(PRINT_ANY, "ifname", "Pause parameters for %s:\n", + nlctx->devname); + + show_bool("autonegotiate", "Autonegotiate:\t%s\n", + tb[ETHTOOL_A_PAUSE_AUTONEG]); + show_bool("rx", "RX:\t\t%s\n", tb[ETHTOOL_A_PAUSE_RX]); + show_bool("tx", "TX:\t\t%s\n", tb[ETHTOOL_A_PAUSE_TX]); + + if (!nlctx->is_monitor && tb[ETHTOOL_A_PAUSE_AUTONEG] && + mnl_attr_get_u8(tb[ETHTOOL_A_PAUSE_AUTONEG])) { + ret = show_pause_autoneg_status(nlctx); + if (ret < 0) + goto err_close_dev; + } + if (tb[ETHTOOL_A_PAUSE_STATS]) { + ret = show_pause_stats(tb[ETHTOOL_A_PAUSE_STATS]); + if (ret < 0) + goto err_close_dev; + } + if (!silent) + print_nl(); + + close_json_object(); + + return MNL_CB_OK; + +err_close_dev: + close_json_object(); + return err_ret; +} + +int nl_gpause(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + u32 flags; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PAUSE_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + flags = get_stats_flag(nlctx, ETHTOOL_MSG_PAUSE_GET, + ETHTOOL_A_PAUSE_HEADER); + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_PAUSE_GET, + ETHTOOL_A_PAUSE_HEADER, flags); + if (ret < 0) + return ret; + + new_json_obj(ctx->json); + ret = nlsock_send_get_request(nlsk, pause_reply_cb); + delete_json_obj(); + return ret; +} + +/* PAUSE_SET */ + +static const struct param_parser spause_params[] = { + { + .arg = "autoneg", + .type = ETHTOOL_A_PAUSE_AUTONEG, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "rx", + .type = ETHTOOL_A_PAUSE_RX, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "tx", + .type = ETHTOOL_A_PAUSE_TX, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + {} +}; + +int nl_spause(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PAUSE_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "-A"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_PAUSE_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_PAUSE_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, spause_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 76; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 76; +} diff --git a/netlink/permaddr.c b/netlink/permaddr.c new file mode 100644 index 0000000..006eac6 --- /dev/null +++ b/netlink/permaddr.c @@ -0,0 +1,114 @@ +/* + * permaddr.c - netlink implementation of permanent address request + * + * Implementation of "ethtool -P " + */ + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" + +/* PERMADDR_GET */ + +static int permaddr_prep_request(struct nl_socket *nlsk) +{ + unsigned int nlm_flags = NLM_F_REQUEST | NLM_F_ACK; + struct nl_context *nlctx = nlsk->nlctx; + const char *devname = nlctx->ctx->devname; + struct nl_msg_buff *msgbuff = &nlsk->msgbuff; + struct ifinfomsg *ifinfo; + struct nlmsghdr *nlhdr; + int ret; + + if (devname && !strcmp(devname, WILDCARD_DEVNAME)) { + devname = NULL; + nlm_flags |= NLM_F_DUMP; + } + nlctx->is_dump = !devname; + + ret = msgbuff_realloc(msgbuff, MNL_SOCKET_BUFFER_SIZE); + if (ret < 0) + return ret; + memset(msgbuff->buff, '\0', NLMSG_HDRLEN + sizeof(*ifinfo)); + + nlhdr = mnl_nlmsg_put_header(msgbuff->buff); + nlhdr->nlmsg_type = RTM_GETLINK; + nlhdr->nlmsg_flags = nlm_flags; + msgbuff->nlhdr = nlhdr; + ifinfo = mnl_nlmsg_put_extra_header(nlhdr, sizeof(*ifinfo)); + + if (devname) { + uint16_t type = IFLA_IFNAME; + + if (strlen(devname) >= IFNAMSIZ) + type = IFLA_ALT_IFNAME; + if (ethnla_put_strz(msgbuff, type, devname)) + return -EMSGSIZE; + } + if (ethnla_put_u32(msgbuff, IFLA_EXT_MASK, RTEXT_FILTER_SKIP_STATS)) + return -EMSGSIZE; + + return 0; +} + +int permaddr_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[__IFLA_MAX] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + const uint8_t *permaddr; + unsigned int i; + int ret; + + if (nlhdr->nlmsg_type != RTM_NEWLINK) + goto err; + ret = mnl_attr_parse(nlhdr, sizeof(struct ifinfomsg), attr_cb, + &tb_info); + if (ret < 0 || !tb[IFLA_IFNAME]) + goto err; + nlctx->devname = mnl_attr_get_str(tb[IFLA_IFNAME]); + if (!dev_ok(nlctx)) + goto err; + + if (!tb[IFLA_PERM_ADDRESS]) { + if (!nlctx->is_dump) + printf("Permanent address: not set\n"); + return MNL_CB_OK; + } + + if (nlctx->is_dump) + printf("Permanent address of %s:", nlctx->devname); + else + printf("Permanent address:"); + permaddr = mnl_attr_get_payload(tb[IFLA_PERM_ADDRESS]); + for (i = 0; i < mnl_attr_get_payload_len(tb[IFLA_PERM_ADDRESS]); i++) + printf("%c%02x", i ? ':' : ' ', permaddr[i]); + putchar('\n'); + return MNL_CB_OK; + +err: + if (nlctx->is_dump || nlctx->is_monitor) + return MNL_CB_OK; + nlctx->exit_code = 2; + return MNL_CB_ERROR; +} + +int nl_permaddr(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + int ret; + + ret = netlink_init_rtnl_socket(nlctx); + if (ret < 0) + return ret; + ret = permaddr_prep_request(nlctx->rtnl_socket); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlctx->rtnl_socket, permaddr_reply_cb); +} diff --git a/netlink/prettymsg.c b/netlink/prettymsg.c new file mode 100644 index 0000000..fbf684f --- /dev/null +++ b/netlink/prettymsg.c @@ -0,0 +1,262 @@ +/* + * prettymsg.c - human readable message dump + * + * Support for pretty print of an ethtool netlink message + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "prettymsg.h" + +#define __INDENT 4 +#define __DUMP_LINE 16 +#define __DUMP_BLOCK 4 + +static void __print_binary_short(uint8_t *adata, unsigned int alen) +{ + unsigned int i; + + if (!alen) + return; + printf("%02x", adata[0]); + for (i = 1; i < alen; i++) + printf("%c%02x", (i % __DUMP_BLOCK) ? ':' : ' ', adata[i]); +} + +static void __print_binary_long(uint8_t *adata, unsigned int alen, + unsigned int level) +{ + unsigned int i; + + for (i = 0; i < alen; i++) { + if (i % __DUMP_LINE == 0) + printf("\n%*s", __INDENT * (level + 2), ""); + else if (i % __DUMP_BLOCK == 0) + printf(" "); + else + putchar(' '); + printf("%02x", adata[i]); + } +} + +static int pretty_print_attr(const struct nlattr *attr, + const struct pretty_nla_desc *desc, + unsigned int ndesc, unsigned int level, + int err_offset, bool in_array) +{ + unsigned int alen = mnl_attr_get_payload_len(attr); + unsigned int atype = mnl_attr_get_type(attr); + unsigned int desc_idx = in_array ? 0 : atype; + void *adata = mnl_attr_get_payload(attr); + const struct pretty_nla_desc *adesc; + const char *prefix = " "; + bool nested; + + adesc = (desc && desc_idx < ndesc) ? &desc[desc_idx] : NULL; + nested = (adesc && (adesc->format == NLA_NESTED || + adesc->format == NLA_ARRAY)) || + (attr->nla_type & NLA_F_NESTED); + if (err_offset >= 0 && + err_offset < (nested ? NLA_HDRLEN : attr->nla_len)) { + prefix = "===>"; + if (err_offset) + fprintf(stderr, + "ethtool: bad_attr inside an attribute (offset %d)\n", + err_offset); + } + if (adesc && adesc->name && !in_array) + printf("%s%*s%s", prefix, level * __INDENT, "", adesc->name); + else + printf("%s%*s[%u]", prefix, level * __INDENT, "", atype); + + if (nested) { + struct nlattr *child; + int ret = 0; + + putchar('\n'); + mnl_attr_for_each_nested(child, attr) { + bool array = adesc && adesc->format == NLA_ARRAY; + unsigned int child_off; + + child_off = (const char *)child - (const char *)attr; + ret = pretty_print_attr(child, + adesc ? adesc->children : NULL, + adesc ? adesc->n_children : 0, + level + 1, + err_offset - child_off, array); + if (ret < 0) + break; + } + + return ret; + } + + printf(" = "); + switch(adesc ? adesc->format : NLA_BINARY) { + case NLA_U8: + printf("%u", mnl_attr_get_u8(attr)); + break; + case NLA_U16: + printf("%u", mnl_attr_get_u16(attr)); + break; + case NLA_U32: + printf("%u", mnl_attr_get_u32(attr)); + break; + case NLA_U64: + printf("%" PRIu64, mnl_attr_get_u64(attr)); + break; + case NLA_X8: + printf("0x%02x", mnl_attr_get_u8(attr)); + break; + case NLA_X16: + printf("0x%04x", mnl_attr_get_u16(attr)); + break; + case NLA_X32: + printf("0x%08x", mnl_attr_get_u32(attr)); + break; + case NLA_X64: + printf("%" PRIx64, mnl_attr_get_u64(attr)); + break; + case NLA_S8: + printf("%d", (int)mnl_attr_get_u8(attr)); + break; + case NLA_S16: + printf("%d", (int)mnl_attr_get_u16(attr)); + break; + case NLA_S32: + printf("%d", (int)mnl_attr_get_u32(attr)); + break; + case NLA_S64: + printf("%" PRId64, (int64_t)mnl_attr_get_u64(attr)); + break; + case NLA_STRING: + printf("\"%.*s\"", alen, (const char *)adata); + break; + case NLA_FLAG: + printf("true"); + break; + case NLA_BOOL: + printf("%s", mnl_attr_get_u8(attr) ? "on" : "off"); + break; + case NLA_U8_ENUM: + case NLA_U32_ENUM: { + uint32_t val; + + if (adesc->format == NLA_U8_ENUM) + val = mnl_attr_get_u8(attr); + else + val = mnl_attr_get_u32(attr); + + if (adesc && val < adesc->n_names && adesc->names[val]) + printf("%s", adesc->names[val]); + else + printf("%u", val); + break; + } + default: + if (alen <= __DUMP_LINE) + __print_binary_short(adata, alen); + else + __print_binary_long(adata, alen, level); + } + putchar('\n'); + + return 0; +} + +static int pretty_print_nlmsg(const struct nlmsghdr *nlhdr, + unsigned int payload_offset, + const struct pretty_nla_desc *desc, + unsigned int ndesc, unsigned int err_offset) +{ + const struct nlattr *attr; + int attr_offset; + int ret; + + mnl_attr_for_each(attr, nlhdr, payload_offset) { + attr_offset = (const char *)attr - (const char *)nlhdr; + ret = pretty_print_attr(attr, desc, ndesc, 1, + err_offset - attr_offset, false); + if (ret < 0) + return ret; + } + + return 0; +} + +int pretty_print_genlmsg(const struct nlmsghdr *nlhdr, + const struct pretty_nlmsg_desc *desc, + unsigned int ndesc, unsigned int err_offset) +{ + const struct pretty_nlmsg_desc *msg_desc; + const struct genlmsghdr *genlhdr; + + if (mnl_nlmsg_get_payload_len(nlhdr) < GENL_HDRLEN) { + fprintf(stderr, "ethtool: message too short (%u bytes)\n", + nlhdr->nlmsg_len); + return -EINVAL; + } + genlhdr = mnl_nlmsg_get_payload(nlhdr); + msg_desc = (desc && genlhdr->cmd < ndesc) ? &desc[genlhdr->cmd] : NULL; + if (msg_desc && msg_desc->name) + printf(" %s\n", msg_desc->name); + else + printf(" [%u]\n", genlhdr->cmd); + + return pretty_print_nlmsg(nlhdr, GENL_HDRLEN, + msg_desc ? msg_desc->attrs : NULL, + msg_desc ? msg_desc->n_attrs : 0, err_offset); +} + +static void rtm_link_summary(const struct ifinfomsg *ifinfo) +{ + if (ifinfo->ifi_family) + printf(" family=%u", ifinfo->ifi_family); + if (ifinfo->ifi_type) + printf(" type=0x%04x", ifinfo->ifi_type); + if (ifinfo->ifi_index) + printf(" ifindex=%d", ifinfo->ifi_index); + if (ifinfo->ifi_flags) + printf(" flags=0x%x", ifinfo->ifi_flags); + if (ifinfo->ifi_change) + printf(" change=0x%x", ifinfo->ifi_change); +} + +int pretty_print_rtnlmsg(const struct nlmsghdr *nlhdr, unsigned int err_offset) +{ + const unsigned int idx = (nlhdr->nlmsg_type - RTM_BASE) / 4; + const struct pretty_nlmsg_desc *msg_desc = NULL; + unsigned int hdrlen = USHRT_MAX; + + if (nlhdr->nlmsg_type < rtnl_msg_n_desc) + msg_desc = &rtnl_msg_desc[nlhdr->nlmsg_type]; + if (idx < rtnl_msghdr_n_len) + hdrlen = rtnl_msghdr_lengths[idx]; + if (hdrlen < USHRT_MAX && mnl_nlmsg_get_payload_len(nlhdr) < hdrlen) { + fprintf(stderr, "ethtool: message too short (%u bytes)\n", + nlhdr->nlmsg_len); + return -EINVAL; + } + if (msg_desc && msg_desc->name) + printf(" %s", msg_desc->name); + else + printf(" [%u]", nlhdr->nlmsg_type); + if (idx == (RTM_NEWLINK - RTM_BASE) / 4) + rtm_link_summary(mnl_nlmsg_get_payload(nlhdr)); + putchar('\n'); + if (hdrlen == USHRT_MAX) + return 0; + + return pretty_print_nlmsg(nlhdr, hdrlen, + msg_desc ? msg_desc->attrs : NULL, + msg_desc ? msg_desc->n_attrs : 0, err_offset); +} diff --git a/netlink/prettymsg.h b/netlink/prettymsg.h new file mode 100644 index 0000000..8ca1db3 --- /dev/null +++ b/netlink/prettymsg.h @@ -0,0 +1,146 @@ +/* + * prettymsg.h - human readable message dump + * + * Support for pretty print of an ethtool netlink message + */ + +#ifndef ETHTOOL_NETLINK_PRETTYMSG_H__ +#define ETHTOOL_NETLINK_PRETTYMSG_H__ + +#include + +/* data structures for message format descriptions */ + +enum pretty_nla_format { + NLA_INVALID, + NLA_BINARY, + NLA_U8, + NLA_U16, + NLA_U32, + NLA_U64, + NLA_X8, + NLA_X16, + NLA_X32, + NLA_X64, + NLA_S8, + NLA_S16, + NLA_S32, + NLA_S64, + NLA_STRING, + NLA_FLAG, + NLA_BOOL, + NLA_NESTED, + NLA_ARRAY, + NLA_U8_ENUM, + NLA_U32_ENUM, +}; + +struct pretty_nla_desc { + enum pretty_nla_format format; + const char *name; + union { + const struct pretty_nla_desc *children; + const char *const *names; + }; + union { + unsigned int n_children; + unsigned int n_names; + }; +}; + +struct pretty_nlmsg_desc { + const char *name; + const struct pretty_nla_desc *attrs; + unsigned int n_attrs; +}; + +/* helper macros for message format descriptions */ + +#define NLATTR_DESC(_name, _fmt) \ + [_name] = { \ + .format = _fmt, \ + .name = #_name, \ + } + +#define NLATTR_DESC_INVALID(_name) NLATTR_DESC(_name, NLA_INVALID) +#define NLATTR_DESC_U8(_name) NLATTR_DESC(_name, NLA_U8) +#define NLATTR_DESC_U16(_name) NLATTR_DESC(_name, NLA_U16) +#define NLATTR_DESC_U32(_name) NLATTR_DESC(_name, NLA_U32) +#define NLATTR_DESC_U64(_name) NLATTR_DESC(_name, NLA_U64) +#define NLATTR_DESC_X8(_name) NLATTR_DESC(_name, NLA_X8) +#define NLATTR_DESC_X16(_name) NLATTR_DESC(_name, NLA_X16) +#define NLATTR_DESC_X32(_name) NLATTR_DESC(_name, NLA_X32) +#define NLATTR_DESC_X64(_name) NLATTR_DESC(_name, NLA_X64) +#define NLATTR_DESC_S8(_name) NLATTR_DESC(_name, NLA_U8) +#define NLATTR_DESC_S16(_name) NLATTR_DESC(_name, NLA_U16) +#define NLATTR_DESC_S32(_name) NLATTR_DESC(_name, NLA_U32) +#define NLATTR_DESC_S64(_name) NLATTR_DESC(_name, NLA_S64) +#define NLATTR_DESC_STRING(_name) NLATTR_DESC(_name, NLA_STRING) +#define NLATTR_DESC_FLAG(_name) NLATTR_DESC(_name, NLA_FLAG) +#define NLATTR_DESC_BOOL(_name) NLATTR_DESC(_name, NLA_BOOL) +#define NLATTR_DESC_BINARY(_name) NLATTR_DESC(_name, NLA_BINARY) + +#define NLATTR_DESC_NESTED(_name, _children_desc) \ + [_name] = { \ + .format = NLA_NESTED, \ + .name = #_name, \ + .children = __ ## _children_desc ## _desc, \ + .n_children = ARRAY_SIZE(__ ## _children_desc ## _desc), \ + } +#define NLATTR_DESC_NESTED_NODESC(_name) NLATTR_DESC(_name, NLA_NESTED) +#define NLATTR_DESC_ARRAY(_name, _children_desc) \ + [_name] = { \ + .format = NLA_ARRAY, \ + .name = #_name, \ + .children = __ ## _children_desc ## _desc, \ + .n_children = 1, \ + } +#define NLATTR_DESC_U8_ENUM(_name, _names_table) \ + [_name] = { \ + .format = NLA_U8_ENUM, \ + .name = #_name, \ + .names = __ ## _names_table ## _names, \ + .n_children = ARRAY_SIZE(__ ## _names_table ## _names), \ + } +#define NLATTR_DESC_U32_ENUM(_name, _names_table) \ + [_name] = { \ + .format = NLA_U32_ENUM, \ + .name = #_name, \ + .names = __ ## _names_table ## _names, \ + .n_children = ARRAY_SIZE(__ ## _names_table ## _names), \ + } + +#define NLMSG_DESC(_name, _attrs) \ + [_name] = { \ + .name = #_name, \ + .attrs = __ ## _attrs ## _desc, \ + .n_attrs = ARRAY_SIZE(__ ## _attrs ## _desc), \ + } + +#define NLMSG_DESC_INVALID(_name) \ + [_name] = { \ + .name = #_name, \ + } + +/* function to pretty print a genetlink message */ +int pretty_print_genlmsg(const struct nlmsghdr *nlhdr, + const struct pretty_nlmsg_desc *desc, + unsigned int ndesc, unsigned int err_offset); +int pretty_print_rtnlmsg(const struct nlmsghdr *nlhdr, unsigned int err_offset); + +/* message descriptions */ + +extern const struct pretty_nlmsg_desc ethnl_umsg_desc[]; +extern const unsigned int ethnl_umsg_n_desc; +extern const struct pretty_nlmsg_desc ethnl_kmsg_desc[]; +extern const unsigned int ethnl_kmsg_n_desc; + +extern const struct pretty_nlmsg_desc genlctrl_msg_desc[]; +extern const unsigned int genlctrl_msg_n_desc; + +extern const struct pretty_nlmsg_desc rtnl_msg_desc[]; +extern const unsigned int rtnl_msg_n_desc; +extern const unsigned short rtnl_msghdr_lengths[]; +extern const unsigned int rtnl_msghdr_n_len; + +#endif /* ETHTOOL_NETLINK_PRETTYMSG_H__ */ diff --git a/netlink/privflags.c b/netlink/privflags.c new file mode 100644 index 0000000..299ccdc --- /dev/null +++ b/netlink/privflags.c @@ -0,0 +1,158 @@ +/* + * privflags.c - netlink implementation of private flags commands + * + * Implementation of "ethtool --show-priv-flags " and + * "ethtool --set-priv-flags ..." + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "strset.h" +#include "bitset.h" +#include "parser.h" + +/* PRIVFLAGS_GET */ + +static void privflags_maxlen_walk_cb(unsigned int idx, const char *name, + bool val __maybe_unused, void *data) +{ + unsigned int *maxlen = data; + unsigned int len, n; + + if (name) + len = strlen(name); + else { + len = 3; /* strlen("bit") */ + for (n = idx ?: 1; n; n /= 10) + len++; /* plus number of ditigs */ + } + if (len > *maxlen) + *maxlen = len; +} + +static void privflags_dump_walk_cb(unsigned int idx, const char *name, bool val, + void *data) +{ + unsigned int *maxlen = data; + char buff[16]; + + if (!name) { + snprintf(buff, sizeof(buff) - 1, "bit%u", idx); + name = buff; + } + printf("%-*s: %s\n", *maxlen, name, val ? "on" : "off"); +} + +int privflags_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_PRIVFLAGS_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + const struct stringset *flag_names = NULL; + struct nl_context *nlctx = data; + unsigned int maxlen = 0; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0 || !tb[ETHTOOL_A_PRIVFLAGS_FLAGS]) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_PRIVFLAGS_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + if (bitset_is_compact(tb[ETHTOOL_A_PRIVFLAGS_FLAGS])) { + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + return err_ret; + flag_names = perdev_stringset(nlctx->devname, ETH_SS_PRIV_FLAGS, + nlctx->ethnl2_socket); + } + + ret = walk_bitset(tb[ETHTOOL_A_PRIVFLAGS_FLAGS], flag_names, + privflags_maxlen_walk_cb, &maxlen); + if (ret < 0) + return err_ret; + if (silent) + putchar('\n'); + printf("Private flags for %s:\n", nlctx->devname); + ret = walk_bitset(tb[ETHTOOL_A_PRIVFLAGS_FLAGS], flag_names, + privflags_dump_walk_cb, &maxlen); + return (ret < 0) ? err_ret : MNL_CB_OK; +} + +int nl_gprivflags(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PRIVFLAGS_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_PRIVFLAGS_GET, + ETHTOOL_A_PRIVFLAGS_HEADER, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, privflags_reply_cb); +} + +/* PRIVFLAGS_SET */ + +static const struct bitset_parser_data privflags_parser_data = { + .force_hex = false, + .no_mask = false, +}; + +int nl_sprivflags(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PRIVFLAGS_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "--set-priv-flags"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_PRIVFLAGS_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_PRIVFLAGS_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parse_bitset(nlctx, ETHTOOL_A_PRIVFLAGS_FLAGS, + &privflags_parser_data, msgbuff, NULL); + if (ret < 0) + return -EINVAL; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 2; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 1; +} diff --git a/netlink/rings.c b/netlink/rings.c new file mode 100644 index 0000000..6284035 --- /dev/null +++ b/netlink/rings.c @@ -0,0 +1,181 @@ +/* + * rings.c - netlink implementation of ring commands + * + * Implementation of "ethtool -g " and "ethtool -G ..." + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "parser.h" + +/* RINGS_GET */ + +int rings_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_RINGS_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + unsigned char tcp_hds; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_RINGS_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + putchar('\n'); + printf("Ring parameters for %s:\n", nlctx->devname); + printf("Pre-set maximums:\n"); + show_u32(tb[ETHTOOL_A_RINGS_RX_MAX], "RX:\t\t"); + show_u32(tb[ETHTOOL_A_RINGS_RX_MINI_MAX], "RX Mini:\t"); + show_u32(tb[ETHTOOL_A_RINGS_RX_JUMBO_MAX], "RX Jumbo:\t"); + show_u32(tb[ETHTOOL_A_RINGS_TX_MAX], "TX:\t\t"); + printf("Current hardware settings:\n"); + show_u32(tb[ETHTOOL_A_RINGS_RX], "RX:\t\t"); + show_u32(tb[ETHTOOL_A_RINGS_RX_MINI], "RX Mini:\t"); + show_u32(tb[ETHTOOL_A_RINGS_RX_JUMBO], "RX Jumbo:\t"); + show_u32(tb[ETHTOOL_A_RINGS_TX], "TX:\t\t"); + show_u32(tb[ETHTOOL_A_RINGS_RX_BUF_LEN], "RX Buf Len:\t\t"); + show_u32(tb[ETHTOOL_A_RINGS_CQE_SIZE], "CQE Size:\t\t"); + show_bool("tx-push", "TX Push:\t%s\n", tb[ETHTOOL_A_RINGS_TX_PUSH]); + + tcp_hds = tb[ETHTOOL_A_RINGS_TCP_DATA_SPLIT] ? + mnl_attr_get_u8(tb[ETHTOOL_A_RINGS_TCP_DATA_SPLIT]) : 0; + printf("TCP data split:\t"); + switch (tcp_hds) { + case ETHTOOL_TCP_DATA_SPLIT_UNKNOWN: + printf("n/a\n"); + break; + case ETHTOOL_TCP_DATA_SPLIT_DISABLED: + printf("off\n"); + break; + case ETHTOOL_TCP_DATA_SPLIT_ENABLED: + printf("on\n"); + break; + default: + printf("unknown(%d)\n", tcp_hds); + break; + } + + return MNL_CB_OK; +} + +int nl_gring(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_RINGS_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_RINGS_GET, + ETHTOOL_A_RINGS_HEADER, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, rings_reply_cb); +} + +/* RINGS_SET */ + +static const struct param_parser sring_params[] = { + { + .arg = "rx", + .type = ETHTOOL_A_RINGS_RX, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-mini", + .type = ETHTOOL_A_RINGS_RX_MINI, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-jumbo", + .type = ETHTOOL_A_RINGS_RX_JUMBO, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx", + .type = ETHTOOL_A_RINGS_TX, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-buf-len", + .type = ETHTOOL_A_RINGS_RX_BUF_LEN, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "cqe-size", + .type = ETHTOOL_A_RINGS_CQE_SIZE, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-push", + .type = ETHTOOL_A_RINGS_TX_PUSH, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + {} +}; + +int nl_sring(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_RINGS_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "-G"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_RINGS_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_RINGS_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, sring_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 81; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 81; +} diff --git a/netlink/settings.c b/netlink/settings.c new file mode 100644 index 0000000..ea86e36 --- /dev/null +++ b/netlink/settings.c @@ -0,0 +1,1277 @@ +/* + * settings.c - netlink implementation of settings commands + * + * Implementation of "ethtool " and "ethtool -s ...". + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "strset.h" +#include "bitset.h" +#include "parser.h" + +/* GET_SETTINGS */ + +struct link_mode_info { + enum link_mode_class class; + u32 speed; + u8 duplex; +}; + +static const char *const names_duplex[] = { + [DUPLEX_HALF] = "Half", + [DUPLEX_FULL] = "Full", +}; + +static const char *const names_master_slave_state[] = { + [MASTER_SLAVE_STATE_UNKNOWN] = "unknown", + [MASTER_SLAVE_STATE_MASTER] = "master", + [MASTER_SLAVE_STATE_SLAVE] = "slave", + [MASTER_SLAVE_STATE_ERR] = "resolution error", +}; + +static const char *const names_master_slave_cfg[] = { + [MASTER_SLAVE_CFG_UNKNOWN] = "unknown", + [MASTER_SLAVE_CFG_MASTER_PREFERRED] = "preferred master", + [MASTER_SLAVE_CFG_SLAVE_PREFERRED] = "preferred slave", + [MASTER_SLAVE_CFG_MASTER_FORCE] = "forced master", + [MASTER_SLAVE_CFG_SLAVE_FORCE] = "forced slave", +}; + +static const char *const names_port[] = { + [PORT_TP] = "Twisted Pair", + [PORT_AUI] = "AUI", + [PORT_BNC] = "BNC", + [PORT_MII] = "MII", + [PORT_FIBRE] = "FIBRE", + [PORT_DA] = "Direct Attach Copper", + [PORT_NONE] = "None", + [PORT_OTHER] = "Other", +}; + +static const char *const names_transceiver[] = { + [XCVR_INTERNAL] = "internal", + [XCVR_EXTERNAL] = "external", +}; + +/* the practice of putting completely unrelated flags into link mode bitmaps + * is rather unfortunate but as even ethtool_link_ksettings preserved that, + * there is little chance of getting them separated any time soon so let's + * sort them out ourselves + */ +#define __REAL(_speed) \ + { .class = LM_CLASS_REAL, .speed = _speed, .duplex = DUPLEX_FULL } +#define __HALF_DUPLEX(_speed) \ + { .class = LM_CLASS_REAL, .speed = _speed, .duplex = DUPLEX_HALF } +#define __SPECIAL(_class) \ + { .class = LM_CLASS_ ## _class } + +static const struct link_mode_info link_modes[] = { + [ETHTOOL_LINK_MODE_10baseT_Half_BIT] = __HALF_DUPLEX(10), + [ETHTOOL_LINK_MODE_10baseT_Full_BIT] = __REAL(10), + [ETHTOOL_LINK_MODE_100baseT_Half_BIT] = __HALF_DUPLEX(100), + [ETHTOOL_LINK_MODE_100baseT_Full_BIT] = __REAL(100), + [ETHTOOL_LINK_MODE_1000baseT_Half_BIT] = __HALF_DUPLEX(1000), + [ETHTOOL_LINK_MODE_1000baseT_Full_BIT] = __REAL(1000), + [ETHTOOL_LINK_MODE_Autoneg_BIT] = __SPECIAL(AUTONEG), + [ETHTOOL_LINK_MODE_TP_BIT] = __SPECIAL(PORT), + [ETHTOOL_LINK_MODE_AUI_BIT] = __SPECIAL(PORT), + [ETHTOOL_LINK_MODE_MII_BIT] = __SPECIAL(PORT), + [ETHTOOL_LINK_MODE_FIBRE_BIT] = __SPECIAL(PORT), + [ETHTOOL_LINK_MODE_BNC_BIT] = __SPECIAL(PORT), + [ETHTOOL_LINK_MODE_10000baseT_Full_BIT] = __REAL(10000), + [ETHTOOL_LINK_MODE_Pause_BIT] = __SPECIAL(PAUSE), + [ETHTOOL_LINK_MODE_Asym_Pause_BIT] = __SPECIAL(PAUSE), + [ETHTOOL_LINK_MODE_2500baseX_Full_BIT] = __REAL(2500), + [ETHTOOL_LINK_MODE_Backplane_BIT] = __SPECIAL(PORT), + [ETHTOOL_LINK_MODE_1000baseKX_Full_BIT] = __REAL(1000), + [ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT] = __REAL(10000), + [ETHTOOL_LINK_MODE_10000baseKR_Full_BIT] = __REAL(10000), + [ETHTOOL_LINK_MODE_10000baseR_FEC_BIT] = __REAL(10000), + [ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT] = __REAL(20000), + [ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT] = __REAL(20000), + [ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT] = __REAL(40000), + [ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT] = __REAL(40000), + [ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT] = __REAL(40000), + [ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT] = __REAL(40000), + [ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT] = __REAL(56000), + [ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT] = __REAL(56000), + [ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT] = __REAL(56000), + [ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT] = __REAL(56000), + [ETHTOOL_LINK_MODE_25000baseCR_Full_BIT] = __REAL(25000), + [ETHTOOL_LINK_MODE_25000baseKR_Full_BIT] = __REAL(25000), + [ETHTOOL_LINK_MODE_25000baseSR_Full_BIT] = __REAL(25000), + [ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT] = __REAL(50000), + [ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT] = __REAL(50000), + [ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT] = __REAL(50000), + [ETHTOOL_LINK_MODE_1000baseX_Full_BIT] = __REAL(1000), + [ETHTOOL_LINK_MODE_10000baseCR_Full_BIT] = __REAL(10000), + [ETHTOOL_LINK_MODE_10000baseSR_Full_BIT] = __REAL(10000), + [ETHTOOL_LINK_MODE_10000baseLR_Full_BIT] = __REAL(10000), + [ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT] = __REAL(10000), + [ETHTOOL_LINK_MODE_10000baseER_Full_BIT] = __REAL(10000), + [ETHTOOL_LINK_MODE_2500baseT_Full_BIT] = __REAL(2500), + [ETHTOOL_LINK_MODE_5000baseT_Full_BIT] = __REAL(5000), + [ETHTOOL_LINK_MODE_FEC_NONE_BIT] = __SPECIAL(FEC), + [ETHTOOL_LINK_MODE_FEC_RS_BIT] = __SPECIAL(FEC), + [ETHTOOL_LINK_MODE_FEC_BASER_BIT] = __SPECIAL(FEC), + [ETHTOOL_LINK_MODE_50000baseKR_Full_BIT] = __REAL(50000), + [ETHTOOL_LINK_MODE_50000baseSR_Full_BIT] = __REAL(50000), + [ETHTOOL_LINK_MODE_50000baseCR_Full_BIT] = __REAL(50000), + [ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT] = __REAL(50000), + [ETHTOOL_LINK_MODE_50000baseDR_Full_BIT] = __REAL(50000), + [ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_100baseT1_Full_BIT] = __REAL(100), + [ETHTOOL_LINK_MODE_1000baseT1_Full_BIT] = __REAL(1000), + [ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_FEC_LLRS_BIT] = __SPECIAL(FEC), + [ETHTOOL_LINK_MODE_100000baseKR_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseSR_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseCR_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_100000baseDR_Full_BIT] = __REAL(100000), + [ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT] = __REAL(200000), + [ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT] = __REAL(400000), + [ETHTOOL_LINK_MODE_100baseFX_Half_BIT] = __HALF_DUPLEX(100), + [ETHTOOL_LINK_MODE_100baseFX_Full_BIT] = __REAL(100), + [ETHTOOL_LINK_MODE_10baseT1L_Full_BIT] = __REAL(10), +}; +const unsigned int link_modes_count = ARRAY_SIZE(link_modes); + +#undef __REAL +#undef __HALF_DUPLEX +#undef __SPECIAL + +static bool lm_class_match(unsigned int mode, enum link_mode_class class) +{ + unsigned int mode_class = (mode < link_modes_count) ? + link_modes[mode].class : LM_CLASS_UNKNOWN; + + return mode_class == class || + (class == LM_CLASS_REAL && mode_class == LM_CLASS_UNKNOWN); +} + +static void print_enum(const char *const *info, unsigned int n_info, + unsigned int val, const char *label) +{ + if (val >= n_info || !info[val]) + printf("\t%s: Unknown! (%d)\n", label, val); + else + printf("\t%s: %s\n", label, info[val]); +} + +static int dump_pause(const struct nlattr *attr, bool mask, const char *label) +{ + bool pause, asym; + int ret = 0; + + pause = bitset_get_bit(attr, mask, ETHTOOL_LINK_MODE_Pause_BIT, &ret); + if (ret < 0) + goto err; + asym = bitset_get_bit(attr, mask, ETHTOOL_LINK_MODE_Asym_Pause_BIT, + &ret); + if (ret < 0) + goto err; + + printf("\t%s", label); + if (pause) + printf("%s\n", asym ? "Symmetric Receive-only" : "Symmetric"); + else + printf("%s\n", asym ? "Transmit-only" : "No"); + + return 0; +err: + fprintf(stderr, "malformed netlink message (pause modes)\n"); + return ret; +} + +static void print_banner(struct nl_context *nlctx) +{ + if (nlctx->no_banner) + return; + printf("Settings for %s:\n", nlctx->devname); + nlctx->no_banner = true; +} + +int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset, + bool mask, unsigned int class, const char *before, + const char *between, const char *after, const char *if_none) +{ + const struct nlattr *bitset_tb[ETHTOOL_A_BITSET_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(bitset_tb); + const unsigned int before_len = strlen(before); + unsigned int prev = UINT_MAX - 1; + const struct nlattr *bits; + const struct nlattr *bit; + bool first = true; + bool nomask; + int ret; + + ret = mnl_attr_parse_nested(bitset, attr_cb, &bitset_tb_info); + if (ret < 0) + goto err_nonl; + + nomask = bitset_tb[ETHTOOL_A_BITSET_NOMASK]; + /* Trying to print the mask of a "no mask" bitset doesn't make sense */ + if (mask && nomask) { + ret = -EFAULT; + goto err_nonl; + } + + bits = bitset_tb[ETHTOOL_A_BITSET_BITS]; + + if (!bits) { + const struct stringset *lm_strings; + unsigned int count; + unsigned int idx; + const char *name; + + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + goto err_nonl; + lm_strings = global_stringset(ETH_SS_LINK_MODES, + nlctx->ethnl2_socket); + bits = mask ? bitset_tb[ETHTOOL_A_BITSET_MASK] : + bitset_tb[ETHTOOL_A_BITSET_VALUE]; + ret = -EFAULT; + if (!bits || !bitset_tb[ETHTOOL_A_BITSET_SIZE]) + goto err_nonl; + count = mnl_attr_get_u32(bitset_tb[ETHTOOL_A_BITSET_SIZE]); + if (mnl_attr_get_payload_len(bits) / 4 < (count + 31) / 32) + goto err_nonl; + + printf("\t%s", before); + for (idx = 0; idx < count; idx++) { + const uint32_t *raw_data = mnl_attr_get_payload(bits); + char buff[14]; + + if (!(raw_data[idx / 32] & (1U << (idx % 32)))) + continue; + if (!lm_class_match(idx, class)) + continue; + name = get_string(lm_strings, idx); + if (!name) { + snprintf(buff, sizeof(buff), "BIT%u", idx); + name = buff; + } + if (first) + first = false; + /* ugly hack to preserve old output format */ + if (class == LM_CLASS_REAL && (idx == prev + 1) && + prev < link_modes_count && + link_modes[prev].class == LM_CLASS_REAL && + link_modes[prev].duplex == DUPLEX_HALF) + putchar(' '); + else if (between) + printf("\t%s", between); + else + printf("\n\t%*s", before_len, ""); + printf("%s", name); + prev = idx; + } + goto after; + } + + printf("\t%s", before); + mnl_attr_for_each_nested(bit, bits) { + const struct nlattr *tb[ETHTOOL_A_BITSET_BIT_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + unsigned int idx; + const char *name; + + if (mnl_attr_get_type(bit) != ETHTOOL_A_BITSET_BITS_BIT) + continue; + ret = mnl_attr_parse_nested(bit, attr_cb, &tb_info); + if (ret < 0) + goto err; + ret = -EFAULT; + if (!tb[ETHTOOL_A_BITSET_BIT_INDEX] || + !tb[ETHTOOL_A_BITSET_BIT_NAME]) + goto err; + if (!mask && !nomask && !tb[ETHTOOL_A_BITSET_BIT_VALUE]) + continue; + + idx = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_BIT_INDEX]); + name = mnl_attr_get_str(tb[ETHTOOL_A_BITSET_BIT_NAME]); + if (!lm_class_match(idx, class)) + continue; + if (first) { + first = false; + } else { + /* ugly hack to preserve old output format */ + if ((class == LM_CLASS_REAL) && (idx == prev + 1) && + (prev < link_modes_count) && + (link_modes[prev].class == LM_CLASS_REAL) && + (link_modes[prev].duplex == DUPLEX_HALF)) + putchar(' '); + else if (between) + printf("\t%s", between); + else + printf("\n\t%*s", before_len, ""); + } + printf("%s", name); + prev = idx; + } +after: + if (first && if_none) + printf("%s", if_none); + printf("%s", after); + + return 0; +err: + putchar('\n'); +err_nonl: + fflush(stdout); + fprintf(stderr, "malformed netlink message (link_modes)\n"); + return ret; +} + +static int dump_our_modes(struct nl_context *nlctx, const struct nlattr *attr) +{ + bool autoneg; + int ret; + + print_banner(nlctx); + ret = dump_link_modes(nlctx, attr, true, LM_CLASS_PORT, + "Supported ports: [ ", " ", " ]\n", NULL); + if (ret < 0) + return ret; + + ret = dump_link_modes(nlctx, attr, true, LM_CLASS_REAL, + "Supported link modes: ", NULL, "\n", + "Not reported"); + if (ret < 0) + return ret; + ret = dump_pause(attr, true, "Supported pause frame use: "); + if (ret < 0) + return ret; + + autoneg = bitset_get_bit(attr, true, ETHTOOL_LINK_MODE_Autoneg_BIT, + &ret); + if (ret < 0) + return ret; + printf("\tSupports auto-negotiation: %s\n", autoneg ? "Yes" : "No"); + + ret = dump_link_modes(nlctx, attr, true, LM_CLASS_FEC, + "Supported FEC modes: ", " ", "\n", + "Not reported"); + if (ret < 0) + return ret; + + ret = dump_link_modes(nlctx, attr, false, LM_CLASS_REAL, + "Advertised link modes: ", NULL, "\n", + "Not reported"); + if (ret < 0) + return ret; + + ret = dump_pause(attr, false, "Advertised pause frame use: "); + if (ret < 0) + return ret; + autoneg = bitset_get_bit(attr, false, ETHTOOL_LINK_MODE_Autoneg_BIT, + &ret); + if (ret < 0) + return ret; + printf("\tAdvertised auto-negotiation: %s\n", autoneg ? "Yes" : "No"); + + ret = dump_link_modes(nlctx, attr, false, LM_CLASS_FEC, + "Advertised FEC modes: ", " ", "\n", + "Not reported"); + return ret; +} + +static int dump_peer_modes(struct nl_context *nlctx, const struct nlattr *attr) +{ + bool autoneg; + int ret; + + print_banner(nlctx); + ret = dump_link_modes(nlctx, attr, false, LM_CLASS_REAL, + "Link partner advertised link modes: ", + NULL, "\n", "Not reported"); + if (ret < 0) + return ret; + + ret = dump_pause(attr, false, + "Link partner advertised pause frame use: "); + if (ret < 0) + return ret; + + autoneg = bitset_get_bit(attr, false, + ETHTOOL_LINK_MODE_Autoneg_BIT, &ret); + if (ret < 0) + return ret; + printf("\tLink partner advertised auto-negotiation: %s\n", + autoneg ? "Yes" : "No"); + + ret = dump_link_modes(nlctx, attr, false, LM_CLASS_FEC, + "Link partner advertised FEC modes: ", + " ", "\n", "Not reported"); + return ret; +} + +int linkmodes_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_LINKMODES_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + int ret; + + if (nlctx->is_dump || nlctx->is_monitor) + nlctx->no_banner = false; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_LINKMODES_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + if (tb[ETHTOOL_A_LINKMODES_OURS]) { + ret = dump_our_modes(nlctx, tb[ETHTOOL_A_LINKMODES_OURS]); + if (ret < 0) + goto err; + } + if (tb[ETHTOOL_A_LINKMODES_PEER]) { + ret = dump_peer_modes(nlctx, tb[ETHTOOL_A_LINKMODES_PEER]); + if (ret < 0) + goto err; + } + if (tb[ETHTOOL_A_LINKMODES_SPEED]) { + uint32_t val = mnl_attr_get_u32(tb[ETHTOOL_A_LINKMODES_SPEED]); + + print_banner(nlctx); + if (val == 0 || val == (uint16_t)(-1) || val == (uint32_t)(-1)) + printf("\tSpeed: Unknown!\n"); + else + printf("\tSpeed: %uMb/s\n", val); + } + if (tb[ETHTOOL_A_LINKMODES_LANES]) { + uint32_t val = mnl_attr_get_u32(tb[ETHTOOL_A_LINKMODES_LANES]); + + print_banner(nlctx); + printf("\tLanes: %u\n", val); + } + if (tb[ETHTOOL_A_LINKMODES_DUPLEX]) { + uint8_t val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKMODES_DUPLEX]); + + print_banner(nlctx); + print_enum(names_duplex, ARRAY_SIZE(names_duplex), val, + "Duplex"); + } + if (tb[ETHTOOL_A_LINKMODES_AUTONEG]) { + int autoneg = mnl_attr_get_u8(tb[ETHTOOL_A_LINKMODES_AUTONEG]); + + print_banner(nlctx); + printf("\tAuto-negotiation: %s\n", + (autoneg == AUTONEG_DISABLE) ? "off" : "on"); + } + if (tb[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG]) { + uint8_t val; + + val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG]); + + print_banner(nlctx); + print_enum(names_master_slave_cfg, + ARRAY_SIZE(names_master_slave_cfg), val, + "master-slave cfg"); + } + if (tb[ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE]) { + uint8_t val; + + val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE]); + print_banner(nlctx); + print_enum(names_master_slave_state, + ARRAY_SIZE(names_master_slave_state), val, + "master-slave status"); + } + + return MNL_CB_OK; +err: + if (nlctx->is_monitor || nlctx->is_dump) + return MNL_CB_OK; + fputs("No data available\n", stdout); + nlctx->exit_code = 75; + return MNL_CB_ERROR; +} + +int linkinfo_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_LINKINFO_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + int port = -1; + int ret; + + if (nlctx->is_dump || nlctx->is_monitor) + nlctx->no_banner = false; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_LINKINFO_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + if (tb[ETHTOOL_A_LINKINFO_PORT]) { + uint8_t val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKINFO_PORT]); + + print_banner(nlctx); + print_enum(names_port, ARRAY_SIZE(names_port), val, "Port"); + port = val; + } + if (tb[ETHTOOL_A_LINKINFO_PHYADDR]) { + uint8_t val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKINFO_PHYADDR]); + + print_banner(nlctx); + printf("\tPHYAD: %u\n", val); + } + if (tb[ETHTOOL_A_LINKINFO_TRANSCEIVER]) { + uint8_t val; + + val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKINFO_TRANSCEIVER]); + print_banner(nlctx); + print_enum(names_transceiver, ARRAY_SIZE(names_transceiver), + val, "Transceiver"); + } + if (tb[ETHTOOL_A_LINKINFO_TP_MDIX] && tb[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL] && + port == PORT_TP) { + uint8_t mdix = mnl_attr_get_u8(tb[ETHTOOL_A_LINKINFO_TP_MDIX]); + uint8_t mdix_ctrl = + mnl_attr_get_u8(tb[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL]); + + print_banner(nlctx); + dump_mdix(mdix, mdix_ctrl); + } + + return MNL_CB_OK; +} + +static const char *get_enum_string(const char *const *string_table, unsigned int n_string_table, + unsigned int val) +{ + if (val >= n_string_table || !string_table[val]) + return NULL; + else + return string_table[val]; +} + +static const char *const names_link_ext_state[] = { + [ETHTOOL_LINK_EXT_STATE_AUTONEG] = "Autoneg", + [ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE] = "Link training failure", + [ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH] = "Logical mismatch", + [ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY] = "Bad signal integrity", + [ETHTOOL_LINK_EXT_STATE_NO_CABLE] = "No cable", + [ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE] = "Cable issue", + [ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE] = "EEPROM issue", + [ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE] = "Calibration failure", + [ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED] = "Power budget exceeded", + [ETHTOOL_LINK_EXT_STATE_OVERHEAT] = "Overheat", + [ETHTOOL_LINK_EXT_STATE_MODULE] = "Module", +}; + +static const char *const names_autoneg_link_ext_substate[] = { + [ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED] = + "No partner detected", + [ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED] = + "Ack not received", + [ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED] = + "Next page exchange failed", + [ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE] = + "No partner detected during force mode", + [ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE] = + "FEC mismatch during override", + [ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD] = + "No HCD", +}; + +static const char *const names_link_training_link_ext_substate[] = { + [ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED] = + "KR frame lock not acquired", + [ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT] = + "KR link inhibit timeout", + [ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY] = + "KR Link partner did not set receiver ready", + [ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT] = + "Remote side is not ready yet", +}; + +static const char *const names_link_logical_mismatch_link_ext_substate[] = { + [ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK] = + "PCS did not acquire block lock", + [ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK] = + "PCS did not acquire AM lock", + [ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS] = + "PCS did not get align_status", + [ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED] = + "FC FEC is not locked", + [ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED] = + "RS FEC is not locked", +}; + +static const char *const names_bad_signal_integrity_link_ext_substate[] = { + [ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS] = + "Large number of physical errors", + [ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE] = + "Unsupported rate", + [ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_REFERENCE_CLOCK_LOST] = + "Serdes reference clock lost", + [ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_ALOS] = + "Serdes ALOS", +}; + +static const char *const names_cable_issue_link_ext_substate[] = { + [ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE] = + "Unsupported cable", + [ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE] = + "Cable test failure", +}; + +static const char *const names_module_link_ext_substate[] = { + [ETHTOOL_LINK_EXT_SUBSTATE_MODULE_CMIS_NOT_READY] = + "CMIS module is not in ModuleReady state", +}; + +static const char *link_ext_substate_get(uint8_t link_ext_state_val, uint8_t link_ext_substate_val) +{ + switch (link_ext_state_val) { + case ETHTOOL_LINK_EXT_STATE_AUTONEG: + return get_enum_string(names_autoneg_link_ext_substate, + ARRAY_SIZE(names_autoneg_link_ext_substate), + link_ext_substate_val); + case ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE: + return get_enum_string(names_link_training_link_ext_substate, + ARRAY_SIZE(names_link_training_link_ext_substate), + link_ext_substate_val); + case ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH: + return get_enum_string(names_link_logical_mismatch_link_ext_substate, + ARRAY_SIZE(names_link_logical_mismatch_link_ext_substate), + link_ext_substate_val); + case ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY: + return get_enum_string(names_bad_signal_integrity_link_ext_substate, + ARRAY_SIZE(names_bad_signal_integrity_link_ext_substate), + link_ext_substate_val); + case ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE: + return get_enum_string(names_cable_issue_link_ext_substate, + ARRAY_SIZE(names_cable_issue_link_ext_substate), + link_ext_substate_val); + case ETHTOOL_LINK_EXT_STATE_MODULE: + return get_enum_string(names_module_link_ext_substate, + ARRAY_SIZE(names_module_link_ext_substate), + link_ext_substate_val); + default: + return NULL; + } +} + +static void linkstate_link_ext_substate_print(const struct nlattr *tb[], + uint8_t link_ext_state_val) +{ + uint8_t link_ext_substate_val; + const char *link_ext_substate_str; + + if (!tb[ETHTOOL_A_LINKSTATE_EXT_SUBSTATE]) + return; + + link_ext_substate_val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKSTATE_EXT_SUBSTATE]); + + link_ext_substate_str = link_ext_substate_get(link_ext_state_val, link_ext_substate_val); + if (!link_ext_substate_str) + printf(", %u", link_ext_substate_val); + else + printf(", %s", link_ext_substate_str); +} + +static void linkstate_link_ext_state_print(const struct nlattr *tb[]) +{ + uint8_t link_ext_state_val; + const char *link_ext_state_str; + + if (!tb[ETHTOOL_A_LINKSTATE_EXT_STATE]) + return; + + link_ext_state_val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKSTATE_EXT_STATE]); + + link_ext_state_str = get_enum_string(names_link_ext_state, + ARRAY_SIZE(names_link_ext_state), + link_ext_state_val); + if (!link_ext_state_str) + printf(" (%u", link_ext_state_val); + else + printf(" (%s", link_ext_state_str); + + linkstate_link_ext_substate_print(tb, link_ext_state_val); + printf(")"); +} + +int linkstate_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_LINKSTATE_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + int ret; + + if (nlctx->is_dump || nlctx->is_monitor) + nlctx->no_banner = false; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_LINKSTATE_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + if (tb[ETHTOOL_A_LINKSTATE_LINK]) { + uint8_t val = mnl_attr_get_u8(tb[ETHTOOL_A_LINKSTATE_LINK]); + + print_banner(nlctx); + printf("\tLink detected: %s", val ? "yes" : "no"); + linkstate_link_ext_state_print(tb); + printf("\n"); + } + + if (tb[ETHTOOL_A_LINKSTATE_SQI]) { + uint32_t val = mnl_attr_get_u32(tb[ETHTOOL_A_LINKSTATE_SQI]); + + print_banner(nlctx); + printf("\tSQI: %u", val); + + if (tb[ETHTOOL_A_LINKSTATE_SQI_MAX]) { + uint32_t max; + + max = mnl_attr_get_u32(tb[ETHTOOL_A_LINKSTATE_SQI_MAX]); + printf("/%u\n", max); + } else { + printf("\n"); + } + } + + return MNL_CB_OK; +} + +void wol_modes_cb(unsigned int idx, const char *name __maybe_unused, bool val, + void *data) +{ + struct ethtool_wolinfo *wol = data; + + if (idx >= 32) + return; + wol->supported |= (1U << idx); + if (val) + wol->wolopts |= (1U << idx); +} + +int wol_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_WOL_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + struct ethtool_wolinfo wol = {}; + int ret; + + if (nlctx->is_dump || nlctx->is_monitor) + nlctx->no_banner = false; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_WOL_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + if (tb[ETHTOOL_A_WOL_MODES]) + walk_bitset(tb[ETHTOOL_A_WOL_MODES], NULL, wol_modes_cb, &wol); + if (tb[ETHTOOL_A_WOL_SOPASS]) { + unsigned int len; + + len = mnl_attr_get_payload_len(tb[ETHTOOL_A_WOL_SOPASS]); + if (len != SOPASS_MAX) + fprintf(stderr, "invalid SecureOn password length %u (should be %u)\n", + len, SOPASS_MAX); + else + memcpy(wol.sopass, + mnl_attr_get_payload(tb[ETHTOOL_A_WOL_SOPASS]), + SOPASS_MAX); + } + print_banner(nlctx); + dump_wol(&wol); + + return MNL_CB_OK; +} + +void msgmask_cb(unsigned int idx, const char *name __maybe_unused, bool val, + void *data) +{ + u32 *msg_mask = data; + + if (idx >= 32) + return; + if (val) + *msg_mask |= (1U << idx); +} + +void msgmask_cb2(unsigned int idx __maybe_unused, const char *name, + bool val, void *data __maybe_unused) +{ + if (val) + printf(" %s", name); +} + +int debug_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_DEBUG_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + const struct stringset *msgmask_strings = NULL; + struct nl_context *nlctx = data; + u32 msg_mask = 0; + int ret; + + if (nlctx->is_dump || nlctx->is_monitor) + nlctx->no_banner = false; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_DEBUG_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + if (!tb[ETHTOOL_A_DEBUG_MSGMASK]) + return MNL_CB_OK; + if (bitset_is_compact(tb[ETHTOOL_A_DEBUG_MSGMASK])) { + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + return MNL_CB_OK; + msgmask_strings = global_stringset(ETH_SS_MSG_CLASSES, + nlctx->ethnl2_socket); + } + + print_banner(nlctx); + walk_bitset(tb[ETHTOOL_A_DEBUG_MSGMASK], NULL, msgmask_cb, &msg_mask); + printf(" Current message level: 0x%08x (%u)\n" + " ", + msg_mask, msg_mask); + walk_bitset(tb[ETHTOOL_A_DEBUG_MSGMASK], msgmask_strings, msgmask_cb2, + NULL); + fputc('\n', stdout); + + return MNL_CB_OK; +} + +static int gset_request(struct nl_socket *nlsk, uint8_t msg_type, + uint16_t hdr_attr, mnl_cb_t cb) +{ + int ret; + + ret = nlsock_prep_get_request(nlsk, msg_type, hdr_attr, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, cb); +} + +int nl_gset(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_LINKMODES_GET, true) || + netlink_cmd_check(ctx, ETHTOOL_MSG_LINKINFO_GET, true) || + netlink_cmd_check(ctx, ETHTOOL_MSG_WOL_GET, true) || + netlink_cmd_check(ctx, ETHTOOL_MSG_DEBUG_GET, true) || + netlink_cmd_check(ctx, ETHTOOL_MSG_LINKSTATE_GET, true)) + return -EOPNOTSUPP; + + nlctx->suppress_nlerr = 1; + + ret = gset_request(nlsk, ETHTOOL_MSG_LINKMODES_GET, + ETHTOOL_A_LINKMODES_HEADER, linkmodes_reply_cb); + if (ret == -ENODEV) + return ret; + + ret = gset_request(nlsk, ETHTOOL_MSG_LINKINFO_GET, + ETHTOOL_A_LINKINFO_HEADER, linkinfo_reply_cb); + if (ret == -ENODEV) + return ret; + + ret = gset_request(nlsk, ETHTOOL_MSG_WOL_GET, ETHTOOL_A_WOL_HEADER, + wol_reply_cb); + if (ret == -ENODEV) + return ret; + + ret = gset_request(nlsk, ETHTOOL_MSG_DEBUG_GET, ETHTOOL_A_DEBUG_HEADER, + debug_reply_cb); + if (ret == -ENODEV) + return ret; + + ret = gset_request(nlsk, ETHTOOL_MSG_LINKSTATE_GET, + ETHTOOL_A_LINKSTATE_HEADER, linkstate_reply_cb); + if (ret == -ENODEV) + return ret; + + if (!nlctx->no_banner) { + printf("No data available\n"); + return 75; + } + + + return 0; +} + +/* SET_SETTINGS */ + +enum { + WAKE_PHY_BIT = 0, + WAKE_UCAST_BIT = 1, + WAKE_MCAST_BIT = 2, + WAKE_BCAST_BIT = 3, + WAKE_ARP_BIT = 4, + WAKE_MAGIC_BIT = 5, + WAKE_MAGICSECURE_BIT = 6, + WAKE_FILTER_BIT = 7, +}; + +#define WAKE_ALL (WAKE_PHY | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_ARP | \ + WAKE_MAGIC | WAKE_MAGICSECURE) + +static const struct lookup_entry_u8 port_values[] = { + { .arg = "tp", .val = PORT_TP }, + { .arg = "aui", .val = PORT_AUI }, + { .arg = "mii", .val = PORT_MII }, + { .arg = "fibre", .val = PORT_FIBRE }, + { .arg = "bnc", .val = PORT_BNC }, + { .arg = "da", .val = PORT_DA }, + {} +}; + +static const struct lookup_entry_u8 mdix_values[] = { + { .arg = "auto", .val = ETH_TP_MDI_AUTO }, + { .arg = "on", .val = ETH_TP_MDI_X }, + { .arg = "off", .val = ETH_TP_MDI }, + {} +}; + +static const struct error_parser_data xcvr_parser_data = { + .err_msg = "deprecated parameter '%s' not supported by kernel\n", + .ret_val = -EINVAL, + .extra_args = 1, +}; + +static const struct lookup_entry_u8 autoneg_values[] = { + { .arg = "off", .val = AUTONEG_DISABLE }, + { .arg = "on", .val = AUTONEG_ENABLE }, + {} +}; + +static const struct bitset_parser_data advertise_parser_data = { + .no_mask = false, + .force_hex = true, +}; + +static const struct lookup_entry_u32 duplex_values[] = { + { .arg = "half", .val = DUPLEX_HALF }, + { .arg = "full", .val = DUPLEX_FULL }, + {} +}; + +static const struct lookup_entry_u8 master_slave_values[] = { + { .arg = "preferred-master", .val = MASTER_SLAVE_CFG_MASTER_PREFERRED }, + { .arg = "preferred-slave", .val = MASTER_SLAVE_CFG_SLAVE_PREFERRED }, + { .arg = "forced-master", .val = MASTER_SLAVE_CFG_MASTER_FORCE }, + { .arg = "forced-slave", .val = MASTER_SLAVE_CFG_SLAVE_FORCE }, + {} +}; + +char wol_bit_chars[WOL_MODE_COUNT] = { + [WAKE_PHY_BIT] = 'p', + [WAKE_UCAST_BIT] = 'u', + [WAKE_MCAST_BIT] = 'm', + [WAKE_BCAST_BIT] = 'b', + [WAKE_ARP_BIT] = 'a', + [WAKE_MAGIC_BIT] = 'g', + [WAKE_MAGICSECURE_BIT] = 's', + [WAKE_FILTER_BIT] = 'f', +}; + +const struct char_bitset_parser_data wol_parser_data = { + .bit_chars = wol_bit_chars, + .nbits = WOL_MODE_COUNT, + .reset_char = 'd', +}; + +const struct byte_str_parser_data sopass_parser_data = { + .min_len = 6, + .max_len = 6, + .delim = ':', +}; + +static const struct bitset_parser_data msglvl_parser_data = { + .no_mask = false, + .force_hex = false, +}; + +static const struct param_parser sset_params[] = { + { + .arg = "port", + .group = ETHTOOL_MSG_LINKINFO_SET, + .type = ETHTOOL_A_LINKINFO_PORT, + .handler = nl_parse_lookup_u8, + .handler_data = port_values, + .min_argc = 1, + }, + { + .arg = "mdix", + .group = ETHTOOL_MSG_LINKINFO_SET, + .type = ETHTOOL_A_LINKINFO_TP_MDIX_CTRL, + .handler = nl_parse_lookup_u8, + .handler_data = mdix_values, + .min_argc = 1, + }, + { + .arg = "phyad", + .group = ETHTOOL_MSG_LINKINFO_SET, + .type = ETHTOOL_A_LINKINFO_PHYADDR, + .handler = nl_parse_direct_u8, + .min_argc = 1, + }, + { + .arg = "xcvr", + .group = ETHTOOL_MSG_LINKINFO_SET, + .handler = nl_parse_error, + .handler_data = &xcvr_parser_data, + .min_argc = 1, + }, + { + .arg = "autoneg", + .group = ETHTOOL_MSG_LINKMODES_SET, + .type = ETHTOOL_A_LINKMODES_AUTONEG, + .handler = nl_parse_lookup_u8, + .handler_data = autoneg_values, + .min_argc = 1, + }, + { + .arg = "advertise", + .group = ETHTOOL_MSG_LINKMODES_SET, + .type = ETHTOOL_A_LINKMODES_OURS, + .handler = nl_parse_bitset, + .handler_data = &advertise_parser_data, + .min_argc = 1, + }, + { + .arg = "speed", + .group = ETHTOOL_MSG_LINKMODES_SET, + .type = ETHTOOL_A_LINKMODES_SPEED, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "lanes", + .group = ETHTOOL_MSG_LINKMODES_SET, + .type = ETHTOOL_A_LINKMODES_LANES, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "duplex", + .group = ETHTOOL_MSG_LINKMODES_SET, + .type = ETHTOOL_A_LINKMODES_DUPLEX, + .handler = nl_parse_lookup_u8, + .handler_data = duplex_values, + .min_argc = 1, + }, + { + .arg = "master-slave", + .group = ETHTOOL_MSG_LINKMODES_SET, + .type = ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, + .handler = nl_parse_lookup_u8, + .handler_data = master_slave_values, + .min_argc = 1, + }, + { + .arg = "wol", + .group = ETHTOOL_MSG_WOL_SET, + .type = ETHTOOL_A_WOL_MODES, + .handler = nl_parse_char_bitset, + .handler_data = &wol_parser_data, + .min_argc = 1, + }, + { + .arg = "sopass", + .group = ETHTOOL_MSG_WOL_SET, + .type = ETHTOOL_A_WOL_SOPASS, + .handler = nl_parse_byte_str, + .handler_data = &sopass_parser_data, + .min_argc = 1, + }, + { + .arg = "msglvl", + .group = ETHTOOL_MSG_DEBUG_SET, + .type = ETHTOOL_A_DEBUG_MSGMASK, + .handler = nl_parse_bitset, + .handler_data = &msglvl_parser_data, + .min_argc = 1, + }, + {} +}; + +/* Maximum number of request messages sent to kernel; must be equal to the + * number of different .group values in sset_params[] array. + */ +#define SSET_MAX_MSGS 4 + +static int linkmodes_reply_advert_all_cb(const struct nlmsghdr *nlhdr, + void *data) +{ + const struct nlattr *tb[ETHTOOL_A_LINKMODES_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_msg_buff *req_msgbuff = data; + const struct nlattr *ours_attr; + struct nlattr *req_bitset; + uint32_t *supported_modes; + unsigned int modes_count; + unsigned int i; + int ret; + + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return MNL_CB_ERROR; + ours_attr = tb[ETHTOOL_A_LINKMODES_OURS]; + if (!ours_attr) + return MNL_CB_ERROR; + modes_count = bitset_get_count(tb[ETHTOOL_A_LINKMODES_OURS], &ret); + if (ret < 0) + return MNL_CB_ERROR; + supported_modes = get_compact_bitset_mask(tb[ETHTOOL_A_LINKMODES_OURS]); + if (!supported_modes) + return MNL_CB_ERROR; + + /* keep only "real" link modes */ + for (i = 0; i < modes_count; i++) + if (!lm_class_match(i, LM_CLASS_REAL)) + supported_modes[i / 32] &= ~((uint32_t)1 << (i % 32)); + + req_bitset = ethnla_nest_start(req_msgbuff, ETHTOOL_A_LINKMODES_OURS); + if (!req_bitset) + return MNL_CB_ERROR; + + if (ethnla_put_u32(req_msgbuff, ETHTOOL_A_BITSET_SIZE, modes_count) || + ethnla_put(req_msgbuff, ETHTOOL_A_BITSET_VALUE, + DIV_ROUND_UP(modes_count, 32) * sizeof(uint32_t), + supported_modes) || + ethnla_put(req_msgbuff, ETHTOOL_A_BITSET_MASK, + DIV_ROUND_UP(modes_count, 32) * sizeof(uint32_t), + supported_modes)) { + ethnla_nest_cancel(req_msgbuff, req_bitset); + return MNL_CB_ERROR; + } + + ethnla_nest_end(req_msgbuff, req_bitset); + return MNL_CB_OK; +} + +/* For compatibility reasons with ioctl-based ethtool, when "autoneg on" is + * specified without "advertise", "speed", "duplex" and "lanes", we need to + * query the supported link modes from the kernel and advertise all the "real" + * ones. + */ +static int nl_sset_compat_linkmodes(struct nl_context *nlctx, + struct nl_msg_buff *msgbuff) +{ + const struct nlattr *tb[ETHTOOL_A_LINKMODES_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + ret = mnl_attr_parse(msgbuff->nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + if (!tb[ETHTOOL_A_LINKMODES_AUTONEG] || tb[ETHTOOL_A_LINKMODES_OURS] || + tb[ETHTOOL_A_LINKMODES_SPEED] || tb[ETHTOOL_A_LINKMODES_DUPLEX] || + tb[ETHTOOL_A_LINKMODES_LANES]) + return 0; + if (!mnl_attr_get_u8(tb[ETHTOOL_A_LINKMODES_AUTONEG])) + return 0; + + /* all conditions satisfied, create ETHTOOL_A_LINKMODES_OURS */ + if (netlink_cmd_check(nlctx->ctx, ETHTOOL_MSG_LINKMODES_GET, false) || + netlink_cmd_check(nlctx->ctx, ETHTOOL_MSG_LINKMODES_SET, false)) + return -EOPNOTSUPP; + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_LINKMODES_GET, + ETHTOOL_A_LINKMODES_HEADER, + ETHTOOL_FLAG_COMPACT_BITSETS); + if (ret < 0) + return ret; + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return ret; + return nlsock_process_reply(nlsk, linkmodes_reply_advert_all_cb, + msgbuff); +} + +int nl_sset(struct cmd_context *ctx) +{ + struct nl_msg_buff *msgbuffs[SSET_MAX_MSGS] = {}; + struct nl_context *nlctx = ctx->nlctx; + unsigned int i; + int ret; + + nlctx->cmd = "-s"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + + ret = nl_parser(nlctx, sset_params, NULL, PARSER_GROUP_MSG, msgbuffs); + if (ret < 0) { + ret = 1; + goto out_free; + } + + for (i = 0; i < SSET_MAX_MSGS && msgbuffs[i]; i++) { + struct nl_socket *nlsk = nlctx->ethnl_socket; + + if (msgbuffs[i]->genlhdr->cmd == ETHTOOL_MSG_LINKMODES_SET) { + ret = nl_sset_compat_linkmodes(nlctx, msgbuffs[i]); + if (ret < 0) + goto out_free; + } + ret = nlsock_sendmsg(nlsk, msgbuffs[i]); + if (ret < 0) + goto out_free; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, NULL); + if (ret < 0) + goto out_free; + } + +out_free: + for (i = 0; i < SSET_MAX_MSGS && msgbuffs[i]; i++) { + msgbuff_done(msgbuffs[i]); + free(msgbuffs[i]); + } + if (ret >= 0) + return ret; + return nlctx->exit_code ?: 75; +} diff --git a/netlink/stats.c b/netlink/stats.c new file mode 100644 index 0000000..9f609a4 --- /dev/null +++ b/netlink/stats.c @@ -0,0 +1,319 @@ +/* + * stats.c - netlink implementation of stats + * + * Implementation of "ethtool -S [--groups ] etc." + */ + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "parser.h" +#include "strset.h" + +static int parse_rmon_hist_one(const char *grp_name, const struct nlattr *hist, + const char *dir) +{ + const struct nlattr *tb[ETHTOOL_A_STATS_GRP_HIST_VAL + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + unsigned long long val; + unsigned int low, hi; + int ret; + + ret = mnl_attr_parse_nested(hist, attr_cb, &tb_info); + if (ret < 0) { + fprintf(stderr, "invalid kernel response - malformed histogram entry\n"); + return 1; + } + + if (!tb[ETHTOOL_A_STATS_GRP_HIST_BKT_LOW] || + !tb[ETHTOOL_A_STATS_GRP_HIST_BKT_HI] || + !tb[ETHTOOL_A_STATS_GRP_HIST_VAL]) { + fprintf(stderr, "invalid kernel response - histogram entry missing attributes\n"); + return 1; + } + + low = mnl_attr_get_u32(tb[ETHTOOL_A_STATS_GRP_HIST_BKT_LOW]); + hi = mnl_attr_get_u32(tb[ETHTOOL_A_STATS_GRP_HIST_BKT_HI]); + val = mnl_attr_get_u64(tb[ETHTOOL_A_STATS_GRP_HIST_VAL]); + + if (!is_json_context()) { + fprintf(stdout, "%s-%s-etherStatsPkts", dir, grp_name); + + if (low && hi) { + fprintf(stdout, "%uto%uOctets: %llu\n", low, hi, val); + } else if (hi) { + fprintf(stdout, "%uOctets: %llu\n", hi, val); + } else if (low) { + fprintf(stdout, "%utoMaxOctets: %llu\n", low, val); + } else { + fprintf(stderr, "invalid kernel response - bad histogram entry bounds\n"); + return 1; + } + } else { + open_json_object(NULL); + print_uint(PRINT_JSON, "low", NULL, low); + print_uint(PRINT_JSON, "high", NULL, hi); + print_u64(PRINT_JSON, "val", NULL, val); + close_json_object(); + } + + return 0; +} + +static int parse_rmon_hist(const struct nlattr *grp, const char *grp_name, + const char *name, const char *dir, unsigned int type) +{ + const struct nlattr *attr; + + open_json_array(name, ""); + + mnl_attr_for_each_nested(attr, grp) { + if (mnl_attr_get_type(attr) == type && + parse_rmon_hist_one(grp_name, attr, dir)) + goto err_close_rmon; + } + close_json_array(""); + + return 0; + +err_close_rmon: + close_json_array(""); + return 1; +} + +static int parse_grp(struct nl_context *nlctx, const struct nlattr *grp, + const struct stringset *std_str) +{ + const struct nlattr *tb[ETHTOOL_A_STATS_GRP_SS_ID + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + bool hist_rx = false, hist_tx = false; + const struct stringset *stat_str; + const struct nlattr *attr, *stat; + const char *std_name, *name; + unsigned int ss_id, id, s; + unsigned long long val; + int ret; + + ret = mnl_attr_parse_nested(grp, attr_cb, &tb_info); + if (ret < 0) + return 1; + + if (!tb[ETHTOOL_A_STATS_GRP_ID]) + return 1; + if (!tb[ETHTOOL_A_STATS_GRP_SS_ID]) + return 0; + + id = mnl_attr_get_u32(tb[ETHTOOL_A_STATS_GRP_ID]); + ss_id = mnl_attr_get_u32(tb[ETHTOOL_A_STATS_GRP_SS_ID]); + + stat_str = global_stringset(ss_id, nlctx->ethnl2_socket); + + std_name = get_string(std_str, id); + open_json_object(std_name); + + mnl_attr_for_each_nested(attr, grp) { + switch (mnl_attr_get_type(attr)) { + case ETHTOOL_A_STATS_GRP_STAT: + break; + case ETHTOOL_A_STATS_GRP_HIST_RX: + hist_rx = true; + continue; + case ETHTOOL_A_STATS_GRP_HIST_TX: + hist_tx = true; + continue; + default: + continue; + } + + stat = mnl_attr_get_payload(attr); + ret = mnl_attr_validate(stat, MNL_TYPE_U64); + if (ret) { + fprintf(stderr, "invalid kernel response - bad statistic entry\n"); + goto err_close_grp; + } + s = mnl_attr_get_type(stat); + name = get_string(stat_str, s); + if (!name || !name[0]) + continue; + + if (!is_json_context()) + fprintf(stdout, "%s-%s: ", std_name, name); + + val = mnl_attr_get_u64(stat); + print_u64(PRINT_ANY, name, "%llu\n", val); + } + + if (hist_rx) + parse_rmon_hist(grp, std_name, "rx-pktsNtoM", "rx", + ETHTOOL_A_STATS_GRP_HIST_RX); + if (hist_tx) + parse_rmon_hist(grp, std_name, "tx-pktsNtoM", "tx", + ETHTOOL_A_STATS_GRP_HIST_TX); + + close_json_object(); + + return 0; + +err_close_grp: + close_json_object(); + return 1; +} + +static int stats_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_STATS_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + const struct stringset *std_str; + const struct nlattr *attr; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_STATS_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + return err_ret; + std_str = global_stringset(ETH_SS_STATS_STD, nlctx->ethnl2_socket); + + if (silent) + print_nl(); + + open_json_object(NULL); + + print_string(PRINT_ANY, "ifname", "Standard stats for %s:\n", + nlctx->devname); + + mnl_attr_for_each(attr, nlhdr, GENL_HDRLEN) { + if (mnl_attr_get_type(attr) == ETHTOOL_A_STATS_GRP) { + ret = parse_grp(nlctx, attr, std_str); + if (ret) + goto err_close_dev; + } + } + + close_json_object(); + + return MNL_CB_OK; + +err_close_dev: + close_json_object(); + return err_ret; +} + +static const struct bitset_parser_data stats_parser_data = { + .no_mask = true, + .force_hex = false, +}; + +static int stats_parse_all_groups(struct nl_context *nlctx, uint16_t type, + const void *data, struct nl_msg_buff *msgbuff, + void *dest) +{ + const struct stringset *std_str; + struct nlattr *nest; + int i, ret, nbits; + uint32_t *bits; + + if (data || dest) + return -EFAULT; + + /* ethnl2 and strset code already does caching */ + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + return ret; + std_str = global_stringset(ETH_SS_STATS_STD, nlctx->ethnl2_socket); + + nbits = get_count(std_str); + bits = calloc(DIV_ROUND_UP(nbits, 32), sizeof(uint32_t)); + if (!bits) + return -ENOMEM; + + for (i = 0; i < nbits; i++) + bits[i / 32] |= 1U << (i % 32); + + ret = -EMSGSIZE; + nest = ethnla_nest_start(msgbuff, type); + if (!nest) + goto err_free; + + if (ethnla_put_flag(msgbuff, ETHTOOL_A_BITSET_NOMASK, true) || + ethnla_put_u32(msgbuff, ETHTOOL_A_BITSET_SIZE, nbits) || + ethnla_put(msgbuff, ETHTOOL_A_BITSET_VALUE, + DIV_ROUND_UP(nbits, 32) * sizeof(uint32_t), bits)) + goto err_cancel; + + ethnla_nest_end(msgbuff, nest); + free(bits); + return 0; + +err_cancel: + ethnla_nest_cancel(msgbuff, nest); +err_free: + free(bits); + return ret; +} + +static const struct param_parser stats_params[] = { + { + .arg = "--groups", + .type = ETHTOOL_A_STATS_GROUPS, + .handler = nl_parse_bitset, + .handler_data = &stats_parser_data, + .min_argc = 1, + .alt_group = 1, + }, + { + .arg = "--all-groups", + .type = ETHTOOL_A_STATS_GROUPS, + .handler = stats_parse_all_groups, + .alt_group = 1, + }, + {} +}; + +int nl_gstats(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_STATS_GET, + ETHTOOL_A_STATS_HEADER, 0); + if (ret < 0) + return ret; + + nlctx->cmd = "-S"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + + ret = nl_parser(nlctx, stats_params, NULL, PARSER_GROUP_NONE, NULL); + if (ret < 0) + return 1; + + new_json_obj(ctx->json); + ret = nlsock_send_get_request(nlsk, stats_reply_cb); + delete_json_obj(); + return ret; +} + +bool nl_gstats_chk(struct cmd_context *ctx) +{ + return ctx->argc; +} diff --git a/netlink/strset.c b/netlink/strset.c new file mode 100644 index 0000000..fbc9c17 --- /dev/null +++ b/netlink/strset.c @@ -0,0 +1,297 @@ +/* + * strset.c - string set handling + * + * Implementation of local cache of ethtool string sets. + */ + +#include +#include + +#include "../internal.h" +#include "netlink.h" +#include "nlsock.h" +#include "msgbuff.h" + +struct stringset { + const char **strings; + void *raw_data; + unsigned int count; + bool loaded; +}; + +struct perdev_strings { + int ifindex; + char devname[ALTIFNAMSIZ]; + struct stringset strings[ETH_SS_COUNT]; + struct perdev_strings *next; +}; + +/* universal string sets */ +static struct stringset global_strings[ETH_SS_COUNT]; +/* linked list of string sets related to network devices */ +static struct perdev_strings *device_strings; + +static void drop_stringset(struct stringset *set) +{ + if (!set) + return; + + free(set->strings); + free(set->raw_data); + memset(set, 0, sizeof(*set)); +} + +static int import_stringset(struct stringset *dest, const struct nlattr *nest) +{ + const struct nlattr *tb_stringset[ETHTOOL_A_STRINGSET_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb_stringset); + const struct nlattr *string; + unsigned int size; + unsigned int count; + unsigned int idx; + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_stringset_info); + if (ret < 0) + return ret; + if (!tb_stringset[ETHTOOL_A_STRINGSET_ID] || + !tb_stringset[ETHTOOL_A_STRINGSET_COUNT] || + !tb_stringset[ETHTOOL_A_STRINGSET_STRINGS]) + return -EFAULT; + idx = mnl_attr_get_u32(tb_stringset[ETHTOOL_A_STRINGSET_ID]); + if (idx >= ETH_SS_COUNT) + return 0; + if (dest[idx].loaded) + drop_stringset(&dest[idx]); + dest[idx].loaded = true; + count = mnl_attr_get_u32(tb_stringset[ETHTOOL_A_STRINGSET_COUNT]); + if (count == 0) + return 0; + + size = mnl_attr_get_len(tb_stringset[ETHTOOL_A_STRINGSET_STRINGS]); + ret = -ENOMEM; + dest[idx].raw_data = malloc(size); + if (!dest[idx].raw_data) + goto err; + memcpy(dest[idx].raw_data, tb_stringset[ETHTOOL_A_STRINGSET_STRINGS], + size); + dest[idx].strings = calloc(count, sizeof(dest[idx].strings[0])); + if (!dest[idx].strings) + goto err; + dest[idx].count = count; + + nest = dest[idx].raw_data; + mnl_attr_for_each_nested(string, nest) { + const struct nlattr *tb[ETHTOOL_A_STRING_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + unsigned int i; + + if (mnl_attr_get_type(string) != ETHTOOL_A_STRINGS_STRING) + continue; + ret = mnl_attr_parse_nested(string, attr_cb, &tb_info); + if (ret < 0) + goto err; + ret = -EFAULT; + if (!tb[ETHTOOL_A_STRING_INDEX] || !tb[ETHTOOL_A_STRING_VALUE]) + goto err; + + i = mnl_attr_get_u32(tb[ETHTOOL_A_STRING_INDEX]); + if (i >= count) + goto err; + dest[idx].strings[i] = + mnl_attr_get_payload(tb[ETHTOOL_A_STRING_VALUE]); + } + + return 0; +err: + drop_stringset(&dest[idx]); + return ret; +} + +static struct perdev_strings *get_perdev_by_ifindex(int ifindex) +{ + struct perdev_strings *perdev = device_strings; + + while (perdev && perdev->ifindex != ifindex) + perdev = perdev->next; + if (perdev) + return perdev; + + /* not found, allocate and insert into list */ + perdev = calloc(sizeof(*perdev), 1); + if (!perdev) + return NULL; + perdev->ifindex = ifindex; + perdev->next = device_strings; + device_strings = perdev; + + return perdev; +} + +static int strset_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_STRSET_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + char devname[ALTIFNAMSIZ] = ""; + struct stringset *dest; + struct nlattr *attr; + int ifindex = 0; + int ret; + + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return ret; + if (tb[ETHTOOL_A_STRSET_HEADER]) { + ret = get_dev_info(tb[ETHTOOL_A_STRSET_HEADER], &ifindex, + devname); + if (ret < 0) + return MNL_CB_OK; + if (ifindex && nlctx->filter_devname && + strncmp(devname, nlctx->filter_devname, ALTIFNAMSIZ)) + return MNL_CB_OK; + } + + if (ifindex) { + struct perdev_strings *perdev; + + perdev = get_perdev_by_ifindex(ifindex); + if (!perdev) + return MNL_CB_OK; + copy_devname(perdev->devname, devname); + dest = perdev->strings; + } else { + dest = global_strings; + } + + if (!tb[ETHTOOL_A_STRSET_STRINGSETS]) + return MNL_CB_OK; + mnl_attr_for_each_nested(attr, tb[ETHTOOL_A_STRSET_STRINGSETS]) { + if (mnl_attr_get_type(attr) == + ETHTOOL_A_STRINGSETS_STRINGSET) + import_stringset(dest, attr); + } + + return MNL_CB_OK; +} + +static int fill_stringset_id(struct nl_msg_buff *msgbuff, unsigned int type) +{ + struct nlattr *nest_sets; + struct nlattr *nest_set; + + nest_sets = ethnla_nest_start(msgbuff, ETHTOOL_A_STRSET_STRINGSETS); + if (!nest_sets) + return -EMSGSIZE; + nest_set = ethnla_nest_start(msgbuff, ETHTOOL_A_STRINGSETS_STRINGSET); + if (!nest_set) + goto err; + if (ethnla_put_u32(msgbuff, ETHTOOL_A_STRINGSET_ID, type)) + goto err; + ethnla_nest_end(msgbuff, nest_set); + ethnla_nest_end(msgbuff, nest_sets); + return 0; + +err: + ethnla_nest_cancel(msgbuff, nest_sets); + return -EMSGSIZE; +} + +static int stringset_load_request(struct nl_socket *nlsk, const char *devname, + int type, bool is_dump) +{ + struct nl_msg_buff *msgbuff = &nlsk->msgbuff; + int ret; + + ret = msg_init(nlsk->nlctx, msgbuff, ETHTOOL_MSG_STRSET_GET, + NLM_F_REQUEST | NLM_F_ACK | (is_dump ? NLM_F_DUMP : 0)); + if (ret < 0) + return ret; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_STRSET_HEADER, devname, 0)) + return -EMSGSIZE; + if (type >= 0) { + ret = fill_stringset_id(msgbuff, type); + if (ret < 0) + return ret; + } + + ret = nlsock_send_get_request(nlsk, strset_reply_cb); + return ret; +} + +/* interface */ + +const struct stringset *global_stringset(unsigned int type, + struct nl_socket *nlsk) +{ + int ret; + + if (type >= ETH_SS_COUNT) + return NULL; + if (global_strings[type].loaded) + return &global_strings[type]; + ret = stringset_load_request(nlsk, NULL, type, false); + return ret < 0 ? NULL : &global_strings[type]; +} + +const struct stringset *perdev_stringset(const char *devname, unsigned int type, + struct nl_socket *nlsk) +{ + const struct perdev_strings *p; + int ret; + + if (type >= ETH_SS_COUNT) + return NULL; + for (p = device_strings; p; p = p->next) + if (!strcmp(p->devname, devname)) + return &p->strings[type]; + + ret = stringset_load_request(nlsk, devname, type, false); + if (ret < 0) + return NULL; + for (p = device_strings; p; p = p->next) + if (!strcmp(p->devname, devname)) + return &p->strings[type]; + + return NULL; +} + +unsigned int get_count(const struct stringset *set) +{ + return set->count; +} + +const char *get_string(const struct stringset *set, unsigned int idx) +{ + if (!set || idx >= set->count) + return NULL; + return set->strings[idx]; +} + +int preload_global_strings(struct nl_socket *nlsk) +{ + return stringset_load_request(nlsk, NULL, -1, false); +} + +int preload_perdev_strings(struct nl_socket *nlsk, const char *dev) +{ + return stringset_load_request(nlsk, dev, -1, !dev); +} + +void cleanup_all_strings(void) +{ + struct perdev_strings *perdev; + unsigned int i; + + for (i = 0; i < ETH_SS_COUNT; i++) + drop_stringset(&global_strings[i]); + + perdev = device_strings; + while (perdev) { + device_strings = perdev->next; + for (i = 0; i < ETH_SS_COUNT; i++) + drop_stringset(&perdev->strings[i]); + free(perdev); + perdev = device_strings; + } +} diff --git a/netlink/strset.h b/netlink/strset.h new file mode 100644 index 0000000..72a4a39 --- /dev/null +++ b/netlink/strset.h @@ -0,0 +1,25 @@ +/* + * strset.h - string set handling + * + * Interface for local cache of ethtool string sets. + */ + +#ifndef ETHTOOL_NETLINK_STRSET_H__ +#define ETHTOOL_NETLINK_STRSET_H__ + +struct nl_socket; +struct stringset; + +const struct stringset *global_stringset(unsigned int type, + struct nl_socket *nlsk); +const struct stringset *perdev_stringset(const char *dev, unsigned int type, + struct nl_socket *nlsk); + +unsigned int get_count(const struct stringset *set); +const char *get_string(const struct stringset *set, unsigned int idx); + +int preload_global_strings(struct nl_socket *nlsk); +int preload_perdev_strings(struct nl_socket *nlsk, const char *dev); +void cleanup_all_strings(void); + +#endif /* ETHTOOL_NETLINK_STRSET_H__ */ diff --git a/netlink/tsinfo.c b/netlink/tsinfo.c new file mode 100644 index 0000000..c6571ff --- /dev/null +++ b/netlink/tsinfo.c @@ -0,0 +1,124 @@ +/* + * tsinfo.c - netlink implementation of timestamping commands + * + * Implementation of "ethtool -T " + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "bitset.h" + +/* TSINFO_GET */ + +static void tsinfo_dump_cb(unsigned int idx, const char *name, bool val, + void *data __maybe_unused) +{ + if (!val) + return; + + if (name) + printf("\t%s\n", name); + else + printf("\tbit%u\n", idx); +} + +static int tsinfo_dump_list(struct nl_context *nlctx, const struct nlattr *attr, + const char *label, const char *if_empty, + unsigned int stringset_id) +{ + const struct stringset *strings = NULL; + int ret; + + printf("%s:", label); + ret = 0; + if (!attr || bitset_is_empty(attr, false, &ret)) { + printf("%s\n", if_empty); + return ret; + } + putchar('\n'); + if (ret < 0) + return ret; + + if (bitset_is_compact(attr)) { + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + return ret; + strings = global_stringset(stringset_id, nlctx->ethnl2_socket); + } + return walk_bitset(attr, strings, tsinfo_dump_cb, NULL); +} + +int tsinfo_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_TSINFO_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_TSINFO_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + putchar('\n'); + printf("Time stamping parameters for %s:\n", nlctx->devname); + + ret = tsinfo_dump_list(nlctx, tb[ETHTOOL_A_TSINFO_TIMESTAMPING], + "Capabilities", "", ETH_SS_SOF_TIMESTAMPING); + if (ret < 0) + return err_ret; + + printf("PTP Hardware Clock: "); + if (tb[ETHTOOL_A_TSINFO_PHC_INDEX]) + printf("%d\n", + mnl_attr_get_u32(tb[ETHTOOL_A_TSINFO_PHC_INDEX])); + else + printf("none\n"); + + ret = tsinfo_dump_list(nlctx, tb[ETHTOOL_A_TSINFO_TX_TYPES], + "Hardware Transmit Timestamp Modes", " none", + ETH_SS_TS_TX_TYPES); + if (ret < 0) + return err_ret; + + ret = tsinfo_dump_list(nlctx, tb[ETHTOOL_A_TSINFO_RX_FILTERS], + "Hardware Receive Filter Modes", " none", + ETH_SS_TS_RX_FILTERS); + if (ret < 0) + return err_ret; + + return MNL_CB_OK; +} + +int nl_tsinfo(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_TSINFO_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_TSINFO_GET, + ETHTOOL_A_TSINFO_HEADER, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, tsinfo_reply_cb); +} diff --git a/netlink/tunnels.c b/netlink/tunnels.c new file mode 100644 index 0000000..b464046 --- /dev/null +++ b/netlink/tunnels.c @@ -0,0 +1,236 @@ +/* + * tunnel.c - device tunnel information + * + * Implementation of "ethtool --show-tunnels " + */ + +#include +#include +#include +#include + +#include "../common.h" +#include "../internal.h" + +#include "bitset.h" +#include "netlink.h" +#include "strset.h" + +/* TUNNEL_INFO_GET */ + +static int +tunnel_info_strings_load(struct nl_context *nlctx, + const struct stringset **strings) +{ + int ret; + + if (*strings) + return 0; + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + return ret; + *strings = global_stringset(ETH_SS_UDP_TUNNEL_TYPES, + nlctx->ethnl2_socket); + return 0; +} + +static int +tunnel_info_dump_udp_entry(struct nl_context *nlctx, const struct nlattr *entry, + const struct stringset **strings) +{ + const struct nlattr *entry_tb[ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(entry_tb); + const struct nlattr *attr; + unsigned int port, type; + int ret; + + if (tunnel_info_strings_load(nlctx, strings)) + return 1; + + ret = mnl_attr_parse_nested(entry, attr_cb, &entry_tb_info); + if (ret < 0) { + fprintf(stderr, "malformed netlink message (udp entry)\n"); + return 1; + } + + attr = entry_tb[ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT]; + if (!attr || mnl_attr_validate(attr, MNL_TYPE_U16) < 0) { + fprintf(stderr, "malformed netlink message (port)\n"); + return 1; + } + port = ntohs(mnl_attr_get_u16(attr)); + + attr = entry_tb[ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE]; + if (!attr || mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { + fprintf(stderr, "malformed netlink message (tunnel type)\n"); + return 1; + } + type = mnl_attr_get_u32(attr); + + printf(" port %d, %s\n", port, get_string(*strings, type)); + + return 0; +} + +static void tunnel_info_dump_cb(unsigned int idx, const char *name, bool val, + void *data) +{ + bool *first = data; + + if (!val) + return; + + if (!*first) + putchar(','); + *first = false; + + if (name) + printf(" %s", name); + else + printf(" bit%u", idx); +} + +static int +tunnel_info_dump_list(struct nl_context *nlctx, const struct nlattr *attr, + const struct stringset **strings) +{ + bool first = true; + int ret; + + if (bitset_is_empty(attr, false, &ret) || ret) { + if (ret) + return 1; + + printf(" Types: none (static entries)\n"); + return 0; + } + + if (bitset_is_compact(attr) && + tunnel_info_strings_load(nlctx, strings)) + return 1; + + printf(" Types:"); + ret = walk_bitset(attr, *strings, tunnel_info_dump_cb, &first); + putchar('\n'); + return ret; +} + +static int +tunnel_info_dump_udp_table(const struct nlattr *table, struct nl_context *nlctx, + const struct stringset **strings) +{ + const struct nlattr *table_tb[ETHTOOL_A_TUNNEL_UDP_TABLE_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(table_tb); + const struct nlattr *attr; + int i, ret; + + ret = mnl_attr_parse_nested(table, attr_cb, &table_tb_info); + if (ret < 0) { + fprintf(stderr, "malformed netlink message (udp table)\n"); + return 1; + } + + attr = table_tb[ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE]; + if (!attr || mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { + fprintf(stderr, "malformed netlink message (table size)\n"); + return 1; + } + printf(" Size: %d\n", mnl_attr_get_u32(attr)); + + attr = table_tb[ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES]; + if (!attr || tunnel_info_dump_list(nlctx, attr, strings)) { + fprintf(stderr, "malformed netlink message (types)\n"); + return 1; + } + + if (!table_tb[ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY]) { + printf(" No entries\n"); + return 0; + } + + i = 0; + mnl_attr_for_each_nested(attr, table) { + if (mnl_attr_get_type(attr) == ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY) + i++; + } + + printf(" Entries (%d):\n", i++); + mnl_attr_for_each_nested(attr, table) { + if (mnl_attr_get_type(attr) == ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY) + if (tunnel_info_dump_udp_entry(nlctx, attr, strings)) + return 1; + } + + return 0; +} + +static int +tunnel_info_dump_udp(const struct nlattr *udp_ports, struct nl_context *nlctx) +{ + const struct stringset *strings = NULL; + const struct nlattr *table; + int i, err; + + i = 0; + mnl_attr_for_each_nested(table, udp_ports) { + if (mnl_attr_get_type(table) != ETHTOOL_A_TUNNEL_UDP_TABLE) + continue; + + printf(" UDP port table %d: \n", i++); + err = tunnel_info_dump_udp_table(table, nlctx, &strings); + if (err) + return err; + } + + return 0; +} + +static int tunnel_info_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_TUNNEL_INFO_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + const struct nlattr *udp_ports; + struct nl_context *nlctx = data; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_TUNNEL_INFO_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + printf("Tunnel information for %s:\n", nlctx->devname); + + udp_ports = tb[ETHTOOL_A_TUNNEL_INFO_UDP_PORTS]; + if (udp_ports) + if (tunnel_info_dump_udp(udp_ports, nlctx)) + return err_ret; + + return MNL_CB_OK; +} + +int nl_gtunnels(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_TUNNEL_INFO_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_TUNNEL_INFO_GET, + ETHTOOL_A_TUNNEL_INFO_HEADER, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, tunnel_info_reply_cb); +} diff --git a/pcnet32.c b/pcnet32.c new file mode 100644 index 0000000..b87cee7 --- /dev/null +++ b/pcnet32.c @@ -0,0 +1,249 @@ +/* Copyright 2004 IBM Corporation (jklewis@us.ibm.com) */ + +#include +#include +#include "internal.h" + +#define BIT0 0x0001 +#define BIT1 0x0002 +#define BIT2 0x0004 +#define BIT3 0x0008 +#define BIT4 0x0010 +#define BIT5 0x0020 +#define BIT6 0x0040 +#define BIT7 0x0080 +#define BIT8 0x0100 +#define BIT9 0x0200 +#define BIT10 0x0400 +#define BIT11 0x0800 +#define BIT12 0x1000 +#define BIT13 0x2000 +#define BIT14 0x4000 +#define BIT15 0x8000 + +int pcnet32_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs) +{ + int i, csr; + u16 *data = (u16 *) regs->data; + int len = regs->len / 2; + u16 temp,*ptr; + + printf("Driver: %s\n",info->driver); + printf("Version: %s\n",info->version); + + printf("APROM: "); + for (i=0; i<8; i++) + printf(" %04x ", data[i]); + printf("\n"); + + csr = i; + for (; i<100; i++) + { + if (((i-csr) & 7) == 0) printf("CSR%02d: ", i-csr); + printf(" %04x ", data[i]); + if (((i-csr) & 7) == 7) printf("\n"); + } + if (((i-csr) & 7) != 7) printf("\n"); + + csr = i; + for (; i<136; i++) + { + if (((i-csr) & 7) == 0) printf("BCR%02d: ", i-csr); + printf(" %04x ", data[i]); + if (((i-csr) & 7) == 7) printf("\n"); + } + if (((i-csr) & 7) != 7) printf("\n"); + + csr = i; + for (; i> 12) & 0xffff; + switch (temp) { + case 0x2420: + printf(" PCnet/PCI 79C970\n"); + break; + case 0x2621: + printf(" PCnet/PCI II 79C970A\n"); + break; + case 0x2623: + printf(" PCnet/FAST 79C971\n"); + break; + case 0x2624: + printf(" PCnet/FAST+ 79C972\n"); + break; + case 0x2625: + printf(" PCnet/FAST III 79C973\n"); + break; + case 0x2626: + printf(" PCnet/Home 79C978\n"); + break; + case 0x2627: + printf(" PCnet/FAST III 79C975\n"); + break; + case 0x2628: + printf(" PCnet/PRO 79C976\n"); + break; + } + + printf("CSR89: Chip ID Upper 0x%04x\n ",ptr[89]); + temp=ptr[89]; + printf("VER: %04x PARTIDU: %04x\n",temp >> 12,temp & 0x00000fff); + + printf("CSR112: Missed Frame Count 0x%04x\n",ptr[90]); /* 90 is 112 */ + printf("CSR114: RX Collision Count 0x%04x\n",ptr[91]); + + printf("\n"); + + ptr=&data[100]; /* point to BCR 0 */ + + printf("BCR2: Misc. Configuration 0x%04x\n ",ptr[2]); + temp=ptr[2]; + + if(temp & BIT14) printf("TMAULOOP "); + if(temp & BIT12) printf("LEDPE "); + + if(temp & BIT8) printf("APROMWE "); + if(temp & BIT7) printf("INTLEVEL "); + + if(temp & BIT3) printf("EADISEL "); + if(temp & BIT2) printf("AWAKE "); + if(temp & BIT1) printf("ASEL "); + if(temp & BIT0) printf("XMAUSEL "); + + printf("\n"); + + printf("BCR9: Full-Duplex Control 0x%04x\n",ptr[9]); + printf("BCR18: Burst and Bus Control 0x%04x\n",ptr[18]); + + printf("BCR19: EEPROM Control and Status 0x%04x\n ",ptr[19]); + temp=ptr[19]; + if(temp & BIT15) printf("PVALID "); + if(temp & BIT13) printf("EEDET "); + printf("\n"); + + printf("BCR23: PCI Subsystem Vendor ID 0x%04x\n",ptr[23]); + printf("BCR24: PCI Subsystem ID 0x%04x\n",ptr[24]); + printf("BCR31: Software Timer 0x%04x\n",ptr[31]); + printf("BCR32: MII Control and Status 0x%04x\n",ptr[32]); + printf("BCR35: PCI Vendor ID 0x%04x\n",ptr[35]); + + return(0); +} + diff --git a/qsfp.c b/qsfp.c new file mode 100644 index 0000000..1fe5de1 --- /dev/null +++ b/qsfp.c @@ -0,0 +1,1024 @@ +/* + * qsfp.c: Implements SFF-8636 based QSFP+/QSFP28 Diagnostics Memory map. + * + * Copyright 2010 Solarflare Communications Inc. + * Aurelien Guillaume (C) 2012 + * Copyright (C) 2014 Cumulus networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Freeoftware Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Vidya Ravipati + * This implementation is loosely based on current SFP parser + * and SFF-8636 spec Rev 2.7 (ftp://ftp.seagate.com/pub/sff/SFF-8636.PDF) + * by SFF Committee. + */ + +/* + * Description: + * a) The register/memory layout is up to 5 128 byte pages defined by + * a "pages valid" register and switched via a "page select" + * register. Memory of 256 bytes can be memory mapped at a time + * according to SFF 8636. + * b) SFF 8636 based 640 bytes memory layout is presented for parser + * + * SFF 8636 based QSFP Memory Map + * + * 2-Wire Serial Address: 1010000x + * + * Lower Page 00h (128 bytes) + * ====================== + * | | + * |Page Select Byte(127)| + * ====================== + * | + * V + * ---------------------------------------- + * | | | | + * V V V V + * ---------- ---------- --------- ------------ + * | Upper | | Upper | | Upper | | Upper | + * | Page 00h | | Page 01h | | Page 02h | | Page 03h | + * | | |(Optional)| |(Optional)| | (Optional) | + * | | | | | | | | + * | | | | | | | | + * | ID | | AST | | User | | For | + * | Fields | | Table | | EEPROM | | Cable | + * | | | | | Data | | Assemblies | + * | | | | | | | | + * | | | | | | | | + * ----------- ----------- ---------- -------------- + * + * + **/ +#include +#include +#include +#include "internal.h" +#include "sff-common.h" +#include "qsfp.h" +#include "cmis.h" +#include "netlink/extapi.h" + +struct sff8636_memory_map { + const __u8 *lower_memory; + const __u8 *upper_memory[4]; +#define page_00h upper_memory[0x0] +#define page_03h upper_memory[0x3] +}; + +#define SFF8636_PAGE_SIZE 0x80 +#define SFF8636_I2C_ADDRESS 0x50 +#define SFF8636_MAX_CHANNEL_NUM 4 + +#define MAX_DESC_SIZE 42 + +static struct sff8636_aw_flags { + const char *str; /* Human-readable string, null at the end */ + int offset; + __u8 value; /* Alarm is on if (offset & value) != 0. */ +} sff8636_aw_flags[] = { + { "Laser bias current high alarm (Chan 1)", + SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_1_HALARM) }, + { "Laser bias current low alarm (Chan 1)", + SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_1_LALARM) }, + { "Laser bias current high warning (Chan 1)", + SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_1_HWARN) }, + { "Laser bias current low warning (Chan 1)", + SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_1_LWARN) }, + + { "Laser bias current high alarm (Chan 2)", + SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_2_HALARM) }, + { "Laser bias current low alarm (Chan 2)", + SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_2_LALARM) }, + { "Laser bias current high warning (Chan 2)", + SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_2_HWARN) }, + { "Laser bias current low warning (Chan 2)", + SFF8636_TX_BIAS_12_AW_OFFSET, (SFF8636_TX_BIAS_2_LWARN) }, + + { "Laser bias current high alarm (Chan 3)", + SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_3_HALARM) }, + { "Laser bias current low alarm (Chan 3)", + SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_3_LALARM) }, + { "Laser bias current high warning (Chan 3)", + SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_3_HWARN) }, + { "Laser bias current low warning (Chan 3)", + SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_3_LWARN) }, + + { "Laser bias current high alarm (Chan 4)", + SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_4_HALARM) }, + { "Laser bias current low alarm (Chan 4)", + SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_4_LALARM) }, + { "Laser bias current high warning (Chan 4)", + SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_4_HWARN) }, + { "Laser bias current low warning (Chan 4)", + SFF8636_TX_BIAS_34_AW_OFFSET, (SFF8636_TX_BIAS_4_LWARN) }, + + { "Module temperature high alarm", + SFF8636_TEMP_AW_OFFSET, (SFF8636_TEMP_HALARM_STATUS) }, + { "Module temperature low alarm", + SFF8636_TEMP_AW_OFFSET, (SFF8636_TEMP_LALARM_STATUS) }, + { "Module temperature high warning", + SFF8636_TEMP_AW_OFFSET, (SFF8636_TEMP_HWARN_STATUS) }, + { "Module temperature low warning", + SFF8636_TEMP_AW_OFFSET, (SFF8636_TEMP_LWARN_STATUS) }, + + { "Module voltage high alarm", + SFF8636_VCC_AW_OFFSET, (SFF8636_VCC_HALARM_STATUS) }, + { "Module voltage low alarm", + SFF8636_VCC_AW_OFFSET, (SFF8636_VCC_LALARM_STATUS) }, + { "Module voltage high warning", + SFF8636_VCC_AW_OFFSET, (SFF8636_VCC_HWARN_STATUS) }, + { "Module voltage low warning", + SFF8636_VCC_AW_OFFSET, (SFF8636_VCC_LWARN_STATUS) }, + + { "Laser tx power high alarm (Channel 1)", + SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_1_HALARM) }, + { "Laser tx power low alarm (Channel 1)", + SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_1_LALARM) }, + { "Laser tx power high warning (Channel 1)", + SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_1_HWARN) }, + { "Laser tx power low warning (Channel 1)", + SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_1_LWARN) }, + + { "Laser tx power high alarm (Channel 2)", + SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_2_HALARM) }, + { "Laser tx power low alarm (Channel 2)", + SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_2_LALARM) }, + { "Laser tx power high warning (Channel 2)", + SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_2_HWARN) }, + { "Laser tx power low warning (Channel 2)", + SFF8636_TX_PWR_12_AW_OFFSET, (SFF8636_TX_PWR_2_LWARN) }, + + { "Laser tx power high alarm (Channel 3)", + SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_3_HALARM) }, + { "Laser tx power low alarm (Channel 3)", + SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_3_LALARM) }, + { "Laser tx power high warning (Channel 3)", + SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_3_HWARN) }, + { "Laser tx power low warning (Channel 3)", + SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_3_LWARN) }, + + { "Laser tx power high alarm (Channel 4)", + SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_4_HALARM) }, + { "Laser tx power low alarm (Channel 4)", + SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_4_LALARM) }, + { "Laser tx power high warning (Channel 4)", + SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_4_HWARN) }, + { "Laser tx power low warning (Channel 4)", + SFF8636_TX_PWR_34_AW_OFFSET, (SFF8636_TX_PWR_4_LWARN) }, + + { "Laser rx power high alarm (Channel 1)", + SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_1_HALARM) }, + { "Laser rx power low alarm (Channel 1)", + SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_1_LALARM) }, + { "Laser rx power high warning (Channel 1)", + SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_1_HWARN) }, + { "Laser rx power low warning (Channel 1)", + SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_1_LWARN) }, + + { "Laser rx power high alarm (Channel 2)", + SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_2_HALARM) }, + { "Laser rx power low alarm (Channel 2)", + SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_2_LALARM) }, + { "Laser rx power high warning (Channel 2)", + SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_2_HWARN) }, + { "Laser rx power low warning (Channel 2)", + SFF8636_RX_PWR_12_AW_OFFSET, (SFF8636_RX_PWR_2_LWARN) }, + + { "Laser rx power high alarm (Channel 3)", + SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_3_HALARM) }, + { "Laser rx power low alarm (Channel 3)", + SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_3_LALARM) }, + { "Laser rx power high warning (Channel 3)", + SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_3_HWARN) }, + { "Laser rx power low warning (Channel 3)", + SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_3_LWARN) }, + + { "Laser rx power high alarm (Channel 4)", + SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_4_HALARM) }, + { "Laser rx power low alarm (Channel 4)", + SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_4_LALARM) }, + { "Laser rx power high warning (Channel 4)", + SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_4_HWARN) }, + { "Laser rx power low warning (Channel 4)", + SFF8636_RX_PWR_34_AW_OFFSET, (SFF8636_RX_PWR_4_LWARN) }, + + { NULL, 0, 0 }, +}; + +static void sff8636_show_identifier(const struct sff8636_memory_map *map) +{ + sff8024_show_identifier(map->lower_memory, SFF8636_ID_OFFSET); +} + +static void sff8636_show_ext_identifier(const struct sff8636_memory_map *map) +{ + printf("\t%-41s : 0x%02x\n", "Extended identifier", + map->page_00h[SFF8636_EXT_ID_OFFSET]); + + static const char *pfx = + "\tExtended identifier description :"; + + switch (map->page_00h[SFF8636_EXT_ID_OFFSET] & + SFF8636_EXT_ID_PWR_CLASS_MASK) { + case SFF8636_EXT_ID_PWR_CLASS_1: + printf("%s 1.5W max. Power consumption\n", pfx); + break; + case SFF8636_EXT_ID_PWR_CLASS_2: + printf("%s 2.0W max. Power consumption\n", pfx); + break; + case SFF8636_EXT_ID_PWR_CLASS_3: + printf("%s 2.5W max. Power consumption\n", pfx); + break; + case SFF8636_EXT_ID_PWR_CLASS_4: + printf("%s 3.5W max. Power consumption\n", pfx); + break; + } + + if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_TX_MASK) + printf("%s CDR present in TX,", pfx); + else + printf("%s No CDR in TX,", pfx); + + if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_RX_MASK) + printf(" CDR present in RX\n"); + else + printf(" No CDR in RX\n"); + + switch (map->page_00h[SFF8636_EXT_ID_OFFSET] & + SFF8636_EXT_ID_EPWR_CLASS_MASK) { + case SFF8636_EXT_ID_PWR_CLASS_LEGACY: + printf("%s", pfx); + break; + case SFF8636_EXT_ID_PWR_CLASS_5: + printf("%s 4.0W max. Power consumption,", pfx); + break; + case SFF8636_EXT_ID_PWR_CLASS_6: + printf("%s 4.5W max. Power consumption, ", pfx); + break; + case SFF8636_EXT_ID_PWR_CLASS_7: + printf("%s 5.0W max. Power consumption, ", pfx); + break; + } + if (map->lower_memory[SFF8636_PWR_MODE_OFFSET] & + SFF8636_HIGH_PWR_ENABLE) + printf(" High Power Class (> 3.5 W) enabled\n"); + else + printf(" High Power Class (> 3.5 W) not enabled\n"); + printf("\t%-41s : ", "Power set"); + printf("%s\n", ONOFF(map->lower_memory[SFF8636_PWR_MODE_OFFSET] & + SFF8636_LOW_PWR_SET)); + printf("\t%-41s : ", "Power override"); + printf("%s\n", ONOFF(map->lower_memory[SFF8636_PWR_MODE_OFFSET] & + SFF8636_PWR_OVERRIDE)); +} + +static void sff8636_show_connector(const struct sff8636_memory_map *map) +{ + sff8024_show_connector(map->page_00h, SFF8636_CTOR_OFFSET); +} + +static void sff8636_show_transceiver(const struct sff8636_memory_map *map) +{ + static const char *pfx = + "\tTransceiver type :"; + + printf("\t%-41s : 0x%02x 0x%02x 0x%02x " \ + "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + "Transceiver codes", + map->page_00h[SFF8636_ETHERNET_COMP_OFFSET], + map->page_00h[SFF8636_SONET_COMP_OFFSET], + map->page_00h[SFF8636_SAS_COMP_OFFSET], + map->page_00h[SFF8636_GIGE_COMP_OFFSET], + map->page_00h[SFF8636_FC_LEN_OFFSET], + map->page_00h[SFF8636_FC_TECH_OFFSET], + map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET], + map->page_00h[SFF8636_FC_SPEED_OFFSET]); + + /* 10G/40G Ethernet Compliance Codes */ + if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] & + SFF8636_ETHERNET_10G_LRM) + printf("%s 10G Ethernet: 10G Base-LRM\n", pfx); + if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] & + SFF8636_ETHERNET_10G_LR) + printf("%s 10G Ethernet: 10G Base-LR\n", pfx); + if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] & + SFF8636_ETHERNET_10G_SR) + printf("%s 10G Ethernet: 10G Base-SR\n", pfx); + if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] & + SFF8636_ETHERNET_40G_CR4) + printf("%s 40G Ethernet: 40G Base-CR4\n", pfx); + if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] & + SFF8636_ETHERNET_40G_SR4) + printf("%s 40G Ethernet: 40G Base-SR4\n", pfx); + if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] & + SFF8636_ETHERNET_40G_LR4) + printf("%s 40G Ethernet: 40G Base-LR4\n", pfx); + if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] & + SFF8636_ETHERNET_40G_ACTIVE) + printf("%s 40G Ethernet: 40G Active Cable (XLPPI)\n", pfx); + /* Extended Specification Compliance Codes from SFF-8024 */ + if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] & + SFF8636_ETHERNET_RSRVD) { + switch (map->page_00h[SFF8636_OPTION_1_OFFSET]) { + case SFF8636_ETHERNET_UNSPECIFIED: + printf("%s (reserved or unknown)\n", pfx); + break; + case SFF8636_ETHERNET_100G_AOC: + printf("%s 100G Ethernet: 100G AOC or 25GAUI C2M AOC with worst BER of 5x10^(-5)\n", + pfx); + break; + case SFF8636_ETHERNET_100G_SR4: + printf("%s 100G Ethernet: 100G Base-SR4 or 25GBase-SR\n", + pfx); + break; + case SFF8636_ETHERNET_100G_LR4: + printf("%s 100G Ethernet: 100G Base-LR4\n", pfx); + break; + case SFF8636_ETHERNET_100G_ER4: + printf("%s 100G Ethernet: 100G Base-ER4\n", pfx); + break; + case SFF8636_ETHERNET_100G_SR10: + printf("%s 100G Ethernet: 100G Base-SR10\n", pfx); + break; + case SFF8636_ETHERNET_100G_CWDM4_FEC: + printf("%s 100G Ethernet: 100G CWDM4 MSA with FEC\n", pfx); + break; + case SFF8636_ETHERNET_100G_PSM4: + printf("%s 100G Ethernet: 100G PSM4 Parallel SMF\n", pfx); + break; + case SFF8636_ETHERNET_100G_ACC: + printf("%s 100G Ethernet: 100G ACC or 25GAUI C2M ACC with worst BER of 5x10^(-5)\n", + pfx); + break; + case SFF8636_ETHERNET_100G_CWDM4_NO_FEC: + printf("%s 100G Ethernet: 100G CWDM4 MSA without FEC\n", pfx); + break; + case SFF8636_ETHERNET_100G_RSVD1: + printf("%s (reserved or unknown)\n", pfx); + break; + case SFF8636_ETHERNET_100G_CR4: + printf("%s 100G Ethernet: 100G Base-CR4 or 25G Base-CR CA-L\n", + pfx); + break; + case SFF8636_ETHERNET_25G_CR_CA_S: + printf("%s 25G Ethernet: 25G Base-CR CA-S\n", pfx); + break; + case SFF8636_ETHERNET_25G_CR_CA_N: + printf("%s 25G Ethernet: 25G Base-CR CA-N\n", pfx); + break; + case SFF8636_ETHERNET_40G_ER4: + printf("%s 40G Ethernet: 40G Base-ER4\n", pfx); + break; + case SFF8636_ETHERNET_4X10_SR: + printf("%s 4x10G Ethernet: 10G Base-SR\n", pfx); + break; + case SFF8636_ETHERNET_40G_PSM4: + printf("%s 40G Ethernet: 40G PSM4 Parallel SMF\n", pfx); + break; + case SFF8636_ETHERNET_G959_P1I1_2D1: + printf("%s Ethernet: G959.1 profile P1I1-2D1 (10709 MBd, 2km, 1310nm SM)\n", + pfx); + break; + case SFF8636_ETHERNET_G959_P1S1_2D2: + printf("%s Ethernet: G959.1 profile P1S1-2D2 (10709 MBd, 40km, 1550nm SM)\n", + pfx); + break; + case SFF8636_ETHERNET_G959_P1L1_2D2: + printf("%s Ethernet: G959.1 profile P1L1-2D2 (10709 MBd, 80km, 1550nm SM)\n", + pfx); + break; + case SFF8636_ETHERNET_10GT_SFI: + printf("%s 10G Ethernet: 10G Base-T with SFI electrical interface\n", + pfx); + break; + case SFF8636_ETHERNET_100G_CLR4: + printf("%s 100G Ethernet: 100G CLR4\n", pfx); + break; + case SFF8636_ETHERNET_100G_AOC2: + printf("%s 100G Ethernet: 100G AOC or 25GAUI C2M AOC with worst BER of 10^(-12)\n", + pfx); + break; + case SFF8636_ETHERNET_100G_ACC2: + printf("%s 100G Ethernet: 100G ACC or 25GAUI C2M ACC with worst BER of 10^(-12)\n", + pfx); + break; + case SFF8636_ETHERNET_100GE_DWDM2: + printf("%s 100GE-DWDM2 (DWDM transceiver using 2 wavelengths on a 1550 nm DWDM grid with a reach up to 80 km)\n", + pfx); + break; + case SFF8636_ETHERNET_100G_1550NM_WDM: + printf("%s 100G 1550nm WDM (4 wavelengths)\n", pfx); + break; + case SFF8636_ETHERNET_10G_BASET_SR: + printf("%s 10GBASE-T Short Reach (30 meters)\n", pfx); + break; + case SFF8636_ETHERNET_5G_BASET: + printf("%s 5GBASE-T\n", pfx); + break; + case SFF8636_ETHERNET_2HALFG_BASET: + printf("%s 2.5GBASE-T\n", pfx); + break; + case SFF8636_ETHERNET_40G_SWDM4: + printf("%s 40G SWDM4\n", pfx); + break; + case SFF8636_ETHERNET_100G_SWDM4: + printf("%s 100G SWDM4\n", pfx); + break; + case SFF8636_ETHERNET_100G_PAM4_BIDI: + printf("%s 100G PAM4 BiDi\n", pfx); + break; + case SFF8636_ETHERNET_4WDM10_MSA: + printf("%s 4WDM-10 MSA (10km version of 100G CWDM4 with same RS(528,514) FEC in host system)\n", + pfx); + break; + case SFF8636_ETHERNET_4WDM20_MSA: + printf("%s 4WDM-20 MSA (20km version of 100GBASE-LR4 with RS(528,514) FEC in host system)\n", + pfx); + break; + case SFF8636_ETHERNET_4WDM40_MSA: + printf("%s 4WDM-40 MSA (40km reach with APD receiver and RS(528,514) FEC in host system)\n", + pfx); + break; + case SFF8636_ETHERNET_100G_DR: + printf("%s 100GBASE-DR (clause 140), CAUI-4 (no FEC)\n", pfx); + break; + case SFF8636_ETHERNET_100G_FR_NOFEC: + printf("%s 100G-FR or 100GBASE-FR1 (clause 140), CAUI-4 (no FEC)\n", pfx); + break; + case SFF8636_ETHERNET_100G_LR_NOFEC: + printf("%s 100G-LR or 100GBASE-LR1 (clause 140), CAUI-4 (no FEC)\n", pfx); + break; + case SFF8636_ETHERNET_200G_ACC1: + printf("%s Active Copper Cable with 50GAUI, 100GAUI-2 or 200GAUI-4 C2M. Providing a worst BER of 10-6 or below\n", + pfx); + break; + case SFF8636_ETHERNET_200G_AOC1: + printf("%s Active Optical Cable with 50GAUI, 100GAUI-2 or 200GAUI-4 C2M. Providing a worst BER of 10-6 or below\n", + pfx); + break; + case SFF8636_ETHERNET_200G_ACC2: + printf("%s Active Copper Cable with 50GAUI, 100GAUI-2 or 200GAUI-4 C2M. Providing a worst BER of 2.6x10-4 for ACC, 10-5 for AUI, or below\n", + pfx); + break; + case SFF8636_ETHERNET_200G_A0C2: + printf("%s Active Optical Cable with 50GAUI, 100GAUI-2 or 200GAUI-4 C2M. Providing a worst BER of 2.6x10-4 for ACC, 10-5 for AUI, or below\n", + pfx); + break; + case SFF8636_ETHERNET_200G_CR4: + printf("%s 50GBASE-CR, 100GBASE-CR2, or 200GBASE-CR4\n", pfx); + break; + case SFF8636_ETHERNET_200G_SR4: + printf("%s 50GBASE-SR, 100GBASE-SR2, or 200GBASE-SR4\n", pfx); + break; + case SFF8636_ETHERNET_200G_DR4: + printf("%s 50GBASE-FR or 200GBASE-DR4\n", pfx); + break; + case SFF8636_ETHERNET_200G_FR4: + printf("%s 200GBASE-FR4\n", pfx); + break; + case SFF8636_ETHERNET_200G_PSM4: + printf("%s 200G 1550 nm PSM4\n", pfx); + break; + case SFF8636_ETHERNET_50G_LR: + printf("%s 50GBASE-LR\n", pfx); + break; + case SFF8636_ETHERNET_200G_LR4: + printf("%s 200GBASE-LR4\n", pfx); + break; + case SFF8636_ETHERNET_64G_EA: + printf("%s 64GFC EA\n", pfx); + break; + case SFF8636_ETHERNET_64G_SW: + printf("%s 64GFC SW\n", pfx); + break; + case SFF8636_ETHERNET_64G_LW: + printf("%s 64GFC LW\n", pfx); + break; + case SFF8636_ETHERNET_128FC_EA: + printf("%s 128GFC EA\n", pfx); + break; + case SFF8636_ETHERNET_128FC_SW: + printf("%s 128GFC SW\n", pfx); + break; + case SFF8636_ETHERNET_128FC_LW: + printf("%s 128GFC LW\n", pfx); + break; + default: + printf("%s (reserved or unknown)\n", pfx); + break; + } + } + + /* SONET Compliance Codes */ + if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & + (SFF8636_SONET_40G_OTN)) + printf("%s 40G OTN (OTU3B/OTU3C)\n", pfx); + if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_LR)) + printf("%s SONET: OC-48, long reach\n", pfx); + if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_IR)) + printf("%s SONET: OC-48, intermediate reach\n", pfx); + if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_SR)) + printf("%s SONET: OC-48, short reach\n", pfx); + + /* SAS/SATA Compliance Codes */ + if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G)) + printf("%s SAS 6.0G\n", pfx); + if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_3G)) + printf("%s SAS 3.0G\n", pfx); + + /* Ethernet Compliance Codes */ + if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_T) + printf("%s Ethernet: 1000BASE-T\n", pfx); + if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_CX) + printf("%s Ethernet: 1000BASE-CX\n", pfx); + if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_LX) + printf("%s Ethernet: 1000BASE-LX\n", pfx); + if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_SX) + printf("%s Ethernet: 1000BASE-SX\n", pfx); + + /* Fibre Channel link length */ + if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_VERY_LONG) + printf("%s FC: very long distance (V)\n", pfx); + if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_SHORT) + printf("%s FC: short distance (S)\n", pfx); + if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_INT) + printf("%s FC: intermediate distance (I)\n", pfx); + if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_LONG) + printf("%s FC: long distance (L)\n", pfx); + if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_MED) + printf("%s FC: medium distance (M)\n", pfx); + + /* Fibre Channel transmitter technology */ + if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_LONG_LC) + printf("%s FC: Longwave laser (LC)\n", pfx); + if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_ELEC_INTER) + printf("%s FC: Electrical inter-enclosure (EL)\n", pfx); + if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_ELEC_INTRA) + printf("%s FC: Electrical intra-enclosure (EL)\n", pfx); + if (map->page_00h[SFF8636_FC_TECH_OFFSET] & + SFF8636_FC_TECH_SHORT_WO_OFC) + printf("%s FC: Shortwave laser w/o OFC (SN)\n", pfx); + if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_W_OFC) + printf("%s FC: Shortwave laser with OFC (SL)\n", pfx); + if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_LONG_LL) + printf("%s FC: Longwave laser (LL)\n", pfx); + + /* Fibre Channel transmission media */ + if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] & + SFF8636_FC_TRANS_MEDIA_TW) + printf("%s FC: Twin Axial Pair (TW)\n", pfx); + if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] & + SFF8636_FC_TRANS_MEDIA_TP) + printf("%s FC: Twisted Pair (TP)\n", pfx); + if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] & + SFF8636_FC_TRANS_MEDIA_MI) + printf("%s FC: Miniature Coax (MI)\n", pfx); + if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] & + SFF8636_FC_TRANS_MEDIA_TV) + printf("%s FC: Video Coax (TV)\n", pfx); + if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] & + SFF8636_FC_TRANS_MEDIA_M6) + printf("%s FC: Multimode, 62.5m (M6)\n", pfx); + if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] & + SFF8636_FC_TRANS_MEDIA_M5) + printf("%s FC: Multimode, 50m (M5)\n", pfx); + if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] & + SFF8636_FC_TRANS_MEDIA_OM3) + printf("%s FC: Multimode, 50um (OM3)\n", pfx); + if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] & + SFF8636_FC_TRANS_MEDIA_SM) + printf("%s FC: Single Mode (SM)\n", pfx); + + /* Fibre Channel speed */ + if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1200_MBPS) + printf("%s FC: 1200 MBytes/sec\n", pfx); + if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_800_MBPS) + printf("%s FC: 800 MBytes/sec\n", pfx); + if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1600_MBPS) + printf("%s FC: 1600 MBytes/sec\n", pfx); + if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_400_MBPS) + printf("%s FC: 400 MBytes/sec\n", pfx); + if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_200_MBPS) + printf("%s FC: 200 MBytes/sec\n", pfx); + if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_100_MBPS) + printf("%s FC: 100 MBytes/sec\n", pfx); +} + +static void sff8636_show_encoding(const struct sff8636_memory_map *map) +{ + sff8024_show_encoding(map->page_00h, SFF8636_ENCODING_OFFSET, + ETH_MODULE_SFF_8636); +} + +static void sff8636_show_rate_identifier(const struct sff8636_memory_map *map) +{ + /* TODO: Need to fix rate select logic */ + printf("\t%-41s : 0x%02x\n", "Rate identifier", + map->page_00h[SFF8636_EXT_RS_OFFSET]); +} + +static void +sff8636_show_wavelength_or_copper_compliance(const struct sff8636_memory_map *map) +{ + printf("\t%-41s : 0x%02x", "Transmitter technology", + map->page_00h[SFF8636_DEVICE_TECH_OFFSET] & + SFF8636_TRANS_TECH_MASK); + + switch (map->page_00h[SFF8636_DEVICE_TECH_OFFSET] & + SFF8636_TRANS_TECH_MASK) { + case SFF8636_TRANS_850_VCSEL: + printf(" (850 nm VCSEL)\n"); + break; + case SFF8636_TRANS_1310_VCSEL: + printf(" (1310 nm VCSEL)\n"); + break; + case SFF8636_TRANS_1550_VCSEL: + printf(" (1550 nm VCSEL)\n"); + break; + case SFF8636_TRANS_1310_FP: + printf(" (1310 nm FP)\n"); + break; + case SFF8636_TRANS_1310_DFB: + printf(" (1310 nm DFB)\n"); + break; + case SFF8636_TRANS_1550_DFB: + printf(" (1550 nm DFB)\n"); + break; + case SFF8636_TRANS_1310_EML: + printf(" (1310 nm EML)\n"); + break; + case SFF8636_TRANS_1550_EML: + printf(" (1550 nm EML)\n"); + break; + case SFF8636_TRANS_OTHERS: + printf(" (Others/Undefined)\n"); + break; + case SFF8636_TRANS_1490_DFB: + printf(" (1490 nm DFB)\n"); + break; + case SFF8636_TRANS_COPPER_PAS_UNEQUAL: + printf(" (Copper cable unequalized)\n"); + break; + case SFF8636_TRANS_COPPER_PAS_EQUAL: + printf(" (Copper cable passive equalized)\n"); + break; + case SFF8636_TRANS_COPPER_LNR_FAR_EQUAL: + printf(" (Copper cable, near and far end limiting active equalizers)\n"); + break; + case SFF8636_TRANS_COPPER_FAR_EQUAL: + printf(" (Copper cable, far end limiting active equalizers)\n"); + break; + case SFF8636_TRANS_COPPER_NEAR_EQUAL: + printf(" (Copper cable, near end limiting active equalizers)\n"); + break; + case SFF8636_TRANS_COPPER_LNR_EQUAL: + printf(" (Copper cable, linear active equalizers)\n"); + break; + } + + if ((map->page_00h[SFF8636_DEVICE_TECH_OFFSET] & + SFF8636_TRANS_TECH_MASK) >= SFF8636_TRANS_COPPER_PAS_UNEQUAL) { + printf("\t%-41s : %udb\n", "Attenuation at 2.5GHz", + map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET]); + printf("\t%-41s : %udb\n", "Attenuation at 5.0GHz", + map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]); + printf("\t%-41s : %udb\n", "Attenuation at 7.0GHz", + map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]); + printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz", + map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]); + } else { + printf("\t%-41s : %.3lfnm\n", "Laser wavelength", + (((map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) | + map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]) * 0.05)); + printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance", + (((map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) | + map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]) * 0.005)); + } +} + +/* + * 2-byte internal temperature conversions: + * First byte is a signed 8-bit integer, which is the temp decimal part + * Second byte are 1/256th of degree, which are added to the dec part. + */ +#define SFF8636_OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset)) + +static void sff8636_dom_parse(const struct sff8636_memory_map *map, + struct sff_diags *sd) +{ + const __u8 *id = map->lower_memory; + int i = 0; + + /* Monitoring Thresholds for Alarms and Warnings */ + sd->sfp_voltage[MCURR] = OFFSET_TO_U16_PTR(id, SFF8636_VCC_CURR); + sd->sfp_temp[MCURR] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_CURR); + + if (!map->page_03h) + goto out; + + sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_VCC_HALRM); + sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_VCC_LALRM); + sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_VCC_HWARN); + sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_VCC_LWARN); + + sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TEMP_HALRM); + sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TEMP_LALRM); + sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TEMP_HWARN); + sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TEMP_LWARN); + + sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TX_BIAS_HALRM); + sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TX_BIAS_LALRM); + sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TX_BIAS_HWARN); + sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TX_BIAS_LWARN); + + sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TX_PWR_HALRM); + sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TX_PWR_LALRM); + sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TX_PWR_HWARN); + sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_TX_PWR_LWARN); + + sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_RX_PWR_HALRM); + sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_RX_PWR_LALRM); + sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_RX_PWR_HWARN); + sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h, + SFF8636_RX_PWR_LWARN); + +out: + /* Channel Specific Data */ + for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) { + u8 rx_power_offset, tx_bias_offset; + u8 tx_power_offset; + + switch (i) { + case 0: + rx_power_offset = SFF8636_RX_PWR_1_OFFSET; + tx_power_offset = SFF8636_TX_PWR_1_OFFSET; + tx_bias_offset = SFF8636_TX_BIAS_1_OFFSET; + break; + case 1: + rx_power_offset = SFF8636_RX_PWR_2_OFFSET; + tx_power_offset = SFF8636_TX_PWR_2_OFFSET; + tx_bias_offset = SFF8636_TX_BIAS_2_OFFSET; + break; + case 2: + rx_power_offset = SFF8636_RX_PWR_3_OFFSET; + tx_power_offset = SFF8636_TX_PWR_3_OFFSET; + tx_bias_offset = SFF8636_TX_BIAS_3_OFFSET; + break; + case 3: + rx_power_offset = SFF8636_RX_PWR_4_OFFSET; + tx_power_offset = SFF8636_TX_PWR_4_OFFSET; + tx_bias_offset = SFF8636_TX_BIAS_4_OFFSET; + break; + } + sd->scd[i].bias_cur = OFFSET_TO_U16(tx_bias_offset); + sd->scd[i].rx_power = OFFSET_TO_U16(rx_power_offset); + sd->scd[i].tx_power = OFFSET_TO_U16(tx_power_offset); + } +} + +static void sff8636_show_dom(const struct sff8636_memory_map *map) +{ + struct sff_diags sd = {0}; + char *rx_power_string = NULL; + char power_string[MAX_DESC_SIZE]; + int i; + + /* + * There is no clear identifier to signify the existence of + * optical diagnostics similar to SFF-8472. So checking existence + * of page 3, will provide the gurantee for existence of alarms + * and thresholds + * If pagging support exists, then supports_alarms is marked as 1 + */ + if (map->page_03h) + sd.supports_alarms = 1; + + sd.rx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] & + SFF8636_RX_PWR_TYPE_MASK; + sd.tx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] & + SFF8636_RX_PWR_TYPE_MASK; + + sff8636_dom_parse(map, &sd); + + PRINT_TEMP("Module temperature", sd.sfp_temp[MCURR]); + PRINT_VCC("Module voltage", sd.sfp_voltage[MCURR]); + + /* + * SFF-8636/8436 spec is not clear whether RX power/ TX bias + * current fields are supported or not. A valid temperature + * reading is used as existence for TX/RX power. + */ + if ((sd.sfp_temp[MCURR] == 0x0) || + (sd.sfp_temp[MCURR] == (__s16)0xFFFF)) + return; + + printf("\t%-41s : %s\n", "Alarm/warning flags implemented", + (sd.supports_alarms ? "Yes" : "No")); + + for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) { + snprintf(power_string, MAX_DESC_SIZE, "%s (Channel %d)", + "Laser tx bias current", i+1); + PRINT_BIAS(power_string, sd.scd[i].bias_cur); + } + + for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) { + snprintf(power_string, MAX_DESC_SIZE, "%s (Channel %d)", + "Transmit avg optical power", i+1); + PRINT_xX_PWR(power_string, sd.scd[i].tx_power); + } + + if (!sd.rx_power_type) + rx_power_string = "Receiver signal OMA"; + else + rx_power_string = "Rcvr signal avg optical power"; + + for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) { + snprintf(power_string, MAX_DESC_SIZE, "%s(Channel %d)", + rx_power_string, i+1); + PRINT_xX_PWR(power_string, sd.scd[i].rx_power); + } + + if (sd.supports_alarms) { + for (i = 0; sff8636_aw_flags[i].str; ++i) { + printf("\t%-41s : %s\n", sff8636_aw_flags[i].str, + map->lower_memory[sff8636_aw_flags[i].offset] + & sff8636_aw_flags[i].value ? "On" : "Off"); + } + + sff_show_thresholds(sd); + } +} + +static void sff8636_show_page_zero(const struct sff8636_memory_map *map) +{ + sff8636_show_ext_identifier(map); + sff8636_show_connector(map); + sff8636_show_transceiver(map); + sff8636_show_encoding(map); + sff_show_value_with_unit(map->page_00h, SFF8636_BR_NOMINAL_OFFSET, + "BR, Nominal", 100, "Mbps"); + sff8636_show_rate_identifier(map); + sff_show_value_with_unit(map->page_00h, SFF8636_SM_LEN_OFFSET, + "Length (SMF,km)", 1, "km"); + sff_show_value_with_unit(map->page_00h, SFF8636_OM3_LEN_OFFSET, + "Length (OM3 50um)", 2, "m"); + sff_show_value_with_unit(map->page_00h, SFF8636_OM2_LEN_OFFSET, + "Length (OM2 50um)", 1, "m"); + sff_show_value_with_unit(map->page_00h, SFF8636_OM1_LEN_OFFSET, + "Length (OM1 62.5um)", 1, "m"); + sff_show_value_with_unit(map->page_00h, SFF8636_CBL_LEN_OFFSET, + "Length (Copper or Active cable)", 1, "m"); + sff8636_show_wavelength_or_copper_compliance(map); + sff_show_ascii(map->page_00h, SFF8636_VENDOR_NAME_START_OFFSET, + SFF8636_VENDOR_NAME_END_OFFSET, "Vendor name"); + sff8024_show_oui(map->page_00h, SFF8636_VENDOR_OUI_OFFSET); + sff_show_ascii(map->page_00h, SFF8636_VENDOR_PN_START_OFFSET, + SFF8636_VENDOR_PN_END_OFFSET, "Vendor PN"); + sff_show_ascii(map->page_00h, SFF8636_VENDOR_REV_START_OFFSET, + SFF8636_VENDOR_REV_END_OFFSET, "Vendor rev"); + sff_show_ascii(map->page_00h, SFF8636_VENDOR_SN_START_OFFSET, + SFF8636_VENDOR_SN_END_OFFSET, "Vendor SN"); + sff_show_ascii(map->page_00h, SFF8636_DATE_YEAR_OFFSET, + SFF8636_DATE_VENDOR_LOT_OFFSET + 1, "Date code"); + sff_show_revision_compliance(map->lower_memory, + SFF8636_REV_COMPLIANCE_OFFSET); +} + +static void sff8636_show_all_common(const struct sff8636_memory_map *map) +{ + sff8636_show_identifier(map); + switch (map->lower_memory[SFF8636_ID_OFFSET]) { + case SFF8024_ID_QSFP: + case SFF8024_ID_QSFP_PLUS: + case SFF8024_ID_QSFP28: + sff8636_show_page_zero(map); + sff8636_show_dom(map); + break; + } +} + +static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map, + const __u8 *id, __u32 eeprom_len) +{ + /* Lower Memory and Page 00h are always present. + * + * Offset into Upper Memory is between page size and twice the page + * size. Therefore, set the base address of each page to base address + * plus page size multiplied by the page number. + */ + map->lower_memory = id; + map->page_00h = id; + + /* Page 03h is only present when the module memory model is paged and + * not flat and when we got a big enough buffer from the kernel. + */ + if (map->lower_memory[SFF8636_STATUS_2_OFFSET] & + SFF8636_STATUS_PAGE_3_PRESENT || + eeprom_len != ETH_MODULE_SFF_8636_MAX_LEN) + return; + + map->page_03h = id + 3 * SFF8636_PAGE_SIZE; +} + +void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len) +{ + struct sff8636_memory_map map = {}; + + if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD || + id[SFF8636_ID_OFFSET] == SFF8024_ID_OSFP || + id[SFF8636_ID_OFFSET] == SFF8024_ID_DSFP) { + cmis_show_all_ioctl(id); + return; + } + + sff8636_memory_map_init_buf(&map, id, eeprom_len); + sff8636_show_all_common(&map); +} + +static void sff8636_request_init(struct ethtool_module_eeprom *request, u8 page, + u32 offset) +{ + request->offset = offset; + request->length = SFF8636_PAGE_SIZE; + request->page = page; + request->bank = 0; + request->i2c_address = SFF8636_I2C_ADDRESS; + request->data = NULL; +} + +static int +sff8636_memory_map_init_pages(struct cmd_context *ctx, + struct sff8636_memory_map *map) +{ + struct ethtool_module_eeprom request; + int ret; + + /* Lower Memory and Page 00h are always present. + * + * Offset into Upper Memory is between page size and twice the page + * size. Therefore, set the base address of each page to its base + * address minus page size. + */ + sff8636_request_init(&request, 0x0, 0); + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + map->lower_memory = request.data; + + sff8636_request_init(&request, 0x0, SFF8636_PAGE_SIZE); + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + map->page_00h = request.data - SFF8636_PAGE_SIZE; + + /* Page 03h is only present when the module memory model is paged and + * not flat. + */ + if (map->lower_memory[SFF8636_STATUS_2_OFFSET] & + SFF8636_STATUS_PAGE_3_PRESENT) + return 0; + + sff8636_request_init(&request, 0x3, SFF8636_PAGE_SIZE); + ret = nl_get_eeprom_page(ctx, &request); + if (ret < 0) + return ret; + map->page_03h = request.data - SFF8636_PAGE_SIZE; + + return 0; +} + +int sff8636_show_all_nl(struct cmd_context *ctx) +{ + struct sff8636_memory_map map = {}; + int ret; + + ret = sff8636_memory_map_init_pages(ctx, &map); + if (ret < 0) + return ret; + sff8636_show_all_common(&map); + + return 0; +} diff --git a/qsfp.h b/qsfp.h new file mode 100644 index 0000000..aabf09f --- /dev/null +++ b/qsfp.h @@ -0,0 +1,628 @@ +/* + * SFF 8636 standards based QSFP EEPROM Field Definitions + * + * Vidya Ravipati + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#ifndef QSFP_H__ +#define QSFP_H__ + +/*------------------------------------------------------------------------------ + * + * QSFP EEPROM data structures + * + * register info from SFF-8636 Rev 2.7 + */ + +/*------------------------------------------------------------------------------ + * + * Lower Memory Page 00h + * Measurement, Diagnostic and Control Functions + * + */ +/* Identifier - 0 */ +/* Values are defined under SFF8024_ID_OFFSET */ +#define SFF8636_ID_OFFSET 0x00 + +#define SFF8636_REV_COMPLIANCE_OFFSET 0x01 + +#define SFF8636_STATUS_2_OFFSET 0x02 +/* Flat Memory:0- Paging, 1- Page 0 only */ +#define SFF8636_STATUS_PAGE_3_PRESENT (1 << 2) +#define SFF8636_STATUS_INTL_OUTPUT (1 << 1) +#define SFF8636_STATUS_DATA_NOT_READY (1 << 0) + +/* Channel Status Interrupt Flags - 3-5 */ +#define SFF8636_LOS_AW_OFFSET 0x03 +#define SFF8636_TX4_LOS_AW (1 << 7) +#define SFF8636_TX3_LOS_AW (1 << 6) +#define SFF8636_TX2_LOS_AW (1 << 5) +#define SFF8636_TX1_LOS_AW (1 << 4) +#define SFF8636_RX4_LOS_AW (1 << 3) +#define SFF8636_RX3_LOS_AW (1 << 2) +#define SFF8636_RX2_LOS_AW (1 << 1) +#define SFF8636_RX1_LOS_AW (1 << 0) + +#define SFF8636_FAULT_AW_OFFSET 0x04 +#define SFF8636_TX4_FAULT_AW (1 << 3) +#define SFF8636_TX3_FAULT_AW (1 << 2) +#define SFF8636_TX2_FAULT_AW (1 << 1) +#define SFF8636_TX1_FAULT_AW (1 << 0) + +/* Module Monitor Interrupt Flags - 6-8 */ +#define SFF8636_TEMP_AW_OFFSET 0x06 +#define SFF8636_TEMP_HALARM_STATUS (1 << 7) +#define SFF8636_TEMP_LALARM_STATUS (1 << 6) +#define SFF8636_TEMP_HWARN_STATUS (1 << 5) +#define SFF8636_TEMP_LWARN_STATUS (1 << 4) + +#define SFF8636_VCC_AW_OFFSET 0x07 +#define SFF8636_VCC_HALARM_STATUS (1 << 7) +#define SFF8636_VCC_LALARM_STATUS (1 << 6) +#define SFF8636_VCC_HWARN_STATUS (1 << 5) +#define SFF8636_VCC_LWARN_STATUS (1 << 4) + +/* Channel Monitor Interrupt Flags - 9-21 */ +#define SFF8636_RX_PWR_12_AW_OFFSET 0x09 +#define SFF8636_RX_PWR_1_HALARM (1 << 7) +#define SFF8636_RX_PWR_1_LALARM (1 << 6) +#define SFF8636_RX_PWR_1_HWARN (1 << 5) +#define SFF8636_RX_PWR_1_LWARN (1 << 4) +#define SFF8636_RX_PWR_2_HALARM (1 << 3) +#define SFF8636_RX_PWR_2_LALARM (1 << 2) +#define SFF8636_RX_PWR_2_HWARN (1 << 1) +#define SFF8636_RX_PWR_2_LWARN (1 << 0) + +#define SFF8636_RX_PWR_34_AW_OFFSET 0x0A +#define SFF8636_RX_PWR_3_HALARM (1 << 7) +#define SFF8636_RX_PWR_3_LALARM (1 << 6) +#define SFF8636_RX_PWR_3_HWARN (1 << 5) +#define SFF8636_RX_PWR_3_LWARN (1 << 4) +#define SFF8636_RX_PWR_4_HALARM (1 << 3) +#define SFF8636_RX_PWR_4_LALARM (1 << 2) +#define SFF8636_RX_PWR_4_HWARN (1 << 1) +#define SFF8636_RX_PWR_4_LWARN (1 << 0) + +#define SFF8636_TX_BIAS_12_AW_OFFSET 0x0B +#define SFF8636_TX_BIAS_1_HALARM (1 << 7) +#define SFF8636_TX_BIAS_1_LALARM (1 << 6) +#define SFF8636_TX_BIAS_1_HWARN (1 << 5) +#define SFF8636_TX_BIAS_1_LWARN (1 << 4) +#define SFF8636_TX_BIAS_2_HALARM (1 << 3) +#define SFF8636_TX_BIAS_2_LALARM (1 << 2) +#define SFF8636_TX_BIAS_2_HWARN (1 << 1) +#define SFF8636_TX_BIAS_2_LWARN (1 << 0) + +#define SFF8636_TX_BIAS_34_AW_OFFSET 0xC +#define SFF8636_TX_BIAS_3_HALARM (1 << 7) +#define SFF8636_TX_BIAS_3_LALARM (1 << 6) +#define SFF8636_TX_BIAS_3_HWARN (1 << 5) +#define SFF8636_TX_BIAS_3_LWARN (1 << 4) +#define SFF8636_TX_BIAS_4_HALARM (1 << 3) +#define SFF8636_TX_BIAS_4_LALARM (1 << 2) +#define SFF8636_TX_BIAS_4_HWARN (1 << 1) +#define SFF8636_TX_BIAS_4_LWARN (1 << 0) + +#define SFF8636_TX_PWR_12_AW_OFFSET 0x0D +#define SFF8636_TX_PWR_1_HALARM (1 << 7) +#define SFF8636_TX_PWR_1_LALARM (1 << 6) +#define SFF8636_TX_PWR_1_HWARN (1 << 5) +#define SFF8636_TX_PWR_1_LWARN (1 << 4) +#define SFF8636_TX_PWR_2_HALARM (1 << 3) +#define SFF8636_TX_PWR_2_LALARM (1 << 2) +#define SFF8636_TX_PWR_2_HWARN (1 << 1) +#define SFF8636_TX_PWR_2_LWARN (1 << 0) + +#define SFF8636_TX_PWR_34_AW_OFFSET 0x0E +#define SFF8636_TX_PWR_3_HALARM (1 << 7) +#define SFF8636_TX_PWR_3_LALARM (1 << 6) +#define SFF8636_TX_PWR_3_HWARN (1 << 5) +#define SFF8636_TX_PWR_3_LWARN (1 << 4) +#define SFF8636_TX_PWR_4_HALARM (1 << 3) +#define SFF8636_TX_PWR_4_LALARM (1 << 2) +#define SFF8636_TX_PWR_4_HWARN (1 << 1) +#define SFF8636_TX_PWR_4_LWARN (1 << 0) + +/* Module Monitoring Values - 22-33 */ +#define SFF8636_TEMP_CURR 0x16 +#define SFF8636_TEMP_MSB_OFFSET 0x16 +#define SFF8636_TEMP_LSB_OFFSET 0x17 + +#define SFF8636_VCC_CURR 0x1A +#define SFF8636_VCC_MSB_OFFSET 0x1A +#define SFF8636_VCC_LSB_OFFSET 0x1B + +/* Channel Monitoring Values - 34-81 */ +#define SFF8636_RX_PWR_1_OFFSET 0x22 +#define SFF8636_RX_PWR_2_OFFSET 0x24 +#define SFF8636_RX_PWR_3_OFFSET 0x26 +#define SFF8636_RX_PWR_4_OFFSET 0x28 + +#define SFF8636_TX_BIAS_1_OFFSET 0x2A +#define SFF8636_TX_BIAS_2_OFFSET 0x2C +#define SFF8636_TX_BIAS_3_OFFSET 0x2E +#define SFF8636_TX_BIAS_4_OFFSET 0x30 + +#define SFF8636_TX_PWR_1_OFFSET 0x32 +#define SFF8636_TX_PWR_2_OFFSET 0x34 +#define SFF8636_TX_PWR_3_OFFSET 0x36 +#define SFF8636_TX_PWR_4_OFFSET 0x38 + +/* Control Bytes - 86 - 99 */ +#define SFF8636_TX_DISABLE_OFFSET 0x56 +#define SFF8636_TX_DISABLE_4 (1 << 3) +#define SFF8636_TX_DISABLE_3 (1 << 2) +#define SFF8636_TX_DISABLE_2 (1 << 1) +#define SFF8636_TX_DISABLE_1 (1 << 0) + +#define SFF8636_RX_RATE_SELECT_OFFSET 0x57 +#define SFF8636_RX_RATE_SELECT_4_MASK (3 << 6) +#define SFF8636_RX_RATE_SELECT_3_MASK (3 << 4) +#define SFF8636_RX_RATE_SELECT_2_MASK (3 << 2) +#define SFF8636_RX_RATE_SELECT_1_MASK (3 << 0) + +#define SFF8636_TX_RATE_SELECT_OFFSET 0x58 +#define SFF8636_TX_RATE_SELECT_4_MASK (3 << 6) +#define SFF8636_TX_RATE_SELECT_3_MASK (3 << 4) +#define SFF8636_TX_RATE_SELECT_2_MASK (3 << 2) +#define SFF8636_TX_RATE_SELECT_1_MASK (3 << 0) + +#define SFF8636_RX_APP_SELECT_4_OFFSET 0x58 +#define SFF8636_RX_APP_SELECT_3_OFFSET 0x59 +#define SFF8636_RX_APP_SELECT_2_OFFSET 0x5A +#define SFF8636_RX_APP_SELECT_1_OFFSET 0x5B + +#define SFF8636_PWR_MODE_OFFSET 0x5D +#define SFF8636_HIGH_PWR_ENABLE (1 << 2) +#define SFF8636_LOW_PWR_SET (1 << 1) +#define SFF8636_PWR_OVERRIDE (1 << 0) + +#define SFF8636_TX_APP_SELECT_4_OFFSET 0x5E +#define SFF8636_TX_APP_SELECT_3_OFFSET 0x5F +#define SFF8636_TX_APP_SELECT_2_OFFSET 0x60 +#define SFF8636_TX_APP_SELECT_1_OFFSET 0x61 + +#define SFF8636_LOS_MASK_OFFSET 0x64 +#define SFF8636_TX_LOS_4_MASK (1 << 7) +#define SFF8636_TX_LOS_3_MASK (1 << 6) +#define SFF8636_TX_LOS_2_MASK (1 << 5) +#define SFF8636_TX_LOS_1_MASK (1 << 4) +#define SFF8636_RX_LOS_4_MASK (1 << 3) +#define SFF8636_RX_LOS_3_MASK (1 << 2) +#define SFF8636_RX_LOS_2_MASK (1 << 1) +#define SFF8636_RX_LOS_1_MASK (1 << 0) + +#define SFF8636_FAULT_MASK_OFFSET 0x65 +#define SFF8636_TX_FAULT_1_MASK (1 << 3) +#define SFF8636_TX_FAULT_2_MASK (1 << 2) +#define SFF8636_TX_FAULT_3_MASK (1 << 1) +#define SFF8636_TX_FAULT_4_MASK (1 << 0) + +#define SFF8636_TEMP_MASK_OFFSET 0x67 +#define SFF8636_TEMP_HALARM_MASK (1 << 7) +#define SFF8636_TEMP_LALARM_MASK (1 << 6) +#define SFF8636_TEMP_HWARN_MASK (1 << 5) +#define SFF8636_TEMP_LWARN_MASK (1 << 4) + +#define SFF8636_VCC_MASK_OFFSET 0x68 +#define SFF8636_VCC_HALARM_MASK (1 << 7) +#define SFF8636_VCC_LALARM_MASK (1 << 6) +#define SFF8636_VCC_HWARN_MASK (1 << 5) +#define SFF8636_VCC_LWARN_MASK (1 << 4) + +/*------------------------------------------------------------------------------ + * + * Upper Memory Page 00h + * Serial ID - Base ID, Extended ID and Vendor Specific ID fields + * + */ +/* Identifier - 128 */ +/* Identifier values same as Lower Memory Page 00h */ +#define SFF8636_UPPER_PAGE_0_ID_OFFSET 0x80 + +/* Extended Identifier - 128 */ +#define SFF8636_EXT_ID_OFFSET 0x81 +#define SFF8636_EXT_ID_PWR_CLASS_MASK 0xC0 +#define SFF8636_EXT_ID_PWR_CLASS_1 (0 << 6) +#define SFF8636_EXT_ID_PWR_CLASS_2 (1 << 6) +#define SFF8636_EXT_ID_PWR_CLASS_3 (2 << 6) +#define SFF8636_EXT_ID_PWR_CLASS_4 (3 << 6) +#define SFF8636_EXT_ID_CLIE_MASK 0x10 +#define SFF8636_EXT_ID_CLIEI_CODE_PRESENT (1 << 4) +#define SFF8636_EXT_ID_CDR_TX_MASK 0x08 +#define SFF8636_EXT_ID_CDR_TX_PRESENT (1 << 3) +#define SFF8636_EXT_ID_CDR_RX_MASK 0x04 +#define SFF8636_EXT_ID_CDR_RX_PRESENT (1 << 2) +#define SFF8636_EXT_ID_EPWR_CLASS_MASK 0x03 +#define SFF8636_EXT_ID_PWR_CLASS_LEGACY 0 +#define SFF8636_EXT_ID_PWR_CLASS_5 1 +#define SFF8636_EXT_ID_PWR_CLASS_6 2 +#define SFF8636_EXT_ID_PWR_CLASS_7 3 + +/* Connector Values offset - 130 */ +/* Values are defined under SFF8024_CTOR */ +#define SFF8636_CTOR_OFFSET 0x82 +#define SFF8636_CTOR_UNKNOWN 0x00 +#define SFF8636_CTOR_SC 0x01 +#define SFF8636_CTOR_FC_STYLE_1 0x02 +#define SFF8636_CTOR_FC_STYLE_2 0x03 +#define SFF8636_CTOR_BNC_TNC 0x04 +#define SFF8636_CTOR_FC_COAX 0x05 +#define SFF8636_CTOR_FIBER_JACK 0x06 +#define SFF8636_CTOR_LC 0x07 +#define SFF8636_CTOR_MT_RJ 0x08 +#define SFF8636_CTOR_MU 0x09 +#define SFF8636_CTOR_SG 0x0A +#define SFF8636_CTOR_OPT_PT 0x0B +#define SFF8636_CTOR_MPO 0x0C +/* 0D-1Fh --- Reserved */ +#define SFF8636_CTOR_HSDC_II 0x20 +#define SFF8636_CTOR_COPPER_PT 0x21 +#define SFF8636_CTOR_RJ45 0x22 +#define SFF8636_CTOR_NO_SEPARABLE 0x23 +#define SFF8636_CTOR_MXC_2X16 0x24 + +/* Specification Compliance - 131-138 */ +/* Ethernet Compliance Codes - 131 */ +#define SFF8636_ETHERNET_COMP_OFFSET 0x83 +#define SFF8636_ETHERNET_RSRVD (1 << 7) +#define SFF8636_ETHERNET_10G_LRM (1 << 6) +#define SFF8636_ETHERNET_10G_LR (1 << 5) +#define SFF8636_ETHERNET_10G_SR (1 << 4) +#define SFF8636_ETHERNET_40G_CR4 (1 << 3) +#define SFF8636_ETHERNET_40G_SR4 (1 << 2) +#define SFF8636_ETHERNET_40G_LR4 (1 << 1) +#define SFF8636_ETHERNET_40G_ACTIVE (1 << 0) + +/* SONET Compliance Codes - 132 */ +#define SFF8636_SONET_COMP_OFFSET 0x84 +#define SFF8636_SONET_40G_OTN (1 << 3) +#define SFF8636_SONET_OC48_LR (1 << 2) +#define SFF8636_SONET_OC48_IR (1 << 1) +#define SFF8636_SONET_OC48_SR (1 << 0) + +/* SAS/SATA Complaince Codes - 133 */ +#define SFF8636_SAS_COMP_OFFSET 0x85 +#define SFF8636_SAS_12G (1 << 6) +#define SFF8636_SAS_6G (1 << 5) +#define SFF8636_SAS_3G (1 << 4) + +/* Gigabit Ethernet Compliance Codes - 134 */ +#define SFF8636_GIGE_COMP_OFFSET 0x86 +#define SFF8636_GIGE_1000_BASE_T (1 << 3) +#define SFF8636_GIGE_1000_BASE_CX (1 << 2) +#define SFF8636_GIGE_1000_BASE_LX (1 << 1) +#define SFF8636_GIGE_1000_BASE_SX (1 << 0) + +/* Fibre Channel Link length/Transmitter Tech. - 135,136 */ +#define SFF8636_FC_LEN_OFFSET 0x87 +#define SFF8636_FC_LEN_VERY_LONG (1 << 7) +#define SFF8636_FC_LEN_SHORT (1 << 6) +#define SFF8636_FC_LEN_INT (1 << 5) +#define SFF8636_FC_LEN_LONG (1 << 4) +#define SFF8636_FC_LEN_MED (1 << 3) +#define SFF8636_FC_TECH_LONG_LC (1 << 1) +#define SFF8636_FC_TECH_ELEC_INTER (1 << 0) + +#define SFF8636_FC_TECH_OFFSET 0x88 +#define SFF8636_FC_TECH_ELEC_INTRA (1 << 7) +#define SFF8636_FC_TECH_SHORT_WO_OFC (1 << 6) +#define SFF8636_FC_TECH_SHORT_W_OFC (1 << 5) +#define SFF8636_FC_TECH_LONG_LL (1 << 4) + +/* Fibre Channel Transmitter Media - 137 */ +#define SFF8636_FC_TRANS_MEDIA_OFFSET 0x89 +/* Twin Axial Pair */ +#define SFF8636_FC_TRANS_MEDIA_TW (1 << 7) +/* Shielded Twisted Pair */ +#define SFF8636_FC_TRANS_MEDIA_TP (1 << 6) +/* Miniature Coax */ +#define SFF8636_FC_TRANS_MEDIA_MI (1 << 5) +/* Video Coax */ +#define SFF8636_FC_TRANS_MEDIA_TV (1 << 4) +/* Multi-mode 62.5m */ +#define SFF8636_FC_TRANS_MEDIA_M6 (1 << 3) +/* Multi-mode 50m */ +#define SFF8636_FC_TRANS_MEDIA_M5 (1 << 2) +/* Multi-mode 50um */ +#define SFF8636_FC_TRANS_MEDIA_OM3 (1 << 1) +/* Single Mode */ +#define SFF8636_FC_TRANS_MEDIA_SM (1 << 0) + +/* Fibre Channel Speed - 138 */ +#define SFF8636_FC_SPEED_OFFSET 0x8A +#define SFF8636_FC_SPEED_1200_MBPS (1 << 7) +#define SFF8636_FC_SPEED_800_MBPS (1 << 6) +#define SFF8636_FC_SPEED_1600_MBPS (1 << 5) +#define SFF8636_FC_SPEED_400_MBPS (1 << 4) +#define SFF8636_FC_SPEED_200_MBPS (1 << 2) +#define SFF8636_FC_SPEED_100_MBPS (1 << 0) + +/* Encoding - 139 */ +/* Values are defined under SFF8024_ENCODING */ +#define SFF8636_ENCODING_OFFSET 0x8B +#define SFF8636_ENCODING_MANCHESTER 0x06 +#define SFF8636_ENCODING_64B66B 0x05 +#define SFF8636_ENCODING_SONET 0x04 +#define SFF8636_ENCODING_NRZ 0x03 +#define SFF8636_ENCODING_4B5B 0x02 +#define SFF8636_ENCODING_8B10B 0x01 +#define SFF8636_ENCODING_UNSPEC 0x00 + +/* BR, Nominal - 140 */ +#define SFF8636_BR_NOMINAL_OFFSET 0x8C + +/* Extended RateSelect - 141 */ +#define SFF8636_EXT_RS_OFFSET 0x8D +#define SFF8636_EXT_RS_V1 (1 << 0) + +/* Length (Standard SM Fiber)-km - 142 */ +#define SFF8636_SM_LEN_OFFSET 0x8E + +/* Length (OM3)-Unit 2m - 143 */ +#define SFF8636_OM3_LEN_OFFSET 0x8F + +/* Length (OM2)-Unit 1m - 144 */ +#define SFF8636_OM2_LEN_OFFSET 0x90 + +/* Length (OM1)-Unit 1m - 145 */ +#define SFF8636_OM1_LEN_OFFSET 0x91 + +/* Cable Assembly Length -Unit 1m - 146 */ +#define SFF8636_CBL_LEN_OFFSET 0x92 + +/* Device Technology - 147 */ +#define SFF8636_DEVICE_TECH_OFFSET 0x93 +/* Transmitter Technology */ +#define SFF8636_TRANS_TECH_MASK 0xF0 +/* Copper cable, linear active equalizers */ +#define SFF8636_TRANS_COPPER_LNR_EQUAL (15 << 4) +/* Copper cable, near end limiting active equalizers */ +#define SFF8636_TRANS_COPPER_NEAR_EQUAL (14 << 4) +/* Copper cable, far end limiting active equalizers */ +#define SFF8636_TRANS_COPPER_FAR_EQUAL (13 << 4) +/* Copper cable, near & far end limiting active equalizers */ +#define SFF8636_TRANS_COPPER_LNR_FAR_EQUAL (12 << 4) +/* Copper cable, passive equalized */ +#define SFF8636_TRANS_COPPER_PAS_EQUAL (11 << 4) +/* Copper cable, unequalized */ +#define SFF8636_TRANS_COPPER_PAS_UNEQUAL (10 << 4) +/* 1490 nm DFB */ +#define SFF8636_TRANS_1490_DFB (9 << 4) +/* Others */ +#define SFF8636_TRANS_OTHERS (8 << 4) +/* 1550 nm EML */ +#define SFF8636_TRANS_1550_EML (7 << 4) +/* 1310 nm EML */ +#define SFF8636_TRANS_1310_EML (6 << 4) +/* 1550 nm DFB */ +#define SFF8636_TRANS_1550_DFB (5 << 4) +/* 1310 nm DFB */ +#define SFF8636_TRANS_1310_DFB (4 << 4) +/* 1310 nm FP */ +#define SFF8636_TRANS_1310_FP (3 << 4) +/* 1550 nm VCSEL */ +#define SFF8636_TRANS_1550_VCSEL (2 << 4) +/* 1310 nm VCSEL */ +#define SFF8636_TRANS_1310_VCSEL (1 << 4) +/* 850 nm VCSEL */ +#define SFF8636_TRANS_850_VCSEL (0 << 4) + + /* Active/No wavelength control */ +#define SFF8636_DEV_TECH_ACTIVE_WAVE_LEN (1 << 3) +/* Cooled transmitter */ +#define SFF8636_DEV_TECH_COOL_TRANS (1 << 2) +/* APD/Pin Detector */ +#define SFF8636_DEV_TECH_APD_DETECTOR (1 << 1) +/* Transmitter tunable */ +#define SFF8636_DEV_TECH_TUNABLE (1 << 0) + +/* Vendor Name - 148-163 */ +#define SFF8636_VENDOR_NAME_START_OFFSET 0x94 +#define SFF8636_VENDOR_NAME_END_OFFSET 0xA3 + +/* Extended Module Codes - 164 */ +#define SFF8636_EXT_MOD_CODE_OFFSET 0xA4 +#define SFF8636_EXT_MOD_INFINIBAND_EDR (1 << 4) +#define SFF8636_EXT_MOD_INFINIBAND_FDR (1 << 3) +#define SFF8636_EXT_MOD_INFINIBAND_QDR (1 << 2) +#define SFF8636_EXT_MOD_INFINIBAND_DDR (1 << 1) +#define SFF8636_EXT_MOD_INFINIBAND_SDR (1 << 0) + +/* Vendor OUI - 165-167 */ +#define SFF8636_VENDOR_OUI_OFFSET 0xA5 +#define SFF8636_VENDOR_OUI_LEN 3 + +/* Vendor OUI - 165-167 */ +#define SFF8636_VENDOR_PN_START_OFFSET 0xA8 +#define SFF8636_VENDOR_PN_END_OFFSET 0xB7 + +/* Vendor Revision - 184-185 */ +#define SFF8636_VENDOR_REV_START_OFFSET 0xB8 +#define SFF8636_VENDOR_REV_END_OFFSET 0xB9 + +/* Wavelength - 186-187 */ +#define SFF8636_WAVELEN_HIGH_BYTE_OFFSET 0xBA +#define SFF8636_WAVELEN_LOW_BYTE_OFFSET 0xBB + +/* Wavelength Tolerance- 188-189 */ +#define SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET 0xBC +#define SFF8636_WAVE_TOL_LOW_BYTE_OFFSET 0xBD + +/* Max case temp - Other than 70 C - 190 */ +#define SFF8636_MAXCASE_TEMP_OFFSET 0xBE + +/* CC_BASE - 191 */ +#define SFF8636_CC_BASE_OFFSET 0xBF + +/* Option Values - 192-195 */ +#define SFF8636_OPTION_1_OFFSET 0xC0 +#define SFF8636_ETHERNET_UNSPECIFIED 0x00 +#define SFF8636_ETHERNET_100G_AOC 0x01 +#define SFF8636_ETHERNET_100G_SR4 0x02 +#define SFF8636_ETHERNET_100G_LR4 0x03 +#define SFF8636_ETHERNET_100G_ER4 0x04 +#define SFF8636_ETHERNET_100G_SR10 0x05 +#define SFF8636_ETHERNET_100G_CWDM4_FEC 0x06 +#define SFF8636_ETHERNET_100G_PSM4 0x07 +#define SFF8636_ETHERNET_100G_ACC 0x08 +#define SFF8636_ETHERNET_100G_CWDM4_NO_FEC 0x09 +#define SFF8636_ETHERNET_100G_RSVD1 0x0A +#define SFF8636_ETHERNET_100G_CR4 0x0B +#define SFF8636_ETHERNET_25G_CR_CA_S 0x0C +#define SFF8636_ETHERNET_25G_CR_CA_N 0x0D +#define SFF8636_ETHERNET_40G_ER4 0x10 +#define SFF8636_ETHERNET_4X10_SR 0x11 +#define SFF8636_ETHERNET_40G_PSM4 0x12 +#define SFF8636_ETHERNET_G959_P1I1_2D1 0x13 +#define SFF8636_ETHERNET_G959_P1S1_2D2 0x14 +#define SFF8636_ETHERNET_G959_P1L1_2D2 0x15 +#define SFF8636_ETHERNET_10GT_SFI 0x16 +#define SFF8636_ETHERNET_100G_CLR4 0x17 +#define SFF8636_ETHERNET_100G_AOC2 0x18 +#define SFF8636_ETHERNET_100G_ACC2 0x19 + +#define SFF8636_ETHERNET_100GE_DWDM2 0x1A +#define SFF8636_ETHERNET_100G_1550NM_WDM 0x1B +#define SFF8636_ETHERNET_10G_BASET_SR 0x1C +#define SFF8636_ETHERNET_5G_BASET 0x1D +#define SFF8636_ETHERNET_2HALFG_BASET 0x1E +#define SFF8636_ETHERNET_40G_SWDM4 0x1F +#define SFF8636_ETHERNET_100G_SWDM4 0x20 +#define SFF8636_ETHERNET_100G_PAM4_BIDI 0x21 +#define SFF8636_ETHERNET_4WDM10_MSA 0x22 +#define SFF8636_ETHERNET_4WDM20_MSA 0x23 +#define SFF8636_ETHERNET_4WDM40_MSA 0x24 +#define SFF8636_ETHERNET_100G_DR 0x25 +#define SFF8636_ETHERNET_100G_FR_NOFEC 0x26 +#define SFF8636_ETHERNET_100G_LR_NOFEC 0x27 +/* 28h-2Fh reserved */ +#define SFF8636_ETHERNET_200G_ACC1 0x30 +#define SFF8636_ETHERNET_200G_AOC1 0x31 +#define SFF8636_ETHERNET_200G_ACC2 0x32 +#define SFF8636_ETHERNET_200G_A0C2 0x33 +/* 34h-3Fh reserved */ +#define SFF8636_ETHERNET_200G_CR4 0x40 +#define SFF8636_ETHERNET_200G_SR4 0x41 +#define SFF8636_ETHERNET_200G_DR4 0x42 +#define SFF8636_ETHERNET_200G_FR4 0x43 +#define SFF8636_ETHERNET_200G_PSM4 0x44 +#define SFF8636_ETHERNET_50G_LR 0x45 +#define SFF8636_ETHERNET_200G_LR4 0x46 +/* 47h-4Fh reserved */ +#define SFF8636_ETHERNET_64G_EA 0x50 +#define SFF8636_ETHERNET_64G_SW 0x51 +#define SFF8636_ETHERNET_64G_LW 0x52 +#define SFF8636_ETHERNET_128FC_EA 0x53 +#define SFF8636_ETHERNET_128FC_SW 0x54 +#define SFF8636_ETHERNET_128FC_LW 0x55 +/* 56h-5Fh reserved */ + +#define SFF8636_OPTION_2_OFFSET 0xC1 +/* Rx output amplitude */ +#define SFF8636_O2_RX_OUTPUT_AMP (1 << 0) +#define SFF8636_OPTION_3_OFFSET 0xC2 +/* Rx Squelch Disable */ +#define SFF8636_O3_RX_SQL_DSBL (1 << 3) +/* Rx Output Disable capable */ +#define SFF8636_O3_RX_OUTPUT_DSBL (1 << 2) +/* Tx Squelch Disable */ +#define SFF8636_O3_TX_SQL_DSBL (1 << 1) +/* Tx Squelch Impl */ +#define SFF8636_O3_TX_SQL_IMPL (1 << 0) +#define SFF8636_OPTION_4_OFFSET 0xC3 +/* Memory Page 02 present */ +#define SFF8636_O4_PAGE_02_PRESENT (1 << 7) +/* Memory Page 01 present */ +#define SFF8636_O4_PAGE_01_PRESENT (1 << 6) +/* Rate Select implemented */ +#define SFF8636_O4_RATE_SELECT (1 << 5) +/* Tx_DISABLE implemented */ +#define SFF8636_O4_TX_DISABLE (1 << 4) +/* Tx_FAULT implemented */ +#define SFF8636_O4_TX_FAULT (1 << 3) +/* Tx Squelch implemented */ +#define SFF8636_O4_TX_SQUELCH (1 << 2) +/* Tx Loss of Signal */ +#define SFF8636_O4_TX_LOS (1 << 1) + +/* Vendor SN - 196-211 */ +#define SFF8636_VENDOR_SN_START_OFFSET 0xC4 +#define SFF8636_VENDOR_SN_END_OFFSET 0xD3 + +/* Vendor Date - 212-219 */ +#define SFF8636_DATE_YEAR_OFFSET 0xD4 +#define SFF8636_DATE_YEAR_LEN 2 +#define SFF8636_DATE_MONTH_OFFSET 0xD6 +#define SFF8636_DATE_MONTH_LEN 2 +#define SFF8636_DATE_DAY_OFFSET 0xD8 +#define SFF8636_DATE_DAY_LEN 2 +#define SFF8636_DATE_VENDOR_LOT_OFFSET 0xDA +#define SFF8636_DATE_VENDOR_LOT_LEN 2 + +/* Diagnostic Monitoring Type - 220 */ +#define SFF8636_DIAG_TYPE_OFFSET 0xDC +#define SFF8636_RX_PWR_TYPE_MASK 0x8 +#define SFF8636_RX_PWR_TYPE_AVG_PWR (1 << 3) +#define SFF8636_RX_PWR_TYPE_OMA (0 << 3) +#define SFF8636_TX_PWR_TYPE_MASK 0x4 +#define SFF8636_TX_PWR_TYPE_AVG_PWR (1 << 2) + +/* Enhanced Options - 221 */ +#define SFF8636_ENH_OPTIONS_OFFSET 0xDD +#define SFF8636_RATE_SELECT_EXT_SUPPORT (1 << 3) +#define SFF8636_RATE_SELECT_APP_TABLE_SUPPORT (1 << 2) + +/* Check code - 223 */ +#define SFF8636_CC_EXT_OFFSET 0xDF +#define SFF8636_CC_EXT_LEN 1 + +/*------------------------------------------------------------------------------ + * + * Upper Memory Page 03h + * Contains module thresholds, channel thresholds and masks, + * and optional channel controls + * + * Offset - Page Num(3) * PageSize(0x80) + Page offset + */ + +/* 3 * 128 + Lower page 00h(128) */ +#define SFF8636_PAGE03H_OFFSET (128 * 4) + +/* Module Thresholds (48 Bytes) 128-175 */ +/* MSB at low address, LSB at high address */ +#define SFF8636_TEMP_HALRM 0x80 +#define SFF8636_TEMP_LALRM 0x82 +#define SFF8636_TEMP_HWARN 0x84 +#define SFF8636_TEMP_LWARN 0x86 + +#define SFF8636_VCC_HALRM 0x90 +#define SFF8636_VCC_LALRM 0x92 +#define SFF8636_VCC_HWARN 0x94 +#define SFF8636_VCC_LWARN 0x96 + +#define SFF8636_RX_PWR_HALRM 0xB0 +#define SFF8636_RX_PWR_LALRM 0xB2 +#define SFF8636_RX_PWR_HWARN 0xB4 +#define SFF8636_RX_PWR_LWARN 0xB6 + +#define SFF8636_TX_BIAS_HALRM 0xB8 +#define SFF8636_TX_BIAS_LALRM 0xBA +#define SFF8636_TX_BIAS_HWARN 0xBC +#define SFF8636_TX_BIAS_LWARN 0xBE + +#define SFF8636_TX_PWR_HALRM 0xC0 +#define SFF8636_TX_PWR_LALRM 0xC2 +#define SFF8636_TX_PWR_HWARN 0xC4 +#define SFF8636_TX_PWR_LWARN 0xC6 + +#define ETH_MODULE_SFF_8636_MAX_LEN 640 +#define ETH_MODULE_SFF_8436_MAX_LEN 640 + +#endif /* QSFP_H__ */ diff --git a/realtek.c b/realtek.c new file mode 100644 index 0000000..ee0c611 --- /dev/null +++ b/realtek.c @@ -0,0 +1,689 @@ +/* Copyright 2001 Sun Microsystems (thockin@sun.com) */ +#include +#include +#include "internal.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +enum chip_type { + RTL8139 = 1, + RTL8139_K, + RTL8139A, + RTL8139A_G, + RTL8139B, + RTL8130, + RTL8139C, + RTL8100, + RTL8100B_8139D, + RTL8139Cp, + RTL8101, + + /* chips not handled by 8139too/8139cp module */ + RTL_GIGA_MAC_VER_01, + RTL_GIGA_MAC_VER_02, + RTL_GIGA_MAC_VER_03, + RTL_GIGA_MAC_VER_04, + RTL_GIGA_MAC_VER_05, + RTL_GIGA_MAC_VER_06, + RTL_GIGA_MAC_VER_07, + RTL_GIGA_MAC_VER_08, + RTL_GIGA_MAC_VER_09, + RTL_GIGA_MAC_VER_10, + RTL_GIGA_MAC_VER_11, + RTL_GIGA_MAC_VER_12, + RTL_GIGA_MAC_VER_13, + RTL_GIGA_MAC_VER_14, + RTL_GIGA_MAC_VER_15, + RTL_GIGA_MAC_VER_16, + RTL_GIGA_MAC_VER_17, + RTL_GIGA_MAC_VER_18, + RTL_GIGA_MAC_VER_19, + RTL_GIGA_MAC_VER_20, + RTL_GIGA_MAC_VER_21, + RTL_GIGA_MAC_VER_22, + RTL_GIGA_MAC_VER_23, + RTL_GIGA_MAC_VER_24, + RTL_GIGA_MAC_VER_25, + RTL_GIGA_MAC_VER_26, + RTL_GIGA_MAC_VER_27, + RTL_GIGA_MAC_VER_28, + RTL_GIGA_MAC_VER_29, + RTL_GIGA_MAC_VER_30, + RTL_GIGA_MAC_VER_31, + RTL_GIGA_MAC_VER_32, + RTL_GIGA_MAC_VER_33, + RTL_GIGA_MAC_VER_34, + RTL_GIGA_MAC_VER_35, + RTL_GIGA_MAC_VER_36, + RTL_GIGA_MAC_VER_37, + RTL_GIGA_MAC_VER_38, + RTL_GIGA_MAC_VER_39, + RTL_GIGA_MAC_VER_40, + RTL_GIGA_MAC_VER_41, + RTL_GIGA_MAC_VER_42, + RTL_GIGA_MAC_VER_43, + RTL_GIGA_MAC_VER_44, +}; + +static const char * const chip_names[] = { + [RTL8139] = "8139", + [RTL8139_K] = "8139-K", + [RTL8139A] = "8139A", + [RTL8139A_G] = "8139A-G", + [RTL8139B] = "8139B", + [RTL8130] = "8130", + [RTL8139C] = "8139C", + [RTL8100] = "8100", + [RTL8100B_8139D] = "8100B/8139D", + [RTL8139Cp] = "8139C+", + [RTL8101] = "8101", + + /* chips not handled by 8139too/8139cp module */ + [RTL_GIGA_MAC_VER_01] = "8169", + [RTL_GIGA_MAC_VER_02] = "8169s", + [RTL_GIGA_MAC_VER_03] = "8110s", + [RTL_GIGA_MAC_VER_04] = "8169sb/8110sb", + [RTL_GIGA_MAC_VER_05] = "8169sc/8110sc", + [RTL_GIGA_MAC_VER_06] = "8169sc/8110sc", + [RTL_GIGA_MAC_VER_07] = "8102e", + [RTL_GIGA_MAC_VER_08] = "8102e", + [RTL_GIGA_MAC_VER_09] = "8102e", + [RTL_GIGA_MAC_VER_10] = "8101e", + [RTL_GIGA_MAC_VER_11] = "8168b/8111b", + [RTL_GIGA_MAC_VER_12] = "8168b/8111b", + [RTL_GIGA_MAC_VER_13] = "8101e", + [RTL_GIGA_MAC_VER_14] = "8100e", + [RTL_GIGA_MAC_VER_15] = "8100e", + [RTL_GIGA_MAC_VER_16] = "8101e", + [RTL_GIGA_MAC_VER_17] = "8168b/8111b", + [RTL_GIGA_MAC_VER_18] = "8168cp/8111cp", + [RTL_GIGA_MAC_VER_19] = "8168c/8111c", + [RTL_GIGA_MAC_VER_20] = "8168c/8111c", + [RTL_GIGA_MAC_VER_21] = "8168c/8111c", + [RTL_GIGA_MAC_VER_22] = "8168c/8111c", + [RTL_GIGA_MAC_VER_23] = "8168cp/8111cp", + [RTL_GIGA_MAC_VER_24] = "8168cp/8111cp", + [RTL_GIGA_MAC_VER_25] = "8168d/8111d", + [RTL_GIGA_MAC_VER_26] = "8168d/8111d", + [RTL_GIGA_MAC_VER_27] = "8168dp/8111dp", + [RTL_GIGA_MAC_VER_28] = "8168dp/8111dp", + [RTL_GIGA_MAC_VER_29] = "8105e", + [RTL_GIGA_MAC_VER_30] = "8105e", + [RTL_GIGA_MAC_VER_31] = "8168dp/8111dp", + [RTL_GIGA_MAC_VER_32] = "8168e/8111e", + [RTL_GIGA_MAC_VER_33] = "8168e/8111e", + [RTL_GIGA_MAC_VER_34] = "8168evl/8111evl", + [RTL_GIGA_MAC_VER_35] = "8168f/8111f", + [RTL_GIGA_MAC_VER_36] = "8168f/8111f", + [RTL_GIGA_MAC_VER_37] = "8402", + [RTL_GIGA_MAC_VER_38] = "8411", + [RTL_GIGA_MAC_VER_39] = "8106e", + [RTL_GIGA_MAC_VER_40] = "8168g/8111g", + [RTL_GIGA_MAC_VER_41] = "8168g/8111g", + [RTL_GIGA_MAC_VER_42] = "8168g/8111g", + [RTL_GIGA_MAC_VER_43] = "8106e", + [RTL_GIGA_MAC_VER_44] = "8411", +}; + +static struct chip_info { + u32 id_mask; + u32 id_val; + int mac_version; +} rtl_info_tbl[] = { + { 0xfcc00000, 0x40000000, RTL8139 }, + { 0xfcc00000, 0x60000000, RTL8139_K }, + { 0xfcc00000, 0x70000000, RTL8139A }, + { 0xfcc00000, 0x70800000, RTL8139A_G }, + { 0xfcc00000, 0x78000000, RTL8139B }, + { 0xfcc00000, 0x7c000000, RTL8130 }, + { 0xfcc00000, 0x74000000, RTL8139C }, + { 0xfcc00000, 0x78800000, RTL8100 }, + { 0xfcc00000, 0x74400000, RTL8100B_8139D }, + { 0xfcc00000, 0x74800000, RTL8139Cp }, + { 0xfcc00000, 0x74c00000, RTL8101 }, + + /* chips not handled by 8139too/8139cp module */ + /* 8168G family. */ + { 0x7cf00000, 0x5c800000, RTL_GIGA_MAC_VER_44 }, + { 0x7cf00000, 0x50900000, RTL_GIGA_MAC_VER_42 }, + { 0x7cf00000, 0x4c100000, RTL_GIGA_MAC_VER_41 }, + { 0x7cf00000, 0x4c000000, RTL_GIGA_MAC_VER_40 }, + + /* 8168F family. */ + { 0x7c800000, 0x48800000, RTL_GIGA_MAC_VER_38 }, + { 0x7cf00000, 0x48100000, RTL_GIGA_MAC_VER_36 }, + { 0x7cf00000, 0x48000000, RTL_GIGA_MAC_VER_35 }, + + /* 8168E family. */ + { 0x7c800000, 0x2c800000, RTL_GIGA_MAC_VER_34 }, + { 0x7cf00000, 0x2c200000, RTL_GIGA_MAC_VER_33 }, + { 0x7cf00000, 0x2c100000, RTL_GIGA_MAC_VER_32 }, + { 0x7c800000, 0x2c000000, RTL_GIGA_MAC_VER_33 }, + + /* 8168D family. */ + { 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 }, + { 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 }, + { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 }, + + /* 8168DP family. */ + { 0x7cf00000, 0x28800000, RTL_GIGA_MAC_VER_27 }, + { 0x7cf00000, 0x28a00000, RTL_GIGA_MAC_VER_28 }, + { 0x7cf00000, 0x28b00000, RTL_GIGA_MAC_VER_31 }, + + /* 8168C family. */ + { 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 }, + { 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 }, + { 0x7cf00000, 0x3c800000, RTL_GIGA_MAC_VER_18 }, + { 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_24 }, + { 0x7cf00000, 0x3c000000, RTL_GIGA_MAC_VER_19 }, + { 0x7cf00000, 0x3c200000, RTL_GIGA_MAC_VER_20 }, + { 0x7cf00000, 0x3c300000, RTL_GIGA_MAC_VER_21 }, + { 0x7cf00000, 0x3c400000, RTL_GIGA_MAC_VER_22 }, + { 0x7c800000, 0x3c000000, RTL_GIGA_MAC_VER_22 }, + + /* 8168B family. */ + { 0x7cf00000, 0x38000000, RTL_GIGA_MAC_VER_12 }, + { 0x7cf00000, 0x38500000, RTL_GIGA_MAC_VER_17 }, + { 0x7c800000, 0x38000000, RTL_GIGA_MAC_VER_17 }, + { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, + + /* 8101 family. */ + { 0x7cf00000, 0x44900000, RTL_GIGA_MAC_VER_39 }, + { 0x7c800000, 0x44800000, RTL_GIGA_MAC_VER_39 }, + { 0x7c800000, 0x44000000, RTL_GIGA_MAC_VER_37 }, + { 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 }, + { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 }, + { 0x7cf00000, 0x40900000, RTL_GIGA_MAC_VER_29 }, + { 0x7c800000, 0x40800000, RTL_GIGA_MAC_VER_30 }, + { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 }, + { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 }, + { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 }, + { 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 }, + { 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 }, + { 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 }, + { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 }, + { 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 }, + { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 }, + { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 }, + { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 }, + { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 }, + /* FIXME: where did these entries come from ? -- FR */ + { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 }, + { 0xfc800000, 0x30800000, RTL_GIGA_MAC_VER_14 }, + + /* 8110 family. */ + { 0xfc800000, 0x98000000, RTL_GIGA_MAC_VER_06 }, + { 0xfc800000, 0x18000000, RTL_GIGA_MAC_VER_05 }, + { 0xfc800000, 0x10000000, RTL_GIGA_MAC_VER_04 }, + { 0xfc800000, 0x04000000, RTL_GIGA_MAC_VER_03 }, + { 0xfc800000, 0x00800000, RTL_GIGA_MAC_VER_02 }, + { 0xfc800000, 0x00000000, RTL_GIGA_MAC_VER_01 }, + + { } +}; + +static void +print_intr_bits(u16 mask) +{ + fprintf(stdout, + " %s%s%s%s%s%s%s%s%s%s%s\n", + mask & (1 << 15) ? "SERR " : "", + mask & (1 << 14) ? "TimeOut " : "", + mask & (1 << 8) ? "SWInt " : "", + mask & (1 << 7) ? "TxNoBuf " : "", + mask & (1 << 6) ? "RxFIFO " : "", + mask & (1 << 5) ? "LinkChg " : "", + mask & (1 << 4) ? "RxNoBuf " : "", + mask & (1 << 3) ? "TxErr " : "", + mask & (1 << 2) ? "TxOK " : "", + mask & (1 << 1) ? "RxErr " : "", + mask & (1 << 0) ? "RxOK " : ""); +} + +int +realtek_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *data = (u32 *) regs->data; + u8 *data8 = (u8 *) regs->data; + u32 v; + struct chip_info *ci; + unsigned int board_type; + + v = data[0x40 >> 2]; /* TxConfig */ + + ci = &rtl_info_tbl[0]; + while (ci->mac_version) { + if ((v & ci->id_mask) == ci->id_val) + break; + ci++; + } + board_type = ci->mac_version; + if (!board_type) { + fprintf(stderr, "Unknown RealTek chip (TxConfig: 0x%08x)\n", v); + return 91; + } + + fprintf(stdout, + "RealTek RTL%s registers:\n" + "--------------------------------------------------------\n", + chip_names[board_type]); + + fprintf(stdout, + "0x00: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", + data8[0x00], + data8[0x01], + data8[0x02], + data8[0x03], + data8[0x04], + data8[0x05]); + + fprintf(stdout, + "0x08: Multicast Address Filter 0x%08x 0x%08x\n", + data[0x08 >> 2], + data[0x0c >> 2]); + + if (board_type == RTL8139Cp || board_type >= RTL_GIGA_MAC_VER_01) { + fprintf(stdout, + "0x10: Dump Tally Counter Command 0x%08x 0x%08x\n", + data[0x10 >> 2], + data[0x14 >> 2]); + + fprintf(stdout, + "0x20: Tx Normal Priority Ring Addr 0x%08x 0x%08x\n", + data[0x20 >> 2], + data[0x24 >> 2]); + + fprintf(stdout, + "0x28: Tx High Priority Ring Addr 0x%08x 0x%08x\n", + data[0x28 >> 2], + data[0x2C >> 2]); + } else { + fprintf(stdout, + "0x10: Transmit Status Desc 0 0x%08x\n" + "0x14: Transmit Status Desc 1 0x%08x\n" + "0x18: Transmit Status Desc 2 0x%08x\n" + "0x1C: Transmit Status Desc 3 0x%08x\n", + data[0x10 >> 2], + data[0x14 >> 2], + data[0x18 >> 2], + data[0x1C >> 2]); + fprintf(stdout, + "0x20: Transmit Start Addr 0 0x%08x\n" + "0x24: Transmit Start Addr 1 0x%08x\n" + "0x28: Transmit Start Addr 2 0x%08x\n" + "0x2C: Transmit Start Addr 3 0x%08x\n", + data[0x20 >> 2], + data[0x24 >> 2], + data[0x28 >> 2], + data[0x2C >> 2]); + } + + if (board_type < RTL_GIGA_MAC_VER_11 || + board_type > RTL_GIGA_MAC_VER_17) { + if (board_type >= RTL_GIGA_MAC_VER_01) { + fprintf(stdout, + "0x30: Flash memory read/write 0x%08x\n", + data[0x30 >> 2]); + } else { + fprintf(stdout, + "0x30: Rx buffer addr (C mode) 0x%08x\n", + data[0x30 >> 2]); + } + } + + v = data8[0x36]; + fprintf(stdout, + "0x34: Early Rx Byte Count %8u\n" + "0x36: Early Rx Status 0x%02x\n", + data[0x34 >> 2] & 0xffff, + v); + + if (v & 0xf) { + fprintf(stdout, + " %s%s%s%s\n", + v & (1 << 3) ? "ERxGood " : "", + v & (1 << 2) ? "ERxBad " : "", + v & (1 << 1) ? "ERxOverWrite " : "", + v & (1 << 0) ? "ERxOK " : ""); + } + + v = data8[0x37]; + fprintf(stdout, + "0x37: Command 0x%02x\n" + " Rx %s, Tx %s%s\n", + data8[0x37], + v & (1 << 3) ? "on" : "off", + v & (1 << 2) ? "on" : "off", + v & (1 << 4) ? ", RESET" : ""); + + if (board_type < RTL_GIGA_MAC_VER_01) { + fprintf(stdout, + "0x38: Current Address of Packet Read (C mode) 0x%04x\n" + "0x3A: Current Rx buffer address (C mode) 0x%04x\n", + data[0x38 >> 2] & 0xffff, + data[0x38 >> 2] >> 16); + } + + fprintf(stdout, + "0x3C: Interrupt Mask 0x%04x\n", + data[0x3c >> 2] & 0xffff); + print_intr_bits(data[0x3c >> 2] & 0xffff); + fprintf(stdout, + "0x3E: Interrupt Status 0x%04x\n", + data[0x3c >> 2] >> 16); + print_intr_bits(data[0x3c >> 2] >> 16); + + fprintf(stdout, + "0x40: Tx Configuration 0x%08x\n" + "0x44: Rx Configuration 0x%08x\n" + "0x48: Timer count 0x%08x\n" + "0x4C: Missed packet counter 0x%06x\n", + data[0x40 >> 2], + data[0x44 >> 2], + data[0x48 >> 2], + data[0x4C >> 2] & 0xffffff); + + fprintf(stdout, + "0x50: EEPROM Command 0x%02x\n" + "0x51: Config 0 0x%02x\n" + "0x52: Config 1 0x%02x\n", + data8[0x50], + data8[0x51], + data8[0x52]); + + if (board_type >= RTL_GIGA_MAC_VER_01) { + fprintf(stdout, + "0x53: Config 2 0x%02x\n" + "0x54: Config 3 0x%02x\n" + "0x55: Config 4 0x%02x\n" + "0x56: Config 5 0x%02x\n", + data8[0x53], + data8[0x54], + data8[0x55], + data8[0x56]); + fprintf(stdout, + "0x58: Timer interrupt 0x%08x\n", + data[0x58 >> 2]); + } + else { + if (board_type >= RTL8139A) { + fprintf(stdout, + "0x54: Timer interrupt 0x%08x\n", + data[0x54 >> 2]); + } + fprintf(stdout, + "0x58: Media status 0x%02x\n", + data8[0x58]); + if (board_type >= RTL8139A) { + fprintf(stdout, + "0x59: Config 3 0x%02x\n", + data8[0x59]); + } + if (board_type >= RTL8139B) { + fprintf(stdout, + "0x5A: Config 4 0x%02x\n", + data8[0x5A]); + } + } + + fprintf(stdout, + "0x5C: Multiple Interrupt Select 0x%04x\n", + data[0x5c >> 2] & 0xffff); + + if (board_type >= RTL_GIGA_MAC_VER_01) { + fprintf(stdout, + "0x60: PHY access 0x%08x\n", + data[0x60 >> 2]); + + if (board_type < RTL_GIGA_MAC_VER_11 || + board_type > RTL_GIGA_MAC_VER_17) { + fprintf(stdout, + "0x64: TBI control and status 0x%08x\n", + data[0x64 >> 2]); + fprintf(stdout, + "0x68: TBI Autonegotiation advertisement (ANAR) 0x%04x\n" + "0x6A: TBI Link partner ability (LPAR) 0x%04x\n", + data[0x68 >> 2] & 0xffff, + data[0x68 >> 2] >> 16); + } + + fprintf(stdout, + "0x6C: PHY status 0x%02x\n", + data8[0x6C]); + + fprintf(stdout, + "0x84: PM wakeup frame 0 0x%08x 0x%08x\n" + "0x8C: PM wakeup frame 1 0x%08x 0x%08x\n", + data[0x84 >> 2], + data[0x88 >> 2], + data[0x8C >> 2], + data[0x90 >> 2]); + + fprintf(stdout, + "0x94: PM wakeup frame 2 (low) 0x%08x 0x%08x\n" + "0x9C: PM wakeup frame 2 (high) 0x%08x 0x%08x\n", + data[0x94 >> 2], + data[0x98 >> 2], + data[0x9C >> 2], + data[0xA0 >> 2]); + + fprintf(stdout, + "0xA4: PM wakeup frame 3 (low) 0x%08x 0x%08x\n" + "0xAC: PM wakeup frame 3 (high) 0x%08x 0x%08x\n", + data[0xA4 >> 2], + data[0xA8 >> 2], + data[0xAC >> 2], + data[0xB0 >> 2]); + + fprintf(stdout, + "0xB4: PM wakeup frame 4 (low) 0x%08x 0x%08x\n" + "0xBC: PM wakeup frame 4 (high) 0x%08x 0x%08x\n", + data[0xB4 >> 2], + data[0xB8 >> 2], + data[0xBC >> 2], + data[0xC0 >> 2]); + + fprintf(stdout, + "0xC4: Wakeup frame 0 CRC 0x%04x\n" + "0xC6: Wakeup frame 1 CRC 0x%04x\n" + "0xC8: Wakeup frame 2 CRC 0x%04x\n" + "0xCA: Wakeup frame 3 CRC 0x%04x\n" + "0xCC: Wakeup frame 4 CRC 0x%04x\n", + data[0xC4 >> 2] & 0xffff, + data[0xC4 >> 2] >> 16, + data[0xC8 >> 2] & 0xffff, + data[0xC8 >> 2] >> 16, + data[0xCC >> 2] & 0xffff); + fprintf(stdout, + "0xDA: RX packet maximum size 0x%04x\n", + data[0xD8 >> 2] >> 16); + } + else { + fprintf(stdout, + "0x5E: PCI revision id 0x%02x\n", + data8[0x5e]); + fprintf(stdout, + "0x60: Transmit Status of All Desc (C mode) 0x%04x\n" + "0x62: MII Basic Mode Control Register 0x%04x\n", + data[0x60 >> 2] & 0xffff, + data[0x60 >> 2] >> 16); + fprintf(stdout, + "0x64: MII Basic Mode Status Register 0x%04x\n" + "0x66: MII Autonegotiation Advertising 0x%04x\n", + data[0x64 >> 2] & 0xffff, + data[0x64 >> 2] >> 16); + fprintf(stdout, + "0x68: MII Link Partner Ability 0x%04x\n" + "0x6A: MII Expansion 0x%04x\n", + data[0x68 >> 2] & 0xffff, + data[0x68 >> 2] >> 16); + fprintf(stdout, + "0x6C: MII Disconnect counter 0x%04x\n" + "0x6E: MII False carrier sense counter 0x%04x\n", + data[0x6C >> 2] & 0xffff, + data[0x6C >> 2] >> 16); + fprintf(stdout, + "0x70: MII Nway test 0x%04x\n" + "0x72: MII RX_ER counter 0x%04x\n", + data[0x70 >> 2] & 0xffff, + data[0x70 >> 2] >> 16); + fprintf(stdout, + "0x74: MII CS configuration 0x%04x\n", + data[0x74 >> 2] & 0xffff); + if (board_type >= RTL8139_K) { + fprintf(stdout, + "0x78: PHY parameter 1 0x%08x\n" + "0x7C: Twister parameter 0x%08x\n", + data[0x78 >> 2], + data[0x7C >> 2]); + if (board_type >= RTL8139A) { + fprintf(stdout, + "0x80: PHY parameter 2 0x%02x\n", + data8[0x80]); + } + } + if (board_type == RTL8139Cp) { + fprintf(stdout, + "0x82: Low addr of a Tx Desc w/ Tx DMA OK 0x%04x\n", + data[0x80 >> 2] >> 16); + } else if (board_type == RTL8130) { + fprintf(stdout, + "0x82: MII register 0x%02x\n", + data8[0x82]); + } + if (board_type >= RTL8139A) { + fprintf(stdout, + "0x84: PM CRC for wakeup frame 0 0x%02x\n" + "0x85: PM CRC for wakeup frame 1 0x%02x\n" + "0x86: PM CRC for wakeup frame 2 0x%02x\n" + "0x87: PM CRC for wakeup frame 3 0x%02x\n" + "0x88: PM CRC for wakeup frame 4 0x%02x\n" + "0x89: PM CRC for wakeup frame 5 0x%02x\n" + "0x8A: PM CRC for wakeup frame 6 0x%02x\n" + "0x8B: PM CRC for wakeup frame 7 0x%02x\n", + data8[0x84], + data8[0x85], + data8[0x86], + data8[0x87], + data8[0x88], + data8[0x89], + data8[0x8A], + data8[0x8B]); + fprintf(stdout, + "0x8C: PM wakeup frame 0 0x%08x 0x%08x\n" + "0x94: PM wakeup frame 1 0x%08x 0x%08x\n" + "0x9C: PM wakeup frame 2 0x%08x 0x%08x\n" + "0xA4: PM wakeup frame 3 0x%08x 0x%08x\n" + "0xAC: PM wakeup frame 4 0x%08x 0x%08x\n" + "0xB4: PM wakeup frame 5 0x%08x 0x%08x\n" + "0xBC: PM wakeup frame 6 0x%08x 0x%08x\n" + "0xC4: PM wakeup frame 7 0x%08x 0x%08x\n", + data[0x8C >> 2], + data[0x90 >> 2], + data[0x94 >> 2], + data[0x98 >> 2], + data[0x9C >> 2], + data[0xA0 >> 2], + data[0xA4 >> 2], + data[0xA8 >> 2], + data[0xAC >> 2], + data[0xB0 >> 2], + data[0xB4 >> 2], + data[0xB8 >> 2], + data[0xBC >> 2], + data[0xC0 >> 2], + data[0xC4 >> 2], + data[0xC8 >> 2]); + fprintf(stdout, + "0xCC: PM LSB CRC for wakeup frame 0 0x%02x\n" + "0xCD: PM LSB CRC for wakeup frame 1 0x%02x\n" + "0xCE: PM LSB CRC for wakeup frame 2 0x%02x\n" + "0xCF: PM LSB CRC for wakeup frame 3 0x%02x\n" + "0xD0: PM LSB CRC for wakeup frame 4 0x%02x\n" + "0xD1: PM LSB CRC for wakeup frame 5 0x%02x\n" + "0xD2: PM LSB CRC for wakeup frame 6 0x%02x\n" + "0xD3: PM LSB CRC for wakeup frame 7 0x%02x\n", + data8[0xCC], + data8[0xCD], + data8[0xCE], + data8[0xCF], + data8[0xD0], + data8[0xD1], + data8[0xD2], + data8[0xD3]); + } + if (board_type >= RTL8139B) { + if (board_type != RTL8100 && board_type != RTL8100B_8139D && + board_type != RTL8101) + fprintf(stdout, + "0xD4: Flash memory read/write 0x%08x\n", + data[0xD4 >> 2]); + if (board_type != RTL8130) + fprintf(stdout, + "0xD8: Config 5 0x%02x\n", + data8[0xD8]); + } + } + + if (board_type == RTL8139Cp || board_type >= RTL_GIGA_MAC_VER_01) { + v = data[0xE0 >> 2] & 0xffff; + fprintf(stdout, + "0xE0: C+ Command 0x%04x\n", + v); + if (v & (1 << 9)) + fprintf(stdout, " Big-endian mode\n"); + if (v & (1 << 8)) + fprintf(stdout, " Home LAN enable\n"); + if (v & (1 << 6)) + fprintf(stdout, " VLAN de-tagging\n"); + if (v & (1 << 5)) + fprintf(stdout, " RX checksumming\n"); + if (v & (1 << 4)) + fprintf(stdout, " PCI 64-bit DAC\n"); + if (v & (1 << 3)) + fprintf(stdout, " PCI Multiple RW\n"); + + v = data[0xe0 >> 2] >> 16; + fprintf(stdout, + "0xE2: Interrupt Mitigation 0x%04x\n" + " TxTimer: %u\n" + " TxPackets: %u\n" + " RxTimer: %u\n" + " RxPackets: %u\n", + v, + v >> 12, + (v >> 8) & 0xf, + (v >> 4) & 0xf, + v & 0xf); + + fprintf(stdout, + "0xE4: Rx Ring Addr 0x%08x 0x%08x\n", + data[0xE4 >> 2], + data[0xE8 >> 2]); + + fprintf(stdout, + "0xEC: Early Tx threshold 0x%02x\n", + data8[0xEC]); + + if (board_type == RTL8139Cp) { + fprintf(stdout, + "0xFC: External MII register 0x%08x\n", + data[0xFC >> 2]); + } else if (board_type >= RTL_GIGA_MAC_VER_01 && + (board_type < RTL_GIGA_MAC_VER_11 || + board_type > RTL_GIGA_MAC_VER_17)) { + fprintf(stdout, + "0xF0: Func Event 0x%08x\n" + "0xF4: Func Event Mask 0x%08x\n" + "0xF8: Func Preset State 0x%08x\n" + "0xFC: Func Force Event 0x%08x\n", + data[0xF0 >> 2], + data[0xF4 >> 2], + data[0xF8 >> 2], + data[0xFC >> 2]); + } + } + + return 0; +} diff --git a/rxclass.c b/rxclass.c new file mode 100644 index 0000000..6cf81fd --- /dev/null +++ b/rxclass.c @@ -0,0 +1,1459 @@ +/* + * Copyright (C) 2008 Sun Microsystems, Inc. All rights reserved. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include "internal.h" + +static void invert_flow_mask(struct ethtool_rx_flow_spec *fsp) +{ + size_t i; + + for (i = 0; i < sizeof(fsp->m_u); i++) + fsp->m_u.hdata[i] ^= 0xFF; +} + +static void rxclass_print_ipv4_rule(__be32 sip, __be32 sipm, __be32 dip, + __be32 dipm, u8 tos, u8 tosm) +{ + char sip_str[INET_ADDRSTRLEN]; + char sipm_str[INET_ADDRSTRLEN]; + char dip_str[INET_ADDRSTRLEN]; + char dipm_str[INET_ADDRSTRLEN]; + + fprintf(stdout, + "\tSrc IP addr: %s mask: %s\n" + "\tDest IP addr: %s mask: %s\n" + "\tTOS: 0x%x mask: 0x%x\n", + inet_ntop(AF_INET, &sip, sip_str, INET_ADDRSTRLEN), + inet_ntop(AF_INET, &sipm, sipm_str, INET_ADDRSTRLEN), + inet_ntop(AF_INET, &dip, dip_str, INET_ADDRSTRLEN), + inet_ntop(AF_INET, &dipm, dipm_str, INET_ADDRSTRLEN), + tos, tosm); +} + +static void rxclass_print_ipv6_rule(__be32 *sip, __be32 *sipm, __be32 *dip, + __be32 *dipm, u8 tclass, u8 tclassm) +{ + char sip_str[INET6_ADDRSTRLEN]; + char sipm_str[INET6_ADDRSTRLEN]; + char dip_str[INET6_ADDRSTRLEN]; + char dipm_str[INET6_ADDRSTRLEN]; + + fprintf(stdout, + "\tSrc IP addr: %s mask: %s\n" + "\tDest IP addr: %s mask: %s\n" + "\tTraffic Class: 0x%x mask: 0x%x\n", + inet_ntop(AF_INET6, sip, sip_str, INET6_ADDRSTRLEN), + inet_ntop(AF_INET6, sipm, sipm_str, INET6_ADDRSTRLEN), + inet_ntop(AF_INET6, dip, dip_str, INET6_ADDRSTRLEN), + inet_ntop(AF_INET6, dipm, dipm_str, INET6_ADDRSTRLEN), + tclass, tclassm); +} + +static void rxclass_print_nfc_spec_ext(struct ethtool_rx_flow_spec *fsp) +{ + if (fsp->flow_type & FLOW_EXT) { + u64 data, datam; + __u16 etype, etypem, tci, tcim; + etype = ntohs(fsp->h_ext.vlan_etype); + etypem = ntohs(~fsp->m_ext.vlan_etype); + tci = ntohs(fsp->h_ext.vlan_tci); + tcim = ntohs(~fsp->m_ext.vlan_tci); + data = (u64)ntohl(fsp->h_ext.data[0]) << 32; + data |= (u64)ntohl(fsp->h_ext.data[1]); + datam = (u64)ntohl(~fsp->m_ext.data[0]) << 32; + datam |= (u64)ntohl(~fsp->m_ext.data[1]); + + fprintf(stdout, + "\tVLAN EtherType: 0x%x mask: 0x%x\n" + "\tVLAN: 0x%x mask: 0x%x\n" + "\tUser-defined: 0x%llx mask: 0x%llx\n", + etype, etypem, tci, tcim, data, datam); + } + + if (fsp->flow_type & FLOW_MAC_EXT) { + unsigned char *dmac, *dmacm; + + dmac = fsp->h_ext.h_dest; + dmacm = fsp->m_ext.h_dest; + + fprintf(stdout, + "\tDest MAC addr: %02X:%02X:%02X:%02X:%02X:%02X" + " mask: %02X:%02X:%02X:%02X:%02X:%02X\n", + dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], + dmac[5], dmacm[0], dmacm[1], dmacm[2], dmacm[3], + dmacm[4], dmacm[5]); + } +} + +static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp, + __u32 rss_context) +{ + unsigned char *smac, *smacm, *dmac, *dmacm; + __u32 flow_type; + + fprintf(stdout, "Filter: %d\n", fsp->location); + + flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS); + + invert_flow_mask(fsp); + + switch (flow_type) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + case SCTP_V4_FLOW: + if (flow_type == TCP_V4_FLOW) + fprintf(stdout, "\tRule Type: TCP over IPv4\n"); + else if (flow_type == UDP_V4_FLOW) + fprintf(stdout, "\tRule Type: UDP over IPv4\n"); + else + fprintf(stdout, "\tRule Type: SCTP over IPv4\n"); + rxclass_print_ipv4_rule(fsp->h_u.tcp_ip4_spec.ip4src, + fsp->m_u.tcp_ip4_spec.ip4src, + fsp->h_u.tcp_ip4_spec.ip4dst, + fsp->m_u.tcp_ip4_spec.ip4dst, + fsp->h_u.tcp_ip4_spec.tos, + fsp->m_u.tcp_ip4_spec.tos); + fprintf(stdout, + "\tSrc port: %d mask: 0x%x\n" + "\tDest port: %d mask: 0x%x\n", + ntohs(fsp->h_u.tcp_ip4_spec.psrc), + ntohs(fsp->m_u.tcp_ip4_spec.psrc), + ntohs(fsp->h_u.tcp_ip4_spec.pdst), + ntohs(fsp->m_u.tcp_ip4_spec.pdst)); + break; + case AH_V4_FLOW: + case ESP_V4_FLOW: + if (flow_type == AH_V4_FLOW) + fprintf(stdout, "\tRule Type: IPSEC AH over IPv4\n"); + else + fprintf(stdout, "\tRule Type: IPSEC ESP over IPv4\n"); + rxclass_print_ipv4_rule(fsp->h_u.ah_ip4_spec.ip4src, + fsp->m_u.ah_ip4_spec.ip4src, + fsp->h_u.ah_ip4_spec.ip4dst, + fsp->m_u.ah_ip4_spec.ip4dst, + fsp->h_u.ah_ip4_spec.tos, + fsp->m_u.ah_ip4_spec.tos); + fprintf(stdout, + "\tSPI: %d mask: 0x%x\n", + ntohl(fsp->h_u.esp_ip4_spec.spi), + ntohl(fsp->m_u.esp_ip4_spec.spi)); + break; + case IPV4_USER_FLOW: + fprintf(stdout, "\tRule Type: Raw IPv4\n"); + rxclass_print_ipv4_rule(fsp->h_u.usr_ip4_spec.ip4src, + fsp->m_u.usr_ip4_spec.ip4src, + fsp->h_u.usr_ip4_spec.ip4dst, + fsp->m_u.usr_ip4_spec.ip4dst, + fsp->h_u.usr_ip4_spec.tos, + fsp->m_u.usr_ip4_spec.tos); + fprintf(stdout, + "\tProtocol: %d mask: 0x%x\n" + "\tL4 bytes: 0x%x mask: 0x%x\n", + fsp->h_u.usr_ip4_spec.proto, + fsp->m_u.usr_ip4_spec.proto, + ntohl(fsp->h_u.usr_ip4_spec.l4_4_bytes), + ntohl(fsp->m_u.usr_ip4_spec.l4_4_bytes)); + break; + case TCP_V6_FLOW: + case UDP_V6_FLOW: + case SCTP_V6_FLOW: + if (flow_type == TCP_V6_FLOW) + fprintf(stdout, "\tRule Type: TCP over IPv6\n"); + else if (flow_type == UDP_V6_FLOW) + fprintf(stdout, "\tRule Type: UDP over IPv6\n"); + else + fprintf(stdout, "\tRule Type: SCTP over IPv6\n"); + rxclass_print_ipv6_rule(fsp->h_u.tcp_ip6_spec.ip6src, + fsp->m_u.tcp_ip6_spec.ip6src, + fsp->h_u.tcp_ip6_spec.ip6dst, + fsp->m_u.tcp_ip6_spec.ip6dst, + fsp->h_u.tcp_ip6_spec.tclass, + fsp->m_u.tcp_ip6_spec.tclass); + fprintf(stdout, + "\tSrc port: %d mask: 0x%x\n" + "\tDest port: %d mask: 0x%x\n", + ntohs(fsp->h_u.tcp_ip6_spec.psrc), + ntohs(fsp->m_u.tcp_ip6_spec.psrc), + ntohs(fsp->h_u.tcp_ip6_spec.pdst), + ntohs(fsp->m_u.tcp_ip6_spec.pdst)); + break; + case AH_V6_FLOW: + case ESP_V6_FLOW: + if (flow_type == AH_V6_FLOW) + fprintf(stdout, "\tRule Type: IPSEC AH over IPv6\n"); + else + fprintf(stdout, "\tRule Type: IPSEC ESP over IPv6\n"); + rxclass_print_ipv6_rule(fsp->h_u.ah_ip6_spec.ip6src, + fsp->m_u.ah_ip6_spec.ip6src, + fsp->h_u.ah_ip6_spec.ip6dst, + fsp->m_u.ah_ip6_spec.ip6dst, + fsp->h_u.ah_ip6_spec.tclass, + fsp->m_u.ah_ip6_spec.tclass); + fprintf(stdout, + "\tSPI: %d mask: 0x%x\n", + ntohl(fsp->h_u.esp_ip6_spec.spi), + ntohl(fsp->m_u.esp_ip6_spec.spi)); + break; + case IPV6_USER_FLOW: + fprintf(stdout, "\tRule Type: Raw IPv6\n"); + rxclass_print_ipv6_rule(fsp->h_u.usr_ip6_spec.ip6src, + fsp->m_u.usr_ip6_spec.ip6src, + fsp->h_u.usr_ip6_spec.ip6dst, + fsp->m_u.usr_ip6_spec.ip6dst, + fsp->h_u.usr_ip6_spec.tclass, + fsp->m_u.usr_ip6_spec.tclass); + fprintf(stdout, + "\tProtocol: %d mask: 0x%x\n" + "\tL4 bytes: 0x%x mask: 0x%x\n", + fsp->h_u.usr_ip6_spec.l4_proto, + fsp->m_u.usr_ip6_spec.l4_proto, + ntohl(fsp->h_u.usr_ip6_spec.l4_4_bytes), + ntohl(fsp->m_u.usr_ip6_spec.l4_4_bytes)); + break; + case ETHER_FLOW: + dmac = fsp->h_u.ether_spec.h_dest; + dmacm = fsp->m_u.ether_spec.h_dest; + smac = fsp->h_u.ether_spec.h_source; + smacm = fsp->m_u.ether_spec.h_source; + + fprintf(stdout, + "\tFlow Type: Raw Ethernet\n" + "\tSrc MAC addr: %02X:%02X:%02X:%02X:%02X:%02X" + " mask: %02X:%02X:%02X:%02X:%02X:%02X\n" + "\tDest MAC addr: %02X:%02X:%02X:%02X:%02X:%02X" + " mask: %02X:%02X:%02X:%02X:%02X:%02X\n" + "\tEthertype: 0x%X mask: 0x%X\n", + smac[0], smac[1], smac[2], smac[3], smac[4], smac[5], + smacm[0], smacm[1], smacm[2], smacm[3], smacm[4], + smacm[5], dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], + dmac[5], dmacm[0], dmacm[1], dmacm[2], dmacm[3], + dmacm[4], dmacm[5], + ntohs(fsp->h_u.ether_spec.h_proto), + ntohs(fsp->m_u.ether_spec.h_proto)); + break; + default: + fprintf(stdout, + "\tUnknown Flow type: %d\n", flow_type); + break; + } + + rxclass_print_nfc_spec_ext(fsp); + + if (fsp->flow_type & FLOW_RSS) + fprintf(stdout, "\tRSS Context ID: %u\n", rss_context); + + if (fsp->ring_cookie == RX_CLS_FLOW_DISC) { + fprintf(stdout, "\tAction: Drop\n"); + } else if (fsp->ring_cookie == RX_CLS_FLOW_WAKE) { + fprintf(stdout, "\tAction: Wake-on-LAN\n"); + } else { + u64 vf = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie); + u64 queue = ethtool_get_flow_spec_ring(fsp->ring_cookie); + + /* A value of zero indicates that this rule targeted the main + * function. A positive value indicates which virtual function + * was targeted, so we'll subtract 1 in order to show the + * correct VF index + */ + if (vf) + fprintf(stdout, "\tAction: Direct to VF %llu queue %llu\n", + vf - 1, queue); + else + fprintf(stdout, "\tAction: Direct to queue %llu\n", + queue); + } + + fprintf(stdout, "\n"); +} + +static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp, + __u32 rss_context) +{ + /* print the rule in this location */ + switch (fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS)) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + case SCTP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case TCP_V6_FLOW: + case UDP_V6_FLOW: + case SCTP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case IPV6_USER_FLOW: + case ETHER_FLOW: + rxclass_print_nfc_rule(fsp, rss_context); + break; + case IPV4_USER_FLOW: + if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4) + rxclass_print_nfc_rule(fsp, rss_context); + else /* IPv6 uses IPV6_USER_FLOW */ + fprintf(stderr, "IPV4_USER_FLOW with wrong ip_ver\n"); + break; + default: + fprintf(stderr, "rxclass: Unknown flow type\n"); + break; + } +} + +static int rxclass_get_dev_info(struct cmd_context *ctx, __u32 *count, + int *driver_select) +{ + struct ethtool_rxnfc nfccmd; + int err; + + nfccmd.cmd = ETHTOOL_GRXCLSRLCNT; + nfccmd.data = 0; + err = send_ioctl(ctx, &nfccmd); + *count = nfccmd.rule_cnt; + if (driver_select) + *driver_select = !!(nfccmd.data & RX_CLS_LOC_SPECIAL); + if (err < 0) + perror("rxclass: Cannot get RX class rule count"); + + return err; +} + +int rxclass_rule_get(struct cmd_context *ctx, __u32 loc) +{ + struct ethtool_rxnfc nfccmd; + int err; + + /* fetch rule from netdev */ + nfccmd.cmd = ETHTOOL_GRXCLSRULE; + memset(&nfccmd.fs, 0, sizeof(struct ethtool_rx_flow_spec)); + nfccmd.fs.location = loc; + err = send_ioctl(ctx, &nfccmd); + if (err < 0) { + perror("rxclass: Cannot get RX class rule"); + return err; + } + + /* display rule */ + rxclass_print_rule(&nfccmd.fs, (__u32)nfccmd.rss_context); + return err; +} + +int rxclass_rule_getall(struct cmd_context *ctx) +{ + struct ethtool_rxnfc *nfccmd; + __u32 *rule_locs; + unsigned int i; + __u32 count; + int err; + + /* determine rule count */ + err = rxclass_get_dev_info(ctx, &count, NULL); + if (err < 0) + return err; + + fprintf(stdout, "Total %d rules\n\n", count); + + /* alloc memory for request of location list */ + nfccmd = calloc(1, sizeof(*nfccmd) + (count * sizeof(__u32))); + if (!nfccmd) { + perror("rxclass: Cannot allocate memory for" + " RX class rule locations"); + return -ENOMEM; + } + + /* request location list */ + nfccmd->cmd = ETHTOOL_GRXCLSRLALL; + nfccmd->rule_cnt = count; + err = send_ioctl(ctx, nfccmd); + if (err < 0) { + perror("rxclass: Cannot get RX class rules"); + free(nfccmd); + return err; + } + + /* write locations to bitmap */ + rule_locs = nfccmd->rule_locs; + for (i = 0; i < count; i++) { + err = rxclass_rule_get(ctx, rule_locs[i]); + if (err < 0) + break; + } + + /* free memory and set flag to avoid reinit */ + free(nfccmd); + + return err; +} + +/* + * This is a simple rule manager implementation for ordering rx flow + * classification rules based on newest rules being first in the list. + * The assumption is that this rule manager is the only one adding rules to + * the device's hardware classifier. + */ + +struct rmgr_ctrl { + /* flag for device/driver that can select locations itself */ + int driver_select; + /* slot contains a bitmap indicating which filters are valid */ + unsigned long *slot; + __u32 n_rules; + __u32 size; +}; + +static int rmgr_ins(struct rmgr_ctrl *rmgr, __u32 loc) +{ + /* verify location is in rule manager range */ + if (loc >= rmgr->size) { + fprintf(stderr, "rmgr: Location out of range\n"); + return -1; + } + + /* set bit for the rule */ + set_bit(loc, rmgr->slot); + + return 0; +} + +static int rmgr_find_empty_slot(struct rmgr_ctrl *rmgr, + struct ethtool_rx_flow_spec *fsp) +{ + __u32 loc; + __u32 slot_num; + + /* leave this to the driver if possible */ + if (rmgr->driver_select) + return 0; + + /* start at the end of the list since it is lowest priority */ + loc = rmgr->size - 1; + + /* locate the first slot a rule can be placed in */ + slot_num = loc / BITS_PER_LONG; + + /* + * Avoid testing individual bits by inverting the word and checking + * to see if any bits are left set, if so there are empty spots. By + * moving 1 + loc % BITS_PER_LONG we align ourselves to the last bit + * in the previous word. + * + * If loc rolls over it should be greater than or equal to rmgr->size + * and as such we know we have reached the end of the list. + */ + if (!~(rmgr->slot[slot_num] | (~1UL << rmgr->size % BITS_PER_LONG))) { + loc -= 1 + (loc % BITS_PER_LONG); + slot_num--; + } + + /* + * Now that we are aligned with the last bit in each long we can just + * go though and eliminate all the longs with no free bits + */ + while (loc < rmgr->size && !~(rmgr->slot[slot_num])) { + loc -= BITS_PER_LONG; + slot_num--; + } + + /* + * If we still are inside the range, test individual bits as one is + * likely available for our use. + */ + while (loc < rmgr->size && test_bit(loc, rmgr->slot)) + loc--; + + /* location found, insert rule */ + if (loc < rmgr->size) { + fsp->location = loc; + return rmgr_ins(rmgr, loc); + } + + /* No space to add this rule */ + fprintf(stderr, "rmgr: Cannot find appropriate slot to insert rule\n"); + + return -1; +} + +static int rmgr_init(struct cmd_context *ctx, struct rmgr_ctrl *rmgr) +{ + struct ethtool_rxnfc *nfccmd; + __u32 *rule_locs; + unsigned int i; + int err; + + /* clear rule manager settings */ + memset(rmgr, 0, sizeof(*rmgr)); + + /* request device/driver information */ + err = rxclass_get_dev_info(ctx, &rmgr->n_rules, &rmgr->driver_select); + if (err < 0) + return err; + + /* do not get the table if the device/driver can select locations */ + if (rmgr->driver_select) + return 0; + + /* alloc memory for request of location list */ + nfccmd = calloc(1, sizeof(*nfccmd) + (rmgr->n_rules * sizeof(__u32))); + if (!nfccmd) { + perror("rmgr: Cannot allocate memory for" + " RX class rule locations"); + return -1; + } + + /* request location list */ + nfccmd->cmd = ETHTOOL_GRXCLSRLALL; + nfccmd->rule_cnt = rmgr->n_rules; + err = send_ioctl(ctx, nfccmd); + if (err < 0) { + perror("rmgr: Cannot get RX class rules"); + free(nfccmd); + return err; + } + + /* make certain the table size is valid */ + rmgr->size = nfccmd->data; + if (rmgr->size == 0 || rmgr->size < rmgr->n_rules) { + perror("rmgr: Invalid RX class rules table size"); + return -1; + } + + /* initialize bitmap for storage of valid locations */ + rmgr->slot = calloc(1, BITS_TO_LONGS(rmgr->size) * sizeof(long)); + if (!rmgr->slot) { + perror("rmgr: Cannot allocate memory for RX class rules"); + return -1; + } + + /* write locations to bitmap */ + rule_locs = nfccmd->rule_locs; + for (i = 0; i < rmgr->n_rules; i++) { + err = rmgr_ins(rmgr, rule_locs[i]); + if (err < 0) + break; + } + + free(nfccmd); + + return err; +} + +static void rmgr_cleanup(struct rmgr_ctrl *rmgr) +{ + free(rmgr->slot); + rmgr->slot = NULL; + rmgr->size = 0; +} + +static int rmgr_set_location(struct cmd_context *ctx, + struct ethtool_rx_flow_spec *fsp) +{ + struct rmgr_ctrl rmgr; + int err; + + /* init table of available rules */ + err = rmgr_init(ctx, &rmgr); + if (err < 0) + goto out; + + /* verify rule location */ + err = rmgr_find_empty_slot(&rmgr, fsp); + +out: + /* cleanup table and free resources */ + rmgr_cleanup(&rmgr); + + return err; +} + +int rxclass_rule_ins(struct cmd_context *ctx, + struct ethtool_rx_flow_spec *fsp, __u32 rss_context) +{ + struct ethtool_rxnfc nfccmd; + __u32 loc = fsp->location; + int err; + + /* + * if location is unspecified and driver cannot select locations, pull + * rules from device and allocate a free rule for our use + */ + if (loc & RX_CLS_LOC_SPECIAL) { + err = rmgr_set_location(ctx, fsp); + if (err < 0) + return err; + } + + /* notify netdev of new rule */ + nfccmd.cmd = ETHTOOL_SRXCLSRLINS; + nfccmd.rss_context = rss_context; + nfccmd.fs = *fsp; + err = send_ioctl(ctx, &nfccmd); + if (err < 0) + perror("rmgr: Cannot insert RX class rule"); + else if (loc & RX_CLS_LOC_SPECIAL) + printf("Added rule with ID %d\n", nfccmd.fs.location); + + return 0; +} + +int rxclass_rule_del(struct cmd_context *ctx, __u32 loc) +{ + struct ethtool_rxnfc nfccmd; + int err; + + /* notify netdev of rule removal */ + nfccmd.cmd = ETHTOOL_SRXCLSRLDEL; + nfccmd.fs.location = loc; + err = send_ioctl(ctx, &nfccmd); + if (err < 0) + perror("rmgr: Cannot delete RX class rule"); + + return err; +} + +typedef enum { + OPT_NONE = 0, + OPT_S32, + OPT_U8, + OPT_U16, + OPT_U32, + OPT_U64, + OPT_RING_VF, + OPT_RING_QUEUE, + OPT_BE16, + OPT_BE32, + OPT_BE64, + OPT_IP4, + OPT_IP6, + OPT_MAC, +} rule_opt_type_t; + +#define NFC_FLAG_RING 0x0001 +#define NFC_FLAG_LOC 0x0002 +#define NFC_FLAG_SADDR 0x0004 +#define NFC_FLAG_DADDR 0x0008 +#define NFC_FLAG_SPORT 0x0010 +#define NFC_FLAG_DPORT 0x0020 +#define NFC_FLAG_SPI 0x0030 +#define NFC_FLAG_TOS 0x0040 +#define NFC_FLAG_PROTO 0x0080 +#define NTUPLE_FLAG_VLAN 0x0100 +#define NTUPLE_FLAG_UDEF 0x0200 +#define NTUPLE_FLAG_VETH 0x0400 +#define NFC_FLAG_MAC_ADDR 0x0800 +#define NFC_FLAG_RING_VF 0x1000 +#define NFC_FLAG_RING_QUEUE 0x2000 + +struct rule_opts { + const char *name; + rule_opt_type_t type; + u32 flag; + int offset; + int moffset; +}; + +static const struct rule_opts rule_nfc_tcp_ip4[] = { + { "src-ip", OPT_IP4, NFC_FLAG_SADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip4_spec.ip4src), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip4_spec.ip4src) }, + { "dst-ip", OPT_IP4, NFC_FLAG_DADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip4_spec.ip4dst), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip4_spec.ip4dst) }, + { "tos", OPT_U8, NFC_FLAG_TOS, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip4_spec.tos), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip4_spec.tos) }, + { "src-port", OPT_BE16, NFC_FLAG_SPORT, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip4_spec.psrc), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip4_spec.psrc) }, + { "dst-port", OPT_BE16, NFC_FLAG_DPORT, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip4_spec.pdst), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip4_spec.pdst) }, + { "action", OPT_U64, NFC_FLAG_RING, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "vf", OPT_RING_VF, NFC_FLAG_RING_VF, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "queue", OPT_RING_QUEUE, NFC_FLAG_RING_QUEUE, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "loc", OPT_U32, NFC_FLAG_LOC, + offsetof(struct ethtool_rx_flow_spec, location), -1 }, + { "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) }, + { "vlan", OPT_BE16, NTUPLE_FLAG_VLAN, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) }, + { "user-def", OPT_BE64, NTUPLE_FLAG_UDEF, + offsetof(struct ethtool_rx_flow_spec, h_ext.data), + offsetof(struct ethtool_rx_flow_spec, m_ext.data) }, + { "dst-mac", OPT_MAC, NFC_FLAG_MAC_ADDR, + offsetof(struct ethtool_rx_flow_spec, h_ext.h_dest), + offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) }, +}; + +static const struct rule_opts rule_nfc_esp_ip4[] = { + { "src-ip", OPT_IP4, NFC_FLAG_SADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip4_spec.ip4src), + offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip4_spec.ip4src) }, + { "dst-ip", OPT_IP4, NFC_FLAG_DADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip4_spec.ip4dst), + offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip4_spec.ip4dst) }, + { "tos", OPT_U8, NFC_FLAG_TOS, + offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip4_spec.tos), + offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip4_spec.tos) }, + { "spi", OPT_BE32, NFC_FLAG_SPI, + offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip4_spec.spi), + offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip4_spec.spi) }, + { "action", OPT_U64, NFC_FLAG_RING, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "vf", OPT_RING_VF, NFC_FLAG_RING_VF, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "queue", OPT_RING_QUEUE, NFC_FLAG_RING_QUEUE, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "loc", OPT_U32, NFC_FLAG_LOC, + offsetof(struct ethtool_rx_flow_spec, location), -1 }, + { "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) }, + { "vlan", OPT_BE16, NTUPLE_FLAG_VLAN, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) }, + { "user-def", OPT_BE64, NTUPLE_FLAG_UDEF, + offsetof(struct ethtool_rx_flow_spec, h_ext.data), + offsetof(struct ethtool_rx_flow_spec, m_ext.data) }, + { "dst-mac", OPT_MAC, NFC_FLAG_MAC_ADDR, + offsetof(struct ethtool_rx_flow_spec, h_ext.h_dest), + offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) }, +}; + +static const struct rule_opts rule_nfc_usr_ip4[] = { + { "src-ip", OPT_IP4, NFC_FLAG_SADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip4_spec.ip4src), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip4_spec.ip4src) }, + { "dst-ip", OPT_IP4, NFC_FLAG_DADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip4_spec.ip4dst), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip4_spec.ip4dst) }, + { "tos", OPT_U8, NFC_FLAG_TOS, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip4_spec.tos), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip4_spec.tos) }, + { "l4proto", OPT_U8, NFC_FLAG_PROTO, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip4_spec.proto), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip4_spec.proto) }, + { "l4data", OPT_BE32, NFC_FLAG_SPI, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip4_spec.l4_4_bytes), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip4_spec.l4_4_bytes) }, + { "spi", OPT_BE32, NFC_FLAG_SPI, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip4_spec.l4_4_bytes), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip4_spec.l4_4_bytes) }, + { "src-port", OPT_BE16, NFC_FLAG_SPORT, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip4_spec.l4_4_bytes), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip4_spec.l4_4_bytes) }, + { "dst-port", OPT_BE16, NFC_FLAG_DPORT, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip4_spec.l4_4_bytes) + 2, + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip4_spec.l4_4_bytes) + 2 }, + { "action", OPT_U64, NFC_FLAG_RING, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "vf", OPT_RING_VF, NFC_FLAG_RING_VF, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "queue", OPT_RING_QUEUE, NFC_FLAG_RING_QUEUE, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "loc", OPT_U32, NFC_FLAG_LOC, + offsetof(struct ethtool_rx_flow_spec, location), -1 }, + { "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) }, + { "vlan", OPT_BE16, NTUPLE_FLAG_VLAN, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) }, + { "user-def", OPT_BE64, NTUPLE_FLAG_UDEF, + offsetof(struct ethtool_rx_flow_spec, h_ext.data), + offsetof(struct ethtool_rx_flow_spec, m_ext.data) }, + { "dst-mac", OPT_MAC, NFC_FLAG_MAC_ADDR, + offsetof(struct ethtool_rx_flow_spec, h_ext.h_dest), + offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) }, +}; + +static const struct rule_opts rule_nfc_tcp_ip6[] = { + { "src-ip", OPT_IP6, NFC_FLAG_SADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.ip6src), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.ip6src) }, + { "dst-ip", OPT_IP6, NFC_FLAG_DADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.ip6dst), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.ip6dst) }, + { "tclass", OPT_U8, NFC_FLAG_TOS, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.tclass), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.tclass) }, + { "src-port", OPT_BE16, NFC_FLAG_SPORT, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.psrc), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.psrc) }, + { "dst-port", OPT_BE16, NFC_FLAG_DPORT, + offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.pdst), + offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.pdst) }, + { "action", OPT_U64, NFC_FLAG_RING, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "vf", OPT_RING_VF, NFC_FLAG_RING_VF, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "queue", OPT_RING_QUEUE, NFC_FLAG_RING_QUEUE, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "loc", OPT_U32, NFC_FLAG_LOC, + offsetof(struct ethtool_rx_flow_spec, location), -1 }, + { "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) }, + { "vlan", OPT_BE16, NTUPLE_FLAG_VLAN, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) }, + { "user-def", OPT_BE64, NTUPLE_FLAG_UDEF, + offsetof(struct ethtool_rx_flow_spec, h_ext.data), + offsetof(struct ethtool_rx_flow_spec, m_ext.data) }, + { "dst-mac", OPT_MAC, NFC_FLAG_MAC_ADDR, + offsetof(struct ethtool_rx_flow_spec, h_ext.h_dest), + offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) }, +}; + +static const struct rule_opts rule_nfc_esp_ip6[] = { + { "src-ip", OPT_IP6, NFC_FLAG_SADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip6_spec.ip6src), + offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip6_spec.ip6src) }, + { "dst-ip", OPT_IP6, NFC_FLAG_DADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip6_spec.ip6dst), + offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip6_spec.ip6dst) }, + { "tclass", OPT_U8, NFC_FLAG_TOS, + offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip6_spec.tclass), + offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip6_spec.tclass) }, + { "spi", OPT_BE32, NFC_FLAG_SPI, + offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip6_spec.spi), + offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip6_spec.spi) }, + { "action", OPT_U64, NFC_FLAG_RING, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "vf", OPT_RING_VF, NFC_FLAG_RING_VF, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "queue", OPT_RING_QUEUE, NFC_FLAG_RING_QUEUE, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "loc", OPT_U32, NFC_FLAG_LOC, + offsetof(struct ethtool_rx_flow_spec, location), -1 }, + { "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) }, + { "vlan", OPT_BE16, NTUPLE_FLAG_VLAN, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) }, + { "user-def", OPT_BE64, NTUPLE_FLAG_UDEF, + offsetof(struct ethtool_rx_flow_spec, h_ext.data), + offsetof(struct ethtool_rx_flow_spec, m_ext.data) }, + { "dst-mac", OPT_MAC, NFC_FLAG_MAC_ADDR, + offsetof(struct ethtool_rx_flow_spec, h_ext.h_dest), + offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) }, +}; + +static const struct rule_opts rule_nfc_usr_ip6[] = { + { "src-ip", OPT_IP6, NFC_FLAG_SADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.ip6src), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.ip6src) }, + { "dst-ip", OPT_IP6, NFC_FLAG_DADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.ip6dst), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.ip6dst) }, + { "tclass", OPT_U8, NFC_FLAG_TOS, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.tclass), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.tclass) }, + { "l4proto", OPT_U8, NFC_FLAG_PROTO, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_proto), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_proto) }, + { "l4data", OPT_BE32, NFC_FLAG_SPI, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_4_bytes), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_4_bytes) }, + { "spi", OPT_BE32, NFC_FLAG_SPI, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_4_bytes), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_4_bytes) }, + { "src-port", OPT_BE16, NFC_FLAG_SPORT, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_4_bytes), + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_4_bytes) }, + { "dst-port", OPT_BE16, NFC_FLAG_DPORT, + offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_4_bytes) + 2, + offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_4_bytes) + 2 }, + { "action", OPT_U64, NFC_FLAG_RING, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "vf", OPT_RING_VF, NFC_FLAG_RING_VF, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "queue", OPT_RING_QUEUE, NFC_FLAG_RING_QUEUE, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "loc", OPT_U32, NFC_FLAG_LOC, + offsetof(struct ethtool_rx_flow_spec, location), -1 }, + { "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) }, + { "vlan", OPT_BE16, NTUPLE_FLAG_VLAN, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) }, + { "user-def", OPT_BE64, NTUPLE_FLAG_UDEF, + offsetof(struct ethtool_rx_flow_spec, h_ext.data), + offsetof(struct ethtool_rx_flow_spec, m_ext.data) }, + { "dst-mac", OPT_MAC, NFC_FLAG_MAC_ADDR, + offsetof(struct ethtool_rx_flow_spec, h_ext.h_dest), + offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) }, +}; + +static const struct rule_opts rule_nfc_ether[] = { + { "src", OPT_MAC, NFC_FLAG_SADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.ether_spec.h_source), + offsetof(struct ethtool_rx_flow_spec, m_u.ether_spec.h_source) }, + { "dst", OPT_MAC, NFC_FLAG_DADDR, + offsetof(struct ethtool_rx_flow_spec, h_u.ether_spec.h_dest), + offsetof(struct ethtool_rx_flow_spec, m_u.ether_spec.h_dest) }, + { "proto", OPT_BE16, NFC_FLAG_PROTO, + offsetof(struct ethtool_rx_flow_spec, h_u.ether_spec.h_proto), + offsetof(struct ethtool_rx_flow_spec, m_u.ether_spec.h_proto) }, + { "action", OPT_U64, NFC_FLAG_RING, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "vf", OPT_RING_VF, NFC_FLAG_RING_VF, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "queue", OPT_RING_QUEUE, NFC_FLAG_RING_QUEUE, + offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 }, + { "loc", OPT_U32, NFC_FLAG_LOC, + offsetof(struct ethtool_rx_flow_spec, location), -1 }, + { "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) }, + { "vlan", OPT_BE16, NTUPLE_FLAG_VLAN, + offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci), + offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) }, + { "user-def", OPT_BE64, NTUPLE_FLAG_UDEF, + offsetof(struct ethtool_rx_flow_spec, h_ext.data), + offsetof(struct ethtool_rx_flow_spec, m_ext.data) }, +}; + +static int rxclass_get_long(char *str, long long *val, int size) +{ + long long max = ~0ULL >> (65 - size); + char *endp; + + errno = 0; + + *val = strtoll(str, &endp, 0); + + if (*endp || errno || (*val > max) || (*val < ~max)) + return -1; + + return 0; +} + +static int rxclass_get_ulong(char *str, unsigned long long *val, int size) +{ + unsigned long long max = ~0ULL >> (64 - size); + char *endp; + + errno = 0; + + *val = strtoull(str, &endp, 0); + + if (*endp || errno || (*val > max)) + return -1; + + return 0; +} + +static int rxclass_get_ipv4(char *str, __be32 *val) +{ + if (!inet_pton(AF_INET, str, val)) + return -1; + + return 0; +} + +static int rxclass_get_ipv6(char *str, __be32 *val) +{ + if (!inet_pton(AF_INET6, str, val)) + return -1; + + return 0; +} + +static int rxclass_get_ether(char *str, unsigned char *val) +{ + unsigned int buf[ETH_ALEN]; + int count; + + if (!strchr(str, ':')) + return -1; + + count = sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x", + &buf[0], &buf[1], &buf[2], + &buf[3], &buf[4], &buf[5]); + + if (count != ETH_ALEN) + return -1; + + do { + count--; + val[count] = buf[count]; + } while (count); + + return 0; +} + +static int rxclass_get_val(char *str, unsigned char *p, u32 *flags, + const struct rule_opts *opt) +{ + unsigned long long mask = ~0ULL; + int err = 0; + + if (*flags & opt->flag) + return -1; + + *flags |= opt->flag; + + switch (opt->type) { + case OPT_S32: { + long long val; + err = rxclass_get_long(str, &val, 32); + if (err) + return -1; + *(int *)&p[opt->offset] = (int)val; + if (opt->moffset >= 0) + *(int *)&p[opt->moffset] = (int)mask; + break; + } + case OPT_U8: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 8); + if (err) + return -1; + *(u8 *)&p[opt->offset] = (u8)val; + if (opt->moffset >= 0) + *(u8 *)&p[opt->moffset] = (u8)mask; + break; + } + case OPT_U16: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 16); + if (err) + return -1; + *(u16 *)&p[opt->offset] = (u16)val; + if (opt->moffset >= 0) + *(u16 *)&p[opt->moffset] = (u16)mask; + break; + } + case OPT_U32: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 32); + if (err) + return -1; + *(u32 *)&p[opt->offset] = (u32)val; + if (opt->moffset >= 0) + *(u32 *)&p[opt->moffset] = (u32)mask; + break; + } + case OPT_U64: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 64); + if (err) + return -1; + *(u64 *)&p[opt->offset] = (u64)val; + if (opt->moffset >= 0) + *(u64 *)&p[opt->moffset] = (u64)mask; + break; + } + case OPT_RING_VF: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 8); + if (err) + return -1; + + /* The ring_cookie uses 0 to indicate the rule targets the + * main function, so add 1 to the value in order to target the + * correct virtual function. + */ + val++; + + *(u64 *)&p[opt->offset] &= ~ETHTOOL_RX_FLOW_SPEC_RING_VF; + *(u64 *)&p[opt->offset] |= (u64)val << ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF; + break; + } + case OPT_RING_QUEUE: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 32); + if (err) + return -1; + *(u64 *)&p[opt->offset] &= ~ETHTOOL_RX_FLOW_SPEC_RING; + *(u64 *)&p[opt->offset] |= (u64)val; + break; + } + case OPT_BE16: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 16); + if (err) + return -1; + *(__be16 *)&p[opt->offset] = htons((u16)val); + if (opt->moffset >= 0) + *(__be16 *)&p[opt->moffset] = (__be16)mask; + break; + } + case OPT_BE32: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 32); + if (err) + return -1; + *(__be32 *)&p[opt->offset] = htonl((u32)val); + if (opt->moffset >= 0) + *(__be32 *)&p[opt->moffset] = (__be32)mask; + break; + } + case OPT_BE64: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 64); + if (err) + return -1; + *(__be64 *)&p[opt->offset] = htonll((u64)val); + if (opt->moffset >= 0) + *(__be64 *)&p[opt->moffset] = (__be64)mask; + break; + } + case OPT_IP4: { + __be32 val; + err = rxclass_get_ipv4(str, &val); + if (err) + return -1; + *(__be32 *)&p[opt->offset] = val; + if (opt->moffset >= 0) + *(__be32 *)&p[opt->moffset] = (__be32)mask; + break; + } + case OPT_IP6: { + __be32 val[4]; + err = rxclass_get_ipv6(str, val); + if (err) + return -1; + memcpy(&p[opt->offset], val, sizeof(val)); + if (opt->moffset >= 0) + memset(&p[opt->moffset], mask, sizeof(val)); + break; + } + case OPT_MAC: { + unsigned char val[ETH_ALEN]; + err = rxclass_get_ether(str, val); + if (err) + return -1; + memcpy(&p[opt->offset], val, ETH_ALEN); + if (opt->moffset >= 0) + memcpy(&p[opt->moffset], &mask, ETH_ALEN); + break; + } + case OPT_NONE: + default: + return -1; + } + + return 0; +} + +static int rxclass_get_mask(char *str, unsigned char *p, + const struct rule_opts *opt) +{ + int err = 0; + + if (opt->moffset < 0) + return -1; + + switch (opt->type) { + case OPT_S32: { + long long val; + err = rxclass_get_long(str, &val, 32); + if (err) + return -1; + *(int *)&p[opt->moffset] = ~(int)val; + break; + } + case OPT_U8: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 8); + if (err) + return -1; + *(u8 *)&p[opt->moffset] = ~(u8)val; + break; + } + case OPT_U16: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 16); + if (err) + return -1; + *(u16 *)&p[opt->moffset] = ~(u16)val; + break; + } + case OPT_U32: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 32); + if (err) + return -1; + *(u32 *)&p[opt->moffset] = ~(u32)val; + break; + } + case OPT_U64: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 64); + if (err) + return -1; + *(u64 *)&p[opt->moffset] = ~(u64)val; + break; + } + case OPT_BE16: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 16); + if (err) + return -1; + *(__be16 *)&p[opt->moffset] = ~htons((u16)val); + break; + } + case OPT_BE32: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 32); + if (err) + return -1; + *(__be32 *)&p[opt->moffset] = ~htonl((u32)val); + break; + } + case OPT_BE64: { + unsigned long long val; + err = rxclass_get_ulong(str, &val, 64); + if (err) + return -1; + *(__be64 *)&p[opt->moffset] = ~htonll((u64)val); + break; + } + case OPT_IP4: { + __be32 val; + err = rxclass_get_ipv4(str, &val); + if (err) + return -1; + *(__be32 *)&p[opt->moffset] = ~val; + break; + } + case OPT_IP6: { + __be32 val[4], *field; + int i; + err = rxclass_get_ipv6(str, val); + if (err) + return -1; + field = (__be32 *)&p[opt->moffset]; + for (i = 0; i < 4; i++) + field[i] = ~val[i]; + break; + } + case OPT_MAC: { + unsigned char val[ETH_ALEN]; + int i; + err = rxclass_get_ether(str, val); + if (err) + return -1; + + for (i = 0; i < ETH_ALEN; i++) + val[i] = ~val[i]; + + memcpy(&p[opt->moffset], val, ETH_ALEN); + break; + } + case OPT_NONE: + default: + return -1; + } + + return 0; +} + +int rxclass_parse_ruleopts(struct cmd_context *ctx, + struct ethtool_rx_flow_spec *fsp, __u32 *rss_context) +{ + const struct rule_opts *options; + unsigned char *p = (unsigned char *)fsp; + int i = 0, n_opts, err; + u32 flags = 0; + int flow_type; + int argc = ctx->argc; + char **argp = ctx->argp; + + if (argc < 1) + goto syntax_err; + + if (!strcmp(argp[0], "tcp4")) + flow_type = TCP_V4_FLOW; + else if (!strcmp(argp[0], "udp4")) + flow_type = UDP_V4_FLOW; + else if (!strcmp(argp[0], "sctp4")) + flow_type = SCTP_V4_FLOW; + else if (!strcmp(argp[0], "ah4")) + flow_type = AH_V4_FLOW; + else if (!strcmp(argp[0], "esp4")) + flow_type = ESP_V4_FLOW; + else if (!strcmp(argp[0], "ip4")) + flow_type = IPV4_USER_FLOW; + else if (!strcmp(argp[0], "tcp6")) + flow_type = TCP_V6_FLOW; + else if (!strcmp(argp[0], "udp6")) + flow_type = UDP_V6_FLOW; + else if (!strcmp(argp[0], "sctp6")) + flow_type = SCTP_V6_FLOW; + else if (!strcmp(argp[0], "ah6")) + flow_type = AH_V6_FLOW; + else if (!strcmp(argp[0], "esp6")) + flow_type = ESP_V6_FLOW; + else if (!strcmp(argp[0], "ip6")) + flow_type = IPV6_USER_FLOW; + else if (!strcmp(argp[0], "ether")) + flow_type = ETHER_FLOW; + else + goto syntax_err; + + switch (flow_type) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + case SCTP_V4_FLOW: + options = rule_nfc_tcp_ip4; + n_opts = ARRAY_SIZE(rule_nfc_tcp_ip4); + break; + case AH_V4_FLOW: + case ESP_V4_FLOW: + options = rule_nfc_esp_ip4; + n_opts = ARRAY_SIZE(rule_nfc_esp_ip4); + break; + case IPV4_USER_FLOW: + options = rule_nfc_usr_ip4; + n_opts = ARRAY_SIZE(rule_nfc_usr_ip4); + break; + case TCP_V6_FLOW: + case UDP_V6_FLOW: + case SCTP_V6_FLOW: + options = rule_nfc_tcp_ip6; + n_opts = ARRAY_SIZE(rule_nfc_tcp_ip6); + break; + case AH_V6_FLOW: + case ESP_V6_FLOW: + options = rule_nfc_esp_ip6; + n_opts = ARRAY_SIZE(rule_nfc_esp_ip6); + break; + case IPV6_USER_FLOW: + options = rule_nfc_usr_ip6; + n_opts = ARRAY_SIZE(rule_nfc_usr_ip6); + break; + case ETHER_FLOW: + options = rule_nfc_ether; + n_opts = ARRAY_SIZE(rule_nfc_ether); + break; + default: + fprintf(stderr, "Add rule, invalid rule type[%s]\n", argp[0]); + return -1; + } + + memset(p, 0, sizeof(*fsp)); + fsp->flow_type = flow_type; + fsp->location = RX_CLS_LOC_ANY; + + for (i = 1; i < argc;) { + const struct rule_opts *opt; + int idx; + + /* special handling for 'context %d' as it doesn't go in + * the struct ethtool_rx_flow_spec + */ + if (!strcmp(argp[i], "context")) { + unsigned long long val; + + i++; + if (i >= argc) { + fprintf(stderr, "'context' missing value\n"); + return -1; + } + + if (rxclass_get_ulong(argp[i], &val, 32)) { + fprintf(stderr, "Invalid context value[%s]\n", + argp[i]); + return -1; + } + + /* Can't use the ALLOC special value as the context ID + * of a filter to insert + */ + if ((__u32)val == ETH_RXFH_CONTEXT_ALLOC) { + fprintf(stderr, "Bad context value %x\n", + (__u32)val); + return -1; + } + + *rss_context = (__u32)val; + fsp->flow_type |= FLOW_RSS; + i++; + continue; + } + + for (opt = options, idx = 0; idx < n_opts; idx++, opt++) { + char mask_name[16]; + + if (strcmp(argp[i], opt->name)) + continue; + + i++; + if (i >= argc) + break; + + err = rxclass_get_val(argp[i], p, &flags, opt); + if (err) { + fprintf(stderr, "Invalid %s value[%s]\n", + opt->name, argp[i]); + return -1; + } + + i++; + if (i >= argc) + break; + + sprintf(mask_name, "%s-mask", opt->name); + if (strcmp(argp[i], "m") && strcmp(argp[i], mask_name)) + break; + + i++; + if (i >= argc) + goto syntax_err; + + err = rxclass_get_mask(argp[i], p, opt); + if (err) { + fprintf(stderr, "Invalid %s mask[%s]\n", + opt->name, argp[i]); + return -1; + } + + i++; + + break; + } + if (idx == n_opts) { + fprintf(stdout, "Add rule, unrecognized option[%s]\n", + argp[i]); + return -1; + } + } + + if ((flags & NFC_FLAG_RING) && (flags & NFC_FLAG_RING_QUEUE)) { + fprintf(stderr, "action and queue are not compatible\n"); + return -1; + } + + if ((flags & NFC_FLAG_RING) && (flags & NFC_FLAG_RING_VF)) { + fprintf(stderr, "action and vf are not compatible\n"); + return -1; + } + + if (flow_type == IPV4_USER_FLOW) + fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4; + if (flags & (NTUPLE_FLAG_VLAN | NTUPLE_FLAG_UDEF | NTUPLE_FLAG_VETH)) + fsp->flow_type |= FLOW_EXT; + if (flags & NFC_FLAG_MAC_ADDR) + fsp->flow_type |= FLOW_MAC_EXT; + + return 0; + +syntax_err: + fprintf(stderr, "Add rule, invalid syntax\n"); + return -1; +} diff --git a/sfc.c b/sfc.c new file mode 100644 index 0000000..340800e --- /dev/null +++ b/sfc.c @@ -0,0 +1,3928 @@ +/**************************************************************************** + * Support for Solarflare Solarstorm network controllers and boards + * Copyright 2010-2012 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#include "internal.h" + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/* Falcon architecture register definitions + * (from linux/drivers/net/ethernet/sfc/farch_regs.h) + */ + +/* ADR_REGION_REG: Address region register */ +#define FR_AZ_ADR_REGION 0x00000000 +#define FRF_AZ_ADR_REGION3_LBN 96 +#define FRF_AZ_ADR_REGION3_WIDTH 18 +#define FRF_AZ_ADR_REGION2_LBN 64 +#define FRF_AZ_ADR_REGION2_WIDTH 18 +#define FRF_AZ_ADR_REGION1_LBN 32 +#define FRF_AZ_ADR_REGION1_WIDTH 18 +#define FRF_AZ_ADR_REGION0_LBN 0 +#define FRF_AZ_ADR_REGION0_WIDTH 18 + +/* INT_EN_REG_KER: Kernel driver Interrupt enable register */ +#define FR_AZ_INT_EN_KER 0x00000010 +#define FRF_AZ_KER_INT_LEVE_SEL_LBN 8 +#define FRF_AZ_KER_INT_LEVE_SEL_WIDTH 6 +#define FRF_AZ_KER_INT_CHAR_LBN 4 +#define FRF_AZ_KER_INT_CHAR_WIDTH 1 +#define FRF_AZ_KER_INT_KER_LBN 3 +#define FRF_AZ_KER_INT_KER_WIDTH 1 +#define FRF_AZ_DRV_INT_EN_KER_LBN 0 +#define FRF_AZ_DRV_INT_EN_KER_WIDTH 1 + +/* INT_EN_REG_CHAR: Char Driver interrupt enable register */ +#define FR_BZ_INT_EN_CHAR 0x00000020 +#define FRF_BZ_CHAR_INT_LEVE_SEL_LBN 8 +#define FRF_BZ_CHAR_INT_LEVE_SEL_WIDTH 6 +#define FRF_BZ_CHAR_INT_CHAR_LBN 4 +#define FRF_BZ_CHAR_INT_CHAR_WIDTH 1 +#define FRF_BZ_CHAR_INT_KER_LBN 3 +#define FRF_BZ_CHAR_INT_KER_WIDTH 1 +#define FRF_BZ_DRV_INT_EN_CHAR_LBN 0 +#define FRF_BZ_DRV_INT_EN_CHAR_WIDTH 1 + +/* INT_ADR_REG_KER: Interrupt host address for Kernel driver */ +#define FR_AZ_INT_ADR_KER 0x00000030 +#define FRF_AZ_NORM_INT_VEC_DIS_KER_LBN 64 +#define FRF_AZ_NORM_INT_VEC_DIS_KER_WIDTH 1 +#define FRF_AZ_INT_ADR_KER_LBN 0 +#define FRF_AZ_INT_ADR_KER_WIDTH 64 + +/* INT_ADR_REG_CHAR: Interrupt host address for Char driver */ +#define FR_BZ_INT_ADR_CHAR 0x00000040 +#define FRF_BZ_NORM_INT_VEC_DIS_CHAR_LBN 64 +#define FRF_BZ_NORM_INT_VEC_DIS_CHAR_WIDTH 1 +#define FRF_BZ_INT_ADR_CHAR_LBN 0 +#define FRF_BZ_INT_ADR_CHAR_WIDTH 64 + +/* INT_ACK_KER: Kernel interrupt acknowledge register */ +#define FR_AA_INT_ACK_KER 0x00000050 +#define FRF_AA_INT_ACK_KER_FIELD_LBN 0 +#define FRF_AA_INT_ACK_KER_FIELD_WIDTH 32 + +/* INT_ISR0_REG: Function 0 Interrupt Acknowledge Status register */ +#define FR_BZ_INT_ISR0 0x00000090 +#define FRF_BZ_INT_ISR_REG_LBN 0 +#define FRF_BZ_INT_ISR_REG_WIDTH 64 + +/* HW_INIT_REG: Hardware initialization register */ +#define FR_AZ_HW_INIT 0x000000c0 +#define FRF_BB_BDMRD_CPLF_FULL_LBN 124 +#define FRF_BB_BDMRD_CPLF_FULL_WIDTH 1 +#define FRF_BB_PCIE_CPL_TIMEOUT_CTRL_LBN 121 +#define FRF_BB_PCIE_CPL_TIMEOUT_CTRL_WIDTH 3 +#define FRF_CZ_TX_MRG_TAGS_LBN 120 +#define FRF_CZ_TX_MRG_TAGS_WIDTH 1 +#define FRF_AB_TRGT_MASK_ALL_LBN 100 +#define FRF_AB_TRGT_MASK_ALL_WIDTH 1 +#define FRF_AZ_DOORBELL_DROP_LBN 92 +#define FRF_AZ_DOORBELL_DROP_WIDTH 8 +#define FRF_AB_TX_RREQ_MASK_EN_LBN 76 +#define FRF_AB_TX_RREQ_MASK_EN_WIDTH 1 +#define FRF_AB_PE_EIDLE_DIS_LBN 75 +#define FRF_AB_PE_EIDLE_DIS_WIDTH 1 +#define FRF_AA_FC_BLOCKING_EN_LBN 45 +#define FRF_AA_FC_BLOCKING_EN_WIDTH 1 +#define FRF_BZ_B2B_REQ_EN_LBN 45 +#define FRF_BZ_B2B_REQ_EN_WIDTH 1 +#define FRF_AA_B2B_REQ_EN_LBN 44 +#define FRF_AA_B2B_REQ_EN_WIDTH 1 +#define FRF_BB_FC_BLOCKING_EN_LBN 44 +#define FRF_BB_FC_BLOCKING_EN_WIDTH 1 +#define FRF_AZ_POST_WR_MASK_LBN 40 +#define FRF_AZ_POST_WR_MASK_WIDTH 4 +#define FRF_AZ_TLP_TC_LBN 34 +#define FRF_AZ_TLP_TC_WIDTH 3 +#define FRF_AZ_TLP_ATTR_LBN 32 +#define FRF_AZ_TLP_ATTR_WIDTH 2 +#define FRF_AB_INTB_VEC_LBN 24 +#define FRF_AB_INTB_VEC_WIDTH 5 +#define FRF_AB_INTA_VEC_LBN 16 +#define FRF_AB_INTA_VEC_WIDTH 5 +#define FRF_AZ_WD_TIMER_LBN 8 +#define FRF_AZ_WD_TIMER_WIDTH 8 +#define FRF_AZ_US_DISABLE_LBN 5 +#define FRF_AZ_US_DISABLE_WIDTH 1 +#define FRF_AZ_TLP_EP_LBN 4 +#define FRF_AZ_TLP_EP_WIDTH 1 +#define FRF_AZ_ATTR_SEL_LBN 3 +#define FRF_AZ_ATTR_SEL_WIDTH 1 +#define FRF_AZ_TD_SEL_LBN 1 +#define FRF_AZ_TD_SEL_WIDTH 1 +#define FRF_AZ_TLP_TD_LBN 0 +#define FRF_AZ_TLP_TD_WIDTH 1 + +/* EE_SPI_HCMD_REG: SPI host command register */ +#define FR_AB_EE_SPI_HCMD 0x00000100 +#define FRF_AB_EE_SPI_HCMD_CMD_EN_LBN 31 +#define FRF_AB_EE_SPI_HCMD_CMD_EN_WIDTH 1 +#define FRF_AB_EE_WR_TIMER_ACTIVE_LBN 28 +#define FRF_AB_EE_WR_TIMER_ACTIVE_WIDTH 1 +#define FRF_AB_EE_SPI_HCMD_SF_SEL_LBN 24 +#define FRF_AB_EE_SPI_HCMD_SF_SEL_WIDTH 1 +#define FRF_AB_EE_SPI_HCMD_DABCNT_LBN 16 +#define FRF_AB_EE_SPI_HCMD_DABCNT_WIDTH 5 +#define FRF_AB_EE_SPI_HCMD_READ_LBN 15 +#define FRF_AB_EE_SPI_HCMD_READ_WIDTH 1 +#define FRF_AB_EE_SPI_HCMD_DUBCNT_LBN 12 +#define FRF_AB_EE_SPI_HCMD_DUBCNT_WIDTH 2 +#define FRF_AB_EE_SPI_HCMD_ADBCNT_LBN 8 +#define FRF_AB_EE_SPI_HCMD_ADBCNT_WIDTH 2 +#define FRF_AB_EE_SPI_HCMD_ENC_LBN 0 +#define FRF_AB_EE_SPI_HCMD_ENC_WIDTH 8 + +/* USR_EV_CFG: User Level Event Configuration register */ +#define FR_CZ_USR_EV_CFG 0x00000100 +#define FRF_CZ_USREV_DIS_LBN 16 +#define FRF_CZ_USREV_DIS_WIDTH 1 +#define FRF_CZ_DFLT_EVQ_LBN 0 +#define FRF_CZ_DFLT_EVQ_WIDTH 10 + +/* EE_SPI_HADR_REG: SPI host address register */ +#define FR_AB_EE_SPI_HADR 0x00000110 +#define FRF_AB_EE_SPI_HADR_DUBYTE_LBN 24 +#define FRF_AB_EE_SPI_HADR_DUBYTE_WIDTH 8 +#define FRF_AB_EE_SPI_HADR_ADR_LBN 0 +#define FRF_AB_EE_SPI_HADR_ADR_WIDTH 24 + +/* EE_SPI_HDATA_REG: SPI host data register */ +#define FR_AB_EE_SPI_HDATA 0x00000120 +#define FRF_AB_EE_SPI_HDATA3_LBN 96 +#define FRF_AB_EE_SPI_HDATA3_WIDTH 32 +#define FRF_AB_EE_SPI_HDATA2_LBN 64 +#define FRF_AB_EE_SPI_HDATA2_WIDTH 32 +#define FRF_AB_EE_SPI_HDATA1_LBN 32 +#define FRF_AB_EE_SPI_HDATA1_WIDTH 32 +#define FRF_AB_EE_SPI_HDATA0_LBN 0 +#define FRF_AB_EE_SPI_HDATA0_WIDTH 32 + +/* EE_BASE_PAGE_REG: Expansion ROM base mirror register */ +#define FR_AB_EE_BASE_PAGE 0x00000130 +#define FRF_AB_EE_EXPROM_MASK_LBN 16 +#define FRF_AB_EE_EXPROM_MASK_WIDTH 13 +#define FRF_AB_EE_EXP_ROM_WINDOW_BASE_LBN 0 +#define FRF_AB_EE_EXP_ROM_WINDOW_BASE_WIDTH 13 + +/* EE_VPD_CFG0_REG: SPI/VPD configuration register 0 */ +#define FR_AB_EE_VPD_CFG0 0x00000140 +#define FRF_AB_EE_SF_FASTRD_EN_LBN 127 +#define FRF_AB_EE_SF_FASTRD_EN_WIDTH 1 +#define FRF_AB_EE_SF_CLOCK_DIV_LBN 120 +#define FRF_AB_EE_SF_CLOCK_DIV_WIDTH 7 +#define FRF_AB_EE_VPD_WIP_POLL_LBN 119 +#define FRF_AB_EE_VPD_WIP_POLL_WIDTH 1 +#define FRF_AB_EE_EE_CLOCK_DIV_LBN 112 +#define FRF_AB_EE_EE_CLOCK_DIV_WIDTH 7 +#define FRF_AB_EE_EE_WR_TMR_VALUE_LBN 96 +#define FRF_AB_EE_EE_WR_TMR_VALUE_WIDTH 16 +#define FRF_AB_EE_VPDW_LENGTH_LBN 80 +#define FRF_AB_EE_VPDW_LENGTH_WIDTH 15 +#define FRF_AB_EE_VPDW_BASE_LBN 64 +#define FRF_AB_EE_VPDW_BASE_WIDTH 15 +#define FRF_AB_EE_VPD_WR_CMD_EN_LBN 56 +#define FRF_AB_EE_VPD_WR_CMD_EN_WIDTH 8 +#define FRF_AB_EE_VPD_BASE_LBN 32 +#define FRF_AB_EE_VPD_BASE_WIDTH 24 +#define FRF_AB_EE_VPD_LENGTH_LBN 16 +#define FRF_AB_EE_VPD_LENGTH_WIDTH 15 +#define FRF_AB_EE_VPD_AD_SIZE_LBN 8 +#define FRF_AB_EE_VPD_AD_SIZE_WIDTH 5 +#define FRF_AB_EE_VPD_ACCESS_ON_LBN 5 +#define FRF_AB_EE_VPD_ACCESS_ON_WIDTH 1 +#define FRF_AB_EE_VPD_ACCESS_BLOCK_LBN 4 +#define FRF_AB_EE_VPD_ACCESS_BLOCK_WIDTH 1 +#define FRF_AB_EE_VPD_DEV_SF_SEL_LBN 2 +#define FRF_AB_EE_VPD_DEV_SF_SEL_WIDTH 1 +#define FRF_AB_EE_VPD_EN_AD9_MODE_LBN 1 +#define FRF_AB_EE_VPD_EN_AD9_MODE_WIDTH 1 +#define FRF_AB_EE_VPD_EN_LBN 0 +#define FRF_AB_EE_VPD_EN_WIDTH 1 + +/* EE_VPD_SW_CNTL_REG: VPD access SW control register */ +#define FR_AB_EE_VPD_SW_CNTL 0x00000150 +#define FRF_AB_EE_VPD_CYCLE_PENDING_LBN 31 +#define FRF_AB_EE_VPD_CYCLE_PENDING_WIDTH 1 +#define FRF_AB_EE_VPD_CYC_WRITE_LBN 28 +#define FRF_AB_EE_VPD_CYC_WRITE_WIDTH 1 +#define FRF_AB_EE_VPD_CYC_ADR_LBN 0 +#define FRF_AB_EE_VPD_CYC_ADR_WIDTH 15 + +/* EE_VPD_SW_DATA_REG: VPD access SW data register */ +#define FR_AB_EE_VPD_SW_DATA 0x00000160 +#define FRF_AB_EE_VPD_CYC_DAT_LBN 0 +#define FRF_AB_EE_VPD_CYC_DAT_WIDTH 32 + +/* PBMX_DBG_IADDR_REG: Capture Module address register */ +#define FR_CZ_PBMX_DBG_IADDR 0x000001f0 +#define FRF_CZ_PBMX_DBG_IADDR_LBN 0 +#define FRF_CZ_PBMX_DBG_IADDR_WIDTH 32 + +/* PCIE_CORE_INDIRECT_REG: Indirect Access to PCIE Core registers */ +#define FR_BB_PCIE_CORE_INDIRECT 0x000001f0 +#define FRF_BB_PCIE_CORE_TARGET_DATA_LBN 32 +#define FRF_BB_PCIE_CORE_TARGET_DATA_WIDTH 32 +#define FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR_LBN 15 +#define FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR_WIDTH 1 +#define FRF_BB_PCIE_CORE_TARGET_REG_ADRS_LBN 0 +#define FRF_BB_PCIE_CORE_TARGET_REG_ADRS_WIDTH 12 + +/* PBMX_DBG_IDATA_REG: Capture Module data register */ +#define FR_CZ_PBMX_DBG_IDATA 0x000001f8 +#define FRF_CZ_PBMX_DBG_IDATA_LBN 0 +#define FRF_CZ_PBMX_DBG_IDATA_WIDTH 64 + +/* NIC_STAT_REG: NIC status register */ +#define FR_AB_NIC_STAT 0x00000200 +#define FRF_BB_AER_DIS_LBN 34 +#define FRF_BB_AER_DIS_WIDTH 1 +#define FRF_BB_EE_STRAP_EN_LBN 31 +#define FRF_BB_EE_STRAP_EN_WIDTH 1 +#define FRF_BB_EE_STRAP_LBN 24 +#define FRF_BB_EE_STRAP_WIDTH 4 +#define FRF_BB_REVISION_ID_LBN 17 +#define FRF_BB_REVISION_ID_WIDTH 7 +#define FRF_AB_ONCHIP_SRAM_LBN 16 +#define FRF_AB_ONCHIP_SRAM_WIDTH 1 +#define FRF_AB_SF_PRST_LBN 9 +#define FRF_AB_SF_PRST_WIDTH 1 +#define FRF_AB_EE_PRST_LBN 8 +#define FRF_AB_EE_PRST_WIDTH 1 +#define FRF_AB_ATE_MODE_LBN 3 +#define FRF_AB_ATE_MODE_WIDTH 1 +#define FRF_AB_STRAP_PINS_LBN 0 +#define FRF_AB_STRAP_PINS_WIDTH 3 + +/* GPIO_CTL_REG: GPIO control register */ +#define FR_AB_GPIO_CTL 0x00000210 +#define FRF_AB_GPIO_OUT3_LBN 112 +#define FRF_AB_GPIO_OUT3_WIDTH 16 +#define FRF_AB_GPIO_IN3_LBN 104 +#define FRF_AB_GPIO_IN3_WIDTH 8 +#define FRF_AB_GPIO_PWRUP_VALUE3_LBN 96 +#define FRF_AB_GPIO_PWRUP_VALUE3_WIDTH 8 +#define FRF_AB_GPIO_OUT2_LBN 80 +#define FRF_AB_GPIO_OUT2_WIDTH 16 +#define FRF_AB_GPIO_IN2_LBN 72 +#define FRF_AB_GPIO_IN2_WIDTH 8 +#define FRF_AB_GPIO_PWRUP_VALUE2_LBN 64 +#define FRF_AB_GPIO_PWRUP_VALUE2_WIDTH 8 +#define FRF_AB_GPIO15_OEN_LBN 63 +#define FRF_AB_GPIO15_OEN_WIDTH 1 +#define FRF_AB_GPIO14_OEN_LBN 62 +#define FRF_AB_GPIO14_OEN_WIDTH 1 +#define FRF_AB_GPIO13_OEN_LBN 61 +#define FRF_AB_GPIO13_OEN_WIDTH 1 +#define FRF_AB_GPIO12_OEN_LBN 60 +#define FRF_AB_GPIO12_OEN_WIDTH 1 +#define FRF_AB_GPIO11_OEN_LBN 59 +#define FRF_AB_GPIO11_OEN_WIDTH 1 +#define FRF_AB_GPIO10_OEN_LBN 58 +#define FRF_AB_GPIO10_OEN_WIDTH 1 +#define FRF_AB_GPIO9_OEN_LBN 57 +#define FRF_AB_GPIO9_OEN_WIDTH 1 +#define FRF_AB_GPIO8_OEN_LBN 56 +#define FRF_AB_GPIO8_OEN_WIDTH 1 +#define FRF_AB_GPIO15_OUT_LBN 55 +#define FRF_AB_GPIO15_OUT_WIDTH 1 +#define FRF_AB_GPIO14_OUT_LBN 54 +#define FRF_AB_GPIO14_OUT_WIDTH 1 +#define FRF_AB_GPIO13_OUT_LBN 53 +#define FRF_AB_GPIO13_OUT_WIDTH 1 +#define FRF_AB_GPIO12_OUT_LBN 52 +#define FRF_AB_GPIO12_OUT_WIDTH 1 +#define FRF_AB_GPIO11_OUT_LBN 51 +#define FRF_AB_GPIO11_OUT_WIDTH 1 +#define FRF_AB_GPIO10_OUT_LBN 50 +#define FRF_AB_GPIO10_OUT_WIDTH 1 +#define FRF_AB_GPIO9_OUT_LBN 49 +#define FRF_AB_GPIO9_OUT_WIDTH 1 +#define FRF_AB_GPIO8_OUT_LBN 48 +#define FRF_AB_GPIO8_OUT_WIDTH 1 +#define FRF_AB_GPIO15_IN_LBN 47 +#define FRF_AB_GPIO15_IN_WIDTH 1 +#define FRF_AB_GPIO14_IN_LBN 46 +#define FRF_AB_GPIO14_IN_WIDTH 1 +#define FRF_AB_GPIO13_IN_LBN 45 +#define FRF_AB_GPIO13_IN_WIDTH 1 +#define FRF_AB_GPIO12_IN_LBN 44 +#define FRF_AB_GPIO12_IN_WIDTH 1 +#define FRF_AB_GPIO11_IN_LBN 43 +#define FRF_AB_GPIO11_IN_WIDTH 1 +#define FRF_AB_GPIO10_IN_LBN 42 +#define FRF_AB_GPIO10_IN_WIDTH 1 +#define FRF_AB_GPIO9_IN_LBN 41 +#define FRF_AB_GPIO9_IN_WIDTH 1 +#define FRF_AB_GPIO8_IN_LBN 40 +#define FRF_AB_GPIO8_IN_WIDTH 1 +#define FRF_AB_GPIO15_PWRUP_VALUE_LBN 39 +#define FRF_AB_GPIO15_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO14_PWRUP_VALUE_LBN 38 +#define FRF_AB_GPIO14_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO13_PWRUP_VALUE_LBN 37 +#define FRF_AB_GPIO13_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO12_PWRUP_VALUE_LBN 36 +#define FRF_AB_GPIO12_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO11_PWRUP_VALUE_LBN 35 +#define FRF_AB_GPIO11_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO10_PWRUP_VALUE_LBN 34 +#define FRF_AB_GPIO10_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO9_PWRUP_VALUE_LBN 33 +#define FRF_AB_GPIO9_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO8_PWRUP_VALUE_LBN 32 +#define FRF_AB_GPIO8_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_CLK156_OUT_EN_LBN 31 +#define FRF_AB_CLK156_OUT_EN_WIDTH 1 +#define FRF_AB_USE_NIC_CLK_LBN 30 +#define FRF_AB_USE_NIC_CLK_WIDTH 1 +#define FRF_AB_GPIO5_OEN_LBN 29 +#define FRF_AB_GPIO5_OEN_WIDTH 1 +#define FRF_AB_GPIO4_OEN_LBN 28 +#define FRF_AB_GPIO4_OEN_WIDTH 1 +#define FRF_AB_GPIO3_OEN_LBN 27 +#define FRF_AB_GPIO3_OEN_WIDTH 1 +#define FRF_AB_GPIO2_OEN_LBN 26 +#define FRF_AB_GPIO2_OEN_WIDTH 1 +#define FRF_AB_GPIO1_OEN_LBN 25 +#define FRF_AB_GPIO1_OEN_WIDTH 1 +#define FRF_AB_GPIO0_OEN_LBN 24 +#define FRF_AB_GPIO0_OEN_WIDTH 1 +#define FRF_AB_GPIO7_OUT_LBN 23 +#define FRF_AB_GPIO7_OUT_WIDTH 1 +#define FRF_AB_GPIO6_OUT_LBN 22 +#define FRF_AB_GPIO6_OUT_WIDTH 1 +#define FRF_AB_GPIO5_OUT_LBN 21 +#define FRF_AB_GPIO5_OUT_WIDTH 1 +#define FRF_AB_GPIO4_OUT_LBN 20 +#define FRF_AB_GPIO4_OUT_WIDTH 1 +#define FRF_AB_GPIO3_OUT_LBN 19 +#define FRF_AB_GPIO3_OUT_WIDTH 1 +#define FRF_AB_GPIO2_OUT_LBN 18 +#define FRF_AB_GPIO2_OUT_WIDTH 1 +#define FRF_AB_GPIO1_OUT_LBN 17 +#define FRF_AB_GPIO1_OUT_WIDTH 1 +#define FRF_AB_GPIO0_OUT_LBN 16 +#define FRF_AB_GPIO0_OUT_WIDTH 1 +#define FRF_AB_GPIO7_IN_LBN 15 +#define FRF_AB_GPIO7_IN_WIDTH 1 +#define FRF_AB_GPIO6_IN_LBN 14 +#define FRF_AB_GPIO6_IN_WIDTH 1 +#define FRF_AB_GPIO5_IN_LBN 13 +#define FRF_AB_GPIO5_IN_WIDTH 1 +#define FRF_AB_GPIO4_IN_LBN 12 +#define FRF_AB_GPIO4_IN_WIDTH 1 +#define FRF_AB_GPIO3_IN_LBN 11 +#define FRF_AB_GPIO3_IN_WIDTH 1 +#define FRF_AB_GPIO2_IN_LBN 10 +#define FRF_AB_GPIO2_IN_WIDTH 1 +#define FRF_AB_GPIO1_IN_LBN 9 +#define FRF_AB_GPIO1_IN_WIDTH 1 +#define FRF_AB_GPIO0_IN_LBN 8 +#define FRF_AB_GPIO0_IN_WIDTH 1 +#define FRF_AB_GPIO7_PWRUP_VALUE_LBN 7 +#define FRF_AB_GPIO7_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO6_PWRUP_VALUE_LBN 6 +#define FRF_AB_GPIO6_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO5_PWRUP_VALUE_LBN 5 +#define FRF_AB_GPIO5_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO4_PWRUP_VALUE_LBN 4 +#define FRF_AB_GPIO4_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO3_PWRUP_VALUE_LBN 3 +#define FRF_AB_GPIO3_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO2_PWRUP_VALUE_LBN 2 +#define FRF_AB_GPIO2_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO1_PWRUP_VALUE_LBN 1 +#define FRF_AB_GPIO1_PWRUP_VALUE_WIDTH 1 +#define FRF_AB_GPIO0_PWRUP_VALUE_LBN 0 +#define FRF_AB_GPIO0_PWRUP_VALUE_WIDTH 1 + +/* GLB_CTL_REG: Global control register */ +#define FR_AB_GLB_CTL 0x00000220 +#define FRF_AB_EXT_PHY_RST_CTL_LBN 63 +#define FRF_AB_EXT_PHY_RST_CTL_WIDTH 1 +#define FRF_AB_XAUI_SD_RST_CTL_LBN 62 +#define FRF_AB_XAUI_SD_RST_CTL_WIDTH 1 +#define FRF_AB_PCIE_SD_RST_CTL_LBN 61 +#define FRF_AB_PCIE_SD_RST_CTL_WIDTH 1 +#define FRF_AA_PCIX_RST_CTL_LBN 60 +#define FRF_AA_PCIX_RST_CTL_WIDTH 1 +#define FRF_BB_BIU_RST_CTL_LBN 60 +#define FRF_BB_BIU_RST_CTL_WIDTH 1 +#define FRF_AB_PCIE_STKY_RST_CTL_LBN 59 +#define FRF_AB_PCIE_STKY_RST_CTL_WIDTH 1 +#define FRF_AB_PCIE_NSTKY_RST_CTL_LBN 58 +#define FRF_AB_PCIE_NSTKY_RST_CTL_WIDTH 1 +#define FRF_AB_PCIE_CORE_RST_CTL_LBN 57 +#define FRF_AB_PCIE_CORE_RST_CTL_WIDTH 1 +#define FRF_AB_XGRX_RST_CTL_LBN 56 +#define FRF_AB_XGRX_RST_CTL_WIDTH 1 +#define FRF_AB_XGTX_RST_CTL_LBN 55 +#define FRF_AB_XGTX_RST_CTL_WIDTH 1 +#define FRF_AB_EM_RST_CTL_LBN 54 +#define FRF_AB_EM_RST_CTL_WIDTH 1 +#define FRF_AB_EV_RST_CTL_LBN 53 +#define FRF_AB_EV_RST_CTL_WIDTH 1 +#define FRF_AB_SR_RST_CTL_LBN 52 +#define FRF_AB_SR_RST_CTL_WIDTH 1 +#define FRF_AB_RX_RST_CTL_LBN 51 +#define FRF_AB_RX_RST_CTL_WIDTH 1 +#define FRF_AB_TX_RST_CTL_LBN 50 +#define FRF_AB_TX_RST_CTL_WIDTH 1 +#define FRF_AB_EE_RST_CTL_LBN 49 +#define FRF_AB_EE_RST_CTL_WIDTH 1 +#define FRF_AB_CS_RST_CTL_LBN 48 +#define FRF_AB_CS_RST_CTL_WIDTH 1 +#define FRF_AB_HOT_RST_CTL_LBN 40 +#define FRF_AB_HOT_RST_CTL_WIDTH 2 +#define FRF_AB_RST_EXT_PHY_LBN 31 +#define FRF_AB_RST_EXT_PHY_WIDTH 1 +#define FRF_AB_RST_XAUI_SD_LBN 30 +#define FRF_AB_RST_XAUI_SD_WIDTH 1 +#define FRF_AB_RST_PCIE_SD_LBN 29 +#define FRF_AB_RST_PCIE_SD_WIDTH 1 +#define FRF_AA_RST_PCIX_LBN 28 +#define FRF_AA_RST_PCIX_WIDTH 1 +#define FRF_BB_RST_BIU_LBN 28 +#define FRF_BB_RST_BIU_WIDTH 1 +#define FRF_AB_RST_PCIE_STKY_LBN 27 +#define FRF_AB_RST_PCIE_STKY_WIDTH 1 +#define FRF_AB_RST_PCIE_NSTKY_LBN 26 +#define FRF_AB_RST_PCIE_NSTKY_WIDTH 1 +#define FRF_AB_RST_PCIE_CORE_LBN 25 +#define FRF_AB_RST_PCIE_CORE_WIDTH 1 +#define FRF_AB_RST_XGRX_LBN 24 +#define FRF_AB_RST_XGRX_WIDTH 1 +#define FRF_AB_RST_XGTX_LBN 23 +#define FRF_AB_RST_XGTX_WIDTH 1 +#define FRF_AB_RST_EM_LBN 22 +#define FRF_AB_RST_EM_WIDTH 1 +#define FRF_AB_RST_EV_LBN 21 +#define FRF_AB_RST_EV_WIDTH 1 +#define FRF_AB_RST_SR_LBN 20 +#define FRF_AB_RST_SR_WIDTH 1 +#define FRF_AB_RST_RX_LBN 19 +#define FRF_AB_RST_RX_WIDTH 1 +#define FRF_AB_RST_TX_LBN 18 +#define FRF_AB_RST_TX_WIDTH 1 +#define FRF_AB_RST_SF_LBN 17 +#define FRF_AB_RST_SF_WIDTH 1 +#define FRF_AB_RST_CS_LBN 16 +#define FRF_AB_RST_CS_WIDTH 1 +#define FRF_AB_INT_RST_DUR_LBN 4 +#define FRF_AB_INT_RST_DUR_WIDTH 3 +#define FRF_AB_EXT_PHY_RST_DUR_LBN 1 +#define FRF_AB_EXT_PHY_RST_DUR_WIDTH 3 +#define FFE_AB_EXT_PHY_RST_DUR_10240US 7 +#define FFE_AB_EXT_PHY_RST_DUR_5120US 6 +#define FFE_AB_EXT_PHY_RST_DUR_2560US 5 +#define FFE_AB_EXT_PHY_RST_DUR_1280US 4 +#define FFE_AB_EXT_PHY_RST_DUR_640US 3 +#define FFE_AB_EXT_PHY_RST_DUR_320US 2 +#define FFE_AB_EXT_PHY_RST_DUR_160US 1 +#define FFE_AB_EXT_PHY_RST_DUR_80US 0 +#define FRF_AB_SWRST_LBN 0 +#define FRF_AB_SWRST_WIDTH 1 + +/* FATAL_INTR_REG_KER: Fatal interrupt register for Kernel */ +#define FR_AZ_FATAL_INTR_KER 0x00000230 +#define FRF_CZ_SRAM_PERR_INT_P_KER_EN_LBN 44 +#define FRF_CZ_SRAM_PERR_INT_P_KER_EN_WIDTH 1 +#define FRF_AB_PCI_BUSERR_INT_KER_EN_LBN 43 +#define FRF_AB_PCI_BUSERR_INT_KER_EN_WIDTH 1 +#define FRF_CZ_MBU_PERR_INT_KER_EN_LBN 43 +#define FRF_CZ_MBU_PERR_INT_KER_EN_WIDTH 1 +#define FRF_AZ_SRAM_OOB_INT_KER_EN_LBN 42 +#define FRF_AZ_SRAM_OOB_INT_KER_EN_WIDTH 1 +#define FRF_AZ_BUFID_OOB_INT_KER_EN_LBN 41 +#define FRF_AZ_BUFID_OOB_INT_KER_EN_WIDTH 1 +#define FRF_AZ_MEM_PERR_INT_KER_EN_LBN 40 +#define FRF_AZ_MEM_PERR_INT_KER_EN_WIDTH 1 +#define FRF_AZ_RBUF_OWN_INT_KER_EN_LBN 39 +#define FRF_AZ_RBUF_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_TBUF_OWN_INT_KER_EN_LBN 38 +#define FRF_AZ_TBUF_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_RDESCQ_OWN_INT_KER_EN_LBN 37 +#define FRF_AZ_RDESCQ_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_TDESCQ_OWN_INT_KER_EN_LBN 36 +#define FRF_AZ_TDESCQ_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_EVQ_OWN_INT_KER_EN_LBN 35 +#define FRF_AZ_EVQ_OWN_INT_KER_EN_WIDTH 1 +#define FRF_AZ_EVF_OFLO_INT_KER_EN_LBN 34 +#define FRF_AZ_EVF_OFLO_INT_KER_EN_WIDTH 1 +#define FRF_AZ_ILL_ADR_INT_KER_EN_LBN 33 +#define FRF_AZ_ILL_ADR_INT_KER_EN_WIDTH 1 +#define FRF_AZ_SRM_PERR_INT_KER_EN_LBN 32 +#define FRF_AZ_SRM_PERR_INT_KER_EN_WIDTH 1 +#define FRF_CZ_SRAM_PERR_INT_P_KER_LBN 12 +#define FRF_CZ_SRAM_PERR_INT_P_KER_WIDTH 1 +#define FRF_AB_PCI_BUSERR_INT_KER_LBN 11 +#define FRF_AB_PCI_BUSERR_INT_KER_WIDTH 1 +#define FRF_CZ_MBU_PERR_INT_KER_LBN 11 +#define FRF_CZ_MBU_PERR_INT_KER_WIDTH 1 +#define FRF_AZ_SRAM_OOB_INT_KER_LBN 10 +#define FRF_AZ_SRAM_OOB_INT_KER_WIDTH 1 +#define FRF_AZ_BUFID_DC_OOB_INT_KER_LBN 9 +#define FRF_AZ_BUFID_DC_OOB_INT_KER_WIDTH 1 +#define FRF_AZ_MEM_PERR_INT_KER_LBN 8 +#define FRF_AZ_MEM_PERR_INT_KER_WIDTH 1 +#define FRF_AZ_RBUF_OWN_INT_KER_LBN 7 +#define FRF_AZ_RBUF_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_TBUF_OWN_INT_KER_LBN 6 +#define FRF_AZ_TBUF_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_RDESCQ_OWN_INT_KER_LBN 5 +#define FRF_AZ_RDESCQ_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_TDESCQ_OWN_INT_KER_LBN 4 +#define FRF_AZ_TDESCQ_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_EVQ_OWN_INT_KER_LBN 3 +#define FRF_AZ_EVQ_OWN_INT_KER_WIDTH 1 +#define FRF_AZ_EVF_OFLO_INT_KER_LBN 2 +#define FRF_AZ_EVF_OFLO_INT_KER_WIDTH 1 +#define FRF_AZ_ILL_ADR_INT_KER_LBN 1 +#define FRF_AZ_ILL_ADR_INT_KER_WIDTH 1 +#define FRF_AZ_SRM_PERR_INT_KER_LBN 0 +#define FRF_AZ_SRM_PERR_INT_KER_WIDTH 1 + +/* FATAL_INTR_REG_CHAR: Fatal interrupt register for Char */ +#define FR_BZ_FATAL_INTR_CHAR 0x00000240 +#define FRF_CZ_SRAM_PERR_INT_P_CHAR_EN_LBN 44 +#define FRF_CZ_SRAM_PERR_INT_P_CHAR_EN_WIDTH 1 +#define FRF_BB_PCI_BUSERR_INT_CHAR_EN_LBN 43 +#define FRF_BB_PCI_BUSERR_INT_CHAR_EN_WIDTH 1 +#define FRF_CZ_MBU_PERR_INT_CHAR_EN_LBN 43 +#define FRF_CZ_MBU_PERR_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_SRAM_OOB_INT_CHAR_EN_LBN 42 +#define FRF_BZ_SRAM_OOB_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_BUFID_OOB_INT_CHAR_EN_LBN 41 +#define FRF_BZ_BUFID_OOB_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_MEM_PERR_INT_CHAR_EN_LBN 40 +#define FRF_BZ_MEM_PERR_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_RBUF_OWN_INT_CHAR_EN_LBN 39 +#define FRF_BZ_RBUF_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_TBUF_OWN_INT_CHAR_EN_LBN 38 +#define FRF_BZ_TBUF_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_RDESCQ_OWN_INT_CHAR_EN_LBN 37 +#define FRF_BZ_RDESCQ_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_TDESCQ_OWN_INT_CHAR_EN_LBN 36 +#define FRF_BZ_TDESCQ_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_EVQ_OWN_INT_CHAR_EN_LBN 35 +#define FRF_BZ_EVQ_OWN_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_EVF_OFLO_INT_CHAR_EN_LBN 34 +#define FRF_BZ_EVF_OFLO_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_ILL_ADR_INT_CHAR_EN_LBN 33 +#define FRF_BZ_ILL_ADR_INT_CHAR_EN_WIDTH 1 +#define FRF_BZ_SRM_PERR_INT_CHAR_EN_LBN 32 +#define FRF_BZ_SRM_PERR_INT_CHAR_EN_WIDTH 1 +#define FRF_CZ_SRAM_PERR_INT_P_CHAR_LBN 12 +#define FRF_CZ_SRAM_PERR_INT_P_CHAR_WIDTH 1 +#define FRF_BB_PCI_BUSERR_INT_CHAR_LBN 11 +#define FRF_BB_PCI_BUSERR_INT_CHAR_WIDTH 1 +#define FRF_CZ_MBU_PERR_INT_CHAR_LBN 11 +#define FRF_CZ_MBU_PERR_INT_CHAR_WIDTH 1 +#define FRF_BZ_SRAM_OOB_INT_CHAR_LBN 10 +#define FRF_BZ_SRAM_OOB_INT_CHAR_WIDTH 1 +#define FRF_BZ_BUFID_DC_OOB_INT_CHAR_LBN 9 +#define FRF_BZ_BUFID_DC_OOB_INT_CHAR_WIDTH 1 +#define FRF_BZ_MEM_PERR_INT_CHAR_LBN 8 +#define FRF_BZ_MEM_PERR_INT_CHAR_WIDTH 1 +#define FRF_BZ_RBUF_OWN_INT_CHAR_LBN 7 +#define FRF_BZ_RBUF_OWN_INT_CHAR_WIDTH 1 +#define FRF_BZ_TBUF_OWN_INT_CHAR_LBN 6 +#define FRF_BZ_TBUF_OWN_INT_CHAR_WIDTH 1 +#define FRF_BZ_RDESCQ_OWN_INT_CHAR_LBN 5 +#define FRF_BZ_RDESCQ_OWN_INT_CHAR_WIDTH 1 +#define FRF_BZ_TDESCQ_OWN_INT_CHAR_LBN 4 +#define FRF_BZ_TDESCQ_OWN_INT_CHAR_WIDTH 1 +#define FRF_BZ_EVQ_OWN_INT_CHAR_LBN 3 +#define FRF_BZ_EVQ_OWN_INT_CHAR_WIDTH 1 +#define FRF_BZ_EVF_OFLO_INT_CHAR_LBN 2 +#define FRF_BZ_EVF_OFLO_INT_CHAR_WIDTH 1 +#define FRF_BZ_ILL_ADR_INT_CHAR_LBN 1 +#define FRF_BZ_ILL_ADR_INT_CHAR_WIDTH 1 +#define FRF_BZ_SRM_PERR_INT_CHAR_LBN 0 +#define FRF_BZ_SRM_PERR_INT_CHAR_WIDTH 1 + +/* DP_CTRL_REG: Datapath control register */ +#define FR_BZ_DP_CTRL 0x00000250 +#define FRF_BZ_FLS_EVQ_ID_LBN 0 +#define FRF_BZ_FLS_EVQ_ID_WIDTH 12 + +/* MEM_STAT_REG: Memory status register */ +#define FR_AZ_MEM_STAT 0x00000260 +#define FRF_AB_MEM_PERR_VEC_LBN 53 +#define FRF_AB_MEM_PERR_VEC_WIDTH 38 +#define FRF_AB_MBIST_CORR_LBN 38 +#define FRF_AB_MBIST_CORR_WIDTH 15 +#define FRF_AB_MBIST_ERR_LBN 0 +#define FRF_AB_MBIST_ERR_WIDTH 40 +#define FRF_CZ_MEM_PERR_VEC_LBN 0 +#define FRF_CZ_MEM_PERR_VEC_WIDTH 35 + +/* CS_DEBUG_REG: Debug register */ +#define FR_AZ_CS_DEBUG 0x00000270 +#define FRF_AB_GLB_DEBUG2_SEL_LBN 50 +#define FRF_AB_GLB_DEBUG2_SEL_WIDTH 3 +#define FRF_AB_DEBUG_BLK_SEL2_LBN 47 +#define FRF_AB_DEBUG_BLK_SEL2_WIDTH 3 +#define FRF_AB_DEBUG_BLK_SEL1_LBN 44 +#define FRF_AB_DEBUG_BLK_SEL1_WIDTH 3 +#define FRF_AB_DEBUG_BLK_SEL0_LBN 41 +#define FRF_AB_DEBUG_BLK_SEL0_WIDTH 3 +#define FRF_CZ_CS_PORT_NUM_LBN 40 +#define FRF_CZ_CS_PORT_NUM_WIDTH 2 +#define FRF_AB_MISC_DEBUG_ADDR_LBN 36 +#define FRF_AB_MISC_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_SERDES_DEBUG_ADDR_LBN 31 +#define FRF_AB_SERDES_DEBUG_ADDR_WIDTH 5 +#define FRF_CZ_CS_PORT_FPE_LBN 1 +#define FRF_CZ_CS_PORT_FPE_WIDTH 35 +#define FRF_AB_EM_DEBUG_ADDR_LBN 26 +#define FRF_AB_EM_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_SR_DEBUG_ADDR_LBN 21 +#define FRF_AB_SR_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_EV_DEBUG_ADDR_LBN 16 +#define FRF_AB_EV_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_RX_DEBUG_ADDR_LBN 11 +#define FRF_AB_RX_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_TX_DEBUG_ADDR_LBN 6 +#define FRF_AB_TX_DEBUG_ADDR_WIDTH 5 +#define FRF_AB_CS_BIU_DEBUG_ADDR_LBN 1 +#define FRF_AB_CS_BIU_DEBUG_ADDR_WIDTH 5 +#define FRF_AZ_CS_DEBUG_EN_LBN 0 +#define FRF_AZ_CS_DEBUG_EN_WIDTH 1 + +/* DRIVER_REG: Driver scratch register [0-7] */ +#define FR_AZ_DRIVER 0x00000280 +#define FR_AZ_DRIVER_STEP 16 +#define FR_AZ_DRIVER_ROWS 8 +#define FRF_AZ_DRIVER_DW0_LBN 0 +#define FRF_AZ_DRIVER_DW0_WIDTH 32 + +/* ALTERA_BUILD_REG: Altera build register */ +#define FR_AZ_ALTERA_BUILD 0x00000300 +#define FRF_AZ_ALTERA_BUILD_VER_LBN 0 +#define FRF_AZ_ALTERA_BUILD_VER_WIDTH 32 + +/* CSR_SPARE_REG: Spare register */ +#define FR_AZ_CSR_SPARE 0x00000310 +#define FRF_AB_MEM_PERR_EN_LBN 64 +#define FRF_AB_MEM_PERR_EN_WIDTH 38 +#define FRF_CZ_MEM_PERR_EN_LBN 64 +#define FRF_CZ_MEM_PERR_EN_WIDTH 35 +#define FRF_AB_MEM_PERR_EN_TX_DATA_LBN 72 +#define FRF_AB_MEM_PERR_EN_TX_DATA_WIDTH 2 +#define FRF_AZ_CSR_SPARE_BITS_LBN 0 +#define FRF_AZ_CSR_SPARE_BITS_WIDTH 32 + +/* PCIE_SD_CTL0123_REG: PCIE SerDes control register 0 to 3 */ +#define FR_AB_PCIE_SD_CTL0123 0x00000320 +#define FRF_AB_PCIE_TESTSIG_H_LBN 96 +#define FRF_AB_PCIE_TESTSIG_H_WIDTH 19 +#define FRF_AB_PCIE_TESTSIG_L_LBN 64 +#define FRF_AB_PCIE_TESTSIG_L_WIDTH 19 +#define FRF_AB_PCIE_OFFSET_LBN 56 +#define FRF_AB_PCIE_OFFSET_WIDTH 8 +#define FRF_AB_PCIE_OFFSETEN_H_LBN 55 +#define FRF_AB_PCIE_OFFSETEN_H_WIDTH 1 +#define FRF_AB_PCIE_OFFSETEN_L_LBN 54 +#define FRF_AB_PCIE_OFFSETEN_L_WIDTH 1 +#define FRF_AB_PCIE_HIVMODE_H_LBN 53 +#define FRF_AB_PCIE_HIVMODE_H_WIDTH 1 +#define FRF_AB_PCIE_HIVMODE_L_LBN 52 +#define FRF_AB_PCIE_HIVMODE_L_WIDTH 1 +#define FRF_AB_PCIE_PARRESET_H_LBN 51 +#define FRF_AB_PCIE_PARRESET_H_WIDTH 1 +#define FRF_AB_PCIE_PARRESET_L_LBN 50 +#define FRF_AB_PCIE_PARRESET_L_WIDTH 1 +#define FRF_AB_PCIE_LPBKWDRV_H_LBN 49 +#define FRF_AB_PCIE_LPBKWDRV_H_WIDTH 1 +#define FRF_AB_PCIE_LPBKWDRV_L_LBN 48 +#define FRF_AB_PCIE_LPBKWDRV_L_WIDTH 1 +#define FRF_AB_PCIE_LPBK_LBN 40 +#define FRF_AB_PCIE_LPBK_WIDTH 8 +#define FRF_AB_PCIE_PARLPBK_LBN 32 +#define FRF_AB_PCIE_PARLPBK_WIDTH 8 +#define FRF_AB_PCIE_RXTERMADJ_H_LBN 30 +#define FRF_AB_PCIE_RXTERMADJ_H_WIDTH 2 +#define FRF_AB_PCIE_RXTERMADJ_L_LBN 28 +#define FRF_AB_PCIE_RXTERMADJ_L_WIDTH 2 +#define FFE_AB_PCIE_RXTERMADJ_MIN15PCNT 3 +#define FFE_AB_PCIE_RXTERMADJ_PL10PCNT 2 +#define FFE_AB_PCIE_RXTERMADJ_MIN17PCNT 1 +#define FFE_AB_PCIE_RXTERMADJ_NOMNL 0 +#define FRF_AB_PCIE_TXTERMADJ_H_LBN 26 +#define FRF_AB_PCIE_TXTERMADJ_H_WIDTH 2 +#define FRF_AB_PCIE_TXTERMADJ_L_LBN 24 +#define FRF_AB_PCIE_TXTERMADJ_L_WIDTH 2 +#define FFE_AB_PCIE_TXTERMADJ_MIN15PCNT 3 +#define FFE_AB_PCIE_TXTERMADJ_PL10PCNT 2 +#define FFE_AB_PCIE_TXTERMADJ_MIN17PCNT 1 +#define FFE_AB_PCIE_TXTERMADJ_NOMNL 0 +#define FRF_AB_PCIE_RXEQCTL_H_LBN 18 +#define FRF_AB_PCIE_RXEQCTL_H_WIDTH 2 +#define FRF_AB_PCIE_RXEQCTL_L_LBN 16 +#define FRF_AB_PCIE_RXEQCTL_L_WIDTH 2 +#define FFE_AB_PCIE_RXEQCTL_OFF_ALT 3 +#define FFE_AB_PCIE_RXEQCTL_OFF 2 +#define FFE_AB_PCIE_RXEQCTL_MIN 1 +#define FFE_AB_PCIE_RXEQCTL_MAX 0 +#define FRF_AB_PCIE_HIDRV_LBN 8 +#define FRF_AB_PCIE_HIDRV_WIDTH 8 +#define FRF_AB_PCIE_LODRV_LBN 0 +#define FRF_AB_PCIE_LODRV_WIDTH 8 + +/* PCIE_SD_CTL45_REG: PCIE SerDes control register 4 and 5 */ +#define FR_AB_PCIE_SD_CTL45 0x00000330 +#define FRF_AB_PCIE_DTX7_LBN 60 +#define FRF_AB_PCIE_DTX7_WIDTH 4 +#define FRF_AB_PCIE_DTX6_LBN 56 +#define FRF_AB_PCIE_DTX6_WIDTH 4 +#define FRF_AB_PCIE_DTX5_LBN 52 +#define FRF_AB_PCIE_DTX5_WIDTH 4 +#define FRF_AB_PCIE_DTX4_LBN 48 +#define FRF_AB_PCIE_DTX4_WIDTH 4 +#define FRF_AB_PCIE_DTX3_LBN 44 +#define FRF_AB_PCIE_DTX3_WIDTH 4 +#define FRF_AB_PCIE_DTX2_LBN 40 +#define FRF_AB_PCIE_DTX2_WIDTH 4 +#define FRF_AB_PCIE_DTX1_LBN 36 +#define FRF_AB_PCIE_DTX1_WIDTH 4 +#define FRF_AB_PCIE_DTX0_LBN 32 +#define FRF_AB_PCIE_DTX0_WIDTH 4 +#define FRF_AB_PCIE_DEQ7_LBN 28 +#define FRF_AB_PCIE_DEQ7_WIDTH 4 +#define FRF_AB_PCIE_DEQ6_LBN 24 +#define FRF_AB_PCIE_DEQ6_WIDTH 4 +#define FRF_AB_PCIE_DEQ5_LBN 20 +#define FRF_AB_PCIE_DEQ5_WIDTH 4 +#define FRF_AB_PCIE_DEQ4_LBN 16 +#define FRF_AB_PCIE_DEQ4_WIDTH 4 +#define FRF_AB_PCIE_DEQ3_LBN 12 +#define FRF_AB_PCIE_DEQ3_WIDTH 4 +#define FRF_AB_PCIE_DEQ2_LBN 8 +#define FRF_AB_PCIE_DEQ2_WIDTH 4 +#define FRF_AB_PCIE_DEQ1_LBN 4 +#define FRF_AB_PCIE_DEQ1_WIDTH 4 +#define FRF_AB_PCIE_DEQ0_LBN 0 +#define FRF_AB_PCIE_DEQ0_WIDTH 4 + +/* PCIE_PCS_CTL_STAT_REG: PCIE PCS control and status register */ +#define FR_AB_PCIE_PCS_CTL_STAT 0x00000340 +#define FRF_AB_PCIE_PRBSERRCOUNT0_H_LBN 52 +#define FRF_AB_PCIE_PRBSERRCOUNT0_H_WIDTH 4 +#define FRF_AB_PCIE_PRBSERRCOUNT0_L_LBN 48 +#define FRF_AB_PCIE_PRBSERRCOUNT0_L_WIDTH 4 +#define FRF_AB_PCIE_PRBSERR_LBN 40 +#define FRF_AB_PCIE_PRBSERR_WIDTH 8 +#define FRF_AB_PCIE_PRBSERRH0_LBN 32 +#define FRF_AB_PCIE_PRBSERRH0_WIDTH 8 +#define FRF_AB_PCIE_FASTINIT_H_LBN 15 +#define FRF_AB_PCIE_FASTINIT_H_WIDTH 1 +#define FRF_AB_PCIE_FASTINIT_L_LBN 14 +#define FRF_AB_PCIE_FASTINIT_L_WIDTH 1 +#define FRF_AB_PCIE_CTCDISABLE_H_LBN 13 +#define FRF_AB_PCIE_CTCDISABLE_H_WIDTH 1 +#define FRF_AB_PCIE_CTCDISABLE_L_LBN 12 +#define FRF_AB_PCIE_CTCDISABLE_L_WIDTH 1 +#define FRF_AB_PCIE_PRBSSYNC_H_LBN 11 +#define FRF_AB_PCIE_PRBSSYNC_H_WIDTH 1 +#define FRF_AB_PCIE_PRBSSYNC_L_LBN 10 +#define FRF_AB_PCIE_PRBSSYNC_L_WIDTH 1 +#define FRF_AB_PCIE_PRBSERRACK_H_LBN 9 +#define FRF_AB_PCIE_PRBSERRACK_H_WIDTH 1 +#define FRF_AB_PCIE_PRBSERRACK_L_LBN 8 +#define FRF_AB_PCIE_PRBSERRACK_L_WIDTH 1 +#define FRF_AB_PCIE_PRBSSEL_LBN 0 +#define FRF_AB_PCIE_PRBSSEL_WIDTH 8 + +/* DEBUG_DATA_OUT_REG: Live Debug and Debug 2 out ports */ +#define FR_BB_DEBUG_DATA_OUT 0x00000350 +#define FRF_BB_DEBUG2_PORT_LBN 25 +#define FRF_BB_DEBUG2_PORT_WIDTH 15 +#define FRF_BB_DEBUG1_PORT_LBN 0 +#define FRF_BB_DEBUG1_PORT_WIDTH 25 + +/* EVQ_RPTR_REGP0: Event queue read pointer register */ +#define FR_BZ_EVQ_RPTR_P0 0x00000400 +#define FR_BZ_EVQ_RPTR_P0_STEP 8192 +#define FR_BZ_EVQ_RPTR_P0_ROWS 1024 +/* EVQ_RPTR_REG_KER: Event queue read pointer register */ +#define FR_AA_EVQ_RPTR_KER 0x00011b00 +#define FR_AA_EVQ_RPTR_KER_STEP 4 +#define FR_AA_EVQ_RPTR_KER_ROWS 4 +/* EVQ_RPTR_REG: Event queue read pointer register */ +#define FR_BZ_EVQ_RPTR 0x00fa0000 +#define FR_BZ_EVQ_RPTR_STEP 16 +#define FR_BB_EVQ_RPTR_ROWS 4096 +#define FR_CZ_EVQ_RPTR_ROWS 1024 +/* EVQ_RPTR_REGP123: Event queue read pointer register */ +#define FR_BB_EVQ_RPTR_P123 0x01000400 +#define FR_BB_EVQ_RPTR_P123_STEP 8192 +#define FR_BB_EVQ_RPTR_P123_ROWS 3072 +#define FRF_AZ_EVQ_RPTR_VLD_LBN 15 +#define FRF_AZ_EVQ_RPTR_VLD_WIDTH 1 +#define FRF_AZ_EVQ_RPTR_LBN 0 +#define FRF_AZ_EVQ_RPTR_WIDTH 15 + +/* TIMER_COMMAND_REGP0: Timer Command Registers */ +#define FR_BZ_TIMER_COMMAND_P0 0x00000420 +#define FR_BZ_TIMER_COMMAND_P0_STEP 8192 +#define FR_BZ_TIMER_COMMAND_P0_ROWS 1024 +/* TIMER_COMMAND_REG_KER: Timer Command Registers */ +#define FR_AA_TIMER_COMMAND_KER 0x00000420 +#define FR_AA_TIMER_COMMAND_KER_STEP 8192 +#define FR_AA_TIMER_COMMAND_KER_ROWS 4 +/* TIMER_COMMAND_REGP123: Timer Command Registers */ +#define FR_BB_TIMER_COMMAND_P123 0x01000420 +#define FR_BB_TIMER_COMMAND_P123_STEP 8192 +#define FR_BB_TIMER_COMMAND_P123_ROWS 3072 +#define FRF_CZ_TC_TIMER_MODE_LBN 14 +#define FRF_CZ_TC_TIMER_MODE_WIDTH 2 +#define FRF_AB_TC_TIMER_MODE_LBN 12 +#define FRF_AB_TC_TIMER_MODE_WIDTH 2 +#define FRF_CZ_TC_TIMER_VAL_LBN 0 +#define FRF_CZ_TC_TIMER_VAL_WIDTH 14 +#define FRF_AB_TC_TIMER_VAL_LBN 0 +#define FRF_AB_TC_TIMER_VAL_WIDTH 12 + +/* DRV_EV_REG: Driver generated event register */ +#define FR_AZ_DRV_EV 0x00000440 +#define FRF_AZ_DRV_EV_QID_LBN 64 +#define FRF_AZ_DRV_EV_QID_WIDTH 12 +#define FRF_AZ_DRV_EV_DATA_LBN 0 +#define FRF_AZ_DRV_EV_DATA_WIDTH 64 + +/* EVQ_CTL_REG: Event queue control register */ +#define FR_AZ_EVQ_CTL 0x00000450 +#define FRF_CZ_RX_EVQ_WAKEUP_MASK_LBN 15 +#define FRF_CZ_RX_EVQ_WAKEUP_MASK_WIDTH 10 +#define FRF_BB_RX_EVQ_WAKEUP_MASK_LBN 15 +#define FRF_BB_RX_EVQ_WAKEUP_MASK_WIDTH 6 +#define FRF_AZ_EVQ_OWNERR_CTL_LBN 14 +#define FRF_AZ_EVQ_OWNERR_CTL_WIDTH 1 +#define FRF_AZ_EVQ_FIFO_AF_TH_LBN 7 +#define FRF_AZ_EVQ_FIFO_AF_TH_WIDTH 7 +#define FRF_AZ_EVQ_FIFO_NOTAF_TH_LBN 0 +#define FRF_AZ_EVQ_FIFO_NOTAF_TH_WIDTH 7 + +/* EVQ_CNT1_REG: Event counter 1 register */ +#define FR_AZ_EVQ_CNT1 0x00000460 +#define FRF_AZ_EVQ_CNT_PRE_FIFO_LBN 120 +#define FRF_AZ_EVQ_CNT_PRE_FIFO_WIDTH 7 +#define FRF_AZ_EVQ_CNT_TOBIU_LBN 100 +#define FRF_AZ_EVQ_CNT_TOBIU_WIDTH 20 +#define FRF_AZ_EVQ_TX_REQ_CNT_LBN 80 +#define FRF_AZ_EVQ_TX_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_RX_REQ_CNT_LBN 60 +#define FRF_AZ_EVQ_RX_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_EM_REQ_CNT_LBN 40 +#define FRF_AZ_EVQ_EM_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_CSR_REQ_CNT_LBN 20 +#define FRF_AZ_EVQ_CSR_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_ERR_REQ_CNT_LBN 0 +#define FRF_AZ_EVQ_ERR_REQ_CNT_WIDTH 20 + +/* EVQ_CNT2_REG: Event counter 2 register */ +#define FR_AZ_EVQ_CNT2 0x00000470 +#define FRF_AZ_EVQ_UPD_REQ_CNT_LBN 104 +#define FRF_AZ_EVQ_UPD_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_CLR_REQ_CNT_LBN 84 +#define FRF_AZ_EVQ_CLR_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_RDY_CNT_LBN 80 +#define FRF_AZ_EVQ_RDY_CNT_WIDTH 4 +#define FRF_AZ_EVQ_WU_REQ_CNT_LBN 60 +#define FRF_AZ_EVQ_WU_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_WET_REQ_CNT_LBN 40 +#define FRF_AZ_EVQ_WET_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_INIT_REQ_CNT_LBN 20 +#define FRF_AZ_EVQ_INIT_REQ_CNT_WIDTH 20 +#define FRF_AZ_EVQ_TM_REQ_CNT_LBN 0 +#define FRF_AZ_EVQ_TM_REQ_CNT_WIDTH 20 + +/* USR_EV_REG: Event mailbox register */ +#define FR_CZ_USR_EV 0x00000540 +#define FR_CZ_USR_EV_STEP 8192 +#define FR_CZ_USR_EV_ROWS 1024 +#define FRF_CZ_USR_EV_DATA_LBN 0 +#define FRF_CZ_USR_EV_DATA_WIDTH 32 + +/* BUF_TBL_CFG_REG: Buffer table configuration register */ +#define FR_AZ_BUF_TBL_CFG 0x00000600 +#define FRF_AZ_BUF_TBL_MODE_LBN 3 +#define FRF_AZ_BUF_TBL_MODE_WIDTH 1 + +/* SRM_RX_DC_CFG_REG: SRAM receive descriptor cache configuration register */ +#define FR_AZ_SRM_RX_DC_CFG 0x00000610 +#define FRF_AZ_SRM_CLK_TMP_EN_LBN 21 +#define FRF_AZ_SRM_CLK_TMP_EN_WIDTH 1 +#define FRF_AZ_SRM_RX_DC_BASE_ADR_LBN 0 +#define FRF_AZ_SRM_RX_DC_BASE_ADR_WIDTH 21 + +/* SRM_TX_DC_CFG_REG: SRAM transmit descriptor cache configuration register */ +#define FR_AZ_SRM_TX_DC_CFG 0x00000620 +#define FRF_AZ_SRM_TX_DC_BASE_ADR_LBN 0 +#define FRF_AZ_SRM_TX_DC_BASE_ADR_WIDTH 21 + +/* SRM_CFG_REG: SRAM configuration register */ +#define FR_AZ_SRM_CFG 0x00000630 +#define FRF_AZ_SRM_OOB_ADR_INTEN_LBN 5 +#define FRF_AZ_SRM_OOB_ADR_INTEN_WIDTH 1 +#define FRF_AZ_SRM_OOB_BUF_INTEN_LBN 4 +#define FRF_AZ_SRM_OOB_BUF_INTEN_WIDTH 1 +#define FRF_AZ_SRM_INIT_EN_LBN 3 +#define FRF_AZ_SRM_INIT_EN_WIDTH 1 +#define FRF_AZ_SRM_NUM_BANK_LBN 2 +#define FRF_AZ_SRM_NUM_BANK_WIDTH 1 +#define FRF_AZ_SRM_BANK_SIZE_LBN 0 +#define FRF_AZ_SRM_BANK_SIZE_WIDTH 2 + +/* BUF_TBL_UPD_REG: Buffer table update register */ +#define FR_AZ_BUF_TBL_UPD 0x00000650 +#define FRF_AZ_BUF_UPD_CMD_LBN 63 +#define FRF_AZ_BUF_UPD_CMD_WIDTH 1 +#define FRF_AZ_BUF_CLR_CMD_LBN 62 +#define FRF_AZ_BUF_CLR_CMD_WIDTH 1 +#define FRF_AZ_BUF_CLR_END_ID_LBN 32 +#define FRF_AZ_BUF_CLR_END_ID_WIDTH 20 +#define FRF_AZ_BUF_CLR_START_ID_LBN 0 +#define FRF_AZ_BUF_CLR_START_ID_WIDTH 20 + +/* SRM_UPD_EVQ_REG: Buffer table update register */ +#define FR_AZ_SRM_UPD_EVQ 0x00000660 +#define FRF_AZ_SRM_UPD_EVQ_ID_LBN 0 +#define FRF_AZ_SRM_UPD_EVQ_ID_WIDTH 12 + +/* SRAM_PARITY_REG: SRAM parity register. */ +#define FR_AZ_SRAM_PARITY 0x00000670 +#define FRF_CZ_BYPASS_ECC_LBN 3 +#define FRF_CZ_BYPASS_ECC_WIDTH 1 +#define FRF_CZ_SEC_INT_LBN 2 +#define FRF_CZ_SEC_INT_WIDTH 1 +#define FRF_CZ_FORCE_SRAM_DOUBLE_ERR_LBN 1 +#define FRF_CZ_FORCE_SRAM_DOUBLE_ERR_WIDTH 1 +#define FRF_AB_FORCE_SRAM_PERR_LBN 0 +#define FRF_AB_FORCE_SRAM_PERR_WIDTH 1 +#define FRF_CZ_FORCE_SRAM_SINGLE_ERR_LBN 0 +#define FRF_CZ_FORCE_SRAM_SINGLE_ERR_WIDTH 1 + +/* RX_CFG_REG: Receive configuration register */ +#define FR_AZ_RX_CFG 0x00000800 +#define FRF_CZ_RX_MIN_KBUF_SIZE_LBN 72 +#define FRF_CZ_RX_MIN_KBUF_SIZE_WIDTH 14 +#define FRF_CZ_RX_HDR_SPLIT_EN_LBN 71 +#define FRF_CZ_RX_HDR_SPLIT_EN_WIDTH 1 +#define FRF_CZ_RX_HDR_SPLIT_PLD_BUF_SIZE_LBN 62 +#define FRF_CZ_RX_HDR_SPLIT_PLD_BUF_SIZE_WIDTH 9 +#define FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE_LBN 53 +#define FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE_WIDTH 9 +#define FRF_CZ_RX_PRE_RFF_IPG_LBN 49 +#define FRF_CZ_RX_PRE_RFF_IPG_WIDTH 4 +#define FRF_BZ_RX_TCP_SUP_LBN 48 +#define FRF_BZ_RX_TCP_SUP_WIDTH 1 +#define FRF_BZ_RX_INGR_EN_LBN 47 +#define FRF_BZ_RX_INGR_EN_WIDTH 1 +#define FRF_BZ_RX_IP_HASH_LBN 46 +#define FRF_BZ_RX_IP_HASH_WIDTH 1 +#define FRF_BZ_RX_HASH_ALG_LBN 45 +#define FRF_BZ_RX_HASH_ALG_WIDTH 1 +#define FRF_BZ_RX_HASH_INSRT_HDR_LBN 44 +#define FRF_BZ_RX_HASH_INSRT_HDR_WIDTH 1 +#define FRF_BZ_RX_DESC_PUSH_EN_LBN 43 +#define FRF_BZ_RX_DESC_PUSH_EN_WIDTH 1 +#define FRF_BZ_RX_RDW_PATCH_EN_LBN 42 +#define FRF_BZ_RX_RDW_PATCH_EN_WIDTH 1 +#define FRF_BB_RX_PCI_BURST_SIZE_LBN 39 +#define FRF_BB_RX_PCI_BURST_SIZE_WIDTH 3 +#define FRF_BZ_RX_OWNERR_CTL_LBN 38 +#define FRF_BZ_RX_OWNERR_CTL_WIDTH 1 +#define FRF_BZ_RX_XON_TX_TH_LBN 33 +#define FRF_BZ_RX_XON_TX_TH_WIDTH 5 +#define FRF_AA_RX_DESC_PUSH_EN_LBN 35 +#define FRF_AA_RX_DESC_PUSH_EN_WIDTH 1 +#define FRF_AA_RX_RDW_PATCH_EN_LBN 34 +#define FRF_AA_RX_RDW_PATCH_EN_WIDTH 1 +#define FRF_AA_RX_PCI_BURST_SIZE_LBN 31 +#define FRF_AA_RX_PCI_BURST_SIZE_WIDTH 3 +#define FRF_BZ_RX_XOFF_TX_TH_LBN 28 +#define FRF_BZ_RX_XOFF_TX_TH_WIDTH 5 +#define FRF_AA_RX_OWNERR_CTL_LBN 30 +#define FRF_AA_RX_OWNERR_CTL_WIDTH 1 +#define FRF_AA_RX_XON_TX_TH_LBN 25 +#define FRF_AA_RX_XON_TX_TH_WIDTH 5 +#define FRF_BZ_RX_USR_BUF_SIZE_LBN 19 +#define FRF_BZ_RX_USR_BUF_SIZE_WIDTH 9 +#define FRF_AA_RX_XOFF_TX_TH_LBN 20 +#define FRF_AA_RX_XOFF_TX_TH_WIDTH 5 +#define FRF_AA_RX_USR_BUF_SIZE_LBN 11 +#define FRF_AA_RX_USR_BUF_SIZE_WIDTH 9 +#define FRF_BZ_RX_XON_MAC_TH_LBN 10 +#define FRF_BZ_RX_XON_MAC_TH_WIDTH 9 +#define FRF_AA_RX_XON_MAC_TH_LBN 6 +#define FRF_AA_RX_XON_MAC_TH_WIDTH 5 +#define FRF_BZ_RX_XOFF_MAC_TH_LBN 1 +#define FRF_BZ_RX_XOFF_MAC_TH_WIDTH 9 +#define FRF_AA_RX_XOFF_MAC_TH_LBN 1 +#define FRF_AA_RX_XOFF_MAC_TH_WIDTH 5 +#define FRF_AZ_RX_XOFF_MAC_EN_LBN 0 +#define FRF_AZ_RX_XOFF_MAC_EN_WIDTH 1 + +/* RX_FILTER_CTL_REG: Receive filter control registers */ +#define FR_BZ_RX_FILTER_CTL 0x00000810 +#define FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT_LBN 94 +#define FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT_WIDTH 8 +#define FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT_LBN 86 +#define FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT_WIDTH 8 +#define FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES_LBN 85 +#define FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES_WIDTH 1 +#define FRF_CZ_RX_VLAN_MATCH_ETHERTYPE_LBN 69 +#define FRF_CZ_RX_VLAN_MATCH_ETHERTYPE_WIDTH 16 +#define FRF_CZ_MULTICAST_NOMATCH_Q_ID_LBN 57 +#define FRF_CZ_MULTICAST_NOMATCH_Q_ID_WIDTH 12 +#define FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED_LBN 56 +#define FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED_WIDTH 1 +#define FRF_CZ_MULTICAST_NOMATCH_IP_OVERRIDE_LBN 55 +#define FRF_CZ_MULTICAST_NOMATCH_IP_OVERRIDE_WIDTH 1 +#define FRF_CZ_UNICAST_NOMATCH_Q_ID_LBN 43 +#define FRF_CZ_UNICAST_NOMATCH_Q_ID_WIDTH 12 +#define FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED_LBN 42 +#define FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED_WIDTH 1 +#define FRF_CZ_UNICAST_NOMATCH_IP_OVERRIDE_LBN 41 +#define FRF_CZ_UNICAST_NOMATCH_IP_OVERRIDE_WIDTH 1 +#define FRF_BZ_SCATTER_ENBL_NO_MATCH_Q_LBN 40 +#define FRF_BZ_SCATTER_ENBL_NO_MATCH_Q_WIDTH 1 +#define FRF_BZ_UDP_FULL_SRCH_LIMIT_LBN 32 +#define FRF_BZ_UDP_FULL_SRCH_LIMIT_WIDTH 8 +#define FRF_BZ_NUM_KER_LBN 24 +#define FRF_BZ_NUM_KER_WIDTH 2 +#define FRF_BZ_UDP_WILD_SRCH_LIMIT_LBN 16 +#define FRF_BZ_UDP_WILD_SRCH_LIMIT_WIDTH 8 +#define FRF_BZ_TCP_WILD_SRCH_LIMIT_LBN 8 +#define FRF_BZ_TCP_WILD_SRCH_LIMIT_WIDTH 8 +#define FRF_BZ_TCP_FULL_SRCH_LIMIT_LBN 0 +#define FRF_BZ_TCP_FULL_SRCH_LIMIT_WIDTH 8 + +/* RX_FLUSH_DESCQ_REG: Receive flush descriptor queue register */ +#define FR_AZ_RX_FLUSH_DESCQ 0x00000820 +#define FRF_AZ_RX_FLUSH_DESCQ_CMD_LBN 24 +#define FRF_AZ_RX_FLUSH_DESCQ_CMD_WIDTH 1 +#define FRF_AZ_RX_FLUSH_DESCQ_LBN 0 +#define FRF_AZ_RX_FLUSH_DESCQ_WIDTH 12 + +/* RX_DESC_UPD_REGP0: Receive descriptor update register. */ +#define FR_BZ_RX_DESC_UPD_P0 0x00000830 +#define FR_BZ_RX_DESC_UPD_P0_STEP 8192 +#define FR_BZ_RX_DESC_UPD_P0_ROWS 1024 +/* RX_DESC_UPD_REG_KER: Receive descriptor update register. */ +#define FR_AA_RX_DESC_UPD_KER 0x00000830 +#define FR_AA_RX_DESC_UPD_KER_STEP 8192 +#define FR_AA_RX_DESC_UPD_KER_ROWS 4 +/* RX_DESC_UPD_REGP123: Receive descriptor update register. */ +#define FR_BB_RX_DESC_UPD_P123 0x01000830 +#define FR_BB_RX_DESC_UPD_P123_STEP 8192 +#define FR_BB_RX_DESC_UPD_P123_ROWS 3072 +#define FRF_AZ_RX_DESC_WPTR_LBN 96 +#define FRF_AZ_RX_DESC_WPTR_WIDTH 12 +#define FRF_AZ_RX_DESC_PUSH_CMD_LBN 95 +#define FRF_AZ_RX_DESC_PUSH_CMD_WIDTH 1 +#define FRF_AZ_RX_DESC_LBN 0 +#define FRF_AZ_RX_DESC_WIDTH 64 + +/* RX_DC_CFG_REG: Receive descriptor cache configuration register */ +#define FR_AZ_RX_DC_CFG 0x00000840 +#define FRF_AB_RX_MAX_PF_LBN 2 +#define FRF_AB_RX_MAX_PF_WIDTH 2 +#define FRF_AZ_RX_DC_SIZE_LBN 0 +#define FRF_AZ_RX_DC_SIZE_WIDTH 2 +#define FFE_AZ_RX_DC_SIZE_64 3 +#define FFE_AZ_RX_DC_SIZE_32 2 +#define FFE_AZ_RX_DC_SIZE_16 1 +#define FFE_AZ_RX_DC_SIZE_8 0 + +/* RX_DC_PF_WM_REG: Receive descriptor cache pre-fetch watermark register */ +#define FR_AZ_RX_DC_PF_WM 0x00000850 +#define FRF_AZ_RX_DC_PF_HWM_LBN 6 +#define FRF_AZ_RX_DC_PF_HWM_WIDTH 6 +#define FRF_AZ_RX_DC_PF_LWM_LBN 0 +#define FRF_AZ_RX_DC_PF_LWM_WIDTH 6 + +/* RX_RSS_TKEY_REG: RSS Toeplitz hash key */ +#define FR_BZ_RX_RSS_TKEY 0x00000860 +#define FRF_BZ_RX_RSS_TKEY_HI_LBN 64 +#define FRF_BZ_RX_RSS_TKEY_HI_WIDTH 64 +#define FRF_BZ_RX_RSS_TKEY_LO_LBN 0 +#define FRF_BZ_RX_RSS_TKEY_LO_WIDTH 64 + +/* RX_NODESC_DROP_REG: Receive dropped packet counter register */ +#define FR_AZ_RX_NODESC_DROP 0x00000880 +#define FRF_CZ_RX_NODESC_DROP_CNT_LBN 0 +#define FRF_CZ_RX_NODESC_DROP_CNT_WIDTH 32 +#define FRF_AB_RX_NODESC_DROP_CNT_LBN 0 +#define FRF_AB_RX_NODESC_DROP_CNT_WIDTH 16 + +/* RX_SELF_RST_REG: Receive self reset register */ +#define FR_AA_RX_SELF_RST 0x00000890 +#define FRF_AA_RX_ISCSI_DIS_LBN 17 +#define FRF_AA_RX_ISCSI_DIS_WIDTH 1 +#define FRF_AA_RX_SW_RST_REG_LBN 16 +#define FRF_AA_RX_SW_RST_REG_WIDTH 1 +#define FRF_AA_RX_NODESC_WAIT_DIS_LBN 9 +#define FRF_AA_RX_NODESC_WAIT_DIS_WIDTH 1 +#define FRF_AA_RX_SELF_RST_EN_LBN 8 +#define FRF_AA_RX_SELF_RST_EN_WIDTH 1 +#define FRF_AA_RX_MAX_PF_LAT_LBN 4 +#define FRF_AA_RX_MAX_PF_LAT_WIDTH 4 +#define FRF_AA_RX_MAX_LU_LAT_LBN 0 +#define FRF_AA_RX_MAX_LU_LAT_WIDTH 4 + +/* RX_DEBUG_REG: undocumented register */ +#define FR_AZ_RX_DEBUG 0x000008a0 +#define FRF_AZ_RX_DEBUG_LBN 0 +#define FRF_AZ_RX_DEBUG_WIDTH 64 + +/* RX_PUSH_DROP_REG: Receive descriptor push dropped counter register */ +#define FR_AZ_RX_PUSH_DROP 0x000008b0 +#define FRF_AZ_RX_PUSH_DROP_CNT_LBN 0 +#define FRF_AZ_RX_PUSH_DROP_CNT_WIDTH 32 + +/* RX_RSS_IPV6_REG1: IPv6 RSS Toeplitz hash key low bytes */ +#define FR_CZ_RX_RSS_IPV6_REG1 0x000008d0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN 0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH 128 + +/* RX_RSS_IPV6_REG2: IPv6 RSS Toeplitz hash key middle bytes */ +#define FR_CZ_RX_RSS_IPV6_REG2 0x000008e0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN 0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH 128 + +/* RX_RSS_IPV6_REG3: IPv6 RSS Toeplitz hash key upper bytes and IPv6 RSS settings */ +#define FR_CZ_RX_RSS_IPV6_REG3 0x000008f0 +#define FRF_CZ_RX_RSS_IPV6_THASH_ENABLE_LBN 66 +#define FRF_CZ_RX_RSS_IPV6_THASH_ENABLE_WIDTH 1 +#define FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE_LBN 65 +#define FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE_WIDTH 1 +#define FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS_LBN 64 +#define FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS_WIDTH 1 +#define FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN 0 +#define FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH 64 + +/* TX_FLUSH_DESCQ_REG: Transmit flush descriptor queue register */ +#define FR_AZ_TX_FLUSH_DESCQ 0x00000a00 +#define FRF_AZ_TX_FLUSH_DESCQ_CMD_LBN 12 +#define FRF_AZ_TX_FLUSH_DESCQ_CMD_WIDTH 1 +#define FRF_AZ_TX_FLUSH_DESCQ_LBN 0 +#define FRF_AZ_TX_FLUSH_DESCQ_WIDTH 12 + +/* TX_DESC_UPD_REGP0: Transmit descriptor update register. */ +#define FR_BZ_TX_DESC_UPD_P0 0x00000a10 +#define FR_BZ_TX_DESC_UPD_P0_STEP 8192 +#define FR_BZ_TX_DESC_UPD_P0_ROWS 1024 +/* TX_DESC_UPD_REG_KER: Transmit descriptor update register. */ +#define FR_AA_TX_DESC_UPD_KER 0x00000a10 +#define FR_AA_TX_DESC_UPD_KER_STEP 8192 +#define FR_AA_TX_DESC_UPD_KER_ROWS 8 +/* TX_DESC_UPD_REGP123: Transmit descriptor update register. */ +#define FR_BB_TX_DESC_UPD_P123 0x01000a10 +#define FR_BB_TX_DESC_UPD_P123_STEP 8192 +#define FR_BB_TX_DESC_UPD_P123_ROWS 3072 +#define FRF_AZ_TX_DESC_WPTR_LBN 96 +#define FRF_AZ_TX_DESC_WPTR_WIDTH 12 +#define FRF_AZ_TX_DESC_PUSH_CMD_LBN 95 +#define FRF_AZ_TX_DESC_PUSH_CMD_WIDTH 1 +#define FRF_AZ_TX_DESC_LBN 0 +#define FRF_AZ_TX_DESC_WIDTH 95 + +/* TX_DC_CFG_REG: Transmit descriptor cache configuration register */ +#define FR_AZ_TX_DC_CFG 0x00000a20 +#define FRF_AZ_TX_DC_SIZE_LBN 0 +#define FRF_AZ_TX_DC_SIZE_WIDTH 2 +#define FFE_AZ_TX_DC_SIZE_32 2 +#define FFE_AZ_TX_DC_SIZE_16 1 +#define FFE_AZ_TX_DC_SIZE_8 0 + +/* TX_CHKSM_CFG_REG: Transmit checksum configuration register */ +#define FR_AA_TX_CHKSM_CFG 0x00000a30 +#define FRF_AA_TX_Q_CHKSM_DIS_96_127_LBN 96 +#define FRF_AA_TX_Q_CHKSM_DIS_96_127_WIDTH 32 +#define FRF_AA_TX_Q_CHKSM_DIS_64_95_LBN 64 +#define FRF_AA_TX_Q_CHKSM_DIS_64_95_WIDTH 32 +#define FRF_AA_TX_Q_CHKSM_DIS_32_63_LBN 32 +#define FRF_AA_TX_Q_CHKSM_DIS_32_63_WIDTH 32 +#define FRF_AA_TX_Q_CHKSM_DIS_0_31_LBN 0 +#define FRF_AA_TX_Q_CHKSM_DIS_0_31_WIDTH 32 + +/* TX_CFG_REG: Transmit configuration register */ +#define FR_AZ_TX_CFG 0x00000a50 +#define FRF_CZ_TX_CONT_LOOKUP_THRESH_RANGE_LBN 114 +#define FRF_CZ_TX_CONT_LOOKUP_THRESH_RANGE_WIDTH 8 +#define FRF_CZ_TX_FILTER_TEST_MODE_BIT_LBN 113 +#define FRF_CZ_TX_FILTER_TEST_MODE_BIT_WIDTH 1 +#define FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE_LBN 105 +#define FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE_LBN 97 +#define FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE_LBN 89 +#define FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE_LBN 81 +#define FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE_LBN 73 +#define FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE_LBN 65 +#define FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE_WIDTH 8 +#define FRF_CZ_TX_FILTER_ALL_VLAN_ETHERTYPES_BIT_LBN 64 +#define FRF_CZ_TX_FILTER_ALL_VLAN_ETHERTYPES_BIT_WIDTH 1 +#define FRF_CZ_TX_VLAN_MATCH_ETHERTYPE_RANGE_LBN 48 +#define FRF_CZ_TX_VLAN_MATCH_ETHERTYPE_RANGE_WIDTH 16 +#define FRF_CZ_TX_FILTER_EN_BIT_LBN 47 +#define FRF_CZ_TX_FILTER_EN_BIT_WIDTH 1 +#define FRF_AZ_TX_IP_ID_P0_OFS_LBN 16 +#define FRF_AZ_TX_IP_ID_P0_OFS_WIDTH 15 +#define FRF_AZ_TX_NO_EOP_DISC_EN_LBN 5 +#define FRF_AZ_TX_NO_EOP_DISC_EN_WIDTH 1 +#define FRF_AZ_TX_P1_PRI_EN_LBN 4 +#define FRF_AZ_TX_P1_PRI_EN_WIDTH 1 +#define FRF_AZ_TX_OWNERR_CTL_LBN 2 +#define FRF_AZ_TX_OWNERR_CTL_WIDTH 1 +#define FRF_AA_TX_NON_IP_DROP_DIS_LBN 1 +#define FRF_AA_TX_NON_IP_DROP_DIS_WIDTH 1 +#define FRF_AZ_TX_IP_ID_REP_EN_LBN 0 +#define FRF_AZ_TX_IP_ID_REP_EN_WIDTH 1 + +/* TX_PUSH_DROP_REG: Transmit push dropped register */ +#define FR_AZ_TX_PUSH_DROP 0x00000a60 +#define FRF_AZ_TX_PUSH_DROP_CNT_LBN 0 +#define FRF_AZ_TX_PUSH_DROP_CNT_WIDTH 32 + +/* TX_RESERVED_REG: Transmit configuration register */ +#define FR_AZ_TX_RESERVED 0x00000a80 +#define FRF_AZ_TX_EVT_CNT_LBN 121 +#define FRF_AZ_TX_EVT_CNT_WIDTH 7 +#define FRF_AZ_TX_PREF_AGE_CNT_LBN 119 +#define FRF_AZ_TX_PREF_AGE_CNT_WIDTH 2 +#define FRF_AZ_TX_RD_COMP_TMR_LBN 96 +#define FRF_AZ_TX_RD_COMP_TMR_WIDTH 23 +#define FRF_AZ_TX_PUSH_EN_LBN 89 +#define FRF_AZ_TX_PUSH_EN_WIDTH 1 +#define FRF_AZ_TX_PUSH_CHK_DIS_LBN 88 +#define FRF_AZ_TX_PUSH_CHK_DIS_WIDTH 1 +#define FRF_AZ_TX_D_FF_FULL_P0_LBN 85 +#define FRF_AZ_TX_D_FF_FULL_P0_WIDTH 1 +#define FRF_AZ_TX_DMAR_ST_P0_LBN 81 +#define FRF_AZ_TX_DMAR_ST_P0_WIDTH 1 +#define FRF_AZ_TX_DMAQ_ST_LBN 78 +#define FRF_AZ_TX_DMAQ_ST_WIDTH 1 +#define FRF_AZ_TX_RX_SPACER_LBN 64 +#define FRF_AZ_TX_RX_SPACER_WIDTH 8 +#define FRF_AZ_TX_DROP_ABORT_EN_LBN 60 +#define FRF_AZ_TX_DROP_ABORT_EN_WIDTH 1 +#define FRF_AZ_TX_SOFT_EVT_EN_LBN 59 +#define FRF_AZ_TX_SOFT_EVT_EN_WIDTH 1 +#define FRF_AZ_TX_PS_EVT_DIS_LBN 58 +#define FRF_AZ_TX_PS_EVT_DIS_WIDTH 1 +#define FRF_AZ_TX_RX_SPACER_EN_LBN 57 +#define FRF_AZ_TX_RX_SPACER_EN_WIDTH 1 +#define FRF_AZ_TX_XP_TIMER_LBN 52 +#define FRF_AZ_TX_XP_TIMER_WIDTH 5 +#define FRF_AZ_TX_PREF_SPACER_LBN 44 +#define FRF_AZ_TX_PREF_SPACER_WIDTH 8 +#define FRF_AZ_TX_PREF_WD_TMR_LBN 22 +#define FRF_AZ_TX_PREF_WD_TMR_WIDTH 22 +#define FRF_AZ_TX_ONLY1TAG_LBN 21 +#define FRF_AZ_TX_ONLY1TAG_WIDTH 1 +#define FRF_AZ_TX_PREF_THRESHOLD_LBN 19 +#define FRF_AZ_TX_PREF_THRESHOLD_WIDTH 2 +#define FRF_AZ_TX_ONE_PKT_PER_Q_LBN 18 +#define FRF_AZ_TX_ONE_PKT_PER_Q_WIDTH 1 +#define FRF_AZ_TX_DIS_NON_IP_EV_LBN 17 +#define FRF_AZ_TX_DIS_NON_IP_EV_WIDTH 1 +#define FRF_AA_TX_DMA_FF_THR_LBN 16 +#define FRF_AA_TX_DMA_FF_THR_WIDTH 1 +#define FRF_AZ_TX_DMA_SPACER_LBN 8 +#define FRF_AZ_TX_DMA_SPACER_WIDTH 8 +#define FRF_AA_TX_TCP_DIS_LBN 7 +#define FRF_AA_TX_TCP_DIS_WIDTH 1 +#define FRF_BZ_TX_FLUSH_MIN_LEN_EN_LBN 7 +#define FRF_BZ_TX_FLUSH_MIN_LEN_EN_WIDTH 1 +#define FRF_AA_TX_IP_DIS_LBN 6 +#define FRF_AA_TX_IP_DIS_WIDTH 1 +#define FRF_AZ_TX_MAX_CPL_LBN 2 +#define FRF_AZ_TX_MAX_CPL_WIDTH 2 +#define FFE_AZ_TX_MAX_CPL_16 3 +#define FFE_AZ_TX_MAX_CPL_8 2 +#define FFE_AZ_TX_MAX_CPL_4 1 +#define FFE_AZ_TX_MAX_CPL_NOLIMIT 0 +#define FRF_AZ_TX_MAX_PREF_LBN 0 +#define FRF_AZ_TX_MAX_PREF_WIDTH 2 +#define FFE_AZ_TX_MAX_PREF_32 3 +#define FFE_AZ_TX_MAX_PREF_16 2 +#define FFE_AZ_TX_MAX_PREF_8 1 +#define FFE_AZ_TX_MAX_PREF_OFF 0 + +/* TX_PACE_REG: Transmit pace control register */ +#define FR_BZ_TX_PACE 0x00000a90 +#define FRF_BZ_TX_PACE_SB_NOT_AF_LBN 19 +#define FRF_BZ_TX_PACE_SB_NOT_AF_WIDTH 10 +#define FRF_BZ_TX_PACE_SB_AF_LBN 9 +#define FRF_BZ_TX_PACE_SB_AF_WIDTH 10 +#define FRF_BZ_TX_PACE_FB_BASE_LBN 5 +#define FRF_BZ_TX_PACE_FB_BASE_WIDTH 4 +#define FRF_BZ_TX_PACE_BIN_TH_LBN 0 +#define FRF_BZ_TX_PACE_BIN_TH_WIDTH 5 + +/* TX_PACE_DROP_QID_REG: PACE Drop QID Counter */ +#define FR_BZ_TX_PACE_DROP_QID 0x00000aa0 +#define FRF_BZ_TX_PACE_QID_DRP_CNT_LBN 0 +#define FRF_BZ_TX_PACE_QID_DRP_CNT_WIDTH 16 + +/* TX_VLAN_REG: Transmit VLAN tag register */ +#define FR_BB_TX_VLAN 0x00000ae0 +#define FRF_BB_TX_VLAN_EN_LBN 127 +#define FRF_BB_TX_VLAN_EN_WIDTH 1 +#define FRF_BB_TX_VLAN7_PORT1_EN_LBN 125 +#define FRF_BB_TX_VLAN7_PORT1_EN_WIDTH 1 +#define FRF_BB_TX_VLAN7_PORT0_EN_LBN 124 +#define FRF_BB_TX_VLAN7_PORT0_EN_WIDTH 1 +#define FRF_BB_TX_VLAN7_LBN 112 +#define FRF_BB_TX_VLAN7_WIDTH 12 +#define FRF_BB_TX_VLAN6_PORT1_EN_LBN 109 +#define FRF_BB_TX_VLAN6_PORT1_EN_WIDTH 1 +#define FRF_BB_TX_VLAN6_PORT0_EN_LBN 108 +#define FRF_BB_TX_VLAN6_PORT0_EN_WIDTH 1 +#define FRF_BB_TX_VLAN6_LBN 96 +#define FRF_BB_TX_VLAN6_WIDTH 12 +#define FRF_BB_TX_VLAN5_PORT1_EN_LBN 93 +#define FRF_BB_TX_VLAN5_PORT1_EN_WIDTH 1 +#define FRF_BB_TX_VLAN5_PORT0_EN_LBN 92 +#define FRF_BB_TX_VLAN5_PORT0_EN_WIDTH 1 +#define FRF_BB_TX_VLAN5_LBN 80 +#define FRF_BB_TX_VLAN5_WIDTH 12 +#define FRF_BB_TX_VLAN4_PORT1_EN_LBN 77 +#define FRF_BB_TX_VLAN4_PORT1_EN_WIDTH 1 +#define FRF_BB_TX_VLAN4_PORT0_EN_LBN 76 +#define FRF_BB_TX_VLAN4_PORT0_EN_WIDTH 1 +#define FRF_BB_TX_VLAN4_LBN 64 +#define FRF_BB_TX_VLAN4_WIDTH 12 +#define FRF_BB_TX_VLAN3_PORT1_EN_LBN 61 +#define FRF_BB_TX_VLAN3_PORT1_EN_WIDTH 1 +#define FRF_BB_TX_VLAN3_PORT0_EN_LBN 60 +#define FRF_BB_TX_VLAN3_PORT0_EN_WIDTH 1 +#define FRF_BB_TX_VLAN3_LBN 48 +#define FRF_BB_TX_VLAN3_WIDTH 12 +#define FRF_BB_TX_VLAN2_PORT1_EN_LBN 45 +#define FRF_BB_TX_VLAN2_PORT1_EN_WIDTH 1 +#define FRF_BB_TX_VLAN2_PORT0_EN_LBN 44 +#define FRF_BB_TX_VLAN2_PORT0_EN_WIDTH 1 +#define FRF_BB_TX_VLAN2_LBN 32 +#define FRF_BB_TX_VLAN2_WIDTH 12 +#define FRF_BB_TX_VLAN1_PORT1_EN_LBN 29 +#define FRF_BB_TX_VLAN1_PORT1_EN_WIDTH 1 +#define FRF_BB_TX_VLAN1_PORT0_EN_LBN 28 +#define FRF_BB_TX_VLAN1_PORT0_EN_WIDTH 1 +#define FRF_BB_TX_VLAN1_LBN 16 +#define FRF_BB_TX_VLAN1_WIDTH 12 +#define FRF_BB_TX_VLAN0_PORT1_EN_LBN 13 +#define FRF_BB_TX_VLAN0_PORT1_EN_WIDTH 1 +#define FRF_BB_TX_VLAN0_PORT0_EN_LBN 12 +#define FRF_BB_TX_VLAN0_PORT0_EN_WIDTH 1 +#define FRF_BB_TX_VLAN0_LBN 0 +#define FRF_BB_TX_VLAN0_WIDTH 12 + +/* TX_IPFIL_PORTEN_REG: Transmit filter control register */ +#define FR_BZ_TX_IPFIL_PORTEN 0x00000af0 +#define FRF_BZ_TX_MADR0_FIL_EN_LBN 64 +#define FRF_BZ_TX_MADR0_FIL_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL31_PORT_EN_LBN 62 +#define FRF_BB_TX_IPFIL31_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL30_PORT_EN_LBN 60 +#define FRF_BB_TX_IPFIL30_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL29_PORT_EN_LBN 58 +#define FRF_BB_TX_IPFIL29_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL28_PORT_EN_LBN 56 +#define FRF_BB_TX_IPFIL28_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL27_PORT_EN_LBN 54 +#define FRF_BB_TX_IPFIL27_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL26_PORT_EN_LBN 52 +#define FRF_BB_TX_IPFIL26_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL25_PORT_EN_LBN 50 +#define FRF_BB_TX_IPFIL25_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL24_PORT_EN_LBN 48 +#define FRF_BB_TX_IPFIL24_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL23_PORT_EN_LBN 46 +#define FRF_BB_TX_IPFIL23_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL22_PORT_EN_LBN 44 +#define FRF_BB_TX_IPFIL22_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL21_PORT_EN_LBN 42 +#define FRF_BB_TX_IPFIL21_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL20_PORT_EN_LBN 40 +#define FRF_BB_TX_IPFIL20_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL19_PORT_EN_LBN 38 +#define FRF_BB_TX_IPFIL19_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL18_PORT_EN_LBN 36 +#define FRF_BB_TX_IPFIL18_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL17_PORT_EN_LBN 34 +#define FRF_BB_TX_IPFIL17_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL16_PORT_EN_LBN 32 +#define FRF_BB_TX_IPFIL16_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL15_PORT_EN_LBN 30 +#define FRF_BB_TX_IPFIL15_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL14_PORT_EN_LBN 28 +#define FRF_BB_TX_IPFIL14_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL13_PORT_EN_LBN 26 +#define FRF_BB_TX_IPFIL13_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL12_PORT_EN_LBN 24 +#define FRF_BB_TX_IPFIL12_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL11_PORT_EN_LBN 22 +#define FRF_BB_TX_IPFIL11_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL10_PORT_EN_LBN 20 +#define FRF_BB_TX_IPFIL10_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL9_PORT_EN_LBN 18 +#define FRF_BB_TX_IPFIL9_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL8_PORT_EN_LBN 16 +#define FRF_BB_TX_IPFIL8_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL7_PORT_EN_LBN 14 +#define FRF_BB_TX_IPFIL7_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL6_PORT_EN_LBN 12 +#define FRF_BB_TX_IPFIL6_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL5_PORT_EN_LBN 10 +#define FRF_BB_TX_IPFIL5_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL4_PORT_EN_LBN 8 +#define FRF_BB_TX_IPFIL4_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL3_PORT_EN_LBN 6 +#define FRF_BB_TX_IPFIL3_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL2_PORT_EN_LBN 4 +#define FRF_BB_TX_IPFIL2_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL1_PORT_EN_LBN 2 +#define FRF_BB_TX_IPFIL1_PORT_EN_WIDTH 1 +#define FRF_BB_TX_IPFIL0_PORT_EN_LBN 0 +#define FRF_BB_TX_IPFIL0_PORT_EN_WIDTH 1 + +/* TX_IPFIL_TBL: Transmit IP source address filter table */ +#define FR_BB_TX_IPFIL_TBL 0x00000b00 +#define FR_BB_TX_IPFIL_TBL_STEP 16 +#define FR_BB_TX_IPFIL_TBL_ROWS 16 +#define FRF_BB_TX_IPFIL_MASK_1_LBN 96 +#define FRF_BB_TX_IPFIL_MASK_1_WIDTH 32 +#define FRF_BB_TX_IP_SRC_ADR_1_LBN 64 +#define FRF_BB_TX_IP_SRC_ADR_1_WIDTH 32 +#define FRF_BB_TX_IPFIL_MASK_0_LBN 32 +#define FRF_BB_TX_IPFIL_MASK_0_WIDTH 32 +#define FRF_BB_TX_IP_SRC_ADR_0_LBN 0 +#define FRF_BB_TX_IP_SRC_ADR_0_WIDTH 32 + +/* MD_TXD_REG: PHY management transmit data register */ +#define FR_AB_MD_TXD 0x00000c00 +#define FRF_AB_MD_TXD_LBN 0 +#define FRF_AB_MD_TXD_WIDTH 16 + +/* MD_RXD_REG: PHY management receive data register */ +#define FR_AB_MD_RXD 0x00000c10 +#define FRF_AB_MD_RXD_LBN 0 +#define FRF_AB_MD_RXD_WIDTH 16 + +/* MD_CS_REG: PHY management configuration & status register */ +#define FR_AB_MD_CS 0x00000c20 +#define FRF_AB_MD_RD_EN_CMD_LBN 15 +#define FRF_AB_MD_RD_EN_CMD_WIDTH 1 +#define FRF_AB_MD_WR_EN_CMD_LBN 14 +#define FRF_AB_MD_WR_EN_CMD_WIDTH 1 +#define FRF_AB_MD_ADDR_CMD_LBN 13 +#define FRF_AB_MD_ADDR_CMD_WIDTH 1 +#define FRF_AB_MD_PT_LBN 7 +#define FRF_AB_MD_PT_WIDTH 3 +#define FRF_AB_MD_PL_LBN 6 +#define FRF_AB_MD_PL_WIDTH 1 +#define FRF_AB_MD_INT_CLR_LBN 5 +#define FRF_AB_MD_INT_CLR_WIDTH 1 +#define FRF_AB_MD_GC_LBN 4 +#define FRF_AB_MD_GC_WIDTH 1 +#define FRF_AB_MD_PRSP_LBN 3 +#define FRF_AB_MD_PRSP_WIDTH 1 +#define FRF_AB_MD_RIC_LBN 2 +#define FRF_AB_MD_RIC_WIDTH 1 +#define FRF_AB_MD_RDC_LBN 1 +#define FRF_AB_MD_RDC_WIDTH 1 +#define FRF_AB_MD_WRC_LBN 0 +#define FRF_AB_MD_WRC_WIDTH 1 + +/* MD_PHY_ADR_REG: PHY management PHY address register */ +#define FR_AB_MD_PHY_ADR 0x00000c30 +#define FRF_AB_MD_PHY_ADR_LBN 0 +#define FRF_AB_MD_PHY_ADR_WIDTH 16 + +/* MD_ID_REG: PHY management ID register */ +#define FR_AB_MD_ID 0x00000c40 +#define FRF_AB_MD_PRT_ADR_LBN 11 +#define FRF_AB_MD_PRT_ADR_WIDTH 5 +#define FRF_AB_MD_DEV_ADR_LBN 6 +#define FRF_AB_MD_DEV_ADR_WIDTH 5 + +/* MD_STAT_REG: PHY management status & mask register */ +#define FR_AB_MD_STAT 0x00000c50 +#define FRF_AB_MD_PINT_LBN 4 +#define FRF_AB_MD_PINT_WIDTH 1 +#define FRF_AB_MD_DONE_LBN 3 +#define FRF_AB_MD_DONE_WIDTH 1 +#define FRF_AB_MD_BSERR_LBN 2 +#define FRF_AB_MD_BSERR_WIDTH 1 +#define FRF_AB_MD_LNFL_LBN 1 +#define FRF_AB_MD_LNFL_WIDTH 1 +#define FRF_AB_MD_BSY_LBN 0 +#define FRF_AB_MD_BSY_WIDTH 1 + +/* MAC_STAT_DMA_REG: Port MAC statistical counter DMA register */ +#define FR_AB_MAC_STAT_DMA 0x00000c60 +#define FRF_AB_MAC_STAT_DMA_CMD_LBN 48 +#define FRF_AB_MAC_STAT_DMA_CMD_WIDTH 1 +#define FRF_AB_MAC_STAT_DMA_ADR_LBN 0 +#define FRF_AB_MAC_STAT_DMA_ADR_WIDTH 48 + +/* MAC_CTRL_REG: Port MAC control register */ +#define FR_AB_MAC_CTRL 0x00000c80 +#define FRF_AB_MAC_XOFF_VAL_LBN 16 +#define FRF_AB_MAC_XOFF_VAL_WIDTH 16 +#define FRF_BB_TXFIFO_DRAIN_EN_LBN 7 +#define FRF_BB_TXFIFO_DRAIN_EN_WIDTH 1 +#define FRF_AB_MAC_XG_DISTXCRC_LBN 5 +#define FRF_AB_MAC_XG_DISTXCRC_WIDTH 1 +#define FRF_AB_MAC_BCAD_ACPT_LBN 4 +#define FRF_AB_MAC_BCAD_ACPT_WIDTH 1 +#define FRF_AB_MAC_UC_PROM_LBN 3 +#define FRF_AB_MAC_UC_PROM_WIDTH 1 +#define FRF_AB_MAC_LINK_STATUS_LBN 2 +#define FRF_AB_MAC_LINK_STATUS_WIDTH 1 +#define FRF_AB_MAC_SPEED_LBN 0 +#define FRF_AB_MAC_SPEED_WIDTH 2 +#define FFE_AB_MAC_SPEED_10G 3 +#define FFE_AB_MAC_SPEED_1G 2 +#define FFE_AB_MAC_SPEED_100M 1 +#define FFE_AB_MAC_SPEED_10M 0 + +/* GEN_MODE_REG: General Purpose mode register (external interrupt mask) */ +#define FR_BB_GEN_MODE 0x00000c90 +#define FRF_BB_XFP_PHY_INT_POL_SEL_LBN 3 +#define FRF_BB_XFP_PHY_INT_POL_SEL_WIDTH 1 +#define FRF_BB_XG_PHY_INT_POL_SEL_LBN 2 +#define FRF_BB_XG_PHY_INT_POL_SEL_WIDTH 1 +#define FRF_BB_XFP_PHY_INT_MASK_LBN 1 +#define FRF_BB_XFP_PHY_INT_MASK_WIDTH 1 +#define FRF_BB_XG_PHY_INT_MASK_LBN 0 +#define FRF_BB_XG_PHY_INT_MASK_WIDTH 1 + +/* MAC_MC_HASH_REG0: Multicast address hash table */ +#define FR_AB_MAC_MC_HASH_REG0 0x00000ca0 +#define FRF_AB_MAC_MCAST_HASH0_LBN 0 +#define FRF_AB_MAC_MCAST_HASH0_WIDTH 128 + +/* MAC_MC_HASH_REG1: Multicast address hash table */ +#define FR_AB_MAC_MC_HASH_REG1 0x00000cb0 +#define FRF_AB_MAC_MCAST_HASH1_LBN 0 +#define FRF_AB_MAC_MCAST_HASH1_WIDTH 128 + +/* GM_CFG1_REG: GMAC configuration register 1 */ +#define FR_AB_GM_CFG1 0x00000e00 +#define FRF_AB_GM_SW_RST_LBN 31 +#define FRF_AB_GM_SW_RST_WIDTH 1 +#define FRF_AB_GM_SIM_RST_LBN 30 +#define FRF_AB_GM_SIM_RST_WIDTH 1 +#define FRF_AB_GM_RST_RX_MAC_CTL_LBN 19 +#define FRF_AB_GM_RST_RX_MAC_CTL_WIDTH 1 +#define FRF_AB_GM_RST_TX_MAC_CTL_LBN 18 +#define FRF_AB_GM_RST_TX_MAC_CTL_WIDTH 1 +#define FRF_AB_GM_RST_RX_FUNC_LBN 17 +#define FRF_AB_GM_RST_RX_FUNC_WIDTH 1 +#define FRF_AB_GM_RST_TX_FUNC_LBN 16 +#define FRF_AB_GM_RST_TX_FUNC_WIDTH 1 +#define FRF_AB_GM_LOOP_LBN 8 +#define FRF_AB_GM_LOOP_WIDTH 1 +#define FRF_AB_GM_RX_FC_EN_LBN 5 +#define FRF_AB_GM_RX_FC_EN_WIDTH 1 +#define FRF_AB_GM_TX_FC_EN_LBN 4 +#define FRF_AB_GM_TX_FC_EN_WIDTH 1 +#define FRF_AB_GM_SYNC_RXEN_LBN 3 +#define FRF_AB_GM_SYNC_RXEN_WIDTH 1 +#define FRF_AB_GM_RX_EN_LBN 2 +#define FRF_AB_GM_RX_EN_WIDTH 1 +#define FRF_AB_GM_SYNC_TXEN_LBN 1 +#define FRF_AB_GM_SYNC_TXEN_WIDTH 1 +#define FRF_AB_GM_TX_EN_LBN 0 +#define FRF_AB_GM_TX_EN_WIDTH 1 + +/* GM_CFG2_REG: GMAC configuration register 2 */ +#define FR_AB_GM_CFG2 0x00000e10 +#define FRF_AB_GM_PAMBL_LEN_LBN 12 +#define FRF_AB_GM_PAMBL_LEN_WIDTH 4 +#define FRF_AB_GM_IF_MODE_LBN 8 +#define FRF_AB_GM_IF_MODE_WIDTH 2 +#define FFE_AB_IF_MODE_BYTE_MODE 2 +#define FFE_AB_IF_MODE_NIBBLE_MODE 1 +#define FRF_AB_GM_HUGE_FRM_EN_LBN 5 +#define FRF_AB_GM_HUGE_FRM_EN_WIDTH 1 +#define FRF_AB_GM_LEN_CHK_LBN 4 +#define FRF_AB_GM_LEN_CHK_WIDTH 1 +#define FRF_AB_GM_PAD_CRC_EN_LBN 2 +#define FRF_AB_GM_PAD_CRC_EN_WIDTH 1 +#define FRF_AB_GM_CRC_EN_LBN 1 +#define FRF_AB_GM_CRC_EN_WIDTH 1 +#define FRF_AB_GM_FD_LBN 0 +#define FRF_AB_GM_FD_WIDTH 1 + +/* GM_IPG_REG: GMAC IPG register */ +#define FR_AB_GM_IPG 0x00000e20 +#define FRF_AB_GM_NONB2B_IPG1_LBN 24 +#define FRF_AB_GM_NONB2B_IPG1_WIDTH 7 +#define FRF_AB_GM_NONB2B_IPG2_LBN 16 +#define FRF_AB_GM_NONB2B_IPG2_WIDTH 7 +#define FRF_AB_GM_MIN_IPG_ENF_LBN 8 +#define FRF_AB_GM_MIN_IPG_ENF_WIDTH 8 +#define FRF_AB_GM_B2B_IPG_LBN 0 +#define FRF_AB_GM_B2B_IPG_WIDTH 7 + +/* GM_HD_REG: GMAC half duplex register */ +#define FR_AB_GM_HD 0x00000e30 +#define FRF_AB_GM_ALT_BOFF_VAL_LBN 20 +#define FRF_AB_GM_ALT_BOFF_VAL_WIDTH 4 +#define FRF_AB_GM_ALT_BOFF_EN_LBN 19 +#define FRF_AB_GM_ALT_BOFF_EN_WIDTH 1 +#define FRF_AB_GM_BP_NO_BOFF_LBN 18 +#define FRF_AB_GM_BP_NO_BOFF_WIDTH 1 +#define FRF_AB_GM_DIS_BOFF_LBN 17 +#define FRF_AB_GM_DIS_BOFF_WIDTH 1 +#define FRF_AB_GM_EXDEF_TX_EN_LBN 16 +#define FRF_AB_GM_EXDEF_TX_EN_WIDTH 1 +#define FRF_AB_GM_RTRY_LIMIT_LBN 12 +#define FRF_AB_GM_RTRY_LIMIT_WIDTH 4 +#define FRF_AB_GM_COL_WIN_LBN 0 +#define FRF_AB_GM_COL_WIN_WIDTH 10 + +/* GM_MAX_FLEN_REG: GMAC maximum frame length register */ +#define FR_AB_GM_MAX_FLEN 0x00000e40 +#define FRF_AB_GM_MAX_FLEN_LBN 0 +#define FRF_AB_GM_MAX_FLEN_WIDTH 16 + +/* GM_TEST_REG: GMAC test register */ +#define FR_AB_GM_TEST 0x00000e70 +#define FRF_AB_GM_MAX_BOFF_LBN 3 +#define FRF_AB_GM_MAX_BOFF_WIDTH 1 +#define FRF_AB_GM_REG_TX_FLOW_EN_LBN 2 +#define FRF_AB_GM_REG_TX_FLOW_EN_WIDTH 1 +#define FRF_AB_GM_TEST_PAUSE_LBN 1 +#define FRF_AB_GM_TEST_PAUSE_WIDTH 1 +#define FRF_AB_GM_SHORT_SLOT_LBN 0 +#define FRF_AB_GM_SHORT_SLOT_WIDTH 1 + +/* GM_ADR1_REG: GMAC station address register 1 */ +#define FR_AB_GM_ADR1 0x00000f00 +#define FRF_AB_GM_ADR_B0_LBN 24 +#define FRF_AB_GM_ADR_B0_WIDTH 8 +#define FRF_AB_GM_ADR_B1_LBN 16 +#define FRF_AB_GM_ADR_B1_WIDTH 8 +#define FRF_AB_GM_ADR_B2_LBN 8 +#define FRF_AB_GM_ADR_B2_WIDTH 8 +#define FRF_AB_GM_ADR_B3_LBN 0 +#define FRF_AB_GM_ADR_B3_WIDTH 8 + +/* GM_ADR2_REG: GMAC station address register 2 */ +#define FR_AB_GM_ADR2 0x00000f10 +#define FRF_AB_GM_ADR_B4_LBN 24 +#define FRF_AB_GM_ADR_B4_WIDTH 8 +#define FRF_AB_GM_ADR_B5_LBN 16 +#define FRF_AB_GM_ADR_B5_WIDTH 8 + +/* GMF_CFG0_REG: GMAC FIFO configuration register 0 */ +#define FR_AB_GMF_CFG0 0x00000f20 +#define FRF_AB_GMF_FTFENRPLY_LBN 20 +#define FRF_AB_GMF_FTFENRPLY_WIDTH 1 +#define FRF_AB_GMF_STFENRPLY_LBN 19 +#define FRF_AB_GMF_STFENRPLY_WIDTH 1 +#define FRF_AB_GMF_FRFENRPLY_LBN 18 +#define FRF_AB_GMF_FRFENRPLY_WIDTH 1 +#define FRF_AB_GMF_SRFENRPLY_LBN 17 +#define FRF_AB_GMF_SRFENRPLY_WIDTH 1 +#define FRF_AB_GMF_WTMENRPLY_LBN 16 +#define FRF_AB_GMF_WTMENRPLY_WIDTH 1 +#define FRF_AB_GMF_FTFENREQ_LBN 12 +#define FRF_AB_GMF_FTFENREQ_WIDTH 1 +#define FRF_AB_GMF_STFENREQ_LBN 11 +#define FRF_AB_GMF_STFENREQ_WIDTH 1 +#define FRF_AB_GMF_FRFENREQ_LBN 10 +#define FRF_AB_GMF_FRFENREQ_WIDTH 1 +#define FRF_AB_GMF_SRFENREQ_LBN 9 +#define FRF_AB_GMF_SRFENREQ_WIDTH 1 +#define FRF_AB_GMF_WTMENREQ_LBN 8 +#define FRF_AB_GMF_WTMENREQ_WIDTH 1 +#define FRF_AB_GMF_HSTRSTFT_LBN 4 +#define FRF_AB_GMF_HSTRSTFT_WIDTH 1 +#define FRF_AB_GMF_HSTRSTST_LBN 3 +#define FRF_AB_GMF_HSTRSTST_WIDTH 1 +#define FRF_AB_GMF_HSTRSTFR_LBN 2 +#define FRF_AB_GMF_HSTRSTFR_WIDTH 1 +#define FRF_AB_GMF_HSTRSTSR_LBN 1 +#define FRF_AB_GMF_HSTRSTSR_WIDTH 1 +#define FRF_AB_GMF_HSTRSTWT_LBN 0 +#define FRF_AB_GMF_HSTRSTWT_WIDTH 1 + +/* GMF_CFG1_REG: GMAC FIFO configuration register 1 */ +#define FR_AB_GMF_CFG1 0x00000f30 +#define FRF_AB_GMF_CFGFRTH_LBN 16 +#define FRF_AB_GMF_CFGFRTH_WIDTH 5 +#define FRF_AB_GMF_CFGXOFFRTX_LBN 0 +#define FRF_AB_GMF_CFGXOFFRTX_WIDTH 16 + +/* GMF_CFG2_REG: GMAC FIFO configuration register 2 */ +#define FR_AB_GMF_CFG2 0x00000f40 +#define FRF_AB_GMF_CFGHWM_LBN 16 +#define FRF_AB_GMF_CFGHWM_WIDTH 6 +#define FRF_AB_GMF_CFGLWM_LBN 0 +#define FRF_AB_GMF_CFGLWM_WIDTH 6 + +/* GMF_CFG3_REG: GMAC FIFO configuration register 3 */ +#define FR_AB_GMF_CFG3 0x00000f50 +#define FRF_AB_GMF_CFGHWMFT_LBN 16 +#define FRF_AB_GMF_CFGHWMFT_WIDTH 6 +#define FRF_AB_GMF_CFGFTTH_LBN 0 +#define FRF_AB_GMF_CFGFTTH_WIDTH 6 + +/* GMF_CFG4_REG: GMAC FIFO configuration register 4 */ +#define FR_AB_GMF_CFG4 0x00000f60 +#define FRF_AB_GMF_HSTFLTRFRM_LBN 0 +#define FRF_AB_GMF_HSTFLTRFRM_WIDTH 18 + +/* GMF_CFG5_REG: GMAC FIFO configuration register 5 */ +#define FR_AB_GMF_CFG5 0x00000f70 +#define FRF_AB_GMF_CFGHDPLX_LBN 22 +#define FRF_AB_GMF_CFGHDPLX_WIDTH 1 +#define FRF_AB_GMF_SRFULL_LBN 21 +#define FRF_AB_GMF_SRFULL_WIDTH 1 +#define FRF_AB_GMF_HSTSRFULLCLR_LBN 20 +#define FRF_AB_GMF_HSTSRFULLCLR_WIDTH 1 +#define FRF_AB_GMF_CFGBYTMODE_LBN 19 +#define FRF_AB_GMF_CFGBYTMODE_WIDTH 1 +#define FRF_AB_GMF_HSTDRPLT64_LBN 18 +#define FRF_AB_GMF_HSTDRPLT64_WIDTH 1 +#define FRF_AB_GMF_HSTFLTRFRMDC_LBN 0 +#define FRF_AB_GMF_HSTFLTRFRMDC_WIDTH 18 + +/* TX_SRC_MAC_TBL: Transmit IP source address filter table */ +#define FR_BB_TX_SRC_MAC_TBL 0x00001000 +#define FR_BB_TX_SRC_MAC_TBL_STEP 16 +#define FR_BB_TX_SRC_MAC_TBL_ROWS 16 +#define FRF_BB_TX_SRC_MAC_ADR_1_LBN 64 +#define FRF_BB_TX_SRC_MAC_ADR_1_WIDTH 48 +#define FRF_BB_TX_SRC_MAC_ADR_0_LBN 0 +#define FRF_BB_TX_SRC_MAC_ADR_0_WIDTH 48 + +/* TX_SRC_MAC_CTL_REG: Transmit MAC source address filter control */ +#define FR_BB_TX_SRC_MAC_CTL 0x00001100 +#define FRF_BB_TX_SRC_DROP_CTR_LBN 16 +#define FRF_BB_TX_SRC_DROP_CTR_WIDTH 16 +#define FRF_BB_TX_SRC_FLTR_EN_LBN 15 +#define FRF_BB_TX_SRC_FLTR_EN_WIDTH 1 +#define FRF_BB_TX_DROP_CTR_CLR_LBN 12 +#define FRF_BB_TX_DROP_CTR_CLR_WIDTH 1 +#define FRF_BB_TX_MAC_QID_SEL_LBN 0 +#define FRF_BB_TX_MAC_QID_SEL_WIDTH 3 + +/* XM_ADR_LO_REG: XGMAC address register low */ +#define FR_AB_XM_ADR_LO 0x00001200 +#define FRF_AB_XM_ADR_LO_LBN 0 +#define FRF_AB_XM_ADR_LO_WIDTH 32 + +/* XM_ADR_HI_REG: XGMAC address register high */ +#define FR_AB_XM_ADR_HI 0x00001210 +#define FRF_AB_XM_ADR_HI_LBN 0 +#define FRF_AB_XM_ADR_HI_WIDTH 16 + +/* XM_GLB_CFG_REG: XGMAC global configuration */ +#define FR_AB_XM_GLB_CFG 0x00001220 +#define FRF_AB_XM_RMTFLT_GEN_LBN 17 +#define FRF_AB_XM_RMTFLT_GEN_WIDTH 1 +#define FRF_AB_XM_DEBUG_MODE_LBN 16 +#define FRF_AB_XM_DEBUG_MODE_WIDTH 1 +#define FRF_AB_XM_RX_STAT_EN_LBN 11 +#define FRF_AB_XM_RX_STAT_EN_WIDTH 1 +#define FRF_AB_XM_TX_STAT_EN_LBN 10 +#define FRF_AB_XM_TX_STAT_EN_WIDTH 1 +#define FRF_AB_XM_RX_JUMBO_MODE_LBN 6 +#define FRF_AB_XM_RX_JUMBO_MODE_WIDTH 1 +#define FRF_AB_XM_WAN_MODE_LBN 5 +#define FRF_AB_XM_WAN_MODE_WIDTH 1 +#define FRF_AB_XM_INTCLR_MODE_LBN 3 +#define FRF_AB_XM_INTCLR_MODE_WIDTH 1 +#define FRF_AB_XM_CORE_RST_LBN 0 +#define FRF_AB_XM_CORE_RST_WIDTH 1 + +/* XM_TX_CFG_REG: XGMAC transmit configuration */ +#define FR_AB_XM_TX_CFG 0x00001230 +#define FRF_AB_XM_TX_PROG_LBN 24 +#define FRF_AB_XM_TX_PROG_WIDTH 1 +#define FRF_AB_XM_IPG_LBN 16 +#define FRF_AB_XM_IPG_WIDTH 4 +#define FRF_AB_XM_FCNTL_LBN 10 +#define FRF_AB_XM_FCNTL_WIDTH 1 +#define FRF_AB_XM_TXCRC_LBN 8 +#define FRF_AB_XM_TXCRC_WIDTH 1 +#define FRF_AB_XM_EDRC_LBN 6 +#define FRF_AB_XM_EDRC_WIDTH 1 +#define FRF_AB_XM_AUTO_PAD_LBN 5 +#define FRF_AB_XM_AUTO_PAD_WIDTH 1 +#define FRF_AB_XM_TX_PRMBL_LBN 2 +#define FRF_AB_XM_TX_PRMBL_WIDTH 1 +#define FRF_AB_XM_TXEN_LBN 1 +#define FRF_AB_XM_TXEN_WIDTH 1 +#define FRF_AB_XM_TX_RST_LBN 0 +#define FRF_AB_XM_TX_RST_WIDTH 1 + +/* XM_RX_CFG_REG: XGMAC receive configuration */ +#define FR_AB_XM_RX_CFG 0x00001240 +#define FRF_AB_XM_PASS_LENERR_LBN 26 +#define FRF_AB_XM_PASS_LENERR_WIDTH 1 +#define FRF_AB_XM_PASS_CRC_ERR_LBN 25 +#define FRF_AB_XM_PASS_CRC_ERR_WIDTH 1 +#define FRF_AB_XM_PASS_PRMBLE_ERR_LBN 24 +#define FRF_AB_XM_PASS_PRMBLE_ERR_WIDTH 1 +#define FRF_AB_XM_REJ_BCAST_LBN 20 +#define FRF_AB_XM_REJ_BCAST_WIDTH 1 +#define FRF_AB_XM_ACPT_ALL_MCAST_LBN 11 +#define FRF_AB_XM_ACPT_ALL_MCAST_WIDTH 1 +#define FRF_AB_XM_ACPT_ALL_UCAST_LBN 9 +#define FRF_AB_XM_ACPT_ALL_UCAST_WIDTH 1 +#define FRF_AB_XM_AUTO_DEPAD_LBN 8 +#define FRF_AB_XM_AUTO_DEPAD_WIDTH 1 +#define FRF_AB_XM_RXCRC_LBN 3 +#define FRF_AB_XM_RXCRC_WIDTH 1 +#define FRF_AB_XM_RX_PRMBL_LBN 2 +#define FRF_AB_XM_RX_PRMBL_WIDTH 1 +#define FRF_AB_XM_RXEN_LBN 1 +#define FRF_AB_XM_RXEN_WIDTH 1 +#define FRF_AB_XM_RX_RST_LBN 0 +#define FRF_AB_XM_RX_RST_WIDTH 1 + +/* XM_MGT_INT_MASK: documentation to be written for sum_XM_MGT_INT_MASK */ +#define FR_AB_XM_MGT_INT_MASK 0x00001250 +#define FRF_AB_XM_MSK_STA_INTR_LBN 16 +#define FRF_AB_XM_MSK_STA_INTR_WIDTH 1 +#define FRF_AB_XM_MSK_STAT_CNTR_HF_LBN 9 +#define FRF_AB_XM_MSK_STAT_CNTR_HF_WIDTH 1 +#define FRF_AB_XM_MSK_STAT_CNTR_OF_LBN 8 +#define FRF_AB_XM_MSK_STAT_CNTR_OF_WIDTH 1 +#define FRF_AB_XM_MSK_PRMBLE_ERR_LBN 2 +#define FRF_AB_XM_MSK_PRMBLE_ERR_WIDTH 1 +#define FRF_AB_XM_MSK_RMTFLT_LBN 1 +#define FRF_AB_XM_MSK_RMTFLT_WIDTH 1 +#define FRF_AB_XM_MSK_LCLFLT_LBN 0 +#define FRF_AB_XM_MSK_LCLFLT_WIDTH 1 + +/* XM_FC_REG: XGMAC flow control register */ +#define FR_AB_XM_FC 0x00001270 +#define FRF_AB_XM_PAUSE_TIME_LBN 16 +#define FRF_AB_XM_PAUSE_TIME_WIDTH 16 +#define FRF_AB_XM_RX_MAC_STAT_LBN 11 +#define FRF_AB_XM_RX_MAC_STAT_WIDTH 1 +#define FRF_AB_XM_TX_MAC_STAT_LBN 10 +#define FRF_AB_XM_TX_MAC_STAT_WIDTH 1 +#define FRF_AB_XM_MCNTL_PASS_LBN 8 +#define FRF_AB_XM_MCNTL_PASS_WIDTH 2 +#define FRF_AB_XM_REJ_CNTL_UCAST_LBN 6 +#define FRF_AB_XM_REJ_CNTL_UCAST_WIDTH 1 +#define FRF_AB_XM_REJ_CNTL_MCAST_LBN 5 +#define FRF_AB_XM_REJ_CNTL_MCAST_WIDTH 1 +#define FRF_AB_XM_ZPAUSE_LBN 2 +#define FRF_AB_XM_ZPAUSE_WIDTH 1 +#define FRF_AB_XM_XMIT_PAUSE_LBN 1 +#define FRF_AB_XM_XMIT_PAUSE_WIDTH 1 +#define FRF_AB_XM_DIS_FCNTL_LBN 0 +#define FRF_AB_XM_DIS_FCNTL_WIDTH 1 + +/* XM_PAUSE_TIME_REG: XGMAC pause time register */ +#define FR_AB_XM_PAUSE_TIME 0x00001290 +#define FRF_AB_XM_TX_PAUSE_CNT_LBN 16 +#define FRF_AB_XM_TX_PAUSE_CNT_WIDTH 16 +#define FRF_AB_XM_RX_PAUSE_CNT_LBN 0 +#define FRF_AB_XM_RX_PAUSE_CNT_WIDTH 16 + +/* XM_TX_PARAM_REG: XGMAC transmit parameter register */ +#define FR_AB_XM_TX_PARAM 0x000012d0 +#define FRF_AB_XM_TX_JUMBO_MODE_LBN 31 +#define FRF_AB_XM_TX_JUMBO_MODE_WIDTH 1 +#define FRF_AB_XM_MAX_TX_FRM_SIZE_HI_LBN 19 +#define FRF_AB_XM_MAX_TX_FRM_SIZE_HI_WIDTH 11 +#define FRF_AB_XM_MAX_TX_FRM_SIZE_LO_LBN 16 +#define FRF_AB_XM_MAX_TX_FRM_SIZE_LO_WIDTH 3 +#define FRF_AB_XM_PAD_CHAR_LBN 0 +#define FRF_AB_XM_PAD_CHAR_WIDTH 8 + +/* XM_RX_PARAM_REG: XGMAC receive parameter register */ +#define FR_AB_XM_RX_PARAM 0x000012e0 +#define FRF_AB_XM_MAX_RX_FRM_SIZE_HI_LBN 3 +#define FRF_AB_XM_MAX_RX_FRM_SIZE_HI_WIDTH 11 +#define FRF_AB_XM_MAX_RX_FRM_SIZE_LO_LBN 0 +#define FRF_AB_XM_MAX_RX_FRM_SIZE_LO_WIDTH 3 + +/* XM_MGT_INT_MSK_REG: XGMAC management interrupt mask register */ +#define FR_AB_XM_MGT_INT_MSK 0x000012f0 +#define FRF_AB_XM_STAT_CNTR_OF_LBN 9 +#define FRF_AB_XM_STAT_CNTR_OF_WIDTH 1 +#define FRF_AB_XM_STAT_CNTR_HF_LBN 8 +#define FRF_AB_XM_STAT_CNTR_HF_WIDTH 1 +#define FRF_AB_XM_PRMBLE_ERR_LBN 2 +#define FRF_AB_XM_PRMBLE_ERR_WIDTH 1 +#define FRF_AB_XM_RMTFLT_LBN 1 +#define FRF_AB_XM_RMTFLT_WIDTH 1 +#define FRF_AB_XM_LCLFLT_LBN 0 +#define FRF_AB_XM_LCLFLT_WIDTH 1 + +/* XX_PWR_RST_REG: XGXS/XAUI powerdown/reset register */ +#define FR_AB_XX_PWR_RST 0x00001300 +#define FRF_AB_XX_PWRDND_SIG_LBN 31 +#define FRF_AB_XX_PWRDND_SIG_WIDTH 1 +#define FRF_AB_XX_PWRDNC_SIG_LBN 30 +#define FRF_AB_XX_PWRDNC_SIG_WIDTH 1 +#define FRF_AB_XX_PWRDNB_SIG_LBN 29 +#define FRF_AB_XX_PWRDNB_SIG_WIDTH 1 +#define FRF_AB_XX_PWRDNA_SIG_LBN 28 +#define FRF_AB_XX_PWRDNA_SIG_WIDTH 1 +#define FRF_AB_XX_SIM_MODE_LBN 27 +#define FRF_AB_XX_SIM_MODE_WIDTH 1 +#define FRF_AB_XX_RSTPLLCD_SIG_LBN 25 +#define FRF_AB_XX_RSTPLLCD_SIG_WIDTH 1 +#define FRF_AB_XX_RSTPLLAB_SIG_LBN 24 +#define FRF_AB_XX_RSTPLLAB_SIG_WIDTH 1 +#define FRF_AB_XX_RESETD_SIG_LBN 23 +#define FRF_AB_XX_RESETD_SIG_WIDTH 1 +#define FRF_AB_XX_RESETC_SIG_LBN 22 +#define FRF_AB_XX_RESETC_SIG_WIDTH 1 +#define FRF_AB_XX_RESETB_SIG_LBN 21 +#define FRF_AB_XX_RESETB_SIG_WIDTH 1 +#define FRF_AB_XX_RESETA_SIG_LBN 20 +#define FRF_AB_XX_RESETA_SIG_WIDTH 1 +#define FRF_AB_XX_RSTXGXSRX_SIG_LBN 18 +#define FRF_AB_XX_RSTXGXSRX_SIG_WIDTH 1 +#define FRF_AB_XX_RSTXGXSTX_SIG_LBN 17 +#define FRF_AB_XX_RSTXGXSTX_SIG_WIDTH 1 +#define FRF_AB_XX_SD_RST_ACT_LBN 16 +#define FRF_AB_XX_SD_RST_ACT_WIDTH 1 +#define FRF_AB_XX_PWRDND_EN_LBN 15 +#define FRF_AB_XX_PWRDND_EN_WIDTH 1 +#define FRF_AB_XX_PWRDNC_EN_LBN 14 +#define FRF_AB_XX_PWRDNC_EN_WIDTH 1 +#define FRF_AB_XX_PWRDNB_EN_LBN 13 +#define FRF_AB_XX_PWRDNB_EN_WIDTH 1 +#define FRF_AB_XX_PWRDNA_EN_LBN 12 +#define FRF_AB_XX_PWRDNA_EN_WIDTH 1 +#define FRF_AB_XX_RSTPLLCD_EN_LBN 9 +#define FRF_AB_XX_RSTPLLCD_EN_WIDTH 1 +#define FRF_AB_XX_RSTPLLAB_EN_LBN 8 +#define FRF_AB_XX_RSTPLLAB_EN_WIDTH 1 +#define FRF_AB_XX_RESETD_EN_LBN 7 +#define FRF_AB_XX_RESETD_EN_WIDTH 1 +#define FRF_AB_XX_RESETC_EN_LBN 6 +#define FRF_AB_XX_RESETC_EN_WIDTH 1 +#define FRF_AB_XX_RESETB_EN_LBN 5 +#define FRF_AB_XX_RESETB_EN_WIDTH 1 +#define FRF_AB_XX_RESETA_EN_LBN 4 +#define FRF_AB_XX_RESETA_EN_WIDTH 1 +#define FRF_AB_XX_RSTXGXSRX_EN_LBN 2 +#define FRF_AB_XX_RSTXGXSRX_EN_WIDTH 1 +#define FRF_AB_XX_RSTXGXSTX_EN_LBN 1 +#define FRF_AB_XX_RSTXGXSTX_EN_WIDTH 1 +#define FRF_AB_XX_RST_XX_EN_LBN 0 +#define FRF_AB_XX_RST_XX_EN_WIDTH 1 + +/* XX_SD_CTL_REG: XGXS/XAUI powerdown/reset control register */ +#define FR_AB_XX_SD_CTL 0x00001310 +#define FRF_AB_XX_TERMADJ1_LBN 17 +#define FRF_AB_XX_TERMADJ1_WIDTH 1 +#define FRF_AB_XX_TERMADJ0_LBN 16 +#define FRF_AB_XX_TERMADJ0_WIDTH 1 +#define FRF_AB_XX_HIDRVD_LBN 15 +#define FRF_AB_XX_HIDRVD_WIDTH 1 +#define FRF_AB_XX_LODRVD_LBN 14 +#define FRF_AB_XX_LODRVD_WIDTH 1 +#define FRF_AB_XX_HIDRVC_LBN 13 +#define FRF_AB_XX_HIDRVC_WIDTH 1 +#define FRF_AB_XX_LODRVC_LBN 12 +#define FRF_AB_XX_LODRVC_WIDTH 1 +#define FRF_AB_XX_HIDRVB_LBN 11 +#define FRF_AB_XX_HIDRVB_WIDTH 1 +#define FRF_AB_XX_LODRVB_LBN 10 +#define FRF_AB_XX_LODRVB_WIDTH 1 +#define FRF_AB_XX_HIDRVA_LBN 9 +#define FRF_AB_XX_HIDRVA_WIDTH 1 +#define FRF_AB_XX_LODRVA_LBN 8 +#define FRF_AB_XX_LODRVA_WIDTH 1 +#define FRF_AB_XX_LPBKD_LBN 3 +#define FRF_AB_XX_LPBKD_WIDTH 1 +#define FRF_AB_XX_LPBKC_LBN 2 +#define FRF_AB_XX_LPBKC_WIDTH 1 +#define FRF_AB_XX_LPBKB_LBN 1 +#define FRF_AB_XX_LPBKB_WIDTH 1 +#define FRF_AB_XX_LPBKA_LBN 0 +#define FRF_AB_XX_LPBKA_WIDTH 1 + +/* XX_TXDRV_CTL_REG: XAUI SerDes transmit drive control register */ +#define FR_AB_XX_TXDRV_CTL 0x00001320 +#define FRF_AB_XX_DEQD_LBN 28 +#define FRF_AB_XX_DEQD_WIDTH 4 +#define FRF_AB_XX_DEQC_LBN 24 +#define FRF_AB_XX_DEQC_WIDTH 4 +#define FRF_AB_XX_DEQB_LBN 20 +#define FRF_AB_XX_DEQB_WIDTH 4 +#define FRF_AB_XX_DEQA_LBN 16 +#define FRF_AB_XX_DEQA_WIDTH 4 +#define FRF_AB_XX_DTXD_LBN 12 +#define FRF_AB_XX_DTXD_WIDTH 4 +#define FRF_AB_XX_DTXC_LBN 8 +#define FRF_AB_XX_DTXC_WIDTH 4 +#define FRF_AB_XX_DTXB_LBN 4 +#define FRF_AB_XX_DTXB_WIDTH 4 +#define FRF_AB_XX_DTXA_LBN 0 +#define FRF_AB_XX_DTXA_WIDTH 4 + +/* XX_PRBS_CTL_REG: documentation to be written for sum_XX_PRBS_CTL_REG */ +#define FR_AB_XX_PRBS_CTL 0x00001330 +#define FRF_AB_XX_CH3_RX_PRBS_SEL_LBN 30 +#define FRF_AB_XX_CH3_RX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH3_RX_PRBS_INV_LBN 29 +#define FRF_AB_XX_CH3_RX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH3_RX_PRBS_CHKEN_LBN 28 +#define FRF_AB_XX_CH3_RX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH2_RX_PRBS_SEL_LBN 26 +#define FRF_AB_XX_CH2_RX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH2_RX_PRBS_INV_LBN 25 +#define FRF_AB_XX_CH2_RX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH2_RX_PRBS_CHKEN_LBN 24 +#define FRF_AB_XX_CH2_RX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH1_RX_PRBS_SEL_LBN 22 +#define FRF_AB_XX_CH1_RX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH1_RX_PRBS_INV_LBN 21 +#define FRF_AB_XX_CH1_RX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH1_RX_PRBS_CHKEN_LBN 20 +#define FRF_AB_XX_CH1_RX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH0_RX_PRBS_SEL_LBN 18 +#define FRF_AB_XX_CH0_RX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH0_RX_PRBS_INV_LBN 17 +#define FRF_AB_XX_CH0_RX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH0_RX_PRBS_CHKEN_LBN 16 +#define FRF_AB_XX_CH0_RX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH3_TX_PRBS_SEL_LBN 14 +#define FRF_AB_XX_CH3_TX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH3_TX_PRBS_INV_LBN 13 +#define FRF_AB_XX_CH3_TX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH3_TX_PRBS_CHKEN_LBN 12 +#define FRF_AB_XX_CH3_TX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH2_TX_PRBS_SEL_LBN 10 +#define FRF_AB_XX_CH2_TX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH2_TX_PRBS_INV_LBN 9 +#define FRF_AB_XX_CH2_TX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH2_TX_PRBS_CHKEN_LBN 8 +#define FRF_AB_XX_CH2_TX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH1_TX_PRBS_SEL_LBN 6 +#define FRF_AB_XX_CH1_TX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH1_TX_PRBS_INV_LBN 5 +#define FRF_AB_XX_CH1_TX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH1_TX_PRBS_CHKEN_LBN 4 +#define FRF_AB_XX_CH1_TX_PRBS_CHKEN_WIDTH 1 +#define FRF_AB_XX_CH0_TX_PRBS_SEL_LBN 2 +#define FRF_AB_XX_CH0_TX_PRBS_SEL_WIDTH 2 +#define FRF_AB_XX_CH0_TX_PRBS_INV_LBN 1 +#define FRF_AB_XX_CH0_TX_PRBS_INV_WIDTH 1 +#define FRF_AB_XX_CH0_TX_PRBS_CHKEN_LBN 0 +#define FRF_AB_XX_CH0_TX_PRBS_CHKEN_WIDTH 1 + +/* XX_PRBS_CHK_REG: documentation to be written for sum_XX_PRBS_CHK_REG */ +#define FR_AB_XX_PRBS_CHK 0x00001340 +#define FRF_AB_XX_REV_LB_EN_LBN 16 +#define FRF_AB_XX_REV_LB_EN_WIDTH 1 +#define FRF_AB_XX_CH3_DEG_DET_LBN 15 +#define FRF_AB_XX_CH3_DEG_DET_WIDTH 1 +#define FRF_AB_XX_CH3_LFSR_LOCK_IND_LBN 14 +#define FRF_AB_XX_CH3_LFSR_LOCK_IND_WIDTH 1 +#define FRF_AB_XX_CH3_PRBS_FRUN_LBN 13 +#define FRF_AB_XX_CH3_PRBS_FRUN_WIDTH 1 +#define FRF_AB_XX_CH3_ERR_CHK_LBN 12 +#define FRF_AB_XX_CH3_ERR_CHK_WIDTH 1 +#define FRF_AB_XX_CH2_DEG_DET_LBN 11 +#define FRF_AB_XX_CH2_DEG_DET_WIDTH 1 +#define FRF_AB_XX_CH2_LFSR_LOCK_IND_LBN 10 +#define FRF_AB_XX_CH2_LFSR_LOCK_IND_WIDTH 1 +#define FRF_AB_XX_CH2_PRBS_FRUN_LBN 9 +#define FRF_AB_XX_CH2_PRBS_FRUN_WIDTH 1 +#define FRF_AB_XX_CH2_ERR_CHK_LBN 8 +#define FRF_AB_XX_CH2_ERR_CHK_WIDTH 1 +#define FRF_AB_XX_CH1_DEG_DET_LBN 7 +#define FRF_AB_XX_CH1_DEG_DET_WIDTH 1 +#define FRF_AB_XX_CH1_LFSR_LOCK_IND_LBN 6 +#define FRF_AB_XX_CH1_LFSR_LOCK_IND_WIDTH 1 +#define FRF_AB_XX_CH1_PRBS_FRUN_LBN 5 +#define FRF_AB_XX_CH1_PRBS_FRUN_WIDTH 1 +#define FRF_AB_XX_CH1_ERR_CHK_LBN 4 +#define FRF_AB_XX_CH1_ERR_CHK_WIDTH 1 +#define FRF_AB_XX_CH0_DEG_DET_LBN 3 +#define FRF_AB_XX_CH0_DEG_DET_WIDTH 1 +#define FRF_AB_XX_CH0_LFSR_LOCK_IND_LBN 2 +#define FRF_AB_XX_CH0_LFSR_LOCK_IND_WIDTH 1 +#define FRF_AB_XX_CH0_PRBS_FRUN_LBN 1 +#define FRF_AB_XX_CH0_PRBS_FRUN_WIDTH 1 +#define FRF_AB_XX_CH0_ERR_CHK_LBN 0 +#define FRF_AB_XX_CH0_ERR_CHK_WIDTH 1 + +/* XX_PRBS_ERR_REG: documentation to be written for sum_XX_PRBS_ERR_REG */ +#define FR_AB_XX_PRBS_ERR 0x00001350 +#define FRF_AB_XX_CH3_PRBS_ERR_CNT_LBN 24 +#define FRF_AB_XX_CH3_PRBS_ERR_CNT_WIDTH 8 +#define FRF_AB_XX_CH2_PRBS_ERR_CNT_LBN 16 +#define FRF_AB_XX_CH2_PRBS_ERR_CNT_WIDTH 8 +#define FRF_AB_XX_CH1_PRBS_ERR_CNT_LBN 8 +#define FRF_AB_XX_CH1_PRBS_ERR_CNT_WIDTH 8 +#define FRF_AB_XX_CH0_PRBS_ERR_CNT_LBN 0 +#define FRF_AB_XX_CH0_PRBS_ERR_CNT_WIDTH 8 + +/* XX_CORE_STAT_REG: XAUI XGXS core status register */ +#define FR_AB_XX_CORE_STAT 0x00001360 +#define FRF_AB_XX_FORCE_SIG3_LBN 31 +#define FRF_AB_XX_FORCE_SIG3_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG3_VAL_LBN 30 +#define FRF_AB_XX_FORCE_SIG3_VAL_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG2_LBN 29 +#define FRF_AB_XX_FORCE_SIG2_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG2_VAL_LBN 28 +#define FRF_AB_XX_FORCE_SIG2_VAL_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG1_LBN 27 +#define FRF_AB_XX_FORCE_SIG1_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG1_VAL_LBN 26 +#define FRF_AB_XX_FORCE_SIG1_VAL_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG0_LBN 25 +#define FRF_AB_XX_FORCE_SIG0_WIDTH 1 +#define FRF_AB_XX_FORCE_SIG0_VAL_LBN 24 +#define FRF_AB_XX_FORCE_SIG0_VAL_WIDTH 1 +#define FRF_AB_XX_XGXS_LB_EN_LBN 23 +#define FRF_AB_XX_XGXS_LB_EN_WIDTH 1 +#define FRF_AB_XX_XGMII_LB_EN_LBN 22 +#define FRF_AB_XX_XGMII_LB_EN_WIDTH 1 +#define FRF_AB_XX_MATCH_FAULT_LBN 21 +#define FRF_AB_XX_MATCH_FAULT_WIDTH 1 +#define FRF_AB_XX_ALIGN_DONE_LBN 20 +#define FRF_AB_XX_ALIGN_DONE_WIDTH 1 +#define FRF_AB_XX_SYNC_STAT3_LBN 19 +#define FRF_AB_XX_SYNC_STAT3_WIDTH 1 +#define FRF_AB_XX_SYNC_STAT2_LBN 18 +#define FRF_AB_XX_SYNC_STAT2_WIDTH 1 +#define FRF_AB_XX_SYNC_STAT1_LBN 17 +#define FRF_AB_XX_SYNC_STAT1_WIDTH 1 +#define FRF_AB_XX_SYNC_STAT0_LBN 16 +#define FRF_AB_XX_SYNC_STAT0_WIDTH 1 +#define FRF_AB_XX_COMMA_DET_CH3_LBN 15 +#define FRF_AB_XX_COMMA_DET_CH3_WIDTH 1 +#define FRF_AB_XX_COMMA_DET_CH2_LBN 14 +#define FRF_AB_XX_COMMA_DET_CH2_WIDTH 1 +#define FRF_AB_XX_COMMA_DET_CH1_LBN 13 +#define FRF_AB_XX_COMMA_DET_CH1_WIDTH 1 +#define FRF_AB_XX_COMMA_DET_CH0_LBN 12 +#define FRF_AB_XX_COMMA_DET_CH0_WIDTH 1 +#define FRF_AB_XX_CGRP_ALIGN_CH3_LBN 11 +#define FRF_AB_XX_CGRP_ALIGN_CH3_WIDTH 1 +#define FRF_AB_XX_CGRP_ALIGN_CH2_LBN 10 +#define FRF_AB_XX_CGRP_ALIGN_CH2_WIDTH 1 +#define FRF_AB_XX_CGRP_ALIGN_CH1_LBN 9 +#define FRF_AB_XX_CGRP_ALIGN_CH1_WIDTH 1 +#define FRF_AB_XX_CGRP_ALIGN_CH0_LBN 8 +#define FRF_AB_XX_CGRP_ALIGN_CH0_WIDTH 1 +#define FRF_AB_XX_CHAR_ERR_CH3_LBN 7 +#define FRF_AB_XX_CHAR_ERR_CH3_WIDTH 1 +#define FRF_AB_XX_CHAR_ERR_CH2_LBN 6 +#define FRF_AB_XX_CHAR_ERR_CH2_WIDTH 1 +#define FRF_AB_XX_CHAR_ERR_CH1_LBN 5 +#define FRF_AB_XX_CHAR_ERR_CH1_WIDTH 1 +#define FRF_AB_XX_CHAR_ERR_CH0_LBN 4 +#define FRF_AB_XX_CHAR_ERR_CH0_WIDTH 1 +#define FRF_AB_XX_DISPERR_CH3_LBN 3 +#define FRF_AB_XX_DISPERR_CH3_WIDTH 1 +#define FRF_AB_XX_DISPERR_CH2_LBN 2 +#define FRF_AB_XX_DISPERR_CH2_WIDTH 1 +#define FRF_AB_XX_DISPERR_CH1_LBN 1 +#define FRF_AB_XX_DISPERR_CH1_WIDTH 1 +#define FRF_AB_XX_DISPERR_CH0_LBN 0 +#define FRF_AB_XX_DISPERR_CH0_WIDTH 1 + +/* RX_DESC_PTR_TBL_KER: Receive descriptor pointer table */ +#define FR_AA_RX_DESC_PTR_TBL_KER 0x00011800 +#define FR_AA_RX_DESC_PTR_TBL_KER_STEP 16 +#define FR_AA_RX_DESC_PTR_TBL_KER_ROWS 4 +/* RX_DESC_PTR_TBL: Receive descriptor pointer table */ +#define FR_BZ_RX_DESC_PTR_TBL 0x00f40000 +#define FR_BZ_RX_DESC_PTR_TBL_STEP 16 +#define FR_BB_RX_DESC_PTR_TBL_ROWS 4096 +#define FR_CZ_RX_DESC_PTR_TBL_ROWS 1024 +#define FRF_CZ_RX_HDR_SPLIT_LBN 90 +#define FRF_CZ_RX_HDR_SPLIT_WIDTH 1 +#define FRF_AA_RX_RESET_LBN 89 +#define FRF_AA_RX_RESET_WIDTH 1 +#define FRF_AZ_RX_ISCSI_DDIG_EN_LBN 88 +#define FRF_AZ_RX_ISCSI_DDIG_EN_WIDTH 1 +#define FRF_AZ_RX_ISCSI_HDIG_EN_LBN 87 +#define FRF_AZ_RX_ISCSI_HDIG_EN_WIDTH 1 +#define FRF_AZ_RX_DESC_PREF_ACT_LBN 86 +#define FRF_AZ_RX_DESC_PREF_ACT_WIDTH 1 +#define FRF_AZ_RX_DC_HW_RPTR_LBN 80 +#define FRF_AZ_RX_DC_HW_RPTR_WIDTH 6 +#define FRF_AZ_RX_DESCQ_HW_RPTR_LBN 68 +#define FRF_AZ_RX_DESCQ_HW_RPTR_WIDTH 12 +#define FRF_AZ_RX_DESCQ_SW_WPTR_LBN 56 +#define FRF_AZ_RX_DESCQ_SW_WPTR_WIDTH 12 +#define FRF_AZ_RX_DESCQ_BUF_BASE_ID_LBN 36 +#define FRF_AZ_RX_DESCQ_BUF_BASE_ID_WIDTH 20 +#define FRF_AZ_RX_DESCQ_EVQ_ID_LBN 24 +#define FRF_AZ_RX_DESCQ_EVQ_ID_WIDTH 12 +#define FRF_AZ_RX_DESCQ_OWNER_ID_LBN 10 +#define FRF_AZ_RX_DESCQ_OWNER_ID_WIDTH 14 +#define FRF_AZ_RX_DESCQ_LABEL_LBN 5 +#define FRF_AZ_RX_DESCQ_LABEL_WIDTH 5 +#define FRF_AZ_RX_DESCQ_SIZE_LBN 3 +#define FRF_AZ_RX_DESCQ_SIZE_WIDTH 2 +#define FFE_AZ_RX_DESCQ_SIZE_4K 3 +#define FFE_AZ_RX_DESCQ_SIZE_2K 2 +#define FFE_AZ_RX_DESCQ_SIZE_1K 1 +#define FFE_AZ_RX_DESCQ_SIZE_512 0 +#define FRF_AZ_RX_DESCQ_TYPE_LBN 2 +#define FRF_AZ_RX_DESCQ_TYPE_WIDTH 1 +#define FRF_AZ_RX_DESCQ_JUMBO_LBN 1 +#define FRF_AZ_RX_DESCQ_JUMBO_WIDTH 1 +#define FRF_AZ_RX_DESCQ_EN_LBN 0 +#define FRF_AZ_RX_DESCQ_EN_WIDTH 1 + +/* TX_DESC_PTR_TBL_KER: Transmit descriptor pointer */ +#define FR_AA_TX_DESC_PTR_TBL_KER 0x00011900 +#define FR_AA_TX_DESC_PTR_TBL_KER_STEP 16 +#define FR_AA_TX_DESC_PTR_TBL_KER_ROWS 8 +/* TX_DESC_PTR_TBL: Transmit descriptor pointer */ +#define FR_BZ_TX_DESC_PTR_TBL 0x00f50000 +#define FR_BZ_TX_DESC_PTR_TBL_STEP 16 +#define FR_BB_TX_DESC_PTR_TBL_ROWS 4096 +#define FR_CZ_TX_DESC_PTR_TBL_ROWS 1024 +#define FRF_CZ_TX_DPT_Q_MASK_WIDTH_LBN 94 +#define FRF_CZ_TX_DPT_Q_MASK_WIDTH_WIDTH 2 +#define FRF_CZ_TX_DPT_ETH_FILT_EN_LBN 93 +#define FRF_CZ_TX_DPT_ETH_FILT_EN_WIDTH 1 +#define FRF_CZ_TX_DPT_IP_FILT_EN_LBN 92 +#define FRF_CZ_TX_DPT_IP_FILT_EN_WIDTH 1 +#define FRF_BZ_TX_NON_IP_DROP_DIS_LBN 91 +#define FRF_BZ_TX_NON_IP_DROP_DIS_WIDTH 1 +#define FRF_BZ_TX_IP_CHKSM_DIS_LBN 90 +#define FRF_BZ_TX_IP_CHKSM_DIS_WIDTH 1 +#define FRF_BZ_TX_TCP_CHKSM_DIS_LBN 89 +#define FRF_BZ_TX_TCP_CHKSM_DIS_WIDTH 1 +#define FRF_AZ_TX_DESCQ_EN_LBN 88 +#define FRF_AZ_TX_DESCQ_EN_WIDTH 1 +#define FRF_AZ_TX_ISCSI_DDIG_EN_LBN 87 +#define FRF_AZ_TX_ISCSI_DDIG_EN_WIDTH 1 +#define FRF_AZ_TX_ISCSI_HDIG_EN_LBN 86 +#define FRF_AZ_TX_ISCSI_HDIG_EN_WIDTH 1 +#define FRF_AZ_TX_DC_HW_RPTR_LBN 80 +#define FRF_AZ_TX_DC_HW_RPTR_WIDTH 6 +#define FRF_AZ_TX_DESCQ_HW_RPTR_LBN 68 +#define FRF_AZ_TX_DESCQ_HW_RPTR_WIDTH 12 +#define FRF_AZ_TX_DESCQ_SW_WPTR_LBN 56 +#define FRF_AZ_TX_DESCQ_SW_WPTR_WIDTH 12 +#define FRF_AZ_TX_DESCQ_BUF_BASE_ID_LBN 36 +#define FRF_AZ_TX_DESCQ_BUF_BASE_ID_WIDTH 20 +#define FRF_AZ_TX_DESCQ_EVQ_ID_LBN 24 +#define FRF_AZ_TX_DESCQ_EVQ_ID_WIDTH 12 +#define FRF_AZ_TX_DESCQ_OWNER_ID_LBN 10 +#define FRF_AZ_TX_DESCQ_OWNER_ID_WIDTH 14 +#define FRF_AZ_TX_DESCQ_LABEL_LBN 5 +#define FRF_AZ_TX_DESCQ_LABEL_WIDTH 5 +#define FRF_AZ_TX_DESCQ_SIZE_LBN 3 +#define FRF_AZ_TX_DESCQ_SIZE_WIDTH 2 +#define FFE_AZ_TX_DESCQ_SIZE_4K 3 +#define FFE_AZ_TX_DESCQ_SIZE_2K 2 +#define FFE_AZ_TX_DESCQ_SIZE_1K 1 +#define FFE_AZ_TX_DESCQ_SIZE_512 0 +#define FRF_AZ_TX_DESCQ_TYPE_LBN 1 +#define FRF_AZ_TX_DESCQ_TYPE_WIDTH 2 +#define FRF_AZ_TX_DESCQ_FLUSH_LBN 0 +#define FRF_AZ_TX_DESCQ_FLUSH_WIDTH 1 + +/* EVQ_PTR_TBL_KER: Event queue pointer table */ +#define FR_AA_EVQ_PTR_TBL_KER 0x00011a00 +#define FR_AA_EVQ_PTR_TBL_KER_STEP 16 +#define FR_AA_EVQ_PTR_TBL_KER_ROWS 4 +/* EVQ_PTR_TBL: Event queue pointer table */ +#define FR_BZ_EVQ_PTR_TBL 0x00f60000 +#define FR_BZ_EVQ_PTR_TBL_STEP 16 +#define FR_CZ_EVQ_PTR_TBL_ROWS 1024 +#define FR_BB_EVQ_PTR_TBL_ROWS 4096 +#define FRF_BZ_EVQ_RPTR_IGN_LBN 40 +#define FRF_BZ_EVQ_RPTR_IGN_WIDTH 1 +#define FRF_AB_EVQ_WKUP_OR_INT_EN_LBN 39 +#define FRF_AB_EVQ_WKUP_OR_INT_EN_WIDTH 1 +#define FRF_CZ_EVQ_DOS_PROTECT_EN_LBN 39 +#define FRF_CZ_EVQ_DOS_PROTECT_EN_WIDTH 1 +#define FRF_AZ_EVQ_NXT_WPTR_LBN 24 +#define FRF_AZ_EVQ_NXT_WPTR_WIDTH 15 +#define FRF_AZ_EVQ_EN_LBN 23 +#define FRF_AZ_EVQ_EN_WIDTH 1 +#define FRF_AZ_EVQ_SIZE_LBN 20 +#define FRF_AZ_EVQ_SIZE_WIDTH 3 +#define FFE_AZ_EVQ_SIZE_32K 6 +#define FFE_AZ_EVQ_SIZE_16K 5 +#define FFE_AZ_EVQ_SIZE_8K 4 +#define FFE_AZ_EVQ_SIZE_4K 3 +#define FFE_AZ_EVQ_SIZE_2K 2 +#define FFE_AZ_EVQ_SIZE_1K 1 +#define FFE_AZ_EVQ_SIZE_512 0 +#define FRF_AZ_EVQ_BUF_BASE_ID_LBN 0 +#define FRF_AZ_EVQ_BUF_BASE_ID_WIDTH 20 + +/* BUF_HALF_TBL_KER: Buffer table in half buffer table mode direct access by driver */ +#define FR_AA_BUF_HALF_TBL_KER 0x00018000 +#define FR_AA_BUF_HALF_TBL_KER_STEP 8 +#define FR_AA_BUF_HALF_TBL_KER_ROWS 4096 +/* BUF_HALF_TBL: Buffer table in half buffer table mode direct access by driver */ +#define FR_BZ_BUF_HALF_TBL 0x00800000 +#define FR_BZ_BUF_HALF_TBL_STEP 8 +#define FR_CZ_BUF_HALF_TBL_ROWS 147456 +#define FR_BB_BUF_HALF_TBL_ROWS 524288 +#define FRF_AZ_BUF_ADR_HBUF_ODD_LBN 44 +#define FRF_AZ_BUF_ADR_HBUF_ODD_WIDTH 20 +#define FRF_AZ_BUF_OWNER_ID_HBUF_ODD_LBN 32 +#define FRF_AZ_BUF_OWNER_ID_HBUF_ODD_WIDTH 12 +#define FRF_AZ_BUF_ADR_HBUF_EVEN_LBN 12 +#define FRF_AZ_BUF_ADR_HBUF_EVEN_WIDTH 20 +#define FRF_AZ_BUF_OWNER_ID_HBUF_EVEN_LBN 0 +#define FRF_AZ_BUF_OWNER_ID_HBUF_EVEN_WIDTH 12 + +/* BUF_FULL_TBL_KER: Buffer table in full buffer table mode direct access by driver */ +#define FR_AA_BUF_FULL_TBL_KER 0x00018000 +#define FR_AA_BUF_FULL_TBL_KER_STEP 8 +#define FR_AA_BUF_FULL_TBL_KER_ROWS 4096 +/* BUF_FULL_TBL: Buffer table in full buffer table mode direct access by driver */ +#define FR_BZ_BUF_FULL_TBL 0x00800000 +#define FR_BZ_BUF_FULL_TBL_STEP 8 +#define FR_CZ_BUF_FULL_TBL_ROWS 147456 +#define FR_BB_BUF_FULL_TBL_ROWS 917504 +#define FRF_AZ_BUF_FULL_UNUSED_LBN 51 +#define FRF_AZ_BUF_FULL_UNUSED_WIDTH 13 +#define FRF_AZ_IP_DAT_BUF_SIZE_LBN 50 +#define FRF_AZ_IP_DAT_BUF_SIZE_WIDTH 1 +#define FRF_AZ_BUF_ADR_REGION_LBN 48 +#define FRF_AZ_BUF_ADR_REGION_WIDTH 2 +#define FFE_AZ_BUF_ADR_REGN3 3 +#define FFE_AZ_BUF_ADR_REGN2 2 +#define FFE_AZ_BUF_ADR_REGN1 1 +#define FFE_AZ_BUF_ADR_REGN0 0 +#define FRF_AZ_BUF_ADR_FBUF_LBN 14 +#define FRF_AZ_BUF_ADR_FBUF_WIDTH 34 +#define FRF_AZ_BUF_OWNER_ID_FBUF_LBN 0 +#define FRF_AZ_BUF_OWNER_ID_FBUF_WIDTH 14 + +/* RX_FILTER_TBL0: TCP/IPv4 Receive filter table */ +#define FR_BZ_RX_FILTER_TBL0 0x00f00000 +#define FR_BZ_RX_FILTER_TBL0_STEP 32 +#define FR_BZ_RX_FILTER_TBL0_ROWS 8192 +/* RX_FILTER_TBL1: TCP/IPv4 Receive filter table */ +#define FR_BB_RX_FILTER_TBL1 0x00f00010 +#define FR_BB_RX_FILTER_TBL1_STEP 32 +#define FR_BB_RX_FILTER_TBL1_ROWS 8192 +#define FRF_BZ_RSS_EN_LBN 110 +#define FRF_BZ_RSS_EN_WIDTH 1 +#define FRF_BZ_SCATTER_EN_LBN 109 +#define FRF_BZ_SCATTER_EN_WIDTH 1 +#define FRF_BZ_TCP_UDP_LBN 108 +#define FRF_BZ_TCP_UDP_WIDTH 1 +#define FRF_BZ_RXQ_ID_LBN 96 +#define FRF_BZ_RXQ_ID_WIDTH 12 +#define FRF_BZ_DEST_IP_LBN 64 +#define FRF_BZ_DEST_IP_WIDTH 32 +#define FRF_BZ_DEST_PORT_TCP_LBN 48 +#define FRF_BZ_DEST_PORT_TCP_WIDTH 16 +#define FRF_BZ_SRC_IP_LBN 16 +#define FRF_BZ_SRC_IP_WIDTH 32 +#define FRF_BZ_SRC_TCP_DEST_UDP_LBN 0 +#define FRF_BZ_SRC_TCP_DEST_UDP_WIDTH 16 + +/* RX_MAC_FILTER_TBL0: Receive Ethernet filter table */ +#define FR_CZ_RX_MAC_FILTER_TBL0 0x00f00010 +#define FR_CZ_RX_MAC_FILTER_TBL0_STEP 32 +#define FR_CZ_RX_MAC_FILTER_TBL0_ROWS 512 +#define FRF_CZ_RMFT_RSS_EN_LBN 75 +#define FRF_CZ_RMFT_RSS_EN_WIDTH 1 +#define FRF_CZ_RMFT_SCATTER_EN_LBN 74 +#define FRF_CZ_RMFT_SCATTER_EN_WIDTH 1 +#define FRF_CZ_RMFT_IP_OVERRIDE_LBN 73 +#define FRF_CZ_RMFT_IP_OVERRIDE_WIDTH 1 +#define FRF_CZ_RMFT_RXQ_ID_LBN 61 +#define FRF_CZ_RMFT_RXQ_ID_WIDTH 12 +#define FRF_CZ_RMFT_WILDCARD_MATCH_LBN 60 +#define FRF_CZ_RMFT_WILDCARD_MATCH_WIDTH 1 +#define FRF_CZ_RMFT_DEST_MAC_LBN 12 +#define FRF_CZ_RMFT_DEST_MAC_WIDTH 48 +#define FRF_CZ_RMFT_VLAN_ID_LBN 0 +#define FRF_CZ_RMFT_VLAN_ID_WIDTH 12 + +/* TIMER_TBL: Timer table */ +#define FR_BZ_TIMER_TBL 0x00f70000 +#define FR_BZ_TIMER_TBL_STEP 16 +#define FR_CZ_TIMER_TBL_ROWS 1024 +#define FR_BB_TIMER_TBL_ROWS 4096 +#define FRF_CZ_TIMER_Q_EN_LBN 33 +#define FRF_CZ_TIMER_Q_EN_WIDTH 1 +#define FRF_CZ_INT_ARMD_LBN 32 +#define FRF_CZ_INT_ARMD_WIDTH 1 +#define FRF_CZ_INT_PEND_LBN 31 +#define FRF_CZ_INT_PEND_WIDTH 1 +#define FRF_CZ_HOST_NOTIFY_MODE_LBN 30 +#define FRF_CZ_HOST_NOTIFY_MODE_WIDTH 1 +#define FRF_CZ_RELOAD_TIMER_VAL_LBN 16 +#define FRF_CZ_RELOAD_TIMER_VAL_WIDTH 14 +#define FRF_CZ_TIMER_MODE_LBN 14 +#define FRF_CZ_TIMER_MODE_WIDTH 2 +#define FFE_CZ_TIMER_MODE_INT_HLDOFF 3 +#define FFE_CZ_TIMER_MODE_TRIG_START 2 +#define FFE_CZ_TIMER_MODE_IMMED_START 1 +#define FFE_CZ_TIMER_MODE_DIS 0 +#define FRF_BB_TIMER_MODE_LBN 12 +#define FRF_BB_TIMER_MODE_WIDTH 2 +#define FFE_BB_TIMER_MODE_INT_HLDOFF 2 +#define FFE_BB_TIMER_MODE_TRIG_START 2 +#define FFE_BB_TIMER_MODE_IMMED_START 1 +#define FFE_BB_TIMER_MODE_DIS 0 +#define FRF_CZ_TIMER_VAL_LBN 0 +#define FRF_CZ_TIMER_VAL_WIDTH 14 +#define FRF_BB_TIMER_VAL_LBN 0 +#define FRF_BB_TIMER_VAL_WIDTH 12 + +/* TX_PACE_TBL: Transmit pacing table */ +#define FR_BZ_TX_PACE_TBL 0x00f80000 +#define FR_BZ_TX_PACE_TBL_STEP 16 +#define FR_CZ_TX_PACE_TBL_ROWS 1024 +#define FR_BB_TX_PACE_TBL_ROWS 4096 +#define FRF_BZ_TX_PACE_LBN 0 +#define FRF_BZ_TX_PACE_WIDTH 5 + +/* RX_INDIRECTION_TBL: RX Indirection Table */ +#define FR_BZ_RX_INDIRECTION_TBL 0x00fb0000 +#define FR_BZ_RX_INDIRECTION_TBL_STEP 16 +#define FR_BZ_RX_INDIRECTION_TBL_ROWS 128 +#define FRF_BZ_IT_QUEUE_LBN 0 +#define FRF_BZ_IT_QUEUE_WIDTH 6 + +/* TX_FILTER_TBL0: TCP/IPv4 Transmit filter table */ +#define FR_CZ_TX_FILTER_TBL0 0x00fc0000 +#define FR_CZ_TX_FILTER_TBL0_STEP 16 +#define FR_CZ_TX_FILTER_TBL0_ROWS 8192 +#define FRF_CZ_TIFT_TCP_UDP_LBN 108 +#define FRF_CZ_TIFT_TCP_UDP_WIDTH 1 +#define FRF_CZ_TIFT_TXQ_ID_LBN 96 +#define FRF_CZ_TIFT_TXQ_ID_WIDTH 12 +#define FRF_CZ_TIFT_DEST_IP_LBN 64 +#define FRF_CZ_TIFT_DEST_IP_WIDTH 32 +#define FRF_CZ_TIFT_DEST_PORT_TCP_LBN 48 +#define FRF_CZ_TIFT_DEST_PORT_TCP_WIDTH 16 +#define FRF_CZ_TIFT_SRC_IP_LBN 16 +#define FRF_CZ_TIFT_SRC_IP_WIDTH 32 +#define FRF_CZ_TIFT_SRC_TCP_DEST_UDP_LBN 0 +#define FRF_CZ_TIFT_SRC_TCP_DEST_UDP_WIDTH 16 + +/* TX_MAC_FILTER_TBL0: Transmit Ethernet filter table */ +#define FR_CZ_TX_MAC_FILTER_TBL0 0x00fe0000 +#define FR_CZ_TX_MAC_FILTER_TBL0_STEP 16 +#define FR_CZ_TX_MAC_FILTER_TBL0_ROWS 512 +#define FRF_CZ_TMFT_TXQ_ID_LBN 61 +#define FRF_CZ_TMFT_TXQ_ID_WIDTH 12 +#define FRF_CZ_TMFT_WILDCARD_MATCH_LBN 60 +#define FRF_CZ_TMFT_WILDCARD_MATCH_WIDTH 1 +#define FRF_CZ_TMFT_SRC_MAC_LBN 12 +#define FRF_CZ_TMFT_SRC_MAC_WIDTH 48 +#define FRF_CZ_TMFT_VLAN_ID_LBN 0 +#define FRF_CZ_TMFT_VLAN_ID_WIDTH 12 + +/* MC_TREG_SMEM: MC Shared Memory */ +#define FR_CZ_MC_TREG_SMEM 0x00ff0000 +#define FR_CZ_MC_TREG_SMEM_STEP 4 +#define FR_CZ_MC_TREG_SMEM_ROWS 512 +#define FRF_CZ_MC_TREG_SMEM_ROW_LBN 0 +#define FRF_CZ_MC_TREG_SMEM_ROW_WIDTH 32 + +/* EF10 architecture register definitions + * (from linux/drivers/net/ethernet/sfc/ef10_regs.h) + */ + +/* BIU_HW_REV_ID_REG: */ +#define ER_DZ_BIU_HW_REV_ID 0x00000000 +#define ERF_DZ_HW_REV_ID_LBN 0 +#define ERF_DZ_HW_REV_ID_WIDTH 32 + +/* BIU_MC_SFT_STATUS_REG: */ +#define ER_DZ_BIU_MC_SFT_STATUS 0x00000010 +#define ER_DZ_BIU_MC_SFT_STATUS_STEP 4 +#define ER_DZ_BIU_MC_SFT_STATUS_ROWS 8 +#define ERF_DZ_MC_SFT_STATUS_LBN 0 +#define ERF_DZ_MC_SFT_STATUS_WIDTH 32 + +/* BIU_INT_ISR_REG: */ +#define ER_DZ_BIU_INT_ISR 0x00000090 +#define ERF_DZ_ISR_REG_LBN 0 +#define ERF_DZ_ISR_REG_WIDTH 32 + +/* MC_DB_LWRD_REG: */ +#define ER_DZ_MC_DB_LWRD 0x00000200 +#define ERF_DZ_MC_DOORBELL_L_LBN 0 +#define ERF_DZ_MC_DOORBELL_L_WIDTH 32 + +/* MC_DB_HWRD_REG: */ +#define ER_DZ_MC_DB_HWRD 0x00000204 +#define ERF_DZ_MC_DOORBELL_H_LBN 0 +#define ERF_DZ_MC_DOORBELL_H_WIDTH 32 + +/* + * Register dump definition. This is mostly taken from + * linux/drivers/net/ethernet/sfc/nic.c but has names and bitfield + * definitions added. + * + * The definitions of efx_nic_regs and efx_nic_reg_tables should be + * textually identical to those in the driver, though the structure + * definitions and the macros REGISTER and REGISTER_TABLE_DIMENSIONS + * are defined differently. + */ + +#define REGISTER_REVISION_FA 1 +#define REGISTER_REVISION_FB 2 +#define REGISTER_REVISION_FC 3 +#define REGISTER_REVISION_FZ 3 /* last Falcon arch revision */ +#define REGISTER_REVISION_ED 4 +#define REGISTER_REVISION_EZ 4 /* latest EF10 arch revision */ + +struct efx_nic_reg_field { + const char *name; + u8 lbn, width; + u8 min_revision, max_revision; +}; + +#define REGISTER_FIELD_RENAME(name, display_name, arch, min_rev, max_rev) { \ + display_name, \ + arch ## RF_ ## min_rev ## max_rev ## _ ## name ## _LBN, \ + arch ## RF_ ## min_rev ## max_rev ## _ ## name ## _WIDTH, \ + REGISTER_REVISION_ ## arch ## min_rev, \ + REGISTER_REVISION_ ## arch ## max_rev \ +} +#define REGISTER_FIELD(name, arch, min_rev, max_rev) \ + REGISTER_FIELD_RENAME(name, #name, arch, min_rev, max_rev) +#define REGISTER_FIELD_AA(name) REGISTER_FIELD(name, F, A, A) +#define REGISTER_FIELD_AB(name) REGISTER_FIELD(name, F, A, B) +#define REGISTER_FIELD_AZ(name) REGISTER_FIELD(name, F, A, Z) +#define REGISTER_FIELD_BB(name) REGISTER_FIELD(name, F, B, B) +#define REGISTER_FIELD_BZ(name) REGISTER_FIELD(name, F, B, Z) +#define REGISTER_FIELD_CZ(name) REGISTER_FIELD(name, F, C, Z) +#define REGISTER_FIELD_DZ(name) REGISTER_FIELD(name, E, D, Z) +#define REGISTER_FIELD_AZ_RENAME(name, display_name) \ + REGISTER_FIELD_RENAME(name, display_name, F, A, Z) +#define REGISTER_FIELD_BZ_RENAME(name, display_name) \ + REGISTER_FIELD_RENAME(name, display_name, F, B, Z) +#define REGISTER_FIELD_CZ_RENAME(name, display_name) \ + REGISTER_FIELD_RENAME(name, display_name, F, C, Z) + +static const struct efx_nic_reg_field efx_nic_reg_fields_ADR_REGION[] = { + REGISTER_FIELD_AZ(ADR_REGION0), + REGISTER_FIELD_AZ(ADR_REGION1), + REGISTER_FIELD_AZ(ADR_REGION2), + REGISTER_FIELD_AZ(ADR_REGION3), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_INT_EN_KER[] = { + REGISTER_FIELD_AZ(DRV_INT_EN_KER), + REGISTER_FIELD_AZ(KER_INT_KER), + REGISTER_FIELD_AZ(KER_INT_CHAR), + REGISTER_FIELD_AZ(KER_INT_LEVE_SEL), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_INT_EN_CHAR[] = { + REGISTER_FIELD_BZ(DRV_INT_EN_CHAR), + REGISTER_FIELD_BZ(CHAR_INT_KER), + REGISTER_FIELD_BZ(CHAR_INT_CHAR), + REGISTER_FIELD_BZ(CHAR_INT_LEVE_SEL), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_INT_ADR_KER[] = { + REGISTER_FIELD_AZ(INT_ADR_KER), + REGISTER_FIELD_AZ(NORM_INT_VEC_DIS_KER), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_INT_ADR_CHAR[] = { + REGISTER_FIELD_BZ(INT_ADR_CHAR), + REGISTER_FIELD_BZ(NORM_INT_VEC_DIS_CHAR), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_HW_INIT[] = { + REGISTER_FIELD_AZ(TLP_TD), + REGISTER_FIELD_AZ(TD_SEL), + REGISTER_FIELD_AZ(ATTR_SEL), + REGISTER_FIELD_AZ(TLP_EP), + REGISTER_FIELD_AZ(US_DISABLE), + REGISTER_FIELD_AZ(WD_TIMER), + REGISTER_FIELD_AB(INTA_VEC), + REGISTER_FIELD_AB(INTB_VEC), + REGISTER_FIELD_AZ(TLP_ATTR), + REGISTER_FIELD_AZ(TLP_TC), + REGISTER_FIELD_AZ(POST_WR_MASK), + REGISTER_FIELD_BB(FC_BLOCKING_EN), + REGISTER_FIELD_AA(B2B_REQ_EN), + REGISTER_FIELD_BZ(B2B_REQ_EN), + REGISTER_FIELD_AA(FC_BLOCKING_EN), + REGISTER_FIELD_AB(PE_EIDLE_DIS), + REGISTER_FIELD_AB(TX_RREQ_MASK_EN), + REGISTER_FIELD_AZ(DOORBELL_DROP), + REGISTER_FIELD_AB(TRGT_MASK_ALL), + REGISTER_FIELD_CZ(TX_MRG_TAGS), + REGISTER_FIELD_BB(PCIE_CPL_TIMEOUT_CTRL), + REGISTER_FIELD_BB(BDMRD_CPLF_FULL), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_USR_EV_CFG[] = { + REGISTER_FIELD_CZ(DFLT_EVQ), + REGISTER_FIELD_CZ(USREV_DIS), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_EE_SPI_HCMD[] = { + REGISTER_FIELD_AB(EE_SPI_HCMD_ENC), + REGISTER_FIELD_AB(EE_SPI_HCMD_ADBCNT), + REGISTER_FIELD_AB(EE_SPI_HCMD_DUBCNT), + REGISTER_FIELD_AB(EE_SPI_HCMD_READ), + REGISTER_FIELD_AB(EE_SPI_HCMD_DABCNT), + REGISTER_FIELD_AB(EE_SPI_HCMD_SF_SEL), + REGISTER_FIELD_AB(EE_WR_TIMER_ACTIVE), + REGISTER_FIELD_AB(EE_SPI_HCMD_CMD_EN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_EE_SPI_HADR[] = { + REGISTER_FIELD_AB(EE_SPI_HADR_ADR), + REGISTER_FIELD_AB(EE_SPI_HADR_DUBYTE), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_EE_SPI_HDATA[] = { + REGISTER_FIELD_AB(EE_SPI_HDATA0), + REGISTER_FIELD_AB(EE_SPI_HDATA1), + REGISTER_FIELD_AB(EE_SPI_HDATA2), + REGISTER_FIELD_AB(EE_SPI_HDATA3), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_EE_BASE_PAGE[] = { + REGISTER_FIELD_AB(EE_EXP_ROM_WINDOW_BASE), + REGISTER_FIELD_AB(EE_EXPROM_MASK), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_EE_VPD_CFG0[] = { + REGISTER_FIELD_AB(EE_VPD_EN), + REGISTER_FIELD_AB(EE_VPD_EN_AD9_MODE), + REGISTER_FIELD_AB(EE_VPD_DEV_SF_SEL), + REGISTER_FIELD_AB(EE_VPD_ACCESS_BLOCK), + REGISTER_FIELD_AB(EE_VPD_ACCESS_ON), + REGISTER_FIELD_AB(EE_VPD_AD_SIZE), + REGISTER_FIELD_AB(EE_VPD_LENGTH), + REGISTER_FIELD_AB(EE_VPD_BASE), + REGISTER_FIELD_AB(EE_VPD_WR_CMD_EN), + REGISTER_FIELD_AB(EE_VPDW_BASE), + REGISTER_FIELD_AB(EE_VPDW_LENGTH), + REGISTER_FIELD_AB(EE_EE_WR_TMR_VALUE), + REGISTER_FIELD_AB(EE_EE_CLOCK_DIV), + REGISTER_FIELD_AB(EE_VPD_WIP_POLL), + REGISTER_FIELD_AB(EE_SF_CLOCK_DIV), + REGISTER_FIELD_AB(EE_SF_FASTRD_EN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_NIC_STAT[] = { + REGISTER_FIELD_AB(STRAP_PINS), + REGISTER_FIELD_AB(ATE_MODE), + REGISTER_FIELD_AB(EE_PRST), + REGISTER_FIELD_AB(SF_PRST), + REGISTER_FIELD_AB(ONCHIP_SRAM), + REGISTER_FIELD_BB(REVISION_ID), + REGISTER_FIELD_BB(EE_STRAP), + REGISTER_FIELD_BB(EE_STRAP_EN), + REGISTER_FIELD_BB(AER_DIS), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GPIO_CTL[] = { + REGISTER_FIELD_AB(GPIO0_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO1_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO2_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO3_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO4_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO5_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO6_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO7_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO0_IN), + REGISTER_FIELD_AB(GPIO1_IN), + REGISTER_FIELD_AB(GPIO2_IN), + REGISTER_FIELD_AB(GPIO3_IN), + REGISTER_FIELD_AB(GPIO4_IN), + REGISTER_FIELD_AB(GPIO5_IN), + REGISTER_FIELD_AB(GPIO6_IN), + REGISTER_FIELD_AB(GPIO7_IN), + REGISTER_FIELD_AB(GPIO0_OUT), + REGISTER_FIELD_AB(GPIO1_OUT), + REGISTER_FIELD_AB(GPIO2_OUT), + REGISTER_FIELD_AB(GPIO3_OUT), + REGISTER_FIELD_AB(GPIO4_OUT), + REGISTER_FIELD_AB(GPIO5_OUT), + REGISTER_FIELD_AB(GPIO6_OUT), + REGISTER_FIELD_AB(GPIO7_OUT), + REGISTER_FIELD_AB(GPIO0_OEN), + REGISTER_FIELD_AB(GPIO1_OEN), + REGISTER_FIELD_AB(GPIO2_OEN), + REGISTER_FIELD_AB(GPIO3_OEN), + REGISTER_FIELD_AB(GPIO4_OEN), + REGISTER_FIELD_AB(GPIO5_OEN), + REGISTER_FIELD_AB(USE_NIC_CLK), + REGISTER_FIELD_AB(CLK156_OUT_EN), + REGISTER_FIELD_AB(GPIO8_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO9_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO10_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO11_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO12_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO13_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO14_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO15_PWRUP_VALUE), + REGISTER_FIELD_AB(GPIO8_IN), + REGISTER_FIELD_AB(GPIO9_IN), + REGISTER_FIELD_AB(GPIO10_IN), + REGISTER_FIELD_AB(GPIO11_IN), + REGISTER_FIELD_AB(GPIO12_IN), + REGISTER_FIELD_AB(GPIO13_IN), + REGISTER_FIELD_AB(GPIO14_IN), + REGISTER_FIELD_AB(GPIO15_IN), + REGISTER_FIELD_AB(GPIO8_OUT), + REGISTER_FIELD_AB(GPIO9_OUT), + REGISTER_FIELD_AB(GPIO10_OUT), + REGISTER_FIELD_AB(GPIO11_OUT), + REGISTER_FIELD_AB(GPIO12_OUT), + REGISTER_FIELD_AB(GPIO13_OUT), + REGISTER_FIELD_AB(GPIO14_OUT), + REGISTER_FIELD_AB(GPIO15_OUT), + REGISTER_FIELD_AB(GPIO8_OEN), + REGISTER_FIELD_AB(GPIO9_OEN), + REGISTER_FIELD_AB(GPIO10_OEN), + REGISTER_FIELD_AB(GPIO11_OEN), + REGISTER_FIELD_AB(GPIO12_OEN), + REGISTER_FIELD_AB(GPIO13_OEN), + REGISTER_FIELD_AB(GPIO14_OEN), + REGISTER_FIELD_AB(GPIO15_OEN), + REGISTER_FIELD_AB(GPIO_PWRUP_VALUE2), + REGISTER_FIELD_AB(GPIO_IN2), + REGISTER_FIELD_AB(GPIO_OUT2), + REGISTER_FIELD_AB(GPIO_PWRUP_VALUE3), + REGISTER_FIELD_AB(GPIO_IN3), + REGISTER_FIELD_AB(GPIO_OUT3), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GLB_CTL[] = { + REGISTER_FIELD_AB(SWRST), + REGISTER_FIELD_AB(EXT_PHY_RST_DUR), + REGISTER_FIELD_AB(INT_RST_DUR), + REGISTER_FIELD_AB(RST_CS), + REGISTER_FIELD_AB(RST_SF), + REGISTER_FIELD_AB(RST_TX), + REGISTER_FIELD_AB(RST_RX), + REGISTER_FIELD_AB(RST_SR), + REGISTER_FIELD_AB(RST_EV), + REGISTER_FIELD_AB(RST_EM), + REGISTER_FIELD_AB(RST_XGTX), + REGISTER_FIELD_AB(RST_XGRX), + REGISTER_FIELD_AB(RST_PCIE_CORE), + REGISTER_FIELD_AB(RST_PCIE_NSTKY), + REGISTER_FIELD_AB(RST_PCIE_STKY), + REGISTER_FIELD_BB(RST_BIU), + REGISTER_FIELD_AA(RST_PCIX), + REGISTER_FIELD_AB(RST_PCIE_SD), + REGISTER_FIELD_AB(RST_XAUI_SD), + REGISTER_FIELD_AB(RST_EXT_PHY), + REGISTER_FIELD_AB(HOT_RST_CTL), + REGISTER_FIELD_AB(CS_RST_CTL), + REGISTER_FIELD_AB(EE_RST_CTL), + REGISTER_FIELD_AB(TX_RST_CTL), + REGISTER_FIELD_AB(RX_RST_CTL), + REGISTER_FIELD_AB(SR_RST_CTL), + REGISTER_FIELD_AB(EV_RST_CTL), + REGISTER_FIELD_AB(EM_RST_CTL), + REGISTER_FIELD_AB(XGTX_RST_CTL), + REGISTER_FIELD_AB(XGRX_RST_CTL), + REGISTER_FIELD_AB(PCIE_CORE_RST_CTL), + REGISTER_FIELD_AB(PCIE_NSTKY_RST_CTL), + REGISTER_FIELD_AB(PCIE_STKY_RST_CTL), + REGISTER_FIELD_BB(BIU_RST_CTL), + REGISTER_FIELD_AA(PCIX_RST_CTL), + REGISTER_FIELD_AB(PCIE_SD_RST_CTL), + REGISTER_FIELD_AB(XAUI_SD_RST_CTL), + REGISTER_FIELD_AB(EXT_PHY_RST_CTL), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_DP_CTRL[] = { + REGISTER_FIELD_BZ(FLS_EVQ_ID), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MEM_STAT[] = { + REGISTER_FIELD_CZ(MEM_PERR_VEC), + REGISTER_FIELD_AB(MBIST_ERR), + REGISTER_FIELD_AB(MBIST_CORR), + REGISTER_FIELD_AB(MEM_PERR_VEC), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_CS_DEBUG[] = { + /* This is not a complete list of fields */ + REGISTER_FIELD_AZ(CS_DEBUG_EN), + REGISTER_FIELD_CZ(CS_PORT_NUM), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_ALTERA_BUILD[] = { + REGISTER_FIELD_AZ(ALTERA_BUILD_VER), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_CSR_SPARE[] = { + REGISTER_FIELD_AZ(CSR_SPARE_BITS), + REGISTER_FIELD_AB(MEM_PERR_EN_TX_DATA), + REGISTER_FIELD_CZ(MEM_PERR_EN), + REGISTER_FIELD_AB(MEM_PERR_EN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_PCIE_SD_CTL0123[] = { + REGISTER_FIELD_AB(PCIE_LODRV), + REGISTER_FIELD_AB(PCIE_HIDRV), + REGISTER_FIELD_AB(PCIE_RXEQCTL_L), + REGISTER_FIELD_AB(PCIE_RXEQCTL_H), + REGISTER_FIELD_AB(PCIE_TXTERMADJ_L), + REGISTER_FIELD_AB(PCIE_TXTERMADJ_H), + REGISTER_FIELD_AB(PCIE_RXTERMADJ_L), + REGISTER_FIELD_AB(PCIE_RXTERMADJ_H), + REGISTER_FIELD_AB(PCIE_PARLPBK), + REGISTER_FIELD_AB(PCIE_LPBK), + REGISTER_FIELD_AB(PCIE_LPBKWDRV_L), + REGISTER_FIELD_AB(PCIE_LPBKWDRV_H), + REGISTER_FIELD_AB(PCIE_PARRESET_L), + REGISTER_FIELD_AB(PCIE_PARRESET_H), + REGISTER_FIELD_AB(PCIE_HIVMODE_L), + REGISTER_FIELD_AB(PCIE_HIVMODE_H), + REGISTER_FIELD_AB(PCIE_OFFSETEN_L), + REGISTER_FIELD_AB(PCIE_OFFSETEN_H), + REGISTER_FIELD_AB(PCIE_OFFSET), + REGISTER_FIELD_AB(PCIE_TESTSIG_L), + REGISTER_FIELD_AB(PCIE_TESTSIG_H), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_PCIE_SD_CTL45[] = { + REGISTER_FIELD_AB(PCIE_DEQ0), + REGISTER_FIELD_AB(PCIE_DEQ1), + REGISTER_FIELD_AB(PCIE_DEQ2), + REGISTER_FIELD_AB(PCIE_DEQ3), + REGISTER_FIELD_AB(PCIE_DEQ4), + REGISTER_FIELD_AB(PCIE_DEQ5), + REGISTER_FIELD_AB(PCIE_DEQ6), + REGISTER_FIELD_AB(PCIE_DEQ7), + REGISTER_FIELD_AB(PCIE_DTX0), + REGISTER_FIELD_AB(PCIE_DTX1), + REGISTER_FIELD_AB(PCIE_DTX2), + REGISTER_FIELD_AB(PCIE_DTX3), + REGISTER_FIELD_AB(PCIE_DTX4), + REGISTER_FIELD_AB(PCIE_DTX5), + REGISTER_FIELD_AB(PCIE_DTX6), + REGISTER_FIELD_AB(PCIE_DTX7), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_PCIE_PCS_CTL_STAT[] = { + REGISTER_FIELD_AB(PCIE_PRBSSEL), + REGISTER_FIELD_AB(PCIE_PRBSERRACK_L), + REGISTER_FIELD_AB(PCIE_PRBSERRACK_H), + REGISTER_FIELD_AB(PCIE_PRBSSYNC_L), + REGISTER_FIELD_AB(PCIE_PRBSSYNC_H), + REGISTER_FIELD_AB(PCIE_CTCDISABLE_L), + REGISTER_FIELD_AB(PCIE_CTCDISABLE_H), + REGISTER_FIELD_AB(PCIE_FASTINIT_L), + REGISTER_FIELD_AB(PCIE_FASTINIT_H), + REGISTER_FIELD_AB(PCIE_PRBSERRH0), + REGISTER_FIELD_AB(PCIE_PRBSERR), + REGISTER_FIELD_AB(PCIE_PRBSERRCOUNT0_L), + REGISTER_FIELD_AB(PCIE_PRBSERRCOUNT0_H), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_EVQ_CTL[] = { + REGISTER_FIELD_AZ(EVQ_FIFO_NOTAF_TH), + REGISTER_FIELD_AZ(EVQ_FIFO_AF_TH), + REGISTER_FIELD_AZ(EVQ_OWNERR_CTL), + REGISTER_FIELD_BB(RX_EVQ_WAKEUP_MASK), + REGISTER_FIELD_CZ(RX_EVQ_WAKEUP_MASK), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_EVQ_CNT1[] = { + REGISTER_FIELD_AZ(EVQ_ERR_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_CSR_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_EM_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_RX_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_TX_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_CNT_TOBIU), + REGISTER_FIELD_AZ(EVQ_CNT_PRE_FIFO), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_EVQ_CNT2[] = { + REGISTER_FIELD_AZ(EVQ_TM_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_INIT_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_WET_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_WU_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_RDY_CNT), + REGISTER_FIELD_AZ(EVQ_CLR_REQ_CNT), + REGISTER_FIELD_AZ(EVQ_UPD_REQ_CNT), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_BUF_TBL_CFG[] = { + REGISTER_FIELD_AZ(BUF_TBL_MODE), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_SRM_RX_DC_CFG[] = { + REGISTER_FIELD_AZ(SRM_RX_DC_BASE_ADR), + REGISTER_FIELD_AZ(SRM_CLK_TMP_EN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_SRM_TX_DC_CFG[] = { + REGISTER_FIELD_AZ(SRM_TX_DC_BASE_ADR), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_SRM_CFG[] = { + REGISTER_FIELD_AZ(SRM_BANK_SIZE), + REGISTER_FIELD_AZ(SRM_NUM_BANK), + REGISTER_FIELD_AZ(SRM_INIT_EN), + REGISTER_FIELD_AZ(SRM_OOB_BUF_INTEN), + REGISTER_FIELD_AZ(SRM_OOB_ADR_INTEN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_SRM_UPD_EVQ[] = { + REGISTER_FIELD_AZ(SRM_UPD_EVQ_ID), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_SRAM_PARITY[] = { + REGISTER_FIELD_CZ(FORCE_SRAM_SINGLE_ERR), + REGISTER_FIELD_AB(FORCE_SRAM_PERR), + REGISTER_FIELD_CZ(FORCE_SRAM_DOUBLE_ERR), + REGISTER_FIELD_CZ(SEC_INT), + REGISTER_FIELD_CZ(BYPASS_ECC), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_CFG[] = { + REGISTER_FIELD_AZ(RX_XOFF_MAC_EN), + REGISTER_FIELD_AA(RX_XOFF_MAC_TH), + REGISTER_FIELD_BZ(RX_XOFF_MAC_TH), + REGISTER_FIELD_AA(RX_XON_MAC_TH), + REGISTER_FIELD_BZ(RX_XON_MAC_TH), + REGISTER_FIELD_AA(RX_USR_BUF_SIZE), + REGISTER_FIELD_AA(RX_XOFF_TX_TH), + REGISTER_FIELD_BZ(RX_USR_BUF_SIZE), + REGISTER_FIELD_AA(RX_XON_TX_TH), + REGISTER_FIELD_AA(RX_OWNERR_CTL), + REGISTER_FIELD_BZ(RX_XOFF_TX_TH), + REGISTER_FIELD_AA(RX_PCI_BURST_SIZE), + REGISTER_FIELD_AA(RX_RDW_PATCH_EN), + REGISTER_FIELD_AA(RX_DESC_PUSH_EN), + REGISTER_FIELD_BZ(RX_XON_TX_TH), + REGISTER_FIELD_BZ(RX_OWNERR_CTL), + REGISTER_FIELD_BB(RX_PCI_BURST_SIZE), + REGISTER_FIELD_BZ(RX_RDW_PATCH_EN), + REGISTER_FIELD_BZ(RX_DESC_PUSH_EN), + REGISTER_FIELD_BZ(RX_HASH_INSRT_HDR), + REGISTER_FIELD_BZ(RX_HASH_ALG), + REGISTER_FIELD_BZ(RX_IP_HASH), + REGISTER_FIELD_BZ(RX_INGR_EN), + REGISTER_FIELD_BZ(RX_TCP_SUP), + REGISTER_FIELD_CZ(RX_PRE_RFF_IPG), + REGISTER_FIELD_CZ(RX_HDR_SPLIT_HDR_BUF_SIZE), + REGISTER_FIELD_CZ(RX_HDR_SPLIT_PLD_BUF_SIZE), + REGISTER_FIELD_CZ(RX_HDR_SPLIT_EN), + REGISTER_FIELD_CZ(RX_MIN_KBUF_SIZE), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_FILTER_CTL[] = { + REGISTER_FIELD_BZ(TCP_FULL_SRCH_LIMIT), + REGISTER_FIELD_BZ(TCP_WILD_SRCH_LIMIT), + REGISTER_FIELD_BZ(UDP_WILD_SRCH_LIMIT), + REGISTER_FIELD_BZ(NUM_KER), + REGISTER_FIELD_BZ(UDP_FULL_SRCH_LIMIT), + REGISTER_FIELD_BZ(SCATTER_ENBL_NO_MATCH_Q), + REGISTER_FIELD_CZ(UNICAST_NOMATCH_IP_OVERRIDE), + REGISTER_FIELD_CZ(UNICAST_NOMATCH_RSS_ENABLED), + REGISTER_FIELD_CZ(UNICAST_NOMATCH_Q_ID), + REGISTER_FIELD_CZ(MULTICAST_NOMATCH_IP_OVERRIDE), + REGISTER_FIELD_CZ(MULTICAST_NOMATCH_RSS_ENABLED), + REGISTER_FIELD_CZ(MULTICAST_NOMATCH_Q_ID), + REGISTER_FIELD_CZ(RX_VLAN_MATCH_ETHERTYPE), + REGISTER_FIELD_CZ(RX_FILTER_ALL_VLAN_ETHERTYPES), + REGISTER_FIELD_CZ(ETHERNET_FULL_SEARCH_LIMIT), + REGISTER_FIELD_CZ(ETHERNET_WILDCARD_SEARCH_LIMIT), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_DC_CFG[] = { + REGISTER_FIELD_AZ(RX_DC_SIZE), + REGISTER_FIELD_AB(RX_MAX_PF), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_DC_PF_WM[] = { + REGISTER_FIELD_AZ(RX_DC_PF_LWM), + REGISTER_FIELD_AZ(RX_DC_PF_HWM), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_RSS_TKEY[] = { + REGISTER_FIELD_BZ(RX_RSS_TKEY_LO), + REGISTER_FIELD_BZ(RX_RSS_TKEY_HI), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_SELF_RST[] = { + REGISTER_FIELD_AA(RX_MAX_LU_LAT), + REGISTER_FIELD_AA(RX_MAX_PF_LAT), + REGISTER_FIELD_AA(RX_SELF_RST_EN), + REGISTER_FIELD_AA(RX_NODESC_WAIT_DIS), + REGISTER_FIELD_AA(RX_SW_RST_REG), + REGISTER_FIELD_AA(RX_ISCSI_DIS), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_RSS_IPV6_REG1[] = { + REGISTER_FIELD_CZ(RX_RSS_IPV6_TKEY_LO), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_RSS_IPV6_REG2[] = { + REGISTER_FIELD_CZ(RX_RSS_IPV6_TKEY_MID), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_RSS_IPV6_REG3[] = { + REGISTER_FIELD_CZ(RX_RSS_IPV6_TKEY_HI), + REGISTER_FIELD_CZ(RX_RSS_IPV6_TCP_SUPPRESS), + REGISTER_FIELD_CZ(RX_RSS_IPV6_IP_THASH_ENABLE), + REGISTER_FIELD_CZ(RX_RSS_IPV6_THASH_ENABLE), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_DC_CFG[] = { + REGISTER_FIELD_AZ(TX_DC_SIZE), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_CHKSM_CFG[] = { + REGISTER_FIELD_AA(TX_Q_CHKSM_DIS_0_31), + REGISTER_FIELD_AA(TX_Q_CHKSM_DIS_32_63), + REGISTER_FIELD_AA(TX_Q_CHKSM_DIS_64_95), + REGISTER_FIELD_AA(TX_Q_CHKSM_DIS_96_127), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_CFG[] = { + REGISTER_FIELD_AZ(TX_IP_ID_REP_EN), + REGISTER_FIELD_AA(TX_NON_IP_DROP_DIS), + REGISTER_FIELD_AZ(TX_OWNERR_CTL), + REGISTER_FIELD_AZ(TX_P1_PRI_EN), + REGISTER_FIELD_AZ(TX_NO_EOP_DISC_EN), + REGISTER_FIELD_AZ(TX_IP_ID_P0_OFS), + REGISTER_FIELD_CZ(TX_FILTER_EN_BIT), + REGISTER_FIELD_CZ(TX_VLAN_MATCH_ETHERTYPE_RANGE), + REGISTER_FIELD_CZ(TX_FILTER_ALL_VLAN_ETHERTYPES_BIT), + REGISTER_FIELD_CZ(TX_TCPIP_FILTER_FULL_SEARCH_RANGE), + REGISTER_FIELD_CZ(TX_TCPIP_FILTER_WILD_SEARCH_RANGE), + REGISTER_FIELD_CZ(TX_UDPIP_FILTER_FULL_SEARCH_RANGE), + REGISTER_FIELD_CZ(TX_UDPIP_FILTER_WILD_SEARCH_RANGE), + REGISTER_FIELD_CZ(TX_ETH_FILTER_FULL_SEARCH_RANGE), + REGISTER_FIELD_CZ(TX_ETH_FILTER_WILD_SEARCH_RANGE), + REGISTER_FIELD_CZ(TX_FILTER_TEST_MODE_BIT), + REGISTER_FIELD_CZ(TX_CONT_LOOKUP_THRESH_RANGE), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_RESERVED[] = { + REGISTER_FIELD_AZ(TX_MAX_PREF), + REGISTER_FIELD_AZ(TX_MAX_CPL), + REGISTER_FIELD_AA(TX_IP_DIS), + REGISTER_FIELD_BZ(TX_FLUSH_MIN_LEN_EN), + REGISTER_FIELD_AA(TX_TCP_DIS), + REGISTER_FIELD_AZ(TX_DMA_SPACER), + REGISTER_FIELD_AA(TX_DMA_FF_THR), + REGISTER_FIELD_AZ(TX_DIS_NON_IP_EV), + REGISTER_FIELD_AZ(TX_ONE_PKT_PER_Q), + REGISTER_FIELD_AZ(TX_PREF_THRESHOLD), + REGISTER_FIELD_AZ(TX_ONLY1TAG), + REGISTER_FIELD_AZ(TX_PREF_WD_TMR), + REGISTER_FIELD_AZ(TX_PREF_SPACER), + REGISTER_FIELD_AZ(TX_XP_TIMER), + REGISTER_FIELD_AZ(TX_RX_SPACER_EN), + REGISTER_FIELD_AZ(TX_PS_EVT_DIS), + REGISTER_FIELD_AZ(TX_SOFT_EVT_EN), + REGISTER_FIELD_AZ(TX_DROP_ABORT_EN), + REGISTER_FIELD_AZ(TX_RX_SPACER), + REGISTER_FIELD_AZ(TX_DMAQ_ST), + REGISTER_FIELD_AZ(TX_DMAR_ST_P0), + REGISTER_FIELD_AZ(TX_D_FF_FULL_P0), + REGISTER_FIELD_AZ(TX_PUSH_CHK_DIS), + REGISTER_FIELD_AZ(TX_PUSH_EN), + REGISTER_FIELD_AZ(TX_RD_COMP_TMR), + REGISTER_FIELD_AZ(TX_PREF_AGE_CNT), + REGISTER_FIELD_AZ(TX_EVT_CNT), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_PACE[] = { + REGISTER_FIELD_BZ(TX_PACE_BIN_TH), + REGISTER_FIELD_BZ(TX_PACE_FB_BASE), + REGISTER_FIELD_BZ(TX_PACE_SB_AF), + REGISTER_FIELD_BZ(TX_PACE_SB_NOT_AF), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_VLAN[] = { + REGISTER_FIELD_BB(TX_VLAN0), + REGISTER_FIELD_BB(TX_VLAN0_PORT0_EN), + REGISTER_FIELD_BB(TX_VLAN0_PORT1_EN), + REGISTER_FIELD_BB(TX_VLAN1), + REGISTER_FIELD_BB(TX_VLAN1_PORT0_EN), + REGISTER_FIELD_BB(TX_VLAN1_PORT1_EN), + REGISTER_FIELD_BB(TX_VLAN2), + REGISTER_FIELD_BB(TX_VLAN2_PORT0_EN), + REGISTER_FIELD_BB(TX_VLAN2_PORT1_EN), + REGISTER_FIELD_BB(TX_VLAN3), + REGISTER_FIELD_BB(TX_VLAN3_PORT0_EN), + REGISTER_FIELD_BB(TX_VLAN3_PORT1_EN), + REGISTER_FIELD_BB(TX_VLAN4), + REGISTER_FIELD_BB(TX_VLAN4_PORT0_EN), + REGISTER_FIELD_BB(TX_VLAN4_PORT1_EN), + REGISTER_FIELD_BB(TX_VLAN5), + REGISTER_FIELD_BB(TX_VLAN5_PORT0_EN), + REGISTER_FIELD_BB(TX_VLAN5_PORT1_EN), + REGISTER_FIELD_BB(TX_VLAN6), + REGISTER_FIELD_BB(TX_VLAN6_PORT0_EN), + REGISTER_FIELD_BB(TX_VLAN6_PORT1_EN), + REGISTER_FIELD_BB(TX_VLAN7), + REGISTER_FIELD_BB(TX_VLAN7_PORT0_EN), + REGISTER_FIELD_BB(TX_VLAN7_PORT1_EN), + REGISTER_FIELD_BB(TX_VLAN_EN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_IPFIL_PORTEN[] = { + REGISTER_FIELD_BB(TX_IPFIL0_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL1_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL2_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL3_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL4_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL5_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL6_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL7_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL8_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL9_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL10_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL11_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL12_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL13_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL14_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL15_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL16_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL17_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL18_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL19_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL20_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL21_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL22_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL23_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL24_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL25_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL26_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL27_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL28_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL29_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL30_PORT_EN), + REGISTER_FIELD_BB(TX_IPFIL31_PORT_EN), + REGISTER_FIELD_BZ(TX_MADR0_FIL_EN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_IPFIL_TBL[] = { + REGISTER_FIELD_BB(TX_IP_SRC_ADR_0), + REGISTER_FIELD_BB(TX_IPFIL_MASK_0), + REGISTER_FIELD_BB(TX_IP_SRC_ADR_1), + REGISTER_FIELD_BB(TX_IPFIL_MASK_1), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MD_TXD[] = { + REGISTER_FIELD_AB(MD_TXD), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MD_RXD[] = { + REGISTER_FIELD_AB(MD_RXD), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MD_CS[] = { + REGISTER_FIELD_AB(MD_WRC), + REGISTER_FIELD_AB(MD_RDC), + REGISTER_FIELD_AB(MD_RIC), + REGISTER_FIELD_AB(MD_PRSP), + REGISTER_FIELD_AB(MD_GC), + REGISTER_FIELD_AB(MD_INT_CLR), + REGISTER_FIELD_AB(MD_PL), + REGISTER_FIELD_AB(MD_PT), + REGISTER_FIELD_AB(MD_ADDR_CMD), + REGISTER_FIELD_AB(MD_WR_EN_CMD), + REGISTER_FIELD_AB(MD_RD_EN_CMD), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MD_PHY_ADR[] = { + REGISTER_FIELD_AB(MD_PHY_ADR), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MD_ID[] = { + REGISTER_FIELD_AB(MD_DEV_ADR), + REGISTER_FIELD_AB(MD_PRT_ADR), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MAC_STAT_DMA[] = { + REGISTER_FIELD_AB(MAC_STAT_DMA_ADR), + REGISTER_FIELD_AB(MAC_STAT_DMA_CMD), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MAC_CTRL[] = { + REGISTER_FIELD_AB(MAC_SPEED), + REGISTER_FIELD_AB(MAC_LINK_STATUS), + REGISTER_FIELD_AB(MAC_UC_PROM), + REGISTER_FIELD_AB(MAC_BCAD_ACPT), + REGISTER_FIELD_AB(MAC_XG_DISTXCRC), + REGISTER_FIELD_BB(TXFIFO_DRAIN_EN), + REGISTER_FIELD_AB(MAC_XOFF_VAL), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GEN_MODE[] = { + REGISTER_FIELD_BB(XG_PHY_INT_MASK), + REGISTER_FIELD_BB(XFP_PHY_INT_MASK), + REGISTER_FIELD_BB(XG_PHY_INT_POL_SEL), + REGISTER_FIELD_BB(XFP_PHY_INT_POL_SEL), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MAC_MC_HASH_REG0[] = { + REGISTER_FIELD_AB(MAC_MCAST_HASH0), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MAC_MC_HASH_REG1[] = { + REGISTER_FIELD_AB(MAC_MCAST_HASH1), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GM_CFG1[] = { + REGISTER_FIELD_AB(GM_TX_EN), + REGISTER_FIELD_AB(GM_SYNC_TXEN), + REGISTER_FIELD_AB(GM_RX_EN), + REGISTER_FIELD_AB(GM_SYNC_RXEN), + REGISTER_FIELD_AB(GM_TX_FC_EN), + REGISTER_FIELD_AB(GM_RX_FC_EN), + REGISTER_FIELD_AB(GM_LOOP), + REGISTER_FIELD_AB(GM_RST_TX_FUNC), + REGISTER_FIELD_AB(GM_RST_RX_FUNC), + REGISTER_FIELD_AB(GM_RST_TX_MAC_CTL), + REGISTER_FIELD_AB(GM_RST_RX_MAC_CTL), + REGISTER_FIELD_AB(GM_SIM_RST), + REGISTER_FIELD_AB(GM_SW_RST), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GM_CFG2[] = { + REGISTER_FIELD_AB(GM_FD), + REGISTER_FIELD_AB(GM_CRC_EN), + REGISTER_FIELD_AB(GM_PAD_CRC_EN), + REGISTER_FIELD_AB(GM_LEN_CHK), + REGISTER_FIELD_AB(GM_HUGE_FRM_EN), + REGISTER_FIELD_AB(GM_IF_MODE), + REGISTER_FIELD_AB(GM_PAMBL_LEN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GM_MAX_FLEN[] = { + REGISTER_FIELD_AB(GM_MAX_FLEN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GM_ADR1[] = { + REGISTER_FIELD_AB(GM_ADR_B3), + REGISTER_FIELD_AB(GM_ADR_B2), + REGISTER_FIELD_AB(GM_ADR_B1), + REGISTER_FIELD_AB(GM_ADR_B0), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GM_ADR2[] = { + REGISTER_FIELD_AB(GM_ADR_B5), + REGISTER_FIELD_AB(GM_ADR_B4), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GMF_CFG0[] = { + REGISTER_FIELD_AB(GMF_HSTRSTWT), + REGISTER_FIELD_AB(GMF_HSTRSTSR), + REGISTER_FIELD_AB(GMF_HSTRSTFR), + REGISTER_FIELD_AB(GMF_HSTRSTST), + REGISTER_FIELD_AB(GMF_HSTRSTFT), + REGISTER_FIELD_AB(GMF_WTMENREQ), + REGISTER_FIELD_AB(GMF_SRFENREQ), + REGISTER_FIELD_AB(GMF_FRFENREQ), + REGISTER_FIELD_AB(GMF_STFENREQ), + REGISTER_FIELD_AB(GMF_FTFENREQ), + REGISTER_FIELD_AB(GMF_WTMENRPLY), + REGISTER_FIELD_AB(GMF_SRFENRPLY), + REGISTER_FIELD_AB(GMF_FRFENRPLY), + REGISTER_FIELD_AB(GMF_STFENRPLY), + REGISTER_FIELD_AB(GMF_FTFENRPLY), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GMF_CFG1[] = { + REGISTER_FIELD_AB(GMF_CFGXOFFRTX), + REGISTER_FIELD_AB(GMF_CFGFRTH), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GMF_CFG2[] = { + REGISTER_FIELD_AB(GMF_CFGLWM), + REGISTER_FIELD_AB(GMF_CFGHWM), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GMF_CFG3[] = { + REGISTER_FIELD_AB(GMF_CFGFTTH), + REGISTER_FIELD_AB(GMF_CFGHWMFT), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GMF_CFG4[] = { + REGISTER_FIELD_AB(GMF_HSTFLTRFRM), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_GMF_CFG5[] = { + REGISTER_FIELD_AB(GMF_HSTFLTRFRMDC), + REGISTER_FIELD_AB(GMF_HSTDRPLT64), + REGISTER_FIELD_AB(GMF_CFGBYTMODE), + REGISTER_FIELD_AB(GMF_HSTSRFULLCLR), + REGISTER_FIELD_AB(GMF_SRFULL), + REGISTER_FIELD_AB(GMF_CFGHDPLX), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_SRC_MAC_TBL[] = { + REGISTER_FIELD_BB(TX_SRC_MAC_ADR_0), + REGISTER_FIELD_BB(TX_SRC_MAC_ADR_1), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_SRC_MAC_CTL[] = { + REGISTER_FIELD_BB(TX_MAC_QID_SEL), + REGISTER_FIELD_BB(TX_DROP_CTR_CLR), + REGISTER_FIELD_BB(TX_SRC_FLTR_EN), + REGISTER_FIELD_BB(TX_SRC_DROP_CTR), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_ADR_LO[] = { + REGISTER_FIELD_AB(XM_ADR_LO), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_ADR_HI[] = { + REGISTER_FIELD_AB(XM_ADR_HI), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_GLB_CFG[] = { + REGISTER_FIELD_AB(XM_CORE_RST), + REGISTER_FIELD_AB(XM_INTCLR_MODE), + REGISTER_FIELD_AB(XM_WAN_MODE), + REGISTER_FIELD_AB(XM_RX_JUMBO_MODE), + REGISTER_FIELD_AB(XM_TX_STAT_EN), + REGISTER_FIELD_AB(XM_RX_STAT_EN), + REGISTER_FIELD_AB(XM_DEBUG_MODE), + REGISTER_FIELD_AB(XM_RMTFLT_GEN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_TX_CFG[] = { + REGISTER_FIELD_AB(XM_TX_RST), + REGISTER_FIELD_AB(XM_TXEN), + REGISTER_FIELD_AB(XM_TX_PRMBL), + REGISTER_FIELD_AB(XM_AUTO_PAD), + REGISTER_FIELD_AB(XM_EDRC), + REGISTER_FIELD_AB(XM_TXCRC), + REGISTER_FIELD_AB(XM_FCNTL), + REGISTER_FIELD_AB(XM_IPG), + REGISTER_FIELD_AB(XM_TX_PROG), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_RX_CFG[] = { + REGISTER_FIELD_AB(XM_RX_RST), + REGISTER_FIELD_AB(XM_RXEN), + REGISTER_FIELD_AB(XM_RX_PRMBL), + REGISTER_FIELD_AB(XM_RXCRC), + REGISTER_FIELD_AB(XM_AUTO_DEPAD), + REGISTER_FIELD_AB(XM_ACPT_ALL_UCAST), + REGISTER_FIELD_AB(XM_ACPT_ALL_MCAST), + REGISTER_FIELD_AB(XM_REJ_BCAST), + REGISTER_FIELD_AB(XM_PASS_PRMBLE_ERR), + REGISTER_FIELD_AB(XM_PASS_CRC_ERR), + REGISTER_FIELD_AB(XM_PASS_LENERR), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_MGT_INT_MASK[] = { + REGISTER_FIELD_AB(XM_MSK_LCLFLT), + REGISTER_FIELD_AB(XM_MSK_RMTFLT), + REGISTER_FIELD_AB(XM_MSK_PRMBLE_ERR), + REGISTER_FIELD_AB(XM_MSK_STAT_CNTR_OF), + REGISTER_FIELD_AB(XM_MSK_STAT_CNTR_HF), + REGISTER_FIELD_AB(XM_MSK_STA_INTR), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_FC[] = { + REGISTER_FIELD_AB(XM_DIS_FCNTL), + REGISTER_FIELD_AB(XM_XMIT_PAUSE), + REGISTER_FIELD_AB(XM_ZPAUSE), + REGISTER_FIELD_AB(XM_REJ_CNTL_MCAST), + REGISTER_FIELD_AB(XM_REJ_CNTL_UCAST), + REGISTER_FIELD_AB(XM_MCNTL_PASS), + REGISTER_FIELD_AB(XM_TX_MAC_STAT), + REGISTER_FIELD_AB(XM_RX_MAC_STAT), + REGISTER_FIELD_AB(XM_PAUSE_TIME), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_PAUSE_TIME[] = { + REGISTER_FIELD_AB(XM_RX_PAUSE_CNT), + REGISTER_FIELD_AB(XM_TX_PAUSE_CNT), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_TX_PARAM[] = { + REGISTER_FIELD_AB(XM_PAD_CHAR), + REGISTER_FIELD_AB(XM_MAX_TX_FRM_SIZE_LO), + REGISTER_FIELD_AB(XM_MAX_TX_FRM_SIZE_HI), + REGISTER_FIELD_AB(XM_TX_JUMBO_MODE), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XM_RX_PARAM[] = { + REGISTER_FIELD_AB(XM_MAX_RX_FRM_SIZE_LO), + REGISTER_FIELD_AB(XM_MAX_RX_FRM_SIZE_HI), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XX_PWR_RST[] = { + REGISTER_FIELD_AB(XX_RST_XX_EN), + REGISTER_FIELD_AB(XX_RSTXGXSTX_EN), + REGISTER_FIELD_AB(XX_RSTXGXSRX_EN), + REGISTER_FIELD_AB(XX_RESETA_EN), + REGISTER_FIELD_AB(XX_RESETB_EN), + REGISTER_FIELD_AB(XX_RESETC_EN), + REGISTER_FIELD_AB(XX_RESETD_EN), + REGISTER_FIELD_AB(XX_RSTPLLAB_EN), + REGISTER_FIELD_AB(XX_RSTPLLCD_EN), + REGISTER_FIELD_AB(XX_PWRDNA_EN), + REGISTER_FIELD_AB(XX_PWRDNB_EN), + REGISTER_FIELD_AB(XX_PWRDNC_EN), + REGISTER_FIELD_AB(XX_PWRDND_EN), + REGISTER_FIELD_AB(XX_SD_RST_ACT), + REGISTER_FIELD_AB(XX_RSTXGXSTX_SIG), + REGISTER_FIELD_AB(XX_RSTXGXSRX_SIG), + REGISTER_FIELD_AB(XX_RESETA_SIG), + REGISTER_FIELD_AB(XX_RESETB_SIG), + REGISTER_FIELD_AB(XX_RESETC_SIG), + REGISTER_FIELD_AB(XX_RESETD_SIG), + REGISTER_FIELD_AB(XX_RSTPLLAB_SIG), + REGISTER_FIELD_AB(XX_RSTPLLCD_SIG), + REGISTER_FIELD_AB(XX_SIM_MODE), + REGISTER_FIELD_AB(XX_PWRDNA_SIG), + REGISTER_FIELD_AB(XX_PWRDNB_SIG), + REGISTER_FIELD_AB(XX_PWRDNC_SIG), + REGISTER_FIELD_AB(XX_PWRDND_SIG), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XX_SD_CTL[] = { + REGISTER_FIELD_AB(XX_LPBKA), + REGISTER_FIELD_AB(XX_LPBKB), + REGISTER_FIELD_AB(XX_LPBKC), + REGISTER_FIELD_AB(XX_LPBKD), + REGISTER_FIELD_AB(XX_LODRVA), + REGISTER_FIELD_AB(XX_HIDRVA), + REGISTER_FIELD_AB(XX_LODRVB), + REGISTER_FIELD_AB(XX_HIDRVB), + REGISTER_FIELD_AB(XX_LODRVC), + REGISTER_FIELD_AB(XX_HIDRVC), + REGISTER_FIELD_AB(XX_LODRVD), + REGISTER_FIELD_AB(XX_HIDRVD), + REGISTER_FIELD_AB(XX_TERMADJ0), + REGISTER_FIELD_AB(XX_TERMADJ1), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_XX_TXDRV_CTL[] = { + REGISTER_FIELD_AB(XX_DTXA), + REGISTER_FIELD_AB(XX_DTXB), + REGISTER_FIELD_AB(XX_DTXC), + REGISTER_FIELD_AB(XX_DTXD), + REGISTER_FIELD_AB(XX_DEQA), + REGISTER_FIELD_AB(XX_DEQB), + REGISTER_FIELD_AB(XX_DEQC), + REGISTER_FIELD_AB(XX_DEQD), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_BIU_HW_REV_ID[] = { + REGISTER_FIELD_DZ(HW_REV_ID), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MC_DB_LWRD[] = { + REGISTER_FIELD_DZ(MC_DOORBELL_L), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MC_DB_HWRD[] = { + REGISTER_FIELD_DZ(MC_DOORBELL_H), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_DESC_PTR_TBL[] = { + /* Abbreviate field names to reduce the table width */ + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_EN, "EN"), + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_JUMBO, "JUMBO"), + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_TYPE, "TYPE"), + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_SIZE, "SIZE"), + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_LABEL, "LABEL"), + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_OWNER_ID, "OWNER"), + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_EVQ_ID, "EVQ"), + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_BUF_BASE_ID, "BUF_BASE"), + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_SW_WPTR, "SW_WPTR"), + REGISTER_FIELD_AZ_RENAME(RX_DESCQ_HW_RPTR, "HW_RPTR"), + REGISTER_FIELD_AZ_RENAME(RX_DC_HW_RPTR, "DC_HW_RPTR"), + REGISTER_FIELD_AZ_RENAME(RX_DESC_PREF_ACT, "PREF_ACT"), + REGISTER_FIELD_AZ_RENAME(RX_ISCSI_HDIG_EN, "HDIG"), + REGISTER_FIELD_AZ_RENAME(RX_ISCSI_DDIG_EN, "DDIG"), + REGISTER_FIELD_AA(RX_RESET), + REGISTER_FIELD_CZ_RENAME(RX_HDR_SPLIT, "HDR_SPLIT"), +}; +#define efx_nic_reg_fields_RX_DESC_PTR_TBL_KER efx_nic_reg_fields_RX_DESC_PTR_TBL +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_DESC_PTR_TBL[] = { + /* Abbreviate field names to reduce the table width */ + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_FLUSH, "FLUSH"), + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_TYPE, "TYPE"), + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_SIZE, "SIZE"), + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_LABEL, "LABEL"), + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_OWNER_ID, "OWNER"), + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_EVQ_ID, "EVQ"), + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_BUF_BASE_ID, "BUF_BASE"), + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_SW_WPTR, "SW_WPTR"), + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_HW_RPTR, "HW_RPTR"), + REGISTER_FIELD_AZ_RENAME(TX_DC_HW_RPTR, "DC_HW_RPTR"), + REGISTER_FIELD_AZ_RENAME(TX_ISCSI_HDIG_EN, "HDIG"), + REGISTER_FIELD_AZ_RENAME(TX_ISCSI_DDIG_EN, "DDIG"), + REGISTER_FIELD_AZ_RENAME(TX_DESCQ_EN, "EN"), + REGISTER_FIELD_BZ_RENAME(TX_TCP_CHKSM_DIS, "!TCP_CHKSM"), + REGISTER_FIELD_BZ_RENAME(TX_IP_CHKSM_DIS, "!IP_CHKSM"), + REGISTER_FIELD_BZ_RENAME(TX_NON_IP_DROP_DIS, "!NON_IP_DROP"), + REGISTER_FIELD_CZ_RENAME(TX_DPT_IP_FILT_EN, "IP_FILT"), + REGISTER_FIELD_CZ_RENAME(TX_DPT_ETH_FILT_EN, "ETH_FILT"), + REGISTER_FIELD_CZ_RENAME(TX_DPT_Q_MASK_WIDTH, "Q_MASK_WIDTH"), +}; +#define efx_nic_reg_fields_TX_DESC_PTR_TBL_KER efx_nic_reg_fields_TX_DESC_PTR_TBL +static const struct efx_nic_reg_field efx_nic_reg_fields_EVQ_PTR_TBL[] = { + REGISTER_FIELD_AZ(EVQ_BUF_BASE_ID), + REGISTER_FIELD_AZ(EVQ_SIZE), + REGISTER_FIELD_AZ(EVQ_EN), + REGISTER_FIELD_AZ(EVQ_NXT_WPTR), + REGISTER_FIELD_CZ(EVQ_DOS_PROTECT_EN), + REGISTER_FIELD_AB(EVQ_WKUP_OR_INT_EN), + REGISTER_FIELD_BZ(EVQ_RPTR_IGN), +}; +#define efx_nic_reg_fields_EVQ_PTR_TBL_KER efx_nic_reg_fields_EVQ_PTR_TBL +static const struct efx_nic_reg_field efx_nic_reg_fields_BUF_FULL_TBL[] = { + REGISTER_FIELD_AZ(BUF_OWNER_ID_FBUF), + REGISTER_FIELD_AZ(BUF_ADR_FBUF), + REGISTER_FIELD_AZ(BUF_ADR_REGION), + REGISTER_FIELD_AZ(IP_DAT_BUF_SIZE), + REGISTER_FIELD_AZ(BUF_FULL_UNUSED), +}; +#define efx_nic_reg_fields_BUF_FULL_TBL_KER efx_nic_reg_fields_BUF_FULL_TBL +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_FILTER_TBL0[] = { + /* Source port for full match; destination port for UDP wild match */ + REGISTER_FIELD_BZ_RENAME(SRC_TCP_DEST_UDP, "SRC_PORT"), + REGISTER_FIELD_BZ(SRC_IP), + /* Destination port for full match or TCP wild match */ + REGISTER_FIELD_BZ_RENAME(DEST_PORT_TCP, "DEST_PORT"), + REGISTER_FIELD_BZ(DEST_IP), + REGISTER_FIELD_BZ(RXQ_ID), + REGISTER_FIELD_BZ(TCP_UDP), + REGISTER_FIELD_BZ(SCATTER_EN), + REGISTER_FIELD_BZ(RSS_EN), +}; +#define efx_nic_reg_fields_RX_FILTER_TBL1 efx_nic_reg_fields_RX_FILTER_TBL0 +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_MAC_FILTER_TBL0[] = { + REGISTER_FIELD_CZ(RMFT_VLAN_ID), + REGISTER_FIELD_CZ(RMFT_DEST_MAC), + REGISTER_FIELD_CZ(RMFT_WILDCARD_MATCH), + REGISTER_FIELD_CZ(RMFT_RXQ_ID), + REGISTER_FIELD_CZ(RMFT_IP_OVERRIDE), + REGISTER_FIELD_CZ(RMFT_SCATTER_EN), + REGISTER_FIELD_CZ(RMFT_RSS_EN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TIMER_TBL[] = { + REGISTER_FIELD_BB(TIMER_VAL), + REGISTER_FIELD_CZ(TIMER_VAL), + REGISTER_FIELD_BB(TIMER_MODE), + REGISTER_FIELD_CZ(TIMER_MODE), + REGISTER_FIELD_CZ(RELOAD_TIMER_VAL), + REGISTER_FIELD_CZ(HOST_NOTIFY_MODE), + REGISTER_FIELD_CZ(INT_PEND), + REGISTER_FIELD_CZ(INT_ARMD), + REGISTER_FIELD_CZ(TIMER_Q_EN), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_PACE_TBL[] = { + REGISTER_FIELD_BZ(TX_PACE), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_RX_INDIRECTION_TBL[] = { + REGISTER_FIELD_BZ(IT_QUEUE), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_TX_MAC_FILTER_TBL0[] = { + REGISTER_FIELD_CZ(TMFT_VLAN_ID), + REGISTER_FIELD_CZ(TMFT_SRC_MAC), + REGISTER_FIELD_CZ(TMFT_WILDCARD_MATCH), + REGISTER_FIELD_CZ(TMFT_TXQ_ID), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_MC_TREG_SMEM[] = { + REGISTER_FIELD_CZ(MC_TREG_SMEM_ROW), +}; +static const struct efx_nic_reg_field efx_nic_reg_fields_BIU_MC_SFT_STATUS[] = { + REGISTER_FIELD_DZ(MC_SFT_STATUS), +}; + +struct efx_nic_reg { + const char *name; + const struct efx_nic_reg_field *fields; + u8 field_count; + u8 min_revision, max_revision; +}; + +#define REGISTER(name, arch, min_rev, max_rev) { \ + #name, \ + efx_nic_reg_fields_ ## name, \ + ARRAY_SIZE(efx_nic_reg_fields_ ## name), \ + REGISTER_REVISION_ ## arch ## min_rev, \ + REGISTER_REVISION_ ## arch ## max_rev \ +} +#define REGISTER_AA(name) REGISTER(name, F, A, A) +#define REGISTER_AB(name) REGISTER(name, F, A, B) +#define REGISTER_AZ(name) REGISTER(name, F, A, Z) +#define REGISTER_BB(name) REGISTER(name, F, B, B) +#define REGISTER_BZ(name) REGISTER(name, F, B, Z) +#define REGISTER_CZ(name) REGISTER(name, F, C, Z) +#define REGISTER_DZ(name) REGISTER(name, E, D, Z) + +static const struct efx_nic_reg efx_nic_regs[] = { + REGISTER_AZ(ADR_REGION), + REGISTER_AZ(INT_EN_KER), + REGISTER_BZ(INT_EN_CHAR), + REGISTER_AZ(INT_ADR_KER), + REGISTER_BZ(INT_ADR_CHAR), + /* INT_ACK_KER is WO */ + /* INT_ISR0 is RC */ + REGISTER_AZ(HW_INIT), + REGISTER_CZ(USR_EV_CFG), + REGISTER_AB(EE_SPI_HCMD), + REGISTER_AB(EE_SPI_HADR), + REGISTER_AB(EE_SPI_HDATA), + REGISTER_AB(EE_BASE_PAGE), + REGISTER_AB(EE_VPD_CFG0), + /* EE_VPD_SW_CNTL and EE_VPD_SW_DATA are not used */ + /* PMBX_DBG_IADDR and PBMX_DBG_IDATA are indirect */ + /* PCIE_CORE_INDIRECT is indirect */ + REGISTER_AB(NIC_STAT), + REGISTER_AB(GPIO_CTL), + REGISTER_AB(GLB_CTL), + /* FATAL_INTR_KER and FATAL_INTR_CHAR are partly RC */ + REGISTER_BZ(DP_CTRL), + REGISTER_AZ(MEM_STAT), + REGISTER_AZ(CS_DEBUG), + REGISTER_AZ(ALTERA_BUILD), + REGISTER_AZ(CSR_SPARE), + REGISTER_AB(PCIE_SD_CTL0123), + REGISTER_AB(PCIE_SD_CTL45), + REGISTER_AB(PCIE_PCS_CTL_STAT), + /* DEBUG_DATA_OUT is not used */ + /* DRV_EV is WO */ + REGISTER_AZ(EVQ_CTL), + REGISTER_AZ(EVQ_CNT1), + REGISTER_AZ(EVQ_CNT2), + REGISTER_AZ(BUF_TBL_CFG), + REGISTER_AZ(SRM_RX_DC_CFG), + REGISTER_AZ(SRM_TX_DC_CFG), + REGISTER_AZ(SRM_CFG), + /* BUF_TBL_UPD is WO */ + REGISTER_AZ(SRM_UPD_EVQ), + REGISTER_AZ(SRAM_PARITY), + REGISTER_AZ(RX_CFG), + REGISTER_BZ(RX_FILTER_CTL), + /* RX_FLUSH_DESCQ is WO */ + REGISTER_AZ(RX_DC_CFG), + REGISTER_AZ(RX_DC_PF_WM), + REGISTER_BZ(RX_RSS_TKEY), + /* RX_NODESC_DROP is RC */ + REGISTER_AA(RX_SELF_RST), + /* RX_DEBUG, RX_PUSH_DROP are not used */ + REGISTER_CZ(RX_RSS_IPV6_REG1), + REGISTER_CZ(RX_RSS_IPV6_REG2), + REGISTER_CZ(RX_RSS_IPV6_REG3), + /* TX_FLUSH_DESCQ is WO */ + REGISTER_AZ(TX_DC_CFG), + REGISTER_AA(TX_CHKSM_CFG), + REGISTER_AZ(TX_CFG), + /* TX_PUSH_DROP is not used */ + REGISTER_AZ(TX_RESERVED), + REGISTER_BZ(TX_PACE), + /* TX_PACE_DROP_QID is RC */ + REGISTER_BB(TX_VLAN), + REGISTER_BZ(TX_IPFIL_PORTEN), + REGISTER_AB(MD_TXD), + REGISTER_AB(MD_RXD), + REGISTER_AB(MD_CS), + REGISTER_AB(MD_PHY_ADR), + REGISTER_AB(MD_ID), + /* MD_STAT is RC */ + REGISTER_AB(MAC_STAT_DMA), + REGISTER_AB(MAC_CTRL), + REGISTER_BB(GEN_MODE), + REGISTER_AB(MAC_MC_HASH_REG0), + REGISTER_AB(MAC_MC_HASH_REG1), + REGISTER_AB(GM_CFG1), + REGISTER_AB(GM_CFG2), + /* GM_IPG and GM_HD are not used */ + REGISTER_AB(GM_MAX_FLEN), + /* GM_TEST is not used */ + REGISTER_AB(GM_ADR1), + REGISTER_AB(GM_ADR2), + REGISTER_AB(GMF_CFG0), + REGISTER_AB(GMF_CFG1), + REGISTER_AB(GMF_CFG2), + REGISTER_AB(GMF_CFG3), + REGISTER_AB(GMF_CFG4), + REGISTER_AB(GMF_CFG5), + REGISTER_BB(TX_SRC_MAC_CTL), + REGISTER_AB(XM_ADR_LO), + REGISTER_AB(XM_ADR_HI), + REGISTER_AB(XM_GLB_CFG), + REGISTER_AB(XM_TX_CFG), + REGISTER_AB(XM_RX_CFG), + REGISTER_AB(XM_MGT_INT_MASK), + REGISTER_AB(XM_FC), + REGISTER_AB(XM_PAUSE_TIME), + REGISTER_AB(XM_TX_PARAM), + REGISTER_AB(XM_RX_PARAM), + /* XM_MGT_INT_MSK (note no 'A') is RC */ + REGISTER_AB(XX_PWR_RST), + REGISTER_AB(XX_SD_CTL), + REGISTER_AB(XX_TXDRV_CTL), + /* XX_PRBS_CTL, XX_PRBS_CHK and XX_PRBS_ERR are not used */ + /* XX_CORE_STAT is partly RC */ + REGISTER_DZ(BIU_HW_REV_ID), + REGISTER_DZ(MC_DB_LWRD), + REGISTER_DZ(MC_DB_HWRD), +}; + +struct efx_nic_reg_table { + const char *name; + const struct efx_nic_reg_field *fields; + u8 field_count; + u8 min_revision, max_revision; + u8 step; + u32 rows; +}; + +#define REGISTER_TABLE_DIMENSIONS(name, _, arch, min_rev, max_rev, step, rows) { \ + #name, \ + efx_nic_reg_fields_ ## name, \ + ARRAY_SIZE(efx_nic_reg_fields_ ## name), \ + REGISTER_REVISION_ ## arch ## min_rev, \ + REGISTER_REVISION_ ## arch ## max_rev, \ + step, rows \ +} +#define REGISTER_TABLE(name, arch, min_rev, max_rev) \ + REGISTER_TABLE_DIMENSIONS( \ + name, arch ## R_ ## min_rev ## max_rev ## _ ## name, \ + arch, min_rev, max_rev, \ + arch ## R_ ## min_rev ## max_rev ## _ ## name ## _STEP, \ + arch ## R_ ## min_rev ## max_rev ## _ ## name ## _ROWS) +#define REGISTER_TABLE_AA(name) REGISTER_TABLE(name, F, A, A) +#define REGISTER_TABLE_AZ(name) REGISTER_TABLE(name, F, A, Z) +#define REGISTER_TABLE_BB(name) REGISTER_TABLE(name, F, B, B) +#define REGISTER_TABLE_BZ(name) REGISTER_TABLE(name, F, B, Z) +#define REGISTER_TABLE_BB_CZ(name) \ + REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, F, B, B, \ + FR_BZ_ ## name ## _STEP, \ + FR_BB_ ## name ## _ROWS), \ + REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, F, C, Z, \ + FR_BZ_ ## name ## _STEP, \ + FR_CZ_ ## name ## _ROWS) +#define REGISTER_TABLE_CZ(name) REGISTER_TABLE(name, F, C, Z) +#define REGISTER_TABLE_DZ(name) REGISTER_TABLE(name, E, D, Z) + +static const struct efx_nic_reg_table efx_nic_reg_tables[] = { + /* DRIVER is not used */ + /* EVQ_RPTR, TIMER_COMMAND, USR_EV and {RX,TX}_DESC_UPD are WO */ + REGISTER_TABLE_BB(TX_IPFIL_TBL), + REGISTER_TABLE_BB(TX_SRC_MAC_TBL), + REGISTER_TABLE_AA(RX_DESC_PTR_TBL_KER), + REGISTER_TABLE_BB_CZ(RX_DESC_PTR_TBL), + REGISTER_TABLE_AA(TX_DESC_PTR_TBL_KER), + REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL), + REGISTER_TABLE_AA(EVQ_PTR_TBL_KER), + REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL), + /* We can't reasonably read all of the buffer table (up to 8MB!). + * However this driver will only use a few entries. Reading + * 1K entries allows for some expansion of queue count and + * size before we need to change the version. */ + REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL_KER, FR_AA_BUF_FULL_TBL_KER, + F, A, A, 8, 1024), + REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL, + F, B, Z, 8, 1024), + REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0), + REGISTER_TABLE_BB_CZ(TIMER_TBL), + REGISTER_TABLE_BB_CZ(TX_PACE_TBL), + REGISTER_TABLE_BZ(RX_INDIRECTION_TBL), + /* TX_FILTER_TBL0 is huge and not used by this driver */ + REGISTER_TABLE_CZ(TX_MAC_FILTER_TBL0), + REGISTER_TABLE_CZ(MC_TREG_SMEM), + /* MSIX_PBA_TABLE is not mapped */ + /* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */ + REGISTER_TABLE_BZ(RX_FILTER_TBL0), + REGISTER_TABLE_DZ(BIU_MC_SFT_STATUS), +}; + +static size_t column_width(const struct efx_nic_reg_field *field) +{ + size_t name_width, value_width; + + name_width = strlen(field->name); + value_width = (field->width + 3) >> 2; + + return name_width > value_width ? name_width : value_width; +} + +static size_t column_padding(const struct efx_nic_reg_field *field) +{ + size_t name_width, value_width; + + name_width = strlen(field->name); + value_width = (field->width + 3) >> 2; + + return name_width > value_width ? name_width - value_width : 0; +} + +static void +print_field_value(const struct efx_nic_reg_field *field, const u8 *buf) +{ + unsigned left, right, sig_bits, digit; + + right = field->lbn; + left = right + ((field->width + 3) & ~3); + + /* How many bits are valid for the most significant hex digit? */ + sig_bits = (field->width & 3) ? (field->width & 3) : 4; + + while (left > right) { + left -= 4; + digit = buf[left >> 3]; + if ((left & 7) + sig_bits > 8) + digit |= buf[(left >> 3) + 1] << 8; + digit = (digit >> (left & 7)) & ((1 << sig_bits) - 1); + printf("%x", digit); + sig_bits = 4; /* for all subsequent digits */ + } +} + +static const void * +print_single_register(unsigned revision, const struct efx_nic_reg *reg, + const void *buf) +{ + const struct efx_nic_reg_field *field; + int indent = 0; + size_t i; + + for (i = 0; i < reg->field_count; i++) { + field = ®->fields[i]; + if (revision >= field->min_revision && + revision <= field->max_revision) { + if (indent == 0) + indent = printf("%s: ", reg->name); + else + printf("%*s", indent, ""); + printf("%s = ", field->name); + print_field_value(field, buf); + fputc('\n', stdout); + } + } + + return (const u8 *)buf + 16; +} + +static const void * +print_simple_table(const struct efx_nic_reg_table *table, const void *buf) +{ + const struct efx_nic_reg_field *field = &table->fields[0]; + size_t value_width = (field->width + 3) >> 2; + size_t column_count = 72 / (value_width + 1); + size_t size = table->step > 16 ? 16 : table->step; + size_t i; + + for (i = 0; i < table->rows; i++) { + if (i % column_count == 0) { + if (i != 0) + fputc('\n', stdout); + printf("%4zu ", i); + } + fputc(' ', stdout); + print_field_value(field, buf); + buf = (const u8 *)buf + size; + } + fputc('\n', stdout); + + return buf; +} + +static int buf_is_zero(const u8 *buf, size_t size) +{ + size_t i; + for (i = 0; i < size; i++) + if (buf[i]) + return 0; + return 1; +} + +static const void * +print_complex_table(unsigned revision, const struct efx_nic_reg_table *table, + const void *buf) +{ + const struct efx_nic_reg_field *field; + size_t size = table->step > 16 ? 16 : table->step; + size_t i, j; + + /* Column headings */ + fputs("Row ", stdout); + for (i = 0; i < table->field_count; i++) { + field = &table->fields[i]; + if (revision >= field->min_revision && + revision <= field->max_revision) + printf(" %-*s", (int)column_width(field), + field->name); + } + fputc('\n', stdout); + fputs("----", stdout); + for (i = 0; i < table->field_count; i++) { + field = &table->fields[i]; + if (revision >= field->min_revision && + revision <= field->max_revision) { + fputc(' ', stdout); + for (j = column_width(field); j > 0; j--) + fputc('-', stdout); + } + } + fputc('\n', stdout); + + for (j = 0; j < table->rows; j++) { + if (!buf_is_zero(buf, size)) { + printf("%4zu", j); + for (i = 0; i < table->field_count; i++) { + field = &table->fields[i]; + if (!(revision >= field->min_revision && + revision <= field->max_revision)) + continue; + printf(" %*s", (int)column_padding(field), ""); + print_field_value(field, buf); + } + fputc('\n', stdout); + } + buf = (const u8 *)buf + size; + } + + return buf; +} + +int +sfc_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + const struct efx_nic_reg *reg; + const struct efx_nic_reg_table *table; + unsigned revision = regs->version; + const void *buf = regs->data; + const void *end = regs->data + regs->len; + + if (revision > REGISTER_REVISION_ED) + return -1; + + for (reg = efx_nic_regs; + reg < efx_nic_regs + ARRAY_SIZE(efx_nic_regs) && buf < end; + reg++) { + if (revision >= reg->min_revision && + revision <= reg->max_revision) + buf = print_single_register(revision, reg, buf); + } + + for (table = efx_nic_reg_tables; + table < efx_nic_reg_tables + ARRAY_SIZE(efx_nic_reg_tables) && + buf < end; + table++) { + if (revision >= table->min_revision && + revision <= table->max_revision) { + printf("\n%s:\n", table->name); + if (table->field_count == 1) + buf = print_simple_table(table, buf); + else + buf = print_complex_table(revision, table, buf); + } + } + + return 0; +} diff --git a/sff-common.c b/sff-common.c new file mode 100644 index 0000000..e951cf1 --- /dev/null +++ b/sff-common.c @@ -0,0 +1,361 @@ +/* + * sff-common.c: Implements SFF-8024 Rev 4.0 i.e. Specifcation + * of pluggable I/O configuration + * + * Common utilities across SFF-8436/8636 and SFF-8472/8079 + * are defined in this file + * + * Copyright 2010 Solarflare Communications Inc. + * Aurelien Guillaume (C) 2012 + * Copyright (C) 2014 Cumulus networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Freeoftware Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Vidya Sagar Ravipati + * This implementation is loosely based on current SFP parser + * and SFF-8024 Rev 4.0 spec (ftp://ftp.seagate.com/pub/sff/SFF-8024.PDF) + * by SFF Committee. + */ + +#include +#include +#include "sff-common.h" + +double convert_mw_to_dbm(double mw) +{ + return (10. * log10(mw / 1000.)) + 30.; +} + +void sff_show_value_with_unit(const __u8 *id, unsigned int reg, + const char *name, unsigned int mult, + const char *unit) +{ + unsigned int val = id[reg]; + + printf("\t%-41s : %u%s\n", name, val * mult, unit); +} + +void sff_show_ascii(const __u8 *id, unsigned int first_reg, + unsigned int last_reg, const char *name) +{ + unsigned int reg, val; + + printf("\t%-41s : ", name); + while (first_reg <= last_reg && id[last_reg] == ' ') + last_reg--; + for (reg = first_reg; reg <= last_reg; reg++) { + val = id[reg]; + putchar(((val >= 32) && (val <= 126)) ? val : '_'); + } + printf("\n"); +} + +void sff8024_show_oui(const __u8 *id, int id_offset) +{ + printf("\t%-41s : %02x:%02x:%02x\n", "Vendor OUI", + id[id_offset], id[(id_offset) + 1], + id[(id_offset) + 2]); +} + +void sff8024_show_identifier(const __u8 *id, int id_offset) +{ + printf("\t%-41s : 0x%02x", "Identifier", id[id_offset]); + switch (id[id_offset]) { + case SFF8024_ID_UNKNOWN: + printf(" (no module present, unknown, or unspecified)\n"); + break; + case SFF8024_ID_GBIC: + printf(" (GBIC)\n"); + break; + case SFF8024_ID_SOLDERED_MODULE: + printf(" (module soldered to motherboard)\n"); + break; + case SFF8024_ID_SFP: + printf(" (SFP)\n"); + break; + case SFF8024_ID_300_PIN_XBI: + printf(" (300 pin XBI)\n"); + break; + case SFF8024_ID_XENPAK: + printf(" (XENPAK)\n"); + break; + case SFF8024_ID_XFP: + printf(" (XFP)\n"); + break; + case SFF8024_ID_XFF: + printf(" (XFF)\n"); + break; + case SFF8024_ID_XFP_E: + printf(" (XFP-E)\n"); + break; + case SFF8024_ID_XPAK: + printf(" (XPAK)\n"); + break; + case SFF8024_ID_X2: + printf(" (X2)\n"); + break; + case SFF8024_ID_DWDM_SFP: + printf(" (DWDM-SFP)\n"); + break; + case SFF8024_ID_QSFP: + printf(" (QSFP)\n"); + break; + case SFF8024_ID_QSFP_PLUS: + printf(" (QSFP+)\n"); + break; + case SFF8024_ID_CXP: + printf(" (CXP)\n"); + break; + case SFF8024_ID_HD4X: + printf(" (Shielded Mini Multilane HD 4X)\n"); + break; + case SFF8024_ID_HD8X: + printf(" (Shielded Mini Multilane HD 8X)\n"); + break; + case SFF8024_ID_QSFP28: + printf(" (QSFP28)\n"); + break; + case SFF8024_ID_CXP2: + printf(" (CXP2/CXP28)\n"); + break; + case SFF8024_ID_CDFP: + printf(" (CDFP Style 1/Style 2)\n"); + break; + case SFF8024_ID_HD4X_FANOUT: + printf(" (Shielded Mini Multilane HD 4X Fanout Cable)\n"); + break; + case SFF8024_ID_HD8X_FANOUT: + printf(" (Shielded Mini Multilane HD 8X Fanout Cable)\n"); + break; + case SFF8024_ID_CDFP_S3: + printf(" (CDFP Style 3)\n"); + break; + case SFF8024_ID_MICRO_QSFP: + printf(" (microQSFP)\n"); + break; + case SFF8024_ID_QSFP_DD: + printf(" (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))\n"); + break; + case SFF8024_ID_OSFP: + printf(" (OSFP 8X Pluggable Transceiver)\n"); + break; + case SFF8024_ID_DSFP: + printf(" (DSFP Dual Small Form Factor Pluggable Transceiver)\n"); + break; + default: + printf(" (reserved or unknown)\n"); + break; + } +} + +void sff8024_show_connector(const __u8 *id, int ctor_offset) +{ + printf("\t%-41s : 0x%02x", "Connector", id[ctor_offset]); + switch (id[ctor_offset]) { + case SFF8024_CTOR_UNKNOWN: + printf(" (unknown or unspecified)\n"); + break; + case SFF8024_CTOR_SC: + printf(" (SC)\n"); + break; + case SFF8024_CTOR_FC_STYLE_1: + printf(" (Fibre Channel Style 1 copper)\n"); + break; + case SFF8024_CTOR_FC_STYLE_2: + printf(" (Fibre Channel Style 2 copper)\n"); + break; + case SFF8024_CTOR_BNC_TNC: + printf(" (BNC/TNC)\n"); + break; + case SFF8024_CTOR_FC_COAX: + printf(" (Fibre Channel coaxial headers)\n"); + break; + case SFF8024_CTOR_FIBER_JACK: + printf(" (FibreJack)\n"); + break; + case SFF8024_CTOR_LC: + printf(" (LC)\n"); + break; + case SFF8024_CTOR_MT_RJ: + printf(" (MT-RJ)\n"); + break; + case SFF8024_CTOR_MU: + printf(" (MU)\n"); + break; + case SFF8024_CTOR_SG: + printf(" (SG)\n"); + break; + case SFF8024_CTOR_OPT_PT: + printf(" (Optical pigtail)\n"); + break; + case SFF8024_CTOR_MPO: + printf(" (MPO Parallel Optic)\n"); + break; + case SFF8024_CTOR_MPO_2: + printf(" (MPO Parallel Optic - 2x16)\n"); + break; + case SFF8024_CTOR_HSDC_II: + printf(" (HSSDC II)\n"); + break; + case SFF8024_CTOR_COPPER_PT: + printf(" (Copper pigtail)\n"); + break; + case SFF8024_CTOR_RJ45: + printf(" (RJ45)\n"); + break; + case SFF8024_CTOR_NO_SEPARABLE: + printf(" (No separable connector)\n"); + break; + case SFF8024_CTOR_MXC_2x16: + printf(" (MXC 2x16)\n"); + break; + case SFF8024_CTOR_CS_OPTICAL: + printf(" (CS optical connector)\n"); + break; + case SFF8024_CTOR_CS_OPTICAL_MINI: + printf(" (Mini CS optical connector)\n"); + break; + case SFF8024_CTOR_MPO_2X12: + printf(" (MPO 2x12)\n"); + break; + case SFF8024_CTOR_MPO_1X16: + printf(" (MPO 1x16)\n"); + break; + default: + printf(" (reserved or unknown)\n"); + break; + } +} + +void sff8024_show_encoding(const __u8 *id, int encoding_offset, int sff_type) +{ + printf("\t%-41s : 0x%02x", "Encoding", id[encoding_offset]); + switch (id[encoding_offset]) { + case SFF8024_ENCODING_UNSPEC: + printf(" (unspecified)\n"); + break; + case SFF8024_ENCODING_8B10B: + printf(" (8B/10B)\n"); + break; + case SFF8024_ENCODING_4B5B: + printf(" (4B/5B)\n"); + break; + case SFF8024_ENCODING_NRZ: + printf(" (NRZ)\n"); + break; + case SFF8024_ENCODING_4h: + if (sff_type == ETH_MODULE_SFF_8472) + printf(" (Manchester)\n"); + else if (sff_type == ETH_MODULE_SFF_8636) + printf(" (SONET Scrambled)\n"); + break; + case SFF8024_ENCODING_5h: + if (sff_type == ETH_MODULE_SFF_8472) + printf(" (SONET Scrambled)\n"); + else if (sff_type == ETH_MODULE_SFF_8636) + printf(" (64B/66B)\n"); + break; + case SFF8024_ENCODING_6h: + if (sff_type == ETH_MODULE_SFF_8472) + printf(" (64B/66B)\n"); + else if (sff_type == ETH_MODULE_SFF_8636) + printf(" (Manchester)\n"); + break; + case SFF8024_ENCODING_256B: + printf(" ((256B/257B (transcoded FEC-enabled data))\n"); + break; + case SFF8024_ENCODING_PAM4: + printf(" (PAM4)\n"); + break; + default: + printf(" (reserved or unknown)\n"); + break; + } +} + +void sff_show_thresholds(struct sff_diags sd) +{ + PRINT_BIAS("Laser bias current high alarm threshold", + sd.bias_cur[HALRM]); + PRINT_BIAS("Laser bias current low alarm threshold", + sd.bias_cur[LALRM]); + PRINT_BIAS("Laser bias current high warning threshold", + sd.bias_cur[HWARN]); + PRINT_BIAS("Laser bias current low warning threshold", + sd.bias_cur[LWARN]); + + PRINT_xX_PWR("Laser output power high alarm threshold", + sd.tx_power[HALRM]); + PRINT_xX_PWR("Laser output power low alarm threshold", + sd.tx_power[LALRM]); + PRINT_xX_PWR("Laser output power high warning threshold", + sd.tx_power[HWARN]); + PRINT_xX_PWR("Laser output power low warning threshold", + sd.tx_power[LWARN]); + + PRINT_TEMP("Module temperature high alarm threshold", + sd.sfp_temp[HALRM]); + PRINT_TEMP("Module temperature low alarm threshold", + sd.sfp_temp[LALRM]); + PRINT_TEMP("Module temperature high warning threshold", + sd.sfp_temp[HWARN]); + PRINT_TEMP("Module temperature low warning threshold", + sd.sfp_temp[LWARN]); + + PRINT_VCC("Module voltage high alarm threshold", + sd.sfp_voltage[HALRM]); + PRINT_VCC("Module voltage low alarm threshold", + sd.sfp_voltage[LALRM]); + PRINT_VCC("Module voltage high warning threshold", + sd.sfp_voltage[HWARN]); + PRINT_VCC("Module voltage low warning threshold", + sd.sfp_voltage[LWARN]); + + PRINT_xX_PWR("Laser rx power high alarm threshold", + sd.rx_power[HALRM]); + PRINT_xX_PWR("Laser rx power low alarm threshold", + sd.rx_power[LALRM]); + PRINT_xX_PWR("Laser rx power high warning threshold", + sd.rx_power[HWARN]); + PRINT_xX_PWR("Laser rx power low warning threshold", + sd.rx_power[LWARN]); +} + +void sff_show_revision_compliance(const __u8 *id, int rev_offset) +{ + static const char *pfx = + "\tRevision Compliance :"; + + switch (id[rev_offset]) { + case SFF8636_REV_UNSPECIFIED: + printf("%s Revision not specified\n", pfx); + break; + case SFF8636_REV_8436_48: + printf("%s SFF-8436 Rev 4.8 or earlier\n", pfx); + break; + case SFF8636_REV_8436_8636: + printf("%s SFF-8436 Rev 4.8 or earlier\n", pfx); + break; + case SFF8636_REV_8636_13: + printf("%s SFF-8636 Rev 1.3 or earlier\n", pfx); + break; + case SFF8636_REV_8636_14: + printf("%s SFF-8636 Rev 1.4\n", pfx); + break; + case SFF8636_REV_8636_15: + printf("%s SFF-8636 Rev 1.5\n", pfx); + break; + case SFF8636_REV_8636_20: + printf("%s SFF-8636 Rev 2.0\n", pfx); + break; + case SFF8636_REV_8636_27: + printf("%s SFF-8636 Rev 2.5/2.6/2.7\n", pfx); + break; + default: + printf("%s Unallocated\n", pfx); + break; + } +} diff --git a/sff-common.h b/sff-common.h new file mode 100644 index 0000000..dd12dda --- /dev/null +++ b/sff-common.h @@ -0,0 +1,209 @@ +/* + * sff-common.h: Implements SFF-8024 Rev 4.0 i.e. Specifcation + * of pluggable I/O configuration + * + * Common utilities across SFF-8436/8636 and SFF-8472/8079 + * are defined in this file + * + * Copyright 2010 Solarflare Communications Inc. + * Aurelien Guillaume (C) 2012 + * Copyright (C) 2014 Cumulus networks Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Freeoftware Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Vidya Sagar Ravipati + * This implementation is loosely based on current SFP parser + * and SFF-8024 specs (ftp://ftp.seagate.com/pub/sff/SFF-8024.PDF) + * by SFF Committee. + */ + +#ifndef SFF_COMMON_H__ +#define SFF_COMMON_H__ + +#include +#include "internal.h" + +/* Revision compliance */ +#define SFF8636_REV_UNSPECIFIED 0x00 +#define SFF8636_REV_8436_48 0x01 +#define SFF8636_REV_8436_8636 0x02 +#define SFF8636_REV_8636_13 0x03 +#define SFF8636_REV_8636_14 0x04 +#define SFF8636_REV_8636_15 0x05 +#define SFF8636_REV_8636_20 0x06 +#define SFF8636_REV_8636_27 0x07 + +#define SFF8024_ID_OFFSET 0x00 +#define SFF8024_ID_UNKNOWN 0x00 +#define SFF8024_ID_GBIC 0x01 +#define SFF8024_ID_SOLDERED_MODULE 0x02 +#define SFF8024_ID_SFP 0x03 +#define SFF8024_ID_300_PIN_XBI 0x04 +#define SFF8024_ID_XENPAK 0x05 +#define SFF8024_ID_XFP 0x06 +#define SFF8024_ID_XFF 0x07 +#define SFF8024_ID_XFP_E 0x08 +#define SFF8024_ID_XPAK 0x09 +#define SFF8024_ID_X2 0x0A +#define SFF8024_ID_DWDM_SFP 0x0B +#define SFF8024_ID_QSFP 0x0C +#define SFF8024_ID_QSFP_PLUS 0x0D +#define SFF8024_ID_CXP 0x0E +#define SFF8024_ID_HD4X 0x0F +#define SFF8024_ID_HD8X 0x10 +#define SFF8024_ID_QSFP28 0x11 +#define SFF8024_ID_CXP2 0x12 +#define SFF8024_ID_CDFP 0x13 +#define SFF8024_ID_HD4X_FANOUT 0x14 +#define SFF8024_ID_HD8X_FANOUT 0x15 +#define SFF8024_ID_CDFP_S3 0x16 +#define SFF8024_ID_MICRO_QSFP 0x17 +#define SFF8024_ID_QSFP_DD 0x18 +#define SFF8024_ID_OSFP 0x19 +#define SFF8024_ID_DSFP 0x1B +#define SFF8024_ID_LAST SFF8024_ID_DSFP +#define SFF8024_ID_UNALLOCATED_LAST 0x7F +#define SFF8024_ID_VENDOR_START 0x80 +#define SFF8024_ID_VENDOR_LAST 0xFF + +#define SFF8024_CTOR_UNKNOWN 0x00 +#define SFF8024_CTOR_SC 0x01 +#define SFF8024_CTOR_FC_STYLE_1 0x02 +#define SFF8024_CTOR_FC_STYLE_2 0x03 +#define SFF8024_CTOR_BNC_TNC 0x04 +#define SFF8024_CTOR_FC_COAX 0x05 +#define SFF8024_CTOR_FIBER_JACK 0x06 +#define SFF8024_CTOR_LC 0x07 +#define SFF8024_CTOR_MT_RJ 0x08 +#define SFF8024_CTOR_MU 0x09 +#define SFF8024_CTOR_SG 0x0A +#define SFF8024_CTOR_OPT_PT 0x0B +#define SFF8024_CTOR_MPO 0x0C +#define SFF8024_CTOR_MPO_2 0x0D +/* 0E-1Fh --- Reserved */ +#define SFF8024_CTOR_HSDC_II 0x20 +#define SFF8024_CTOR_COPPER_PT 0x21 +#define SFF8024_CTOR_RJ45 0x22 +#define SFF8024_CTOR_NO_SEPARABLE 0x23 +#define SFF8024_CTOR_MXC_2x16 0x24 +#define SFF8024_CTOR_CS_OPTICAL 0x25 +#define SFF8024_CTOR_CS_OPTICAL_MINI 0x26 +#define SFF8024_CTOR_MPO_2X12 0x27 +#define SFF8024_CTOR_MPO_1X16 0x28 +#define SFF8024_CTOR_LAST SFF8024_CTOR_MPO_1X16 + +#define SFF8024_CTOR_NO_SEP_QSFP_DD 0x6F +#define SFF8024_CTOR_UNALLOCATED_LAST 0x7F +#define SFF8024_CTOR_VENDOR_START 0x80 +#define SFF8024_CTOR_VENDOR_LAST 0xFF + +/* ENCODING Values */ +#define SFF8024_ENCODING_UNSPEC 0x00 +#define SFF8024_ENCODING_8B10B 0x01 +#define SFF8024_ENCODING_4B5B 0x02 +#define SFF8024_ENCODING_NRZ 0x03 +/* + * Value: 04h + * SFF-8472 - Manchester + * SFF-8436/8636 - SONET Scrambled + */ +#define SFF8024_ENCODING_4h 0x04 +/* + * Value: 05h + * SFF-8472 - SONET Scrambled + * SFF-8436/8636 - 64B/66B + */ +#define SFF8024_ENCODING_5h 0x05 +/* + * Value: 06h + * SFF-8472 - 64B/66B + * SFF-8436/8636 - Manchester + */ +#define SFF8024_ENCODING_6h 0x06 +#define SFF8024_ENCODING_256B 0x07 +#define SFF8024_ENCODING_PAM4 0x08 + +/* Most common case: 16-bit unsigned integer in a certain unit */ +#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1]) +#define OFFSET_TO_U16(offset) OFFSET_TO_U16_PTR(id, offset) + +# define PRINT_xX_PWR(string, var) \ + printf("\t%-41s : %.4f mW / %.2f dBm\n", (string), \ + (double)((var) / 10000.), \ + convert_mw_to_dbm((double)((var) / 10000.))) + +#define PRINT_BIAS(string, bias_cur) \ + printf("\t%-41s : %.3f mA\n", (string), \ + (double)(bias_cur / 500.)) + +#define PRINT_TEMP(string, temp) \ + printf("\t%-41s : %.2f degrees C / %.2f degrees F\n", \ + (string), (double)(temp / 256.), \ + (double)(temp / 256. * 1.8 + 32.)) + +#define PRINT_VCC(string, sfp_voltage) \ + printf("\t%-41s : %.4f V\n", (string), \ + (double)(sfp_voltage / 10000.)) + +# define PRINT_xX_THRESH_PWR(string, var, index) \ + PRINT_xX_PWR(string, (var)[(index)]) + +/* Channel Monitoring Fields */ +struct sff_channel_diags { + __u16 bias_cur; /* Measured bias current in 2uA units */ + __u16 rx_power; /* Measured RX Power */ + __u16 tx_power; /* Measured TX Power */ +}; + +/* Module Monitoring Fields */ +struct sff_diags { + +#define MAX_CHANNEL_NUM 32 +#define LWARN 0 +#define HWARN 1 +#define LALRM 2 +#define HALRM 3 +#define MCURR 4 + + /* Supports DOM */ + __u8 supports_dom; + /* Supports alarm/warning thold */ + __u8 supports_alarms; + /* RX Power: 0 = OMA, 1 = Average power */ + __u8 rx_power_type; + /* TX Power: 0 = Not supported, 1 = Average power */ + __u8 tx_power_type; + + __u8 calibrated_ext; /* Is externally calibrated */ + /* [5] tables are low/high warn, low/high alarm, current */ + /* SFP voltage in 0.1mV units */ + __u16 sfp_voltage[5]; + /* SFP Temp in 16-bit signed 1/256 Celcius */ + __s16 sfp_temp[5]; + /* Measured bias current in 2uA units */ + __u16 bias_cur[5]; + /* Measured TX Power */ + __u16 tx_power[5]; + /* Measured RX Power */ + __u16 rx_power[5]; + struct sff_channel_diags scd[MAX_CHANNEL_NUM]; +}; + +double convert_mw_to_dbm(double mw); +void sff_show_value_with_unit(const __u8 *id, unsigned int reg, + const char *name, unsigned int mult, + const char *unit); +void sff_show_ascii(const __u8 *id, unsigned int first_reg, + unsigned int last_reg, const char *name); +void sff_show_thresholds(struct sff_diags sd); + +void sff8024_show_oui(const __u8 *id, int id_offset); +void sff8024_show_identifier(const __u8 *id, int id_offset); +void sff8024_show_connector(const __u8 *id, int ctor_offset); +void sff8024_show_encoding(const __u8 *id, int encoding_offset, int sff_type); +void sff_show_revision_compliance(const __u8 *id, int rev_offset); + +#endif /* SFF_COMMON_H__ */ diff --git a/sfpdiag.c b/sfpdiag.c new file mode 100644 index 0000000..1fa8b7b --- /dev/null +++ b/sfpdiag.c @@ -0,0 +1,281 @@ +/* + * sfpdiag.c: Implements SFF-8472 optics diagnostics. + * + * Aurelien Guillaume (C) 2012 + * This implementation is loosely based on DOM patches + * from Robert Olsson (C) 2009 + * and SFF-8472 specs (ftp://ftp.seagate.com/pub/sff/SFF-8472.PDF) + * by SFF Committee. + */ + +#include +#include +#include +#include "internal.h" +#include "sff-common.h" + +/* Offsets in decimal, for direct comparison with the SFF specs */ + +/* A0-based EEPROM offsets for DOM support checks */ +#define SFF_A0_DOM 92 +#define SFF_A0_OPTIONS 93 +#define SFF_A0_COMP 94 + +/* EEPROM bit values for various registers */ +#define SFF_A0_DOM_EXTCAL (1 << 4) +#define SFF_A0_DOM_INTCAL (1 << 5) +#define SFF_A0_DOM_IMPL (1 << 6) +#define SFF_A0_DOM_PWRT (1 << 3) + +#define SFF_A0_OPTIONS_AW (1 << 7) + +/* + * See ethtool.c comments about SFF-8472, this is the offset + * at which the A2 page is in the EEPROM blob returned by the + * kernel. + */ +#define SFF_A2_BASE 0x100 + +/* A2-based offsets for DOM */ +#define SFF_A2_TEMP 96 +#define SFF_A2_TEMP_HALRM 0 +#define SFF_A2_TEMP_LALRM 2 +#define SFF_A2_TEMP_HWARN 4 +#define SFF_A2_TEMP_LWARN 6 + +#define SFF_A2_VCC 98 +#define SFF_A2_VCC_HALRM 8 +#define SFF_A2_VCC_LALRM 10 +#define SFF_A2_VCC_HWARN 12 +#define SFF_A2_VCC_LWARN 14 + +#define SFF_A2_BIAS 100 +#define SFF_A2_BIAS_HALRM 16 +#define SFF_A2_BIAS_LALRM 18 +#define SFF_A2_BIAS_HWARN 20 +#define SFF_A2_BIAS_LWARN 22 + +#define SFF_A2_TX_PWR 102 +#define SFF_A2_TX_PWR_HALRM 24 +#define SFF_A2_TX_PWR_LALRM 26 +#define SFF_A2_TX_PWR_HWARN 28 +#define SFF_A2_TX_PWR_LWARN 30 + +#define SFF_A2_RX_PWR 104 +#define SFF_A2_RX_PWR_HALRM 32 +#define SFF_A2_RX_PWR_LALRM 34 +#define SFF_A2_RX_PWR_HWARN 36 +#define SFF_A2_RX_PWR_LWARN 38 + +#define SFF_A2_ALRM_FLG 112 +#define SFF_A2_WARN_FLG 116 + +/* 32-bit little-endian calibration constants */ +#define SFF_A2_CAL_RXPWR4 56 +#define SFF_A2_CAL_RXPWR3 60 +#define SFF_A2_CAL_RXPWR2 64 +#define SFF_A2_CAL_RXPWR1 68 +#define SFF_A2_CAL_RXPWR0 72 + +/* 16-bit little endian calibration constants */ +#define SFF_A2_CAL_TXI_SLP 76 +#define SFF_A2_CAL_TXI_OFF 78 +#define SFF_A2_CAL_TXPWR_SLP 80 +#define SFF_A2_CAL_TXPWR_OFF 82 +#define SFF_A2_CAL_T_SLP 84 +#define SFF_A2_CAL_T_OFF 86 +#define SFF_A2_CAL_V_SLP 88 +#define SFF_A2_CAL_V_OFF 90 + +static struct sff8472_aw_flags { + const char *str; /* Human-readable string, null at the end */ + int offset; /* A2-relative address offset */ + __u8 value; /* Alarm is on if (offset & value) != 0. */ +} sff8472_aw_flags[] = { + { "Laser bias current high alarm", SFF_A2_ALRM_FLG, (1 << 3) }, + { "Laser bias current low alarm", SFF_A2_ALRM_FLG, (1 << 2) }, + { "Laser bias current high warning", SFF_A2_WARN_FLG, (1 << 3) }, + { "Laser bias current low warning", SFF_A2_WARN_FLG, (1 << 2) }, + + { "Laser output power high alarm", SFF_A2_ALRM_FLG, (1 << 1) }, + { "Laser output power low alarm", SFF_A2_ALRM_FLG, (1 << 0) }, + { "Laser output power high warning", SFF_A2_WARN_FLG, (1 << 1) }, + { "Laser output power low warning", SFF_A2_WARN_FLG, (1 << 0) }, + + { "Module temperature high alarm", SFF_A2_ALRM_FLG, (1 << 7) }, + { "Module temperature low alarm", SFF_A2_ALRM_FLG, (1 << 6) }, + { "Module temperature high warning", SFF_A2_WARN_FLG, (1 << 7) }, + { "Module temperature low warning", SFF_A2_WARN_FLG, (1 << 6) }, + + { "Module voltage high alarm", SFF_A2_ALRM_FLG, (1 << 5) }, + { "Module voltage low alarm", SFF_A2_ALRM_FLG, (1 << 4) }, + { "Module voltage high warning", SFF_A2_WARN_FLG, (1 << 5) }, + { "Module voltage low warning", SFF_A2_WARN_FLG, (1 << 4) }, + + { "Laser rx power high alarm", SFF_A2_ALRM_FLG + 1, (1 << 7) }, + { "Laser rx power low alarm", SFF_A2_ALRM_FLG + 1, (1 << 6) }, + { "Laser rx power high warning", SFF_A2_WARN_FLG + 1, (1 << 7) }, + { "Laser rx power low warning", SFF_A2_WARN_FLG + 1, (1 << 6) }, + + { NULL, 0, 0 }, +}; + +/* Most common case: 16-bit unsigned integer in a certain unit */ +#define A2_OFFSET_TO_U16(offset) \ + (id[SFF_A2_BASE + (offset)] << 8 | id[SFF_A2_BASE + (offset) + 1]) + +/* Calibration slope is a number between 0.0 included and 256.0 excluded. */ +#define A2_OFFSET_TO_SLP(offset) \ + (id[SFF_A2_BASE + (offset)] + id[SFF_A2_BASE + (offset) + 1] / 256.) + +/* Calibration offset is an integer from -32768 to 32767 */ +#define A2_OFFSET_TO_OFF(offset) \ + ((__s16)A2_OFFSET_TO_U16(offset)) + +/* RXPWR(x) are IEEE-754 floating point numbers in big-endian format */ +#define A2_OFFSET_TO_RXPWRx(offset) \ + (befloattoh((__u32 *)(id + SFF_A2_BASE + (offset)))) + +/* + * 2-byte internal temperature conversions: + * First byte is a signed 8-bit integer, which is the temp decimal part + * Second byte are 1/256th of degree, which are added to the dec part. + */ +#define A2_OFFSET_TO_TEMP(offset) ((__s16)A2_OFFSET_TO_U16(offset)) + +static void sff8472_dom_parse(const __u8 *id, struct sff_diags *sd) +{ + sd->bias_cur[MCURR] = A2_OFFSET_TO_U16(SFF_A2_BIAS); + sd->bias_cur[HALRM] = A2_OFFSET_TO_U16(SFF_A2_BIAS_HALRM); + sd->bias_cur[LALRM] = A2_OFFSET_TO_U16(SFF_A2_BIAS_LALRM); + sd->bias_cur[HWARN] = A2_OFFSET_TO_U16(SFF_A2_BIAS_HWARN); + sd->bias_cur[LWARN] = A2_OFFSET_TO_U16(SFF_A2_BIAS_LWARN); + + sd->sfp_voltage[MCURR] = A2_OFFSET_TO_U16(SFF_A2_VCC); + sd->sfp_voltage[HALRM] = A2_OFFSET_TO_U16(SFF_A2_VCC_HALRM); + sd->sfp_voltage[LALRM] = A2_OFFSET_TO_U16(SFF_A2_VCC_LALRM); + sd->sfp_voltage[HWARN] = A2_OFFSET_TO_U16(SFF_A2_VCC_HWARN); + sd->sfp_voltage[LWARN] = A2_OFFSET_TO_U16(SFF_A2_VCC_LWARN); + + sd->tx_power[MCURR] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR); + sd->tx_power[HALRM] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_HALRM); + sd->tx_power[LALRM] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_LALRM); + sd->tx_power[HWARN] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_HWARN); + sd->tx_power[LWARN] = A2_OFFSET_TO_U16(SFF_A2_TX_PWR_LWARN); + + sd->rx_power[MCURR] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR); + sd->rx_power[HALRM] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_HALRM); + sd->rx_power[LALRM] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_LALRM); + sd->rx_power[HWARN] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_HWARN); + sd->rx_power[LWARN] = A2_OFFSET_TO_U16(SFF_A2_RX_PWR_LWARN); + + sd->sfp_temp[MCURR] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP); + sd->sfp_temp[HALRM] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_HALRM); + sd->sfp_temp[LALRM] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_LALRM); + sd->sfp_temp[HWARN] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_HWARN); + sd->sfp_temp[LWARN] = A2_OFFSET_TO_TEMP(SFF_A2_TEMP_LWARN); +} + +/* Converts to a float from a big-endian 4-byte source buffer. */ +static float befloattoh(const __u32 *source) +{ + union { + __u32 src; + float dst; + } converter; + + converter.src = ntohl(*source); + return converter.dst; +} + +static void sff8472_calibration(const __u8 *id, struct sff_diags *sd) +{ + __u16 rx_reading; + unsigned int i; + + /* Calibration should occur for all values (threshold and current) */ + for (i = 0; i < ARRAY_SIZE(sd->bias_cur); ++i) { + /* + * Apply calibration formula 1 (Temp., Voltage, Bias, Tx Power) + */ + sd->bias_cur[i] *= A2_OFFSET_TO_SLP(SFF_A2_CAL_TXI_SLP); + sd->tx_power[i] *= A2_OFFSET_TO_SLP(SFF_A2_CAL_TXPWR_SLP); + sd->sfp_voltage[i] *= A2_OFFSET_TO_SLP(SFF_A2_CAL_V_SLP); + sd->sfp_temp[i] *= A2_OFFSET_TO_SLP(SFF_A2_CAL_T_SLP); + + sd->bias_cur[i] += A2_OFFSET_TO_OFF(SFF_A2_CAL_TXI_OFF); + sd->tx_power[i] += A2_OFFSET_TO_OFF(SFF_A2_CAL_TXPWR_OFF); + sd->sfp_voltage[i] += A2_OFFSET_TO_OFF(SFF_A2_CAL_V_OFF); + sd->sfp_temp[i] += A2_OFFSET_TO_OFF(SFF_A2_CAL_T_OFF); + + /* + * Apply calibration formula 2 (Rx Power only) + */ + rx_reading = sd->rx_power[i]; + sd->rx_power[i] = A2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR0); + sd->rx_power[i] += rx_reading * + A2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR1); + sd->rx_power[i] += rx_reading * + A2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR2); + sd->rx_power[i] += rx_reading * + A2_OFFSET_TO_RXPWRx(SFF_A2_CAL_RXPWR3); + } +} + +static void sff8472_parse_eeprom(const __u8 *id, struct sff_diags *sd) +{ + sd->supports_dom = id[SFF_A0_DOM] & SFF_A0_DOM_IMPL; + sd->supports_alarms = id[SFF_A0_OPTIONS] & SFF_A0_OPTIONS_AW; + sd->calibrated_ext = id[SFF_A0_DOM] & SFF_A0_DOM_EXTCAL; + sd->rx_power_type = id[SFF_A0_DOM] & SFF_A0_DOM_PWRT; + + sff8472_dom_parse(id, sd); + + /* + * If the SFP is externally calibrated, we need to read calibration data + * and compensate the already stored readings. + */ + if (sd->calibrated_ext) + sff8472_calibration(id, sd); +} + +void sff8472_show_all(const __u8 *id) +{ + struct sff_diags sd = {0}; + char *rx_power_string = NULL; + int i; + + sff8472_parse_eeprom(id, &sd); + + if (!sd.supports_dom) { + printf("\t%-41s : No\n", "Optical diagnostics support"); + return; + } + printf("\t%-41s : Yes\n", "Optical diagnostics support"); + + PRINT_BIAS("Laser bias current", sd.bias_cur[MCURR]); + PRINT_xX_PWR("Laser output power", sd.tx_power[MCURR]); + + if (!sd.rx_power_type) + rx_power_string = "Receiver signal OMA"; + else + rx_power_string = "Receiver signal average optical power"; + + PRINT_xX_PWR(rx_power_string, sd.rx_power[MCURR]); + + PRINT_TEMP("Module temperature", sd.sfp_temp[MCURR]); + PRINT_VCC("Module voltage", sd.sfp_voltage[MCURR]); + + printf("\t%-41s : %s\n", "Alarm/warning flags implemented", + (sd.supports_alarms ? "Yes" : "No")); + if (sd.supports_alarms) { + + for (i = 0; sff8472_aw_flags[i].str; ++i) { + printf("\t%-41s : %s\n", sff8472_aw_flags[i].str, + id[SFF_A2_BASE + sff8472_aw_flags[i].offset] + & sff8472_aw_flags[i].value ? "On" : "Off"); + } + sff_show_thresholds(sd); + } +} + diff --git a/sfpid.c b/sfpid.c new file mode 100644 index 0000000..1bc45c1 --- /dev/null +++ b/sfpid.c @@ -0,0 +1,505 @@ +/**************************************************************************** + * Support for Solarflare Solarstorm network controllers and boards + * Copyright 2010 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#include "internal.h" +#include "sff-common.h" +#include "netlink/extapi.h" + +#define SFF8079_PAGE_SIZE 0x80 +#define SFF8079_I2C_ADDRESS_LOW 0x50 +#define SFF8079_I2C_ADDRESS_HIGH 0x51 + +static void sff8079_show_identifier(const __u8 *id) +{ + sff8024_show_identifier(id, 0); +} + +static void sff8079_show_ext_identifier(const __u8 *id) +{ + printf("\t%-41s : 0x%02x", "Extended identifier", id[1]); + if (id[1] == 0x00) + printf(" (GBIC not specified / not MOD_DEF compliant)\n"); + else if (id[1] == 0x04) + printf(" (GBIC/SFP defined by 2-wire interface ID)\n"); + else if (id[1] <= 0x07) + printf(" (GBIC compliant with MOD_DEF %u)\n", id[1]); + else + printf(" (unknown)\n"); +} + +static void sff8079_show_connector(const __u8 *id) +{ + sff8024_show_connector(id, 2); +} + +static void sff8079_show_transceiver(const __u8 *id) +{ + static const char *pfx = + "\tTransceiver type :"; + + printf("\t%-41s : 0x%02x 0x%02x 0x%02x " \ + "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + "Transceiver codes", + id[3], id[4], id[5], id[6], + id[7], id[8], id[9], id[10], id[36]); + /* 10G Ethernet Compliance Codes */ + if (id[3] & (1 << 7)) + printf("%s 10G Ethernet: 10G Base-ER" \ + " [SFF-8472 rev10.4 onwards]\n", pfx); + if (id[3] & (1 << 6)) + printf("%s 10G Ethernet: 10G Base-LRM\n", pfx); + if (id[3] & (1 << 5)) + printf("%s 10G Ethernet: 10G Base-LR\n", pfx); + if (id[3] & (1 << 4)) + printf("%s 10G Ethernet: 10G Base-SR\n", pfx); + /* Infiniband Compliance Codes */ + if (id[3] & (1 << 3)) + printf("%s Infiniband: 1X SX\n", pfx); + if (id[3] & (1 << 2)) + printf("%s Infiniband: 1X LX\n", pfx); + if (id[3] & (1 << 1)) + printf("%s Infiniband: 1X Copper Active\n", pfx); + if (id[3] & (1 << 0)) + printf("%s Infiniband: 1X Copper Passive\n", pfx); + /* ESCON Compliance Codes */ + if (id[4] & (1 << 7)) + printf("%s ESCON: ESCON MMF, 1310nm LED\n", pfx); + if (id[4] & (1 << 6)) + printf("%s ESCON: ESCON SMF, 1310nm Laser\n", pfx); + /* SONET Compliance Codes */ + if (id[4] & (1 << 5)) + printf("%s SONET: OC-192, short reach\n", pfx); + if (id[4] & (1 << 4)) + printf("%s SONET: SONET reach specifier bit 1\n", pfx); + if (id[4] & (1 << 3)) + printf("%s SONET: SONET reach specifier bit 2\n", pfx); + if (id[4] & (1 << 2)) + printf("%s SONET: OC-48, long reach\n", pfx); + if (id[4] & (1 << 1)) + printf("%s SONET: OC-48, intermediate reach\n", pfx); + if (id[4] & (1 << 0)) + printf("%s SONET: OC-48, short reach\n", pfx); + if (id[5] & (1 << 6)) + printf("%s SONET: OC-12, single mode, long reach\n", pfx); + if (id[5] & (1 << 5)) + printf("%s SONET: OC-12, single mode, inter. reach\n", pfx); + if (id[5] & (1 << 4)) + printf("%s SONET: OC-12, short reach\n", pfx); + if (id[5] & (1 << 2)) + printf("%s SONET: OC-3, single mode, long reach\n", pfx); + if (id[5] & (1 << 1)) + printf("%s SONET: OC-3, single mode, inter. reach\n", pfx); + if (id[5] & (1 << 0)) + printf("%s SONET: OC-3, short reach\n", pfx); + /* Ethernet Compliance Codes */ + if (id[6] & (1 << 7)) + printf("%s Ethernet: BASE-PX\n", pfx); + if (id[6] & (1 << 6)) + printf("%s Ethernet: BASE-BX10\n", pfx); + if (id[6] & (1 << 5)) + printf("%s Ethernet: 100BASE-FX\n", pfx); + if (id[6] & (1 << 4)) + printf("%s Ethernet: 100BASE-LX/LX10\n", pfx); + if (id[6] & (1 << 3)) + printf("%s Ethernet: 1000BASE-T\n", pfx); + if (id[6] & (1 << 2)) + printf("%s Ethernet: 1000BASE-CX\n", pfx); + if (id[6] & (1 << 1)) + printf("%s Ethernet: 1000BASE-LX\n", pfx); + if (id[6] & (1 << 0)) + printf("%s Ethernet: 1000BASE-SX\n", pfx); + /* Fibre Channel link length */ + if (id[7] & (1 << 7)) + printf("%s FC: very long distance (V)\n", pfx); + if (id[7] & (1 << 6)) + printf("%s FC: short distance (S)\n", pfx); + if (id[7] & (1 << 5)) + printf("%s FC: intermediate distance (I)\n", pfx); + if (id[7] & (1 << 4)) + printf("%s FC: long distance (L)\n", pfx); + if (id[7] & (1 << 3)) + printf("%s FC: medium distance (M)\n", pfx); + /* Fibre Channel transmitter technology */ + if (id[7] & (1 << 2)) + printf("%s FC: Shortwave laser, linear Rx (SA)\n", pfx); + if (id[7] & (1 << 1)) + printf("%s FC: Longwave laser (LC)\n", pfx); + if (id[7] & (1 << 0)) + printf("%s FC: Electrical inter-enclosure (EL)\n", pfx); + if (id[8] & (1 << 7)) + printf("%s FC: Electrical intra-enclosure (EL)\n", pfx); + if (id[8] & (1 << 6)) + printf("%s FC: Shortwave laser w/o OFC (SN)\n", pfx); + if (id[8] & (1 << 5)) + printf("%s FC: Shortwave laser with OFC (SL)\n", pfx); + if (id[8] & (1 << 4)) + printf("%s FC: Longwave laser (LL)\n", pfx); + if (id[8] & (1 << 3)) + printf("%s Active Cable\n", pfx); + if (id[8] & (1 << 2)) + printf("%s Passive Cable\n", pfx); + if (id[8] & (1 << 1)) + printf("%s FC: Copper FC-BaseT\n", pfx); + /* Fibre Channel transmission media */ + if (id[9] & (1 << 7)) + printf("%s FC: Twin Axial Pair (TW)\n", pfx); + if (id[9] & (1 << 6)) + printf("%s FC: Twisted Pair (TP)\n", pfx); + if (id[9] & (1 << 5)) + printf("%s FC: Miniature Coax (MI)\n", pfx); + if (id[9] & (1 << 4)) + printf("%s FC: Video Coax (TV)\n", pfx); + if (id[9] & (1 << 3)) + printf("%s FC: Multimode, 62.5um (M6)\n", pfx); + if (id[9] & (1 << 2)) + printf("%s FC: Multimode, 50um (M5)\n", pfx); + if (id[9] & (1 << 0)) + printf("%s FC: Single Mode (SM)\n", pfx); + /* Fibre Channel speed */ + if (id[10] & (1 << 7)) + printf("%s FC: 1200 MBytes/sec\n", pfx); + if (id[10] & (1 << 6)) + printf("%s FC: 800 MBytes/sec\n", pfx); + if (id[10] & (1 << 4)) + printf("%s FC: 400 MBytes/sec\n", pfx); + if (id[10] & (1 << 2)) + printf("%s FC: 200 MBytes/sec\n", pfx); + if (id[10] & (1 << 0)) + printf("%s FC: 100 MBytes/sec\n", pfx); + /* Extended Specification Compliance Codes from SFF-8024 */ + if (id[36] == 0x1) + printf("%s Extended: 100G AOC or 25GAUI C2M AOC with worst BER of 5x10^(-5)\n", pfx); + if (id[36] == 0x2) + printf("%s Extended: 100G Base-SR4 or 25GBase-SR\n", pfx); + if (id[36] == 0x3) + printf("%s Extended: 100G Base-LR4 or 25GBase-LR\n", pfx); + if (id[36] == 0x4) + printf("%s Extended: 100G Base-ER4 or 25GBase-ER\n", pfx); + if (id[36] == 0x8) + printf("%s Extended: 100G ACC or 25GAUI C2M ACC with worst BER of 5x10^(-5)\n", pfx); + if (id[36] == 0xb) + printf("%s Extended: 100G Base-CR4 or 25G Base-CR CA-L\n", pfx); + if (id[36] == 0xc) + printf("%s Extended: 25G Base-CR CA-S\n", pfx); + if (id[36] == 0xd) + printf("%s Extended: 25G Base-CR CA-N\n", pfx); + if (id[36] == 0x16) + printf("%s Extended: 10Gbase-T with SFI electrical interface\n", pfx); + if (id[36] == 0x18) + printf("%s Extended: 100G AOC or 25GAUI C2M AOC with worst BER of 10^(-12)\n", pfx); + if (id[36] == 0x19) + printf("%s Extended: 100G ACC or 25GAUI C2M ACC with worst BER of 10^(-12)\n", pfx); + if (id[36] == 0x1a) + printf("%s Extended: 100GE-DWDM2 (DWDM transceiver using 2 wavelengths on a 1550 nm DWDM grid with a reach up to 80 km)\n", + pfx); + if (id[36] == 0x1b) + printf("%s Extended: 100G 1550nm WDM (4 wavelengths)\n", pfx); + if (id[36] == 0x1c) + printf("%s Extended: 10Gbase-T Short Reach\n", pfx); + if (id[36] == 0x1d) + printf("%s Extended: 5GBASE-T\n", pfx); + if (id[36] == 0x1e) + printf("%s Extended: 2.5GBASE-T\n", pfx); + if (id[36] == 0x1f) + printf("%s Extended: 40G SWDM4\n", pfx); + if (id[36] == 0x20) + printf("%s Extended: 100G SWDM4\n", pfx); + if (id[36] == 0x21) + printf("%s Extended: 100G PAM4 BiDi\n", pfx); + if (id[36] == 0x22) + printf("%s Extended: 4WDM-10 MSA (10km version of 100G CWDM4 with same RS(528,514) FEC in host system)\n", + pfx); + if (id[36] == 0x23) + printf("%s Extended: 4WDM-20 MSA (20km version of 100GBASE-LR4 with RS(528,514) FEC in host system)\n", + pfx); + if (id[36] == 0x24) + printf("%s Extended: 4WDM-40 MSA (40km reach with APD receiver and RS(528,514) FEC in host system)\n", + pfx); + if (id[36] == 0x25) + printf("%s Extended: 100GBASE-DR (clause 140), CAUI-4 (no FEC)\n", pfx); + if (id[36] == 0x26) + printf("%s Extended: 100G-FR or 100GBASE-FR1 (clause 140), CAUI-4 (no FEC)\n", pfx); + if (id[36] == 0x27) + printf("%s Extended: 100G-LR or 100GBASE-LR1 (clause 140), CAUI-4 (no FEC)\n", pfx); + if (id[36] == 0x30) + printf("%s Extended: Active Copper Cable with 50GAUI, 100GAUI-2 or 200GAUI-4 C2M. Providing a worst BER of 10-6 or below\n", + pfx); + if (id[36] == 0x31) + printf("%s Extended: Active Optical Cable with 50GAUI, 100GAUI-2 or 200GAUI-4 C2M. Providing a worst BER of 10-6 or below\n", + pfx); + if (id[36] == 0x32) + printf("%s Extended: Active Copper Cable with 50GAUI, 100GAUI-2 or 200GAUI-4 C2M. Providing a worst BER of 2.6x10-4 for ACC, 10-5 for AUI, or below\n", + pfx); + if (id[36] == 0x33) + printf("%s Extended: Active Optical Cable with 50GAUI, 100GAUI-2 or 200GAUI-4 C2M. Providing a worst BER of 2.6x10-4 for ACC, 10-5 for AUI, or below\n", + pfx); + if (id[36] == 0x40) + printf("%s Extended: 50GBASE-CR, 100GBASE-CR2, or 200GBASE-CR4\n", pfx); + if (id[36] == 0x41) + printf("%s Extended: 50GBASE-SR, 100GBASE-SR2, or 200GBASE-SR4\n", pfx); + if (id[36] == 0x42) + printf("%s Extended: 50GBASE-FR or 200GBASE-DR4\n", pfx); + if (id[36] == 0x43) + printf("%s Extended: 200GBASE-FR4\n", pfx); + if (id[36] == 0x44) + printf("%s Extended: 200G 1550 nm PSM4\n", pfx); + if (id[36] == 0x45) + printf("%s Extended: 50GBASE-LR\n", pfx); + if (id[36] == 0x46) + printf("%s Extended: 200GBASE-LR4\n", pfx); + if (id[36] == 0x50) + printf("%s Extended: 64GFC EA\n", pfx); + if (id[36] == 0x51) + printf("%s Extended: 64GFC SW\n", pfx); + if (id[36] == 0x52) + printf("%s Extended: 64GFC LW\n", pfx); + if (id[36] == 0x53) + printf("%s Extended: 128GFC EA\n", pfx); + if (id[36] == 0x54) + printf("%s Extended: 128GFC SW\n", pfx); + if (id[36] == 0x55) + printf("%s Extended: 128GFC LW\n", pfx); +} + +static void sff8079_show_encoding(const __u8 *id) +{ + sff8024_show_encoding(id, 11, ETH_MODULE_SFF_8472); +} + +static void sff8079_show_rate_identifier(const __u8 *id) +{ + printf("\t%-41s : 0x%02x", "Rate identifier", id[13]); + switch (id[13]) { + case 0x00: + printf(" (unspecified)\n"); + break; + case 0x01: + printf(" (4/2/1G Rate_Select & AS0/AS1)\n"); + break; + case 0x02: + printf(" (8/4/2G Rx Rate_Select only)\n"); + break; + case 0x03: + printf(" (8/4/2G Independent Rx & Tx Rate_Select)\n"); + break; + case 0x04: + printf(" (8/4/2G Tx Rate_Select only)\n"); + break; + default: + printf(" (reserved or unknown)\n"); + break; + } +} + +static void sff8079_show_oui(const __u8 *id) +{ + printf("\t%-41s : %02x:%02x:%02x\n", "Vendor OUI", + id[37], id[38], id[39]); +} + +static void sff8079_show_wavelength_or_copper_compliance(const __u8 *id) +{ + if (id[8] & (1 << 2)) { + printf("\t%-41s : 0x%02x", "Passive Cu cmplnce.", id[60]); + switch (id[60]) { + case 0x00: + printf(" (unspecified)"); + break; + case 0x01: + printf(" (SFF-8431 appendix E)"); + break; + default: + printf(" (unknown)"); + break; + } + printf(" [SFF-8472 rev10.4 only]\n"); + } else if (id[8] & (1 << 3)) { + printf("\t%-41s : 0x%02x", "Active Cu cmplnce.", id[60]); + switch (id[60]) { + case 0x00: + printf(" (unspecified)"); + break; + case 0x01: + printf(" (SFF-8431 appendix E)"); + break; + case 0x04: + printf(" (SFF-8431 limiting)"); + break; + default: + printf(" (unknown)"); + break; + } + printf(" [SFF-8472 rev10.4 only]\n"); + } else { + printf("\t%-41s : %unm\n", "Laser wavelength", + (id[60] << 8) | id[61]); + } +} + +static void sff8079_show_value_with_unit(const __u8 *id, unsigned int reg, + const char *name, unsigned int mult, + const char *unit) +{ + unsigned int val = id[reg]; + + printf("\t%-41s : %u%s\n", name, val * mult, unit); +} + +static void sff8079_show_ascii(const __u8 *id, unsigned int first_reg, + unsigned int last_reg, const char *name) +{ + unsigned int reg, val; + + printf("\t%-41s : ", name); + while (first_reg <= last_reg && id[last_reg] == ' ') + last_reg--; + for (reg = first_reg; reg <= last_reg; reg++) { + val = id[reg]; + putchar(((val >= 32) && (val <= 126)) ? val : '_'); + } + printf("\n"); +} + +static void sff8079_show_options(const __u8 *id) +{ + static const char *pfx = + "\tOption :"; + + printf("\t%-41s : 0x%02x 0x%02x\n", "Option values", id[64], id[65]); + if (id[65] & (1 << 1)) + printf("%s RX_LOS implemented\n", pfx); + if (id[65] & (1 << 2)) + printf("%s RX_LOS implemented, inverted\n", pfx); + if (id[65] & (1 << 3)) + printf("%s TX_FAULT implemented\n", pfx); + if (id[65] & (1 << 4)) + printf("%s TX_DISABLE implemented\n", pfx); + if (id[65] & (1 << 5)) + printf("%s RATE_SELECT implemented\n", pfx); + if (id[65] & (1 << 6)) + printf("%s Tunable transmitter technology\n", pfx); + if (id[65] & (1 << 7)) + printf("%s Receiver decision threshold implemented\n", pfx); + if (id[64] & (1 << 0)) + printf("%s Linear receiver output implemented\n", pfx); + if (id[64] & (1 << 1)) + printf("%s Power level 2 requirement\n", pfx); + if (id[64] & (1 << 2)) + printf("%s Cooled transceiver implemented\n", pfx); + if (id[64] & (1 << 3)) + printf("%s Retimer or CDR implemented\n", pfx); + if (id[64] & (1 << 4)) + printf("%s Paging implemented\n", pfx); + if (id[64] & (1 << 5)) + printf("%s Power level 3 requirement\n", pfx); +} + +static void sff8079_show_all_common(const __u8 *id) +{ + sff8079_show_identifier(id); + if (((id[0] == 0x02) || (id[0] == 0x03)) && (id[1] == 0x04)) { + unsigned int br_nom, br_min, br_max; + + if (id[12] == 0) { + br_nom = br_min = br_max = 0; + } else if (id[12] == 255) { + br_nom = id[66] * 250; + br_max = id[67]; + br_min = id[67]; + } else { + br_nom = id[12] * 100; + br_max = id[66]; + br_min = id[67]; + } + sff8079_show_ext_identifier(id); + sff8079_show_connector(id); + sff8079_show_transceiver(id); + sff8079_show_encoding(id); + printf("\t%-41s : %u%s\n", "BR, Nominal", br_nom, "MBd"); + sff8079_show_rate_identifier(id); + sff8079_show_value_with_unit(id, 14, + "Length (SMF,km)", 1, "km"); + sff8079_show_value_with_unit(id, 15, "Length (SMF)", 100, "m"); + sff8079_show_value_with_unit(id, 16, "Length (50um)", 10, "m"); + sff8079_show_value_with_unit(id, 17, + "Length (62.5um)", 10, "m"); + sff8079_show_value_with_unit(id, 18, "Length (Copper)", 1, "m"); + sff8079_show_value_with_unit(id, 19, "Length (OM3)", 10, "m"); + sff8079_show_wavelength_or_copper_compliance(id); + sff8079_show_ascii(id, 20, 35, "Vendor name"); + sff8079_show_oui(id); + sff8079_show_ascii(id, 40, 55, "Vendor PN"); + sff8079_show_ascii(id, 56, 59, "Vendor rev"); + sff8079_show_options(id); + printf("\t%-41s : %u%s\n", "BR margin, max", br_max, "%"); + printf("\t%-41s : %u%s\n", "BR margin, min", br_min, "%"); + sff8079_show_ascii(id, 68, 83, "Vendor SN"); + sff8079_show_ascii(id, 84, 91, "Date code"); + } +} + +void sff8079_show_all_ioctl(const __u8 *id) +{ + sff8079_show_all_common(id); +} + +static int sff8079_get_eeprom_page(struct cmd_context *ctx, u8 i2c_address, + __u8 *buf) +{ + struct ethtool_module_eeprom request = { + .length = SFF8079_PAGE_SIZE, + .i2c_address = i2c_address, + }; + int ret; + + ret = nl_get_eeprom_page(ctx, &request); + if (!ret) + memcpy(buf, request.data, SFF8079_PAGE_SIZE); + + return ret; +} + +int sff8079_show_all_nl(struct cmd_context *ctx) +{ + u8 *buf; + int ret; + + /* The SFF-8472 parser expects a single buffer that contains the + * concatenation of the first 256 bytes from addresses A0h and A2h, + * respectively. + */ + buf = calloc(1, ETH_MODULE_SFF_8472_LEN); + if (!buf) + return -ENOMEM; + + /* Read A0h page */ + ret = sff8079_get_eeprom_page(ctx, SFF8079_I2C_ADDRESS_LOW, buf); + if (ret) + goto out; + + sff8079_show_all_common(buf); + + /* Finish if A2h page is not present */ + if (!(buf[92] & (1 << 6))) + goto out; + + /* Read A2h page */ + ret = sff8079_get_eeprom_page(ctx, SFF8079_I2C_ADDRESS_HIGH, + buf + ETH_MODULE_SFF_8079_LEN); + if (ret) + goto out; + + sff8472_show_all(buf); +out: + free(buf); + + return ret; +} diff --git a/shell-completion/bash/ethtool b/shell-completion/bash/ethtool new file mode 100644 index 0000000..46334b5 --- /dev/null +++ b/shell-completion/bash/ethtool @@ -0,0 +1,1278 @@ +# bash completion for ethtool(8) -*- shell-script -*- +# shellcheck shell=bash disable=SC2207 + +# Complete a word representing a set of characters. +# @param $@ chars Characters which may be present in completed set. +_ethtool_compgen_letterset() +{ + local char + for char; do + case "$cur" in + *"$char"*) + # $cur already contains $char + ;; + *) + COMPREPLY+=( "$cur$char" ) + ;; + esac + done +} + +# Generate completions for words matched case-insensitively +# @param $@ choices Completion choices. +_ethtool_compgen_nocase() +{ + local reset + reset=$( shopt -p nocasematch ) + shopt -s nocasematch + + local choice + for choice; do + case "$choice" in + "$cur"*) COMPREPLY+=( "$choice" ) ;; + esac + done + + $reset +} + +# Gets names from a section of ethtool output. +# @param $1 section_bre POSIX BRE matching section heading (without : at end). +# @param $@ ethtool arguments +_ethtool_get_names_in_section() +{ + local section_bre="$1" + shift + + PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" \ + ethtool "$@" 2>/dev/null | + command sed -n " +# Line is section heading iff it ends with : +# From requested section heading to next section heading +/^$section_bre:$/,/:$/ { + # If line is section heading, ignore it + /:$/d + # Remove value and separator, if present + s/[[:space:]]*:.*// + # Remove leading space, if present + s/^[[:space:]]*// + # Print the line + p +}" +} + +# Complete an RSS Context ID +_ethtool_context() +{ + COMPREPLY=( + $(PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" \ + ethtool --show-nfc "${words[2]}" 2>/dev/null | + command sed -n 's/^[[:space:]]*RSS Context ID:[[:space:]]*\([0-9]*\)$/\1/p' | + sort -u) ) +} + +# Complete a network flow traffic type +# Available OPTIONS: +# --hash Complete only types suitable for rx hashing +_ethtool_flow_type() +{ + local types='ah4 ah6 esp4 esp6 ether sctp4 sctp6 tcp4 tcp6 udp4 udp6' + if [ "${1-}" != --hash ]; then + types="$types ip4 ip6" + fi + COMPREPLY=( $( compgen -W "$types" -- "$cur" ) ) +} + +# Completion for ethtool --change +_ethtool_change() +{ + local -A settings=( + [advertise]=notseen + [autoneg]=notseen + [duplex]=notseen + [mdix]=notseen + [msglvl]=notseen + [port]=notseen + [phyad]=notseen + [speed]=notseen + [wol]=notseen + [xcvr]=notseen + [lanes]=notseen + ) + + local -A msgtypes=( + [drv]=notseen + [hw]=notseen + [ifdown]=notseen + [ifup]=notseen + [intr]=notseen + [link]=notseen + [pktdata]=notseen + [probe]=notseen + [rx_err]=notseen + [rx_status]=notseen + [timer]=notseen + [tx_done]=notseen + [tx_err]=notseen + [tx_queued]=notseen + [wol]=notseen + ) + + # Mark seen settings and msgtypes, and whether in msglvl sub-command + local in_msglvl= + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + if [ "$in_msglvl" ] && [ "${msgtypes[$word]+set}" ]; then + msgtypes[$word]=seen + elif [ "${settings[$word]+set}" ]; then + settings[$word]=seen + if [ "$word" = msglvl ]; then + in_msglvl=1 + else + in_msglvl= + fi + fi + done + + if [ "$in_msglvl" ] && [ "${msgtypes[$prev]+set}" ]; then + # All msgtypes take an on/off argument + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return + fi + + case "$prev" in + advertise) + # Hex number + return ;; + autoneg) + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return ;; + duplex) + COMPREPLY=( $( compgen -W 'half full' -- "$cur" ) ) + return ;; + mdix) + COMPREPLY=( $( compgen -W 'auto on off' -- "$cur" ) ) + return ;; + msglvl) + # Unsigned integer or msgtype + COMPREPLY=( $( compgen -W "${!msgtypes[*]}" -- "$cur" ) ) + return ;; + port) + COMPREPLY=( $( compgen -W 'aui bnc fibre mii tp' -- "$cur" ) ) + return ;; + phyad) + # Integer + return ;; + sopass) + _mac_addresses + return ;; + speed) + # Number + return ;; + wol) + # $cur is a set of wol type characters. + _ethtool_compgen_letterset p u m b a g s f d + return ;; + xcvr) + COMPREPLY=( $( compgen -W 'internal external' -- "$cur" ) ) + return ;; + lanes) + # Number + return ;; + esac + + local -a comp_words=() + + # Add settings not seen to completions + local setting + for setting in "${!settings[@]}"; do + if [ "${settings[$setting]}" = notseen ]; then + comp_words+=( "$setting" ) + fi + done + + # Add settings not seen to completions + if [ "$in_msglvl" ]; then + local msgtype + for msgtype in "${!msgtypes[@]}"; do + if [ "${msgtypes[$msgtype]}" = notseen ]; then + comp_words+=( "$msgtype" ) + fi + done + fi + + COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --change-eeprom +_ethtool_change_eeprom() +{ + local -A settings=( + [length]=1 + [magic]=1 + [offset]=1 + [value]=1 + ) + + if [ "${settings[$prev]+set}" ]; then + # All settings take an unsigned integer argument + return + fi + + # Remove settings which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "settings[$word]" + done + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --coalesce +_ethtool_coalesce() +{ + local -A settings=( + [adaptive-rx]=1 + [adaptive-tx]=1 + [pkt-rate-high]=1 + [pkt-rate-low]=1 + [rx-frames]=1 + [rx-frames-high]=1 + [rx-frames-irq]=1 + [rx-frames-low]=1 + [rx-usecs]=1 + [rx-usecs-high]=1 + [rx-usecs-irq]=1 + [rx-usecs-low]=1 + [sample-interval]=1 + [stats-block-usecs]=1 + [tx-frames]=1 + [tx-frames-high]=1 + [tx-frames-irq]=1 + [tx-frames-low]=1 + [tx-usecs]=1 + [tx-usecs-high]=1 + [tx-usecs-irq]=1 + [tx-usecs-low]=1 + ) + + case "$prev" in + adaptive-rx|\ + adaptive-tx) + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return ;; + esac + + if [ "${settings[$prev]+set}" ]; then + # Unsigned integer + return + fi + + # Remove settings which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "settings[$word]" + done + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --config-nfc flow-type +_ethtool_config_nfc_flow_type() +{ + if [ "$cword" -eq 4 ]; then + _ethtool_flow_type --spec + return + fi + + case "$prev" in + context) + _ethtool_context + return ;; + dst|\ + dst-mac|\ + src) + # TODO: Complete only local for dst and remote for src + _mac_addresses + return ;; + dst-ip) + # Note: RX classification, so dst is usually local + case "${words[4]}" in + *4) _ip_addresses -4 return ;; + *6) _ip_addresses -6 return ;; + esac + return ;; + src-ip) + # Note: RX classification, so src is usually remote + # TODO: Remote IP addresses (ARP cache + /etc/hosts + ?) + return ;; + m|\ + *-mask) + # MAC, IP, or integer bitmask + return ;; + esac + + local -A settings=( + [action]=1 + [context]=1 + [loc]=1 + [queue]=1 + [vf]=1 + ) + + if [ "${settings[$prev]+set}" ]; then + # Integer + return + fi + + case "${words[4]}" in + ah4|\ + esp4) + local -A fields=( + [dst-ip]=1 + [dst-mac]=1 + [spi]=1 + [src-ip]=1 + [tos]=1 + [user-def]=1 + [vlan-etype]=1 + [vlan]=1 + ) + ;; + ah6|\ + esp6) + local -A fields=( + [dst-ip]=1 + [dst-mac]=1 + [spi]=1 + [src-ip]=1 + [tclass]=1 + [user-def]=1 + [vlan-etype]=1 + [vlan]=1 + ) + ;; + ether) + local -A fields=( + [dst]=1 + [proto]=1 + [src]=1 + [user-def]=1 + [vlan-etype]=1 + [vlan]=1 + ) + ;; + ip4) + local -A fields=( + [dst-ip]=1 + [dst-mac]=1 + [dst-port]=1 + [l4data]=1 + [l4proto]=1 + [spi]=1 + [src-ip]=1 + [src-port]=1 + [tos]=1 + [user-def]=1 + [vlan-etype]=1 + [vlan]=1 + ) + ;; + ip6) + local -A fields=( + [dst-ip]=1 + [dst-mac]=1 + [dst-port]=1 + [l4data]=1 + [l4proto]=1 + [spi]=1 + [src-ip]=1 + [src-port]=1 + [tclass]=1 + [user-def]=1 + [vlan-etype]=1 + [vlan]=1 + ) + ;; + sctp4|\ + tcp4|\ + udp4) + local -A fields=( + [dst-ip]=1 + [dst-mac]=1 + [dst-port]=1 + [src-ip]=1 + [src-port]=1 + [tos]=1 + [user-def]=1 + [vlan-etype]=1 + [vlan]=1 + ) + ;; + sctp6|\ + tcp6|\ + udp6) + local -A fields=( + [dst-ip]=1 + [dst-mac]=1 + [dst-port]=1 + [src-ip]=1 + [src-port]=1 + [tclass]=1 + [user-def]=1 + [vlan-etype]=1 + [vlan]=1 + ) + ;; + *) + return ;; + esac + + if [ "${fields[$prev]+set}" ]; then + # Integer + return + fi + + # If the previous 2 words were a field+value, suggest a mask + local mask= + if [ "${fields[${words[$cword-2]}]+set}" ]; then + mask="m ${words[$cword-2]}-mask" + fi + + # Remove fields and settings which have been seen + local word + for word in "${words[@]:5:${#words[@]}-6}"; do + unset "fields[$word]" "settings[$word]" + done + + # Remove mutually-exclusive options + if ! [ "${settings[action]+set}" ]; then + unset 'settings[queue]' 'settings[vf]' + fi + if ! [ "${settings[queue]+set}" ]; then + unset 'settings[action]' + fi + if ! [ "${settings[vf]+set}" ]; then + unset 'settings[action]' + fi + + COMPREPLY=( $( compgen -W "$mask ${!fields[*]} ${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --config-nfc +_ethtool_config_nfc() +{ + if [ "$cword" -eq 3 ]; then + COMPREPLY=( $( compgen -W 'delete flow-type rx-flow-hash' -- "$cur" ) ) + return + fi + + case "${words[3]}" in + delete) + # Unsigned integer + return ;; + flow-type) + _ethtool_config_nfc_flow_type + return ;; + rx-flow-hash) + case "$cword" in + 4) + _ethtool_flow_type --hash + return ;; + 5) + _ethtool_compgen_letterset m v t s d f n r + return ;; + 6) + COMPREPLY=( $( compgen -W context -- "$cur" ) ) + return ;; + 7) + _ethtool_context + return ;; + esac + return ;; + esac +} + +# Completion for ethtool --eeprom-dump +_ethtool_eeprom_dump() +{ + local -A settings=( + [length]=1 + [offset]=1 + [raw]=1 + ) + + if [ "$prev" = raw ]; then + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return + fi + + if [ "${settings[$prev]+set}" ]; then + # Unsigned integer argument + return + fi + + # Remove settings which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "settings[$word]" + done + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --features +_ethtool_features() +{ + local -A abbreviations=( + [generic-receive-offload]=gro + [generic-segmentation-offload]=gso + [large-receive-offload]=lro + [ntuple-filters]=ntuple + [receive-hashing]=rxhash + [rx-checksumming]=rx + [rx-vlan-offload]=rxvlan + [scatter-gather]=sg + [tcp-segmentation-offload]=tso + [tx-checksumming]=tx + [tx-vlan-offload]=txvlan + [udp-fragmentation-offload]=ufo + ) + + local -A features=() + local feature status fixed + # shellcheck disable=SC2034 + while read -r feature status fixed; do + if [ -z "$feature" ]; then + # Ignore blank line from empty expansion in here-document + continue + fi + + if [ "$feature" = Features ]; then + # Ignore heading + continue + fi + + if [ "$fixed" = '[fixed]' ]; then + # Fixed features can't be changed + continue + fi + + feature=${feature%:} + if [ "${abbreviations[$feature]+set}" ]; then + features[${abbreviations[$feature]}]=1 + else + features[$feature]=1 + fi + done </dev/null) +ETHTOOL_FEATURES + + if [ "${features[$prev]+set}" ]; then + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return + fi + + # Remove features which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "features[$word]" + done + + COMPREPLY=( $( compgen -W "${!features[*]}" -- "$cur" ) ) +} + +# Complete the current word as a kernel firmware file (for request_firmware) +# See https://www.kernel.org/doc/html/latest/driver-api/firmware/core.html +_ethtool_firmware() +{ + local -a firmware_paths=( + /lib/firmware/updates/ + /lib/firmware/ + ) + + local release + if release=$( uname -r 2>/dev/null ); then + firmware_paths+=( + "/lib/firmware/updates/$release/" + "/lib/firmware/$release/" + ) + fi + + local fw_path_para + if fw_path_para=$( cat /sys/module/firmware_class/parameters/path 2>/dev/null ) \ + && [ -n "$fw_path_para" ]; then + firmware_paths+=( "$fw_path_para" ) + fi + + local -A firmware_files=() + + local firmware_path + for firmware_path in "${firmware_paths[@]}"; do + local firmware_file + for firmware_file in "$firmware_path"*; do + if [ -f "$firmware_file" ]; then + firmware_files[${firmware_file##*/}]=1 + fi + done + done + + local IFS=' +' + COMPREPLY=( $( compgen -W "${!firmware_files[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --flash +_ethtool_flash() +{ + if [ "$cword" -eq 3 ]; then + _ethtool_firmware + return + fi +} + +# Completion for ethtool --get-dump +_ethtool_get_dump() +{ + case "$cword" in + 3) + COMPREPLY=( $( compgen -W data -- "$cur" ) ) + return ;; + 4) + # Output filename + local IFS=' +' + COMPREPLY=( $( compgen -f -- "$cur" ) ) + return ;; + esac +} + +# Completion for ethtool --get-phy-tunable +_ethtool_get_phy_tunable() +{ + if [ "$cword" -eq 3 ]; then + COMPREPLY=( $( compgen -W downshift -- "$cur" ) ) + return + fi +} + +# Completion for ethtool --module-info +_ethtool_module_info() +{ + local -A settings=( + [hex]=1 + [length]=1 + [offset]=1 + [raw]=1 + ) + + case "$prev" in + hex|\ + raw) + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return ;; + esac + + if [ "${settings[$prev]+set}" ]; then + # Unsigned integer argument + return + fi + + # Remove settings which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "settings[$word]" + done + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --pause +_ethtool_pause() +{ + local -A settings=( + [autoneg]=1 + [rx]=1 + [tx]=1 + ) + + if [ "${settings[$prev]+set}" ]; then + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return + fi + + # Remove settings which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "settings[$word]" + done + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --per-queue +_ethtool_per_queue() +{ + local -a subcommands=( + --coalesce + --show-coalesce + ) + + if [ "$cword" -eq 3 ]; then + COMPREPLY=( $( compgen -W "queue_mask ${subcommands[*]}" -- "$cur" ) ) + return + fi + + local sc_start=3 + if [ "${words[3]}" = queue_mask ] ; then + case "$cword" in + 4) + # Hex number + return ;; + 5) + COMPREPLY=( $( compgen -W "${subcommands[*]}" -- "$cur" ) ) + return ;; + esac + + sc_start=5 + fi + + case "${words[$sc_start]}" in + --coalesce) + # Remove --per-queue args to match normal --coalesce invocation + local words=( + "${words[0]}" + --coalesce + "${words[2]}" + "${words[@]:$sc_start+1:${#words[@]}-$sc_start-1}" + ) + _ethtool_coalesce + return ;; + --show-coalesce) + # No args + return ;; + esac +} + +# Completion for ethtool --register-dump +_ethtool_register_dump() +{ + local -A settings=( + [file]=1 + [hex]=1 + [raw]=1 + ) + + case "$prev" in + hex|\ + raw) + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return ;; + file) + local IFS=' +' + COMPREPLY=( $( compgen -f -- "$cur" ) ) + return ;; + esac + + # Remove settings which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "settings[$word]" + done + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --reset +_ethtool_reset() +{ + if [ "$prev" = flags ]; then + # Unsigned integer + return + fi + + local -A flag_names=( + [ap]=1 + [dma]=1 + [filter]=1 + [irq]=1 + [mac]=1 + [mgmt]=1 + [offload]=1 + [phy]=1 + [ram]=1 + ) + + local -A all_flag_names=() + local flag_name + for flag_name in "${!flag_names[@]}"; do + all_flag_names[$flag_name]=1 + all_flag_names[$flag_name-shared]=1 + done + + # Remove all_flag_names which have been seen + local any_dedicated= + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + case "$word" in + all) + # Flags are always additive. + # Nothing to add after "all". + return ;; + dedicated) + any_dedicated=1 + # "dedicated" sets all non-shared flags + for flag_name in "${!flag_names[@]}"; do + unset "all_flag_names[$flag_name]" + done + continue ;; + esac + + if [ "${flag_names[$word]+set}" ]; then + any_dedicated=1 + fi + + unset "all_flag_names[$word]" + done + + COMPREPLY=( $( compgen -W "${!all_flag_names[*]}" -- "$cur" ) ) + + # Although it is permitted to mix named and un-named flags or duplicate + # flags with "all" or "dedicated", it's not likely intentional. + # Reconsider if a real use-case (or good consistency argument) is found. + if [ "$cword" -eq 3 ]; then + COMPREPLY+=( all dedicated flags ) + elif [ -z "$any_dedicated" ]; then + COMPREPLY+=( dedicated ) + fi +} + +# Completion for ethtool --rxfh +_ethtool_rxfh() +{ + local -A settings=( + [context]=1 + [default]=1 + [delete]=1 + [equal]=1 + [hfunc]=1 + [hkey]=1 + [weight]=1 + ) + + case "$prev" in + context) + _ethtool_context + # "new" to create a new context + COMPREPLY+=( new ) + return ;; + equal) + # Positive integer + return ;; + hfunc) + # Complete available RSS hash functions + COMPREPLY=( + $(_ethtool_get_names_in_section 'RSS hash function' \ + --show-rxfh "${words[2]}") + ) + return ;; + hkey) + # Pairs of hex digits separated by : + return ;; + weight) + # Non-negative integer + return ;; + esac + + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + # Remove settings which have been seen + unset "settings[$word]" + + # Remove settings which are mutually-exclusive with seen settings + case "$word" in + context) + unset 'settings[default]' + ;; + default) + unset \ + 'settings[context]' \ + 'settings[delete]' \ + 'settings[equal]' \ + 'settings[weight]' + ;; + delete) + unset \ + 'settings[default]' \ + 'settings[equal]' \ + 'settings[hkey]' \ + 'settings[weight]' + ;; + equal) + unset \ + 'settings[default]' \ + 'settings[delete]' \ + 'settings[weight]' + ;; + hkey) + unset 'settings[delete]' + ;; + weight) + unset \ + 'settings[default]' \ + 'settings[delete]' \ + 'settings[equal]' + ;; + esac + done + + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --set-channels +_ethtool_set_channels() +{ + local -A settings=( + [combined]=1 + [other]=1 + [rx]=1 + [tx]=1 + ) + + if [ "${settings[$prev]+set}" ]; then + # Unsigned integer argument + return + fi + + # Remove settings which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "settings[$word]" + done + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --set-eee +_ethtool_set_eee() +{ + local -A settings=( + [advertise]=1 + [eee]=1 + [tx-lpi]=1 + [tx-timer]=1 + ) + + case "$prev" in + advertise|\ + tx-timer) + # Unsigned integer + return ;; + eee|\ + tx-lpi) + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return ;; + esac + + # Remove settings which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "settings[$word]" + done + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Completion for ethtool --set-fec +_ethtool_set_fec() +{ + if [ "$cword" -eq 3 ]; then + COMPREPLY=( $( compgen -W encoding -- "$cur" ) ) + return + fi + + local -A modes=( + [auto]=auto + [rs]=RS + [off]=off + [baser]=BaseR + ) + + # Remove modes which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + # ethtool recognizes modes case-insensitively + unset "modes[${word,,}]" + done + + _ethtool_compgen_nocase "${modes[@]}" +} + +# Completion for ethtool --set-phy-tunable +_ethtool_set_phy_tunable() +{ + case "$cword" in + 3) + COMPREPLY=( $( compgen -W downshift -- "$cur" ) ) + return ;; + 4) + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return ;; + 5) + COMPREPLY=( $( compgen -W count -- "$cur" ) ) + return ;; + esac +} + +# Completion for ethtool --set-priv-flags +_ethtool_set_priv_flags() +{ + if [ $(( cword % 2 )) -eq 0 ]; then + COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) + return + fi + + # Get available private flags + local -A flags=() + local flag + while IFS= read -r flag; do + # Ignore blank line from empty here-document + if [ -n "$flag" ]; then + flags[$flag]=1 + fi + done </dev/null | + command sed -n 's/^Filter:[[:space:]]*\([0-9]*\)$/\1/p') + ) + fi + return ;; + rx-flow-hash) + case "$cword" in + 4) + _ethtool_flow_type --hash + return ;; + 5) + COMPREPLY=( $( compgen -W context -- "$cur" ) ) + return ;; + 6) + _ethtool_context + return ;; + esac + ;; + esac +} + +# Completion for ethtool --show-rxfh +_ethtool_show_rxfh() +{ + case "$cword" in + 3) + COMPREPLY=( $( compgen -W context -- "$cur" ) ) + return ;; + 4) + _ethtool_context + return ;; + esac +} + +# Completion for ethtool --test +_ethtool_test() +{ + if [ "$cword" -eq 3 ]; then + COMPREPLY=( $( compgen -W 'external_lb offline online' -- "$cur" ) ) + return + fi +} + +# Completion for ethtool --set-module +_ethtool_set_module() +{ + local -A settings=( + [power-mode-policy]=1 + ) + + case "$prev" in + power-mode-policy) + COMPREPLY=( $( compgen -W 'high auto' -- "$cur" ) ) + return ;; + esac + + # Remove settings which have been seen + local word + for word in "${words[@]:3:${#words[@]}-4}"; do + unset "settings[$word]" + done + + COMPREPLY=( $( compgen -W "${!settings[*]}" -- "$cur" ) ) +} + +# Complete any ethtool command +_ethtool() +{ + local cur prev words cword + _init_completion || return + + # Per "Contributing to bash-completion", complete non-duplicate long opts + local -A suggested_funcs=( + [--change-eeprom]=change_eeprom + [--change]=change + [--coalesce]=coalesce + [--config-nfc]=config_nfc + [--driver]=devname + [--dump-module-eeprom]=module_info + [--eeprom-dump]=eeprom_dump + [--features]=features + [--flash]=flash + [--get-dump]=get_dump + [--get-phy-tunable]=get_phy_tunable + [--identify]=devname + [--module-info]=module_info + [--negotiate]=devname + [--offload]=features + [--pause]=pause + [--per-queue]=per_queue + [--phy-statistics]=devname + [--register-dump]=register_dump + [--reset]=reset + [--set-channels]=set_channels + [--set-dump]=devname + [--set-eee]=set_eee + [--set-fec]=set_fec + [--set-phy-tunable]=set_phy_tunable + [--set-priv-flags]=set_priv_flags + [--set-ring]=set_ring + [--set-rxfh-indir]=rxfh + [--show-channels]=devname + [--show-coalesce]=devname + [--show-eee]=devname + [--show-features]=devname + [--show-fec]=devname + [--show-nfc]=show_nfc + [--show-offload]=devname + [--show-pause]=devname + [--show-permaddr]=devname + [--show-priv-flags]=devname + [--show-ring]=devname + [--show-rxfh]=show_rxfh + [--show-time-stamping]=devname + [--statistics]=devname + [--test]=test + [--set-module]=set_module + [--show-module]=devname + ) + local -A other_funcs=( + [--config-ntuple]=config_nfc + [--rxfh]=rxfh + [--show-ntuple]=show_nfc + [--show-rxfh-indir]=devname + [-A]=pause + [-C]=coalesce + [-E]=change_eeprom + [-G]=set_ring + [-K]=features + [-L]=set_channels + [-N]=config_nfc + [-P]=devname + [-Q]=per_queue + [-S]=devname + [-T]=devname + [-U]=config_nfc + [-W]=devname + [-X]=rxfh + [-a]=devname + [-c]=devname + [-d]=register_dump + [-e]=eeprom_dump + [-f]=flash + [-g]=devname + [-i]=devname + [-k]=devname + [-l]=devname + [-m]=module_info + [-n]=show_nfc + [-p]=devname + [-r]=devname + [-s]=change + [-t]=test + [-u]=show_nfc + [-w]=get_dump + [-x]=devname + ) + + if [ "$cword" -le 1 ]; then + _available_interfaces + COMPREPLY+=( + $( compgen -W "--help --version ${!suggested_funcs[*]}" -- "$cur" ) + ) + return + fi + + local func=${suggested_funcs[${words[1]}]-${other_funcs[${words[1]}]-}} + if [ "$func" ]; then + # All sub-commands have devname as their first argument + if [ "$cword" -eq 2 ]; then + _available_interfaces + return + fi + + if [ "$func" != devname ]; then + "_ethtool_$func" + fi + fi +} && +complete -F _ethtool ethtool + +# ex: filetype=sh sts=8 sw=8 ts=8 noet diff --git a/smsc911x.c b/smsc911x.c new file mode 100644 index 0000000..b643504 --- /dev/null +++ b/smsc911x.c @@ -0,0 +1,91 @@ +#include +#include +#include "internal.h" + +int smsc911x_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + unsigned int *smsc_reg = (unsigned int *)regs->data; + + fprintf(stdout, "LAN911x Registers\n"); + fprintf(stdout, "offset 0x50, ID_REV = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x54, INT_CFG = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x58, INT_STS = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x5C, INT_EN = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x60, RESERVED = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x64, BYTE_TEST = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x68, FIFO_INT = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x6C, RX_CFG = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x70, TX_CFG = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x74, HW_CFG = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x78, RX_DP_CTRL = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x7C, RX_FIFO_INF = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x80, TX_FIFO_INF = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x84, PMT_CTRL = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x88, GPIO_CFG = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x8C, GPT_CFG = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x90, GPT_CNT = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x94, FPGA_REV = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x98, ENDIAN = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0x9C, FREE_RUN = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0xA0, RX_DROP = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0xA4, MAC_CSR_CMD = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0xA8, MAC_CSR_DATA = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0xAC, AFC_CFG = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0xB0, E2P_CMD = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "offset 0xB4, E2P_DATA = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "\n"); + + fprintf(stdout, "MAC Registers\n"); + fprintf(stdout, "index 1, MAC_CR = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index 2, ADDRH = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index 3, ADDRL = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index 4, HASHH = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index 5, HASHL = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index 6, MII_ACC = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index 7, MII_DATA = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index 8, FLOW = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index 9, VLAN1 = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index A, VLAN2 = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index B, WUFF = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "index C, WUCSR = 0x%08X\n",*smsc_reg++); + fprintf(stdout, "\n"); + + fprintf(stdout, "PHY Registers\n"); + fprintf(stdout, "index 0, Basic Control Reg = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 1, Basic Status Reg = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 2, PHY identifier 1 = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 3, PHY identifier 2 = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 4, Auto Negotiation Advertisement Reg = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 5, Auto Negotiation Link Partner Ability Reg = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 6, Auto Negotiation Expansion Register = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 7, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 8, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 9, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 10, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 11, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 12, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 13, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 14, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 15, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 16, Silicon Revision Reg = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 17, Mode Control/Status Reg = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 18, Special Modes = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 19, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 20, TSTCNTL = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 21, TSTREAD1 = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 22, TSTREAD2 = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 23, TSTWRITE = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 24, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 25, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 26, Reserved = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 27, Control/Status Indication = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 28, Special internal testability = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 29, Interrupt Source Register = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 30, Interrupt Mask Register = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "index 31, PHY Special Control/Status Register = 0x%04X\n",*smsc_reg++); + fprintf(stdout, "\n"); + + return 0; +} + diff --git a/stmmac.c b/stmmac.c new file mode 100644 index 0000000..5847120 --- /dev/null +++ b/stmmac.c @@ -0,0 +1,71 @@ +/**************************************************************************** + * Support for the Synopsys MAC 10/100/1000 on-chip Ethernet controllers + * + * Copyright (C) 2007-2009 STMicroelectronics Ltd + * + * Author: Giuseppe Cavallaro + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#include "internal.h" + +#define MAC100_DMA_REG_NUM 9 +#define GMAC_REG_NUM 55 +#define GMAC_DMA_REG_NUM 23 + +int st_mac100_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + int i; + unsigned int *stmmac_reg = (unsigned int *)regs->data; + + fprintf(stdout, "ST MAC 10/100 Registers\n"); + fprintf(stdout, "control reg 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "addr HI 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "addr LO 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "multicast hash HI 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "multicast hash LO 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "MII addr 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "MII data %08X\n", *stmmac_reg++); + fprintf(stdout, "flow control 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "VLAN1 tag 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "VLAN2 tag 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "mac wakeup frame 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "mac wakeup crtl 0x%08X\n", *stmmac_reg++); + + fprintf(stdout, "\n"); + fprintf(stdout, "DMA Registers\n"); + for (i = 0; i < MAC100_DMA_REG_NUM; i++) + fprintf(stdout, "CSR%d 0x%08X\n", i, *stmmac_reg++); + + fprintf(stdout, "DMA cur tx buf addr 0x%08X\n", *stmmac_reg++); + fprintf(stdout, "DMA cur rx buf addr 0x%08X\n", *stmmac_reg++); + + fprintf(stdout, "\n"); + + return 0; +} + +int st_gmac_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + int i; + unsigned int *stmmac_reg = (unsigned int *)regs->data; + + fprintf(stdout, "ST GMAC Registers\n"); + fprintf(stdout, "GMAC Registers\n"); + for (i = 0; i < GMAC_REG_NUM; i++) + fprintf(stdout, "Reg%d 0x%08X\n", i, *stmmac_reg++); + + fprintf(stdout, "\n"); + fprintf(stdout, "DMA Registers\n"); + for (i = 0; i < GMAC_DMA_REG_NUM; i++) + fprintf(stdout, "Reg%d 0x%08X\n", i, *stmmac_reg++); + + return 0; +} diff --git a/test-cmdline.c b/test-cmdline.c new file mode 100644 index 0000000..cb803ed --- /dev/null +++ b/test-cmdline.c @@ -0,0 +1,340 @@ +/**************************************************************************** + * Test cases for ethtool command-line parsing + * Copyright 2011 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#define TEST_NO_WRAPPERS +#include "internal.h" + +#ifdef ETHTOOL_ENABLE_NETLINK +#define IS_NL 1 +#else +#define IS_NL 0 +#endif + +static struct test_case { + int rc; + const char *args; +} test_cases[] = { + { 1, "" }, + { 0, "devname" }, + { 0, "15_char_devname" }, + /* netlink interface allows names up to 127 characters */ + { !IS_NL, "16_char_devname!" }, + { !IS_NL, "127_char_devname0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde" }, + { 1, "128_char_devname0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" }, + /* Argument parsing for -s is specialised */ + { 0, "-s devname" }, + { 0, "--change devname speed 100 duplex half mdix auto" }, + { 1, "-s devname speed foo" }, + { 1, "--change devname speed" }, + { 0, "-s devname duplex half" }, + { 1, "--change devname duplex foo" }, + { 1, "-s devname duplex" }, + { 1, "--change devname mdix foo" }, + { 1, "-s devname mdix" }, + { 0, "--change devname port tp" }, + { 1, "-s devname port foo" }, + { 1, "--change devname port" }, + { 0, "-s devname autoneg on" }, + { 1, "--change devname autoneg foo" }, + { 1, "-s devname autoneg" }, + { 0, "--change devname advertise 0x1" }, + { 0, "--change devname advertise 0xf" }, + { 0, "--change devname advertise 0Xf" }, + { 0, "--change devname advertise 1" }, + { 0, "--change devname advertise f" }, + { 0, "--change devname advertise 01" }, + { 0, "--change devname advertise 0f" }, + { 0, "--change devname advertise 0xfffffffffffffffffffffffffffffffff" }, + { 0, "--change devname advertise fffffffffffffffffffffffffffffffff" }, + { 0, "--change devname advertise 0x0000fffffffffffffffffffffffffffff" }, + { 0, "--change devname advertise 0000fffffffffffffffffffffffffffff" }, + { 1, "-s devname advertise" }, + { 1, "-s devname advertise 0x" }, + { 1, "-s devname advertise foo" }, + { 1, "-s devname advertise 0xfoo" }, + { 1, "--change devname advertise" }, + { 0, "-s devname phyad 1" }, + { 1, "--change devname phyad foo" }, + { 1, "-s devname phyad" }, + /* Deprecated 'xcvr' detected by netlink parser */ + { IS_NL, "--change devname xcvr external" }, + { 1, "-s devname xcvr foo" }, + { 1, "--change devname xcvr" }, + { 0, "-s devname wol p" }, + { 1, "--change devname wol" }, + { 0, "-s devname sopass 01:23:45:67:89:ab" }, + { 1, "--change devname sopass 01:23:45:67:89:" }, + { 1, "-s devname sopass 01:23:45:67:89" }, + { 1, "--change devname sopass" }, + { 0, "-s devname msglvl 1" }, + { 1, "--change devname msglvl" }, + { 0, "-s devname msglvl hw on rx_status off" }, + { 1, "--change devname msglvl hw foo" }, + { 1, "-s devname msglvl hw" }, + { 0, "--change devname speed 100 duplex half port tp autoneg on advertise 0x1 phyad 1 wol p sopass 01:23:45:67:89:ab msglvl 1" }, + /* Deprecated 'xcvr' detected by netlink parser */ + { IS_NL, "--change devname speed 100 duplex half port tp autoneg on advertise 0x1 phyad 1 xcvr external wol p sopass 01:23:45:67:89:ab msglvl 1" }, + { 1, "-s devname foo" }, + { 1, "-s" }, + { 0, "-a devname" }, + { 0, "--show-pause devname" }, + { 1, "-a" }, + /* Many other sub-commands use parse_generic_cmdline() and + * don't need to be check in that much detail. */ + { 0, "-A devname autoneg on" }, + { 1, "--pause devname autoneg foo" }, + { 1, "-A devname autoneg" }, + { 0, "--pause devname rx off" }, + { 0, "-A devname tx on rx on autoneg off" }, + { 1, "--pause devname foo on" }, + { 1, "-A" }, + { 0, "-c devname" }, + { 0, "--show-coalesce devname" }, + { 0, "-C devname adaptive-rx on adaptive-tx off rx-usecs 1 rx-frames 2 rx-usecs-irq 3 rx-frames-irq 4 tx-usecs 5 tx-frames 6 tx-usecs-irq 7 tx-frames-irq 8 stats-block-usecs 9 pkt-rate-low 10" }, + { 0, "--coalesce devname rx-usecs-low 11 rx-frames-low 12 tx-usecs-low 13 tx-frames-low 14 pkt-rate-high 15 rx-usecs-high 16 rx-frames-high 17 tx-usecs-high 18 tx-frames-high 19 sample-interval 20" }, + { 1, "-C devname adaptive-rx foo" }, + { 1, "--coalesce devname adaptive-rx" }, + { 1, "-C devname foo on" }, + { 1, "-C" }, + { 0, "-g devname" }, + { 0, "--show-ring devname" }, + { 1, "-g" }, + { 0, "-G devname rx 1 rx-mini 2 rx-jumbo 3 tx 4" }, + { 0, "--set-ring devname rx 1 rx-mini 2 rx-jumbo 3 tx 4" }, + { 1, "-G devname rx foo" }, + { 1, "--set-ring devname rx" }, + { 1, "-G devname foo 1" }, + { 1, "-G" }, + { 1, "-k" }, + { 1, "-K" }, + { 0, "-i devname" }, + { 0, "--driver devname" }, + { 1, "-i" }, + { 0, "-d devname" }, + { 0, "--register-dump devname raw on file foo" }, + { 1, "-d devname raw foo" }, + { 1, "--register-dump devname file" }, + { 1, "-d devname foo" }, + { 1, "-d" }, + { 0, "-e devname" }, + { 0, "--eeprom-dump devname raw on offset 1 length 2" }, + { 1, "-e devname raw foo" }, + { 1, "--eeprom-dump devname offset foo" }, + { 1, "-e devname length" }, + { 1, "--eeprom-dump devname foo" }, + { 1, "-e" }, + { 0, "-E devname" }, + { 0, "--change-eeprom devname magic 0x87654321 offset 0 value 1" }, + { 0, "-E devname magic 0x87654321 offset 0 length 2" }, + { 1, "-E" }, + { 0, "-r devname" }, + { 0, "--negotiate devname" }, + { 1, "-r" }, + { 0, "-p devname" }, + { 0, "--identify devname 1" }, + { 1, "-p devname 1 foo" }, + { 1, "--identify devname foo" }, + { 1, "-p" }, + /* Argument parsing for -t is specialised */ + { 0, "-t devname" }, + { 0, "--test devname online" }, + { 1, "-t devname foo" }, + { 1, "--test devname online foo" }, + { 0, "-S devname" }, + { 0, "--statistics devname" }, + { 1, "-S" }, + /* Argument parsing for -n/-u is specialised */ + { 0, "-n devname rx-flow-hash tcp4" }, + { 0, "-u devname rx-flow-hash sctp4" }, + { 0, "--show-nfc devname rx-flow-hash udp6" }, + { 0, "--show-ntuple devname rx-flow-hash esp6" }, + { 1, "-n devname rx-flow-hash foo" }, + { 1, "-u devname rx-flow-hash foo" }, + { 1, "--show-nfc devname rx-flow-hash" }, + { 1, "--show-ntuple devname rx-flow-hash" }, + { 1, "-n" }, + /* Argument parsing for -f is specialised */ + { 1, "-f devname" }, + { 0, "--flash devname filename" }, + { 0, "-f devname filename 1" }, + { 1, "-f devname filename 1 foo" }, + { 1, "-f" }, + /* Argument parsing for -N/-U is specialised */ + { 0, "-N devname rx-flow-hash tcp4 mvtsdfn" }, + { 0, "--config-ntuple devname rx-flow-hash tcp4 r" }, + { 1, "-U devname rx-flow-hash tcp4" }, + { 1, "--config-nfc devname rx-flow-hash foo" }, + { 1, "-N devname rx-flow-hash" }, + { 1, "--config-ntuple devname foo" }, + { 0, "-U devname delete 1" }, + { 1, "--config-nfc devname delete foo" }, + { 1, "-N devname delete" }, + { 0, "--config-ntuple devname flow-type ether src 01:23:45:67:89:ab m cd:ef:01:23:45:67 dst 89:ab:cd:ef:01:23 m 45:67:89:ab:cd:ef proto 0x0123 m 0x4567 vlan 0x89ab m 0xcdef action 0" }, + { 0, "-U devname flow-type ether src 01:23:45:67:89:ab src-mask cd:ef:01:23:45:67 dst 89:ab:cd:ef:01:23 dst-mask 45:67:89:ab:cd:ef proto 0x0123 proto-mask 0x4567 vlan 0x89ab vlan-mask 0xcdef action 1" }, + { 1, "--config-nfc devname flow-type ether src 01:23:45:67:89: action 3" }, + { 1, "-N devname flow-type ether src 01:23:45:67:89 action 4" }, + { 0, "--config-ntuple devname flow-type ip4 src-ip 0.123.45.67 m 89.0.123.45 dst-ip 67.89.0.123 m 45.67.89.0 tos 1 m 1 l4proto 0x23 m 0x45 l4data 0xfedcba98 m 76543210 vlan 0x89ab m 0xcdef action 6" }, + { 0, "-U devname flow-type ip4 src-ip 0.123.45.67 src-ip-mask 89.0.123.45 dst-ip 67.89.0.123 dst-ip-mask 45.67.89.0 tos 1 tos-mask 1 l4proto 0x23 l4proto-mask 0x45 l4data 0xfedcba98 l4data-mask 76543210 vlan 0x89ab vlan-mask 0xcdef action 7" }, + { 0, "--config-nfc devname flow-type tcp4 src-ip 0.123.45.67 m 89.0.123.45 dst-ip 67.89.0.123 m 45.67.89.0 tos 1 m 1 src-port 23456 m 7890 dst-port 12345 m 6789 vlan 0x89ab m 0xcdef action 8" }, + { 0, "-N devname flow-type tcp4 src-ip 0.123.45.67 src-ip-mask 89.0.123.45 dst-ip 67.89.0.123 dst-ip-mask 45.67.89.0 tos 1 tos-mask 1 src-port 23456 src-port-mask 7890 dst-port 12345 dst-port-mask 6789 vlan 0x89ab vlan-mask 0xcdef action 9" }, + { 0, "--config-ntuple devname flow-type ah4 src-ip 0.123.45.67 m 89.0.123.45 dst-ip 67.89.0.123 m 45.67.89.0 tos 1 m 1 spi 2 m 3 vlan 0x89ab m 0xcdef action 10" }, + { 0, "-U devname flow-type ah4 src-ip 0.123.45.67 src-ip-mask 89.0.123.45 dst-ip 67.89.0.123 dst-ip-mask 45.67.89.0 tos 1 tos-mask 1 spi 2 spi-mask 3 vlan 0x89ab vlan-mask 0xcdef action 11" }, + { 1, "--config-nfc devname flow-type tcp4 action foo" }, + { 1, "-N devname flow-type foo" }, + { 1, "--config-ntuple devname flow-type" }, + { 1, "-U devname foo" }, + { 1, "-N" }, + { 1, "-U" }, + { 0, "-T devname" }, + { 0, "--show-time-stamping devname" }, + { 1, "-T" }, + { 0, "-x devname" }, + { 0, "--show-rxfh-indir devname" }, + { 0, "--show-rxfh devname" }, + { 1, "-x" }, + /* Argument parsing for -X is specialised */ + { 0, "-X devname equal 2" }, + { 0, "--set-rxfh-indir devname equal 256" }, + { 1, "-X devname equal 0" }, + { 1, "--set-rxfh-indir devname equal foo" }, + { 1, "-X devname equal" }, + { 1, "-X devname start" }, + { 1, "-X devname start 3" }, + { 0, "-X devname start 4 equal 2" }, + { 0, "--set-rxfh-indir devname weight 1 2 3 4" }, + { 0, "--set-rxfh-indir devname start 4 weight 1 2 3 4" }, + { 0, "--rxfh devname hkey 48:15:6e:bb:d8:bd:6f:b1:a4:c6:7a:c4:76:1c:29:98:da:e1:ae:6c:2e:12:2f:c0:b9:be:61:3d:00:54:35:9e:09:05:c7:d7:93:72:4a:ee" }, + { 0, "-X devname hkey 48:15:6e:bb:d8:bd:6f:b1:a4:c6:7a:c4:76:1c:29:98:da:e1:ae:6c:2e:12:2f:c0:b9:be:61:3d:00:54:35:9e:09:05:c7:d7:93:72:4a:ee" }, +#if 0 + /* XXX These won't fail as expected because we don't parse the + * hash key until after the first send_ioctl(). That needs to + * be changed before we enable them. + */ + { 1, "--rxfh devname hkey foo" }, + { 1, "-X devname hkey foo" }, +#endif + { 0, "--rxfh devname hkey 48:15:6e:bb:d8:bd:6f:b1:a4:c6:7a:c4:76:1c:29:98:da:e1:ae:6c:2e:12:2f:c0:b9:be:61:3d:00:54:35:9e:09:05:c7:d7:93:72:4a:ee weight 1 2 3 4" }, + { 0, "-X devname weight 1 2 3 4 hkey 48:15:6e:bb:d8:bd:6f:b1:a4:c6:7a:c4:76:1c:29:98:da:e1:ae:6c:2e:12:2f:c0:b9:be:61:3d:00:54:35:9e:09:05:c7:d7:93:72:4a:ee" }, + { 0, "--rxfh devname hkey 48:15:6e:bb:d8:bd:6f:b1:a4:c6:7a:c4:76:1c:29:98:da:e1:ae:6c:2e:12:2f:c0:b9:be:61:3d:00:54:35:9e:09:05:c7:d7:93:72:4a:ee equal 2" }, + { 0, "-X devname equal 2 hkey 48:15:6e:bb:d8:bd:6f:b1:a4:c6:7a:c4:76:1c:29:98:da:e1:ae:6c:2e:12:2f:c0:b9:be:61:3d:00:54:35:9e:09:05:c7:d7:93:72:4a:ee" }, + { 1, "--rxfh devname weight 1 2 3 4 equal 8" }, + { 1, "-X devname weight 1 2 3 4 equal 8" }, + { 1, "-X devname foo" }, + { 1, "-X" }, + { 0, "-P devname" }, + { 0, "--show-permaddr devname" }, + { 1, "-P" }, + { 0, "-w devname" }, + { 0, "--get-dump devname data filename" }, + { 0, "-w devname data filename" }, + { 1, "--get-dump devname data" }, + { 1, "-w devname foo" }, + { 1, "-w" }, + { 0, "-W devname 1" }, + { 0, "--set-dump devname 2" }, + { 1, "-W devname 1 foo" }, + { 1, "-W devname foo" }, + { 1, "-W" }, + { 0, "-l devname" }, + { 0, "--show-channels devname" }, + { 1, "-l" }, + { 0, "-L devname rx 1 tx 2 other 3 combined 4" }, + { 0, "--set-channels devname rx 1 tx 2 other 3 combined 4" }, + { 1, "-L devname rx foo" }, + { 1, "--set-channels devname rx" }, + { 0, "-L devname" }, + { 1, "-L" }, + { 0, "--show-priv-flags devname" }, + { 1, "--show-priv-flags devname foo" }, + { 1, "--show-priv-flags" }, + { 1, "-m" }, + { 0, "-m devname" }, + { 1, "--dump-module-eeprom" }, + { 0, "--dump-module-eeprom devname" }, + { 1, "--module-info" }, + { 0, "--module-info devname" }, + { 0, "-m devname raw on" }, + { 0, "-m devname raw off" }, + { 0, "-m devname hex on" }, + { 0, "-m devname hex off" }, + { 1, "-m devname hex on raw on" }, + { 0, "-m devname offset 4 length 6" }, + { 1, "--show-eee" }, + { 0, "--show-eee devname" }, + { 1, "--show-eee devname foo" }, + { 1, "--set-eee" }, + { 1, "--set-eee devname" }, + { 1, "--set-eee devname foo" }, + { 0, "--set-eee devname eee on" }, + { 0, "--set-eee devname eee off" }, + { 1, "--set-eee devname eee foo" }, + { 0, "--set-eee devname tx-lpi on" }, + { 0, "--set-eee devname tx-lpi off" }, + { 1, "--set-eee devname tx-lpi foo" }, + { 0, "--set-eee devname tx-timer 42 advertise 0x4321" }, + { 1, "--set-eee devname tx-timer foo" }, + { 1, "--set-eee devname advertise foo" }, + { 1, "--set-fec devname" }, + { 0, "--set-fec devname encoding auto" }, + { 0, "--set-fec devname encoding off" }, + { 0, "--set-fec devname encoding baser rs" }, + { 0, "--set-fec devname encoding auto auto" }, + /* encoding names are validated by kernel with netlink */ + { !IS_NL, "--set-fec devname encoding foo" }, + { !IS_NL, "--set-fec devname encoding auto foo" }, + { !IS_NL, "--set-fec devname encoding none" }, + { 1, "--set-fec devname auto" }, + /* can't test --set-priv-flags yet */ + { 0, "-h" }, + { 0, "--help" }, + { 0, "--version" }, + { 1, "--foo" }, + { 1, "-foo" }, + { 1, "-0" }, +}; + +int send_ioctl(struct cmd_context *ctx __maybe_unused, void *cmd __maybe_unused) +{ + /* If we get this far then parsing succeeded */ + test_exit(0); +} + +#ifdef ETHTOOL_ENABLE_NETLINK +struct nl_socket; +struct nl_msg_buff; + +ssize_t nlsock_sendmsg(struct nl_socket *nlsk __maybe_unused, + struct nl_msg_buff *altbuff __maybe_unused) +{ + /* If we get this far then parsing succeeded */ + test_exit(0); +} +#endif + +int main(void) +{ + struct test_case *tc; + int test_rc; + int rc = 0; + + for (tc = test_cases; tc < test_cases + ARRAY_SIZE(test_cases); tc++) { + if (getenv("ETHTOOL_TEST_VERBOSE")) + printf("I: Test command line: ethtool %s\n", tc->args); + test_rc = test_cmdline(tc->args); + if (test_rc != tc->rc) { + fprintf(stderr, "E: ethtool %s returns %d\n", + tc->args, test_rc); + rc = 1; + } + } + + return rc; +} diff --git a/test-common.c b/test-common.c new file mode 100644 index 0000000..1dab0ce --- /dev/null +++ b/test-common.c @@ -0,0 +1,385 @@ +/**************************************************************************** + * Common test functions for ethtool + * Copyright 2011 Solarflare Communications Inc. + * + * Partly derived from kernel . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#define TEST_NO_WRAPPERS +#include "internal.h" + +/* List utilities */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +static void init_list_head(struct list_head *list) +{ + list->next = list; + list->prev = list; +} + +static void list_add(struct list_head *new, struct list_head *head) +{ + head->next->prev = new; + new->next = head->next; + new->prev = head; + head->next = new; +} + +static void list_del(struct list_head *entry) +{ + entry->next->prev = entry->prev; + entry->prev->next = entry->next; + entry->next = NULL; + entry->prev = NULL; +} + +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/* Free memory at end of test */ + +static struct list_head malloc_list = LIST_HEAD_INIT(malloc_list); + +void *test_malloc(size_t size) +{ + struct list_head *block = malloc(sizeof(*block) + size); + + if (!block) + return NULL; + list_add(block, &malloc_list); + return block + 1; +} + +void *test_calloc(size_t nmemb, size_t size) +{ + void *ptr = test_malloc(nmemb * size); + + if (ptr) + memset(ptr, 0, nmemb * size); + return ptr; +} + +char *test_strdup(const char *s) +{ + size_t size = strlen(s) + 1; + char *dup = test_malloc(size); + + if (dup) + memcpy(dup, s, size); + return dup; +} + +void test_free(void *ptr) +{ + struct list_head *block; + + if (!ptr) + return; + block = (struct list_head *)ptr - 1; + list_del(block); + free(block); +} + +void *test_realloc(void *ptr, size_t size) +{ + struct list_head *block = NULL; + + if (ptr) { + block = (struct list_head *)ptr - 1; + list_del(block); + } + block = realloc(block, sizeof(*block) + size); + if (!block) + return NULL; + list_add(block, &malloc_list); + return block + 1; +} + +static void test_free_all(void) +{ + struct list_head *block, *next; + + list_for_each_safe(block, next, &malloc_list) + free(block); + init_list_head(&malloc_list); +} + +/* Close files at end of test */ + +struct file_node { + struct list_head link; + FILE *fh; + int fd; +}; + +static struct list_head file_list = LIST_HEAD_INIT(file_list); + +int test_open(const char *pathname, int flag, ...) +{ + struct file_node *node; + mode_t mode; + + if (flag & O_CREAT) { + va_list ap; + va_start(ap, flag); + mode = va_arg(ap, mode_t); + va_end(ap); + } else { + mode = 0; + } + + node = malloc(sizeof(*node)); + if (!node) + return -1; + + node->fd = open(pathname, flag, mode); + if (node->fd < 0) { + free(node); + return -1; + } + + node->fh = NULL; + list_add(&node->link, &file_list); + return node->fd; +} + +int test_socket(int domain, int type, int protocol) +{ + struct file_node *node; + + node = malloc(sizeof(*node)); + if (!node) + return -1; + + node->fd = socket(domain, type, protocol); + if (node->fd < 0) { + free(node); + return -1; + } + + node->fh = NULL; + list_add(&node->link, &file_list); + return node->fd; +} + +int test_close(int fd) +{ + struct list_head *head, *next; + + if (fd >= 0) { + list_for_each_safe(head, next, &file_list) { + if (((struct file_node *)head)->fd == fd) { + list_del(head); + free(head); + break; + } + } + } + + return close(fd); +} + +FILE *test_fopen(const char *path, const char *mode) +{ + struct file_node *node; + + node = malloc(sizeof(*node)); + if (!node) + return NULL; + + node->fh = fopen(path, mode); + if (!node->fh) { + free(node); + return NULL; + } + + node->fd = -1; + list_add(&node->link, &file_list); + return node->fh; +} + +int test_fclose(FILE *fh) +{ + struct list_head *head, *next; + + assert(fh); + + list_for_each_safe(head, next, &file_list) { + if (((struct file_node *)head)->fh == fh) { + list_del(head); + free(head); + break; + } + } + + return fclose(fh); +} + +static void test_close_all(void) +{ + struct list_head *head, *next; + struct file_node *node; + + list_for_each_safe(head, next, &file_list) { + node = (struct file_node *)head; + if (node->fh) + fclose(node->fh); + else + close(node->fd); + free(node); + } + init_list_head(&file_list); +} + +/* Wrap test main function */ + +static jmp_buf test_return; +static FILE *orig_stderr; + +void test_exit(int rc) +{ + longjmp(test_return, rc + 1); +} + +int test_ioctl(const struct cmd_expect *expect, void *cmd) +{ + int rc; + + if (!expect->cmd || *(u32 *)cmd != *(const u32 *)expect->cmd) { + /* We have no idea how long this command structure is */ + fprintf(orig_stderr, "Unexpected ioctl: cmd=%#10x\n", + *(u32 *)cmd); + return TEST_IOCTL_MISMATCH; + } + + if (memcmp(cmd, expect->cmd, expect->cmd_len)) { + fprintf(orig_stderr, "Expected ioctl structure:\n"); + dump_hex(orig_stderr, expect->cmd, expect->cmd_len, 0); + fprintf(orig_stderr, "Actual ioctl structure:\n"); + dump_hex(orig_stderr, cmd, expect->cmd_len, 0); + return TEST_IOCTL_MISMATCH; + } + + if (expect->resp) + memcpy(cmd, expect->resp, expect->resp_len); + rc = expect->rc; + + /* Convert kernel return code according to libc convention */ + if (rc >= 0) { + return rc; + } else { + errno = -rc; + return -1; + } +} + +int test_cmdline(const char *args) +{ + int volatile orig_stdout_fd = -1; + int volatile orig_stderr_fd = -1; + char **volatile argv; + int volatile argc; + int dev_null = -1; + const char *arg; + size_t len; + int rc, i; + + /* Convert line to argv */ + argc = 1; + arg = args; + for (;;) { + len = strcspn(arg, " "); + if (len == 0) + break; + argc++; + if (arg[len] == 0) + break; + arg += len + 1; + } + argv = test_calloc(argc + 1, sizeof(argv[0])); + argv[0] = test_strdup("ethtool"); + arg = args; + for (i = 1; i < argc; i++) { + len = strcspn(arg, " "); + argv[i] = test_malloc(len + 1); + memcpy(argv[i], arg, len); + argv[i][len] = 0; + arg += len + 1; + } + + dev_null = open("/dev/null", O_RDWR); + if (dev_null < 0) { + perror("open /dev/null"); + rc = -1; + goto out; + } + + fflush(NULL); + dup2(dev_null, STDIN_FILENO); + if (getenv("TEST_TEST_VERBOSE")) { + orig_stderr = stderr; + } else { + orig_stdout_fd = dup(STDOUT_FILENO); + if (orig_stdout_fd < 0) { + perror("dup stdout"); + rc = -1; + goto out; + } + dup2(dev_null, STDOUT_FILENO); + orig_stderr_fd = dup(STDERR_FILENO); + if (orig_stderr_fd < 0) { + perror("dup stderr"); + rc = -1; + goto out; + } + orig_stderr = fdopen(orig_stderr_fd, "w"); + if (orig_stderr == NULL) { + perror("fdopen orig_stderr_fd"); + rc = -1; + goto out; + } + dup2(dev_null, STDERR_FILENO); + } + + rc = setjmp(test_return); + rc = rc ? rc - 1 : test_main(argc, argv); + +out: + fflush(NULL); + if (orig_stderr_fd >= 0) { + dup2(orig_stderr_fd, STDERR_FILENO); + if (orig_stderr) + fclose(orig_stderr); + else + close(orig_stderr_fd); + } + orig_stderr = NULL; + if (orig_stdout_fd >= 0) { + dup2(orig_stdout_fd, STDOUT_FILENO); + close(orig_stdout_fd); + } + if (dev_null >= 0) + close(dev_null); + + test_free_all(); + test_close_all(); + return rc; +} diff --git a/test-driver b/test-driver new file mode 100755 index 0000000..d86cf69 --- /dev/null +++ b/test-driver @@ -0,0 +1,153 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2016-01-11.22; # UTC + +# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/test-features.c b/test-features.c new file mode 100644 index 0000000..b9f80f0 --- /dev/null +++ b/test-features.c @@ -0,0 +1,555 @@ +/**************************************************************************** + * Test cases for ethtool features + * Copyright 2012 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#include +#include +#define TEST_NO_WRAPPERS +#include "internal.h" + +static const struct { + struct ethtool_sset_info cmd; + u32 data[1]; +} +cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, { 34 } }; + +static const struct ethtool_value +cmd_grxcsum_off = { ETHTOOL_GRXCSUM, 0 }, +cmd_grxcsum_on = { ETHTOOL_GRXCSUM, 1 }, +cmd_srxcsum_off = { ETHTOOL_SRXCSUM, 0 }, +cmd_srxcsum_on = { ETHTOOL_SRXCSUM, 1 }, +cmd_gtxcsum_off = { ETHTOOL_GTXCSUM, 0 }, +cmd_gtxcsum_on = { ETHTOOL_GTXCSUM, 1 }, +cmd_stxcsum_off = { ETHTOOL_STXCSUM, 0 }, +cmd_stxcsum_on = { ETHTOOL_STXCSUM, 1 }, +cmd_gsg_off = { ETHTOOL_GSG, 0 }, +cmd_gsg_on = { ETHTOOL_GSG, 1 }, +cmd_ssg_off = { ETHTOOL_SSG, 0 }, +cmd_ssg_on = { ETHTOOL_SSG, 1 }, +cmd_gtso_off = { ETHTOOL_GTSO, 0 }, +cmd_gtso_on = { ETHTOOL_GTSO, 1 }, +cmd_stso_off = { ETHTOOL_STSO, 0 }, +cmd_stso_on = { ETHTOOL_STSO, 1 }, +cmd_gufo_off = { ETHTOOL_GUFO, 0 }, +cmd_gufo_on = { ETHTOOL_GUFO, 1 }, +cmd_sufo_off = { ETHTOOL_SUFO, 0 }, +cmd_sufo_on = { ETHTOOL_SUFO, 1 }, +cmd_ggso_off = { ETHTOOL_GGSO, 0 }, +cmd_ggso_on = { ETHTOOL_GGSO, 1 }, +cmd_sgso_off = { ETHTOOL_SGSO, 0 }, +cmd_sgso_on = { ETHTOOL_SGSO, 1 }, +cmd_ggro_off = { ETHTOOL_GGRO, 0 }, +cmd_ggro_on = { ETHTOOL_GGRO, 1 }, +cmd_sgro_off = { ETHTOOL_SGRO, 0 }, +cmd_sgro_on = { ETHTOOL_SGRO, 1 }, +cmd_gflags_off = { ETHTOOL_GFLAGS, 0 }, +cmd_gflags_on = { ETHTOOL_GFLAGS, + ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | + ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH }, +cmd_sflags_off = { ETHTOOL_SFLAGS, 0 }, +cmd_sflags_ntuple = { ETHTOOL_GFLAGS, ETH_FLAG_NTUPLE }, +cmd_sflags_on = { ETHTOOL_SFLAGS, + ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | + ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH }, +cmd_sflags_not_rxhash = { ETHTOOL_SFLAGS, + ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | + ETH_FLAG_NTUPLE }; + +static const struct cmd_expect cmd_expect_get_strings_old[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_get_features_off_old[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_get_features_off_old_some_unsup[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, -EOPNOTSUPP }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4, -EOPNOTSUPP }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_get_features_off_old_some_priv[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EPERM }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4, -EPERM }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_set_features_off_old[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL }, + { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) }, + { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) }, + { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) }, + { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) }, + { &cmd_gufo_on, 4, 0, &cmd_gufo_on, sizeof(cmd_gufo_on) }, + { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) }, + { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) }, + { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) }, + { &cmd_srxcsum_off, sizeof(cmd_srxcsum_off), 0, 0, 0 }, + { &cmd_stxcsum_off, sizeof(cmd_stxcsum_off), 0, 0, 0 }, + { &cmd_ssg_off, sizeof(cmd_ssg_off), 0, 0, 0 }, + { &cmd_stso_off, sizeof(cmd_stso_off), 0, 0, 0 }, + { &cmd_sufo_off, sizeof(cmd_sufo_off), 0, 0, 0 }, + { &cmd_sgso_off, sizeof(cmd_sgso_off), 0, 0, 0 }, + { &cmd_sgro_off, sizeof(cmd_sgro_off), 0, 0, 0 }, + { &cmd_sflags_off, sizeof(cmd_sflags_off), 0, 0, 0 }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_sflags_off) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_set_features_on_old[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_srxcsum_on, sizeof(cmd_srxcsum_on), 0, 0, 0 }, + { &cmd_stxcsum_on, sizeof(cmd_stxcsum_on), 0, 0, 0 }, + { &cmd_ssg_on, sizeof(cmd_ssg_on), 0, 0, 0 }, + { &cmd_stso_on, sizeof(cmd_stso_on), 0, 0, 0 }, + { &cmd_sufo_on, sizeof(cmd_sufo_on), 0, 0, 0 }, + { &cmd_sgso_on, sizeof(cmd_sgso_on), 0, 0, 0 }, + { &cmd_sgro_on, sizeof(cmd_sgro_on), 0, 0, 0 }, + { &cmd_sflags_on, sizeof(cmd_sflags_on), 0, 0, 0 }, + { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) }, + { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) }, + { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) }, + { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) }, + { &cmd_gufo_on, 4, 0, &cmd_gufo_on, sizeof(cmd_gufo_on) }, + { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) }, + { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) }, + { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_set_features_unsup_on_old[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_stxcsum_on, sizeof(cmd_stxcsum_on), -EOPNOTSUPP }, + { 0, 0, 0, 0, 0 } +}; + +static const struct { + struct ethtool_gstrings cmd; + u8 data[34][ETH_GSTRING_LEN]; +} +cmd_gstrings = { + { ETHTOOL_GSTRINGS, ETH_SS_FEATURES, 34 }, + { + "tx-scatter-gather", + "tx-checksum-ipv4", + "", + "tx-checksum-ip-generic", + "tx-checksum-ipv6", + "highdma", + "tx-scatter-gather-fraglist", + "tx-vlan-hw-insert", + "rx-vlan-hw-parse", + "rx-vlan-filter", + "vlan-challenged", + "tx-generic-segmentation", + "tx-lockless", + "netns-local", + "rx-gro", + "rx-lro", + "tx-tcp-segmentation", + "tx-udp-fragmentation", + "tx-gso-robust", + "tx-tcp-ecn-segmentation", + "tx-tcp6-segmentation", + "tx-fcoe-segmentation", + "", + "", + "tx-checksum-fcoe-crc", + "tx-checksum-sctp", + "fcoe-mtu", + "rx-ntuple-filter", + "rx-hashing", + "rx-checksum", + "tx-nocache-copy", + "loopback", + "rx-fcs", + "rx-all", + } +}; + +static const struct { + struct ethtool_gfeatures cmd; + struct ethtool_get_features_block data[2]; +} + /* available requested active never_changed */ +/* minimal: only GRO and GSO are available (and GSO won't work) */ +cmd_gfeatures_min_off = { { ETHTOOL_GFEATURES, 2 }, + {{ 0x00004800, 0x00000000, 0x00000000, 0x00003400}, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000}} +}, +cmd_gfeatures_min_on = { { ETHTOOL_GFEATURES, 2 }, + {{ 0x00004800, 0x00004800, 0x00004000, 0x00003400}, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000}} +}, +/* maximal: everything that isn't never-changed is available */ +cmd_gfeatures_max_off = { { ETHTOOL_GFEATURES, 2 }, + {{ 0xffffcbff, 0x00000000, 0x00000000, 0x00003400 }, + { 0x00000003, 0x00000000, 0x00000000, 0x00000000 }} +}, +cmd_gfeatures_max_on = { { ETHTOOL_GFEATURES, 2 }, + {{ 0xffffcbff, 0xffffcbff, 0xffffcbff, 0x00003400 }, + { 0x00000003, 0x00000003, 0x00000003, 0x00000000 }} +}, +/* IPv4: GRO, GSO, SG and some IPv4-specific offloads are available */ +cmd_gfeatures_ipv4_off = { { ETHTOOL_GFEATURES, 2 }, + {{ 0x00014803, 0x00000000, 0x00000000, 0x00003400 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }} +}, +cmd_gfeatures_ipv4_on = { { ETHTOOL_GFEATURES, 2 }, + {{ 0x00014803, 0x00014803, 0x00014803, 0x00003400 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }} +}; + +static const struct { + struct ethtool_sfeatures cmd; + struct ethtool_set_features_block data[2]; +} + /* valid requested */ +cmd_sfeatures_min_on = { { ETHTOOL_SFEATURES, 2 }, + {{ 0x00004800, 0x00004800 }, + { 0x00000000, 0x00000000 }} }, +cmd_sfeatures_min_off = { { ETHTOOL_SFEATURES, 2 }, + {{ 0x00004800, 0x00000000 }, + { 0x00000000, 0x00000000 }} }, +cmd_sfeatures_noop = { { ETHTOOL_SFEATURES, 2 }, + {{ 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000 }} }, +cmd_sfeatures_ipv4_on = { { ETHTOOL_SFEATURES, 2 }, + {{ 0x00014803, 0x00014803 }, + { 0x00000000, 0x00000000 }} }; + +static const struct cmd_expect cmd_expect_get_strings[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), + 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) }, + { &cmd_gstrings, sizeof(cmd_gstrings.cmd), + 0, &cmd_gstrings, sizeof(cmd_gstrings) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_get_features_min_off[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), + 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) }, + { &cmd_gstrings, sizeof(cmd_gstrings.cmd), + 0, &cmd_gstrings, sizeof(cmd_gstrings) }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd), + 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_get_features_max_on[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), + 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) }, + { &cmd_gstrings, sizeof(cmd_gstrings.cmd), + 0, &cmd_gstrings, sizeof(cmd_gstrings) }, + { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) }, + { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) }, + { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) }, + { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) }, + { &cmd_gufo_on, 4, 0, &cmd_gufo_on, sizeof(cmd_gufo_on) }, + { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) }, + { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) }, + { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) }, + { &cmd_gfeatures_max_on, sizeof(cmd_gfeatures_max_on.cmd), + 0, &cmd_gfeatures_max_on, sizeof(cmd_gfeatures_max_on) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_set_features_min_off_min_on[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), + 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) }, + { &cmd_gstrings, sizeof(cmd_gstrings.cmd), + 0, &cmd_gstrings, sizeof(cmd_gstrings) }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd), + 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) }, + { &cmd_sfeatures_min_on, sizeof(cmd_sfeatures_min_on), + ETHTOOL_F_WISH, 0, 0 }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on.cmd), + 0, &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_set_features_min_off_min_off[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), + 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) }, + { &cmd_gstrings, sizeof(cmd_gstrings.cmd), + 0, &cmd_gstrings, sizeof(cmd_gstrings) }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd), + 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) }, + { &cmd_sfeatures_min_off, sizeof(cmd_sfeatures_min_off), 0, 0, 0 }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd), + 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_set_features_min_on_min_off[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), + 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) }, + { &cmd_gstrings, sizeof(cmd_gstrings.cmd), + 0, &cmd_gstrings, sizeof(cmd_gstrings) }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on.cmd), + 0, &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on) }, + { &cmd_sfeatures_min_off, sizeof(cmd_sfeatures_min_off), 0, 0, 0 }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd), + 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_set_features_min_off_unsup_on[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), + 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) }, + { &cmd_gstrings, sizeof(cmd_gstrings.cmd), + 0, &cmd_gstrings, sizeof(cmd_gstrings) }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd), + 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) }, + { &cmd_sfeatures_noop, sizeof(cmd_sfeatures_noop), 0, 0, 0 }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd), + 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) }, + { 0, 0, 0, 0, 0 } +}; + +static const struct cmd_expect cmd_expect_set_features_ipv4_off_many_on[] = { + { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), + 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) }, + { &cmd_gstrings, sizeof(cmd_gstrings.cmd), + 0, &cmd_gstrings, sizeof(cmd_gstrings) }, + { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) }, + { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) }, + { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) }, + { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) }, + { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_ipv4_off, sizeof(cmd_gfeatures_ipv4_off.cmd), + 0, &cmd_gfeatures_ipv4_off, sizeof(cmd_gfeatures_ipv4_off) }, + { &cmd_sfeatures_ipv4_on, sizeof(cmd_sfeatures_ipv4_on), 0, 0, 0 }, + { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) }, + { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) }, + { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) }, + { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) }, + { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) }, + { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) }, + { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) }, + { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) }, + { &cmd_gfeatures_ipv4_on, sizeof(cmd_gfeatures_ipv4_on.cmd), + 0, &cmd_gfeatures_ipv4_on, sizeof(cmd_gfeatures_ipv4_on) }, + { 0, 0, 0, 0, 0 } +}; + +static struct test_case { + int rc; + const char *args; + const struct cmd_expect *expect; +} const test_cases[] = { + { 0, "-k devname", cmd_expect_get_features_off_old }, + { 0, "-k dev_unsup", cmd_expect_get_features_off_old_some_unsup }, + { 0, "-k dev_priv", cmd_expect_get_features_off_old_some_priv }, + { 0, "-K devname rx off tx off sg off tso off ufo off gso off lro off rxvlan off txvlan off ntuple off rxhash off gro off", + cmd_expect_set_features_off_old }, + { 0, "-K devname rx on tx on sg on tso on ufo on gso on lro on rxvlan on txvlan on ntuple on rxhash on gro on", + cmd_expect_set_features_on_old }, + { 1, "-K devname tx on sg on", cmd_expect_set_features_unsup_on_old }, + { 0, "--show-offload devname", cmd_expect_get_features_min_off }, + { 0, "--show-features devname", cmd_expect_get_features_max_on }, + { 0, "-K devname rx on tx on sg on tso on ufo on gso on gro on", + cmd_expect_set_features_min_off_min_on }, + { 0, "-K devname rx off tx off sg off tso off ufo off gso off gro off", + cmd_expect_set_features_min_off_min_off }, + { 0, "-K devname rx off tx off sg off tso off ufo off gso off gro off", + cmd_expect_set_features_min_on_min_off }, + { 1, "-K devname tx on sg on", + cmd_expect_set_features_min_off_unsup_on }, + { 0, "--features devname rx on tx on sg on tso on gso on gro on", + cmd_expect_set_features_ipv4_off_many_on }, + { 1, "-K devname rx foo", cmd_expect_get_strings_old }, + { 1, "-K devname rx foo", cmd_expect_get_strings }, + { 1, "--offload devname rx", cmd_expect_get_strings_old }, + { 1, "--features devname rx", cmd_expect_get_strings }, + { 1, "--features devname foo on", cmd_expect_get_strings_old }, + { 1, "--offload devname foo on", cmd_expect_get_strings }, +}; + +static int expect_matched; +static const struct cmd_expect *expect_next; + +int send_ioctl(struct cmd_context *ctx, void *cmd) +{ + int rc = test_ioctl(expect_next, cmd); + + if (rc == TEST_IOCTL_MISMATCH) { + expect_matched = 0; + test_exit(0); + } + expect_next++; + return rc; +} + +#ifdef ETHTOOL_ENABLE_NETLINK +struct nl_socket; +struct nl_msg_buff; + +ssize_t nlsock_sendmsg(struct nl_socket *nlsk, struct nl_msg_buff *altbuff) +{ + /* Should not be called with test-features */ + exit(1); +} +#endif + +int main(void) +{ + const struct test_case *tc; + int test_rc; + int rc = 0; + + for (tc = test_cases; tc < test_cases + ARRAY_SIZE(test_cases); tc++) { + if (getenv("ETHTOOL_TEST_VERBOSE")) + printf("I: Test command line: ethtool %s\n", tc->args); + expect_matched = 1; + expect_next = tc->expect; + test_rc = test_cmdline(tc->args); + + /* If we found a mismatch, or there is still another + * expected ioctl to match, the test failed. + */ + if (!expect_matched || expect_next->cmd) { + fprintf(stderr, + "E: ethtool %s deviated from the expected " + "ioctl sequence after %zu calls\n", + tc->args, expect_next - tc->expect); + rc = 1; + } else if (test_rc != tc->rc) { + fprintf(stderr, "E: ethtool %s returns %d\n", + tc->args, test_rc); + rc = 1; + } + } + + return rc; +} diff --git a/tg3.c b/tg3.c new file mode 100644 index 0000000..ebdef2d --- /dev/null +++ b/tg3.c @@ -0,0 +1,42 @@ +#include +#include +#include "internal.h" + +#define TG3_MAGIC 0x669955aa + +int tg3_dump_eeprom(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_eeprom *ee) +{ + unsigned int i; + + if (ee->magic != TG3_MAGIC) { + fprintf(stderr, "Magic number 0x%08x does not match 0x%08x\n", + ee->magic, TG3_MAGIC); + return -1; + } + + fprintf(stdout, "Address \tData\n"); + fprintf(stdout, "----------\t----\n"); + for (i = 0; i < ee->len; i++) + fprintf(stdout, "0x%08x\t0x%02x\n", i + ee->offset, ee->data[i]); + + return 0; +} + +int tg3_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + unsigned int i; + u32 reg; + + fprintf(stdout, "Offset\tValue\n"); + fprintf(stdout, "------\t----------\n"); + for (i = 0; i < regs->len; i += sizeof(reg)) { + memcpy(®, ®s->data[i], sizeof(reg)); + if (reg) + fprintf(stdout, "0x%04x\t0x%08x\n", i, reg); + + } + fprintf(stdout, "\n"); + return 0; +} diff --git a/tse.c b/tse.c new file mode 100644 index 0000000..fb00d21 --- /dev/null +++ b/tse.c @@ -0,0 +1,112 @@ +/**************************************************************************** + * Support for the Altera Triple Speed Ethernet 10/100/1000 Controller + * + * Copyright (C) 2014 Altera Corporation + * + * Author: Vince Bridgers + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#include "internal.h" + +#define ALTERA_VERSION_MASK 0xffff +#define ALTERA_ETHTOOL_V1 1 + +int +bitset(u32 val, int bit) +{ + if (val & (1 << bit)) + return 1; + return 0; +} + +int altera_tse_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + int i; + u32 *tsereg = (unsigned int *)regs->data; + u32 version = regs->version; + + if ((version & ALTERA_VERSION_MASK) > ALTERA_ETHTOOL_V1) + return -1; + + /* + * Version 1: Initial TSE driver release. No feature information + * available, 32-bits of version is equal to 1. + * + * Version 2: Lower 16-bits of version is 2, upper 16 bits are: + * Bit 16 - SGMDA or MSGDMA Registers + * Bit 17 - PCS Present + * Bit 18 - Supplementary MAC Address Filter Registers Present + * Bit 19 - Multicast Hash Filter Present + * Bit 20 - IEEE 1588 Feature Present + */ + fprintf(stdout, "Altera TSE 10/100/1000 Registers, Version %d\n", + version); + fprintf(stdout, "---------------------------------------------\n"); + fprintf(stdout, "Revision 0x%08X\n", tsereg[0]); + fprintf(stdout, " Core Version %d.%d\n", + (tsereg[0] & 0xffff) >> 8, + tsereg[0] & 0xff); + fprintf(stdout, " CustVersion 0x%08X\n", tsereg[0] >> 16); + fprintf(stdout, "Scratch 0x%08X\n", tsereg[1]); + fprintf(stdout, "Command/Config 0x%08X\n", tsereg[2]); + fprintf(stdout, " (0)TX_EN %d\n", bitset(tsereg[2], 0)); + fprintf(stdout, " (1)RX_EN %d\n", bitset(tsereg[2], 1)); + fprintf(stdout, " (2)XON_GEN %d\n", bitset(tsereg[2], 2)); + fprintf(stdout, " (3)ETH_SPEED %d\n", bitset(tsereg[2], 3)); + fprintf(stdout, " (4)PROMIS_EN %d\n", bitset(tsereg[2], 4)); + fprintf(stdout, " (5)PAD_EN %d\n", bitset(tsereg[2], 5)); + fprintf(stdout, " (6)CRC_FWD %d\n", bitset(tsereg[2], 6)); + fprintf(stdout, " (7)PAUSE_FWD %d\n", bitset(tsereg[2], 7)); + fprintf(stdout, " (8)PAUSE_IGN %d\n", bitset(tsereg[2], 8)); + fprintf(stdout, " (9)TXADDR_INS %d\n", bitset(tsereg[2], 9)); + fprintf(stdout, " (10)HD_EN %d\n", bitset(tsereg[2], 10)); + fprintf(stdout, " (11)EXCESS_COL %d\n", bitset(tsereg[2], 11)); + fprintf(stdout, " (12)LATE_COL %d\n", bitset(tsereg[2], 12)); + fprintf(stdout, " (13)SW_RESET %d\n", bitset(tsereg[2], 13)); + fprintf(stdout, " (14)MHASH_SEL %d\n", bitset(tsereg[2], 14)); + fprintf(stdout, " (15)LOOP_EN %d\n", bitset(tsereg[2], 15)); + fprintf(stdout, " (16-18)TX_ADDR_SEL %d\n", + (tsereg[2] & 0x30000) >> 16); + fprintf(stdout, " (19)MAGIC_EN %d\n", bitset(tsereg[2], 19)); + fprintf(stdout, " (20)SLEEP %d\n", bitset(tsereg[2], 20)); + fprintf(stdout, " (21)WAKEUP %d\n", bitset(tsereg[2], 21)); + fprintf(stdout, " (22)XOFF_GEN %d\n", bitset(tsereg[2], 22)); + fprintf(stdout, " (23)CTRL_FRAME_EN %d\n", bitset(tsereg[2], 23)); + fprintf(stdout, " (24)NO_LEN_CHECK %d\n", bitset(tsereg[2], 24)); + fprintf(stdout, " (25)ENA_10 %d\n", bitset(tsereg[2], 25)); + fprintf(stdout, " (26)RX_ERR_DISC %d\n", bitset(tsereg[2], 26)); + fprintf(stdout, " (31)CTRL_RESET %d\n", bitset(tsereg[2], 31)); + fprintf(stdout, "mac_0 0x%08X\n", tsereg[3]); + fprintf(stdout, "mac_1 0x%08X\n", tsereg[4]); + fprintf(stdout, "frm_length 0x%08X\n", tsereg[5]); + fprintf(stdout, "pause_quant 0x%08X\n", tsereg[6]); + fprintf(stdout, "rx_section_empty 0x%08X\n", tsereg[7]); + fprintf(stdout, "rx_section_full 0x%08X\n", tsereg[8]); + fprintf(stdout, "tx_section_empty 0x%08X\n", tsereg[9]); + fprintf(stdout, "tx_section_full 0x%08X\n", tsereg[0xa]); + fprintf(stdout, "rx_almost_empty 0x%08X\n", tsereg[0xb]); + fprintf(stdout, "rx_almost_full 0x%08X\n", tsereg[0xc]); + fprintf(stdout, "tx_almost_empty 0x%08X\n", tsereg[0xd]); + fprintf(stdout, "tx_almost_full 0x%08X\n", tsereg[0xe]); + fprintf(stdout, "mdio_addr0 0x%08X\n", tsereg[0xf]); + fprintf(stdout, "mdio_addr1 0x%08X\n", tsereg[0x10]); + fprintf(stdout, "holdoff_quant 0x%08X\n", tsereg[0x11]); + + fprintf(stdout, "tx_ipg_length 0x%08X\n", tsereg[0x17]); + fprintf(stdout, "Transmit Command 0x%08X\n", tsereg[0x3a]); + fprintf(stdout, "Receive Command 0x%08X\n", tsereg[0x3b]); + + for (i = 0; i < 64; i++) + fprintf(stdout, "Multicast Hash[%02d] 0x%08X\n", + i, + tsereg[0x40 + i]); + return 0; +} + diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h new file mode 100644 index 0000000..f1f94f7 --- /dev/null +++ b/uapi/linux/ethtool.h @@ -0,0 +1,2154 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * ethtool.h: Defines for Linux ethtool. + * + * Copyright (C) 1998 David S. Miller (davem@redhat.com) + * Copyright 2001 Jeff Garzik + * Portions Copyright 2001 Sun Microsystems (thockin@sun.com) + * Portions Copyright 2002 Intel (eli.kupermann@intel.com, + * christopher.leech@intel.com, + * scott.feldman@intel.com) + * Portions Copyright (C) Sun Microsystems 2008 + */ + +#ifndef _LINUX_ETHTOOL_H +#define _LINUX_ETHTOOL_H + +#include +#include +#include + +#include /* for INT_MAX */ + +/* All structures exposed to userland should be defined such that they + * have the same layout for 32-bit and 64-bit userland. + */ + +/* Note on reserved space. + * Reserved fields must not be accessed directly by user space because + * they may be replaced by a different field in the future. They must + * be initialized to zero before making the request, e.g. via memset + * of the entire structure or implicitly by not being set in a structure + * initializer. + */ + +/** + * struct ethtool_cmd - DEPRECATED, link control and status + * This structure is DEPRECATED, please use struct ethtool_link_settings. + * @cmd: Command number = %ETHTOOL_GSET or %ETHTOOL_SSET + * @supported: Bitmask of %SUPPORTED_* flags for the link modes, + * physical connectors and other link features for which the + * interface supports autonegotiation or auto-detection. + * Read-only. + * @advertising: Bitmask of %ADVERTISED_* flags for the link modes, + * physical connectors and other link features that are + * advertised through autonegotiation or enabled for + * auto-detection. + * @speed: Low bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN + * @duplex: Duplex mode; one of %DUPLEX_* + * @port: Physical connector type; one of %PORT_* + * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not + * applicable. For clause 45 PHYs this is the PRTAD. + * @transceiver: Historically used to distinguish different possible + * PHY types, but not in a consistent way. Deprecated. + * @autoneg: Enable/disable autonegotiation and auto-detection; + * either %AUTONEG_DISABLE or %AUTONEG_ENABLE + * @mdio_support: Bitmask of %ETH_MDIO_SUPPORTS_* flags for the MDIO + * protocols supported by the interface; 0 if unknown. + * Read-only. + * @maxtxpkt: Historically used to report TX IRQ coalescing; now + * obsoleted by &struct ethtool_coalesce. Read-only; deprecated. + * @maxrxpkt: Historically used to report RX IRQ coalescing; now + * obsoleted by &struct ethtool_coalesce. Read-only; deprecated. + * @speed_hi: High bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN + * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of + * %ETH_TP_MDI_*. If the status is unknown or not applicable, the + * value will be %ETH_TP_MDI_INVALID. Read-only. + * @eth_tp_mdix_ctrl: Ethernet twisted pair MDI(-X) control; one of + * %ETH_TP_MDI_*. If MDI(-X) control is not implemented, reads + * yield %ETH_TP_MDI_INVALID and writes may be ignored or rejected. + * When written successfully, the link should be renegotiated if + * necessary. + * @lp_advertising: Bitmask of %ADVERTISED_* flags for the link modes + * and other link features that the link partner advertised + * through autonegotiation; 0 if unknown or not applicable. + * Read-only. + * @reserved: Reserved for future use; see the note on reserved space. + * + * The link speed in Mbps is split between @speed and @speed_hi. Use + * the ethtool_cmd_speed() and ethtool_cmd_speed_set() functions to + * access it. + * + * If autonegotiation is disabled, the speed and @duplex represent the + * fixed link mode and are writable if the driver supports multiple + * link modes. If it is enabled then they are read-only; if the link + * is up they represent the negotiated link mode; if the link is down, + * the speed is 0, %SPEED_UNKNOWN or the highest enabled speed and + * @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode. + * + * Some hardware interfaces may have multiple PHYs and/or physical + * connectors fitted or do not allow the driver to detect which are + * fitted. For these interfaces @port and/or @phy_address may be + * writable, possibly dependent on @autoneg being %AUTONEG_DISABLE. + * Otherwise, attempts to write different values may be ignored or + * rejected. + * + * Users should assume that all fields not marked read-only are + * writable and subject to validation by the driver. They should use + * %ETHTOOL_GSET to get the current values before making specific + * changes and then applying them with %ETHTOOL_SSET. + * + * Deprecated fields should be ignored by both users and drivers. + */ +struct ethtool_cmd { + __u32 cmd; + __u32 supported; + __u32 advertising; + __u16 speed; + __u8 duplex; + __u8 port; + __u8 phy_address; + __u8 transceiver; + __u8 autoneg; + __u8 mdio_support; + __u32 maxtxpkt; + __u32 maxrxpkt; + __u16 speed_hi; + __u8 eth_tp_mdix; + __u8 eth_tp_mdix_ctrl; + __u32 lp_advertising; + __u32 reserved[2]; +}; + +static __inline__ void ethtool_cmd_speed_set(struct ethtool_cmd *ep, + __u32 speed) +{ + ep->speed = (__u16)(speed & 0xFFFF); + ep->speed_hi = (__u16)(speed >> 16); +} + +static __inline__ __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep) +{ + return (ep->speed_hi << 16) | ep->speed; +} + +/* Device supports clause 22 register access to PHY or peripherals + * using the interface defined in . This should not be + * set if there are known to be no such peripherals present or if + * the driver only emulates clause 22 registers for compatibility. + */ +#define ETH_MDIO_SUPPORTS_C22 1 + +/* Device supports clause 45 register access to PHY or peripherals + * using the interface defined in and . + * This should not be set if there are known to be no such peripherals + * present. + */ +#define ETH_MDIO_SUPPORTS_C45 2 + +#define ETHTOOL_FWVERS_LEN 32 +#define ETHTOOL_BUSINFO_LEN 32 +#define ETHTOOL_EROMVERS_LEN 32 + +/** + * struct ethtool_drvinfo - general driver and device information + * @cmd: Command number = %ETHTOOL_GDRVINFO + * @driver: Driver short name. This should normally match the name + * in its bus driver structure (e.g. pci_driver::name). Must + * not be an empty string. + * @version: Driver version string; may be an empty string + * @fw_version: Firmware version string; may be an empty string + * @erom_version: Expansion ROM version string; may be an empty string + * @bus_info: Device bus address. This should match the dev_name() + * string for the underlying bus device, if there is one. May be + * an empty string. + * @reserved2: Reserved for future use; see the note on reserved space. + * @n_priv_flags: Number of flags valid for %ETHTOOL_GPFLAGS and + * %ETHTOOL_SPFLAGS commands; also the number of strings in the + * %ETH_SS_PRIV_FLAGS set + * @n_stats: Number of u64 statistics returned by the %ETHTOOL_GSTATS + * command; also the number of strings in the %ETH_SS_STATS set + * @testinfo_len: Number of results returned by the %ETHTOOL_TEST + * command; also the number of strings in the %ETH_SS_TEST set + * @eedump_len: Size of EEPROM accessible through the %ETHTOOL_GEEPROM + * and %ETHTOOL_SEEPROM commands, in bytes + * @regdump_len: Size of register dump returned by the %ETHTOOL_GREGS + * command, in bytes + * + * Users can use the %ETHTOOL_GSSET_INFO command to get the number of + * strings in any string set (from Linux 2.6.34). + * + * Drivers should set at most @driver, @version, @fw_version and + * @bus_info in their get_drvinfo() implementation. The ethtool + * core fills in the other fields using other driver operations. + */ +struct ethtool_drvinfo { + __u32 cmd; + char driver[32]; + char version[32]; + char fw_version[ETHTOOL_FWVERS_LEN]; + char bus_info[ETHTOOL_BUSINFO_LEN]; + char erom_version[ETHTOOL_EROMVERS_LEN]; + char reserved2[12]; + __u32 n_priv_flags; + __u32 n_stats; + __u32 testinfo_len; + __u32 eedump_len; + __u32 regdump_len; +}; + +#define SOPASS_MAX 6 + +/** + * struct ethtool_wolinfo - Wake-On-Lan configuration + * @cmd: Command number = %ETHTOOL_GWOL or %ETHTOOL_SWOL + * @supported: Bitmask of %WAKE_* flags for supported Wake-On-Lan modes. + * Read-only. + * @wolopts: Bitmask of %WAKE_* flags for enabled Wake-On-Lan modes. + * @sopass: SecureOn(tm) password; meaningful only if %WAKE_MAGICSECURE + * is set in @wolopts. + */ +struct ethtool_wolinfo { + __u32 cmd; + __u32 supported; + __u32 wolopts; + __u8 sopass[SOPASS_MAX]; +}; + +/* for passing single values */ +struct ethtool_value { + __u32 cmd; + __u32 data; +}; + +#define PFC_STORM_PREVENTION_AUTO 0xffff +#define PFC_STORM_PREVENTION_DISABLE 0 + +enum tunable_id { + ETHTOOL_ID_UNSPEC, + ETHTOOL_RX_COPYBREAK, + ETHTOOL_TX_COPYBREAK, + ETHTOOL_PFC_PREVENTION_TOUT, /* timeout in msecs */ + ETHTOOL_TX_COPYBREAK_BUF_SIZE, + /* + * Add your fresh new tunable attribute above and remember to update + * tunable_strings[] in net/ethtool/common.c + */ + __ETHTOOL_TUNABLE_COUNT, +}; + +enum tunable_type_id { + ETHTOOL_TUNABLE_UNSPEC, + ETHTOOL_TUNABLE_U8, + ETHTOOL_TUNABLE_U16, + ETHTOOL_TUNABLE_U32, + ETHTOOL_TUNABLE_U64, + ETHTOOL_TUNABLE_STRING, + ETHTOOL_TUNABLE_S8, + ETHTOOL_TUNABLE_S16, + ETHTOOL_TUNABLE_S32, + ETHTOOL_TUNABLE_S64, +}; + +struct ethtool_tunable { + __u32 cmd; + __u32 id; + __u32 type_id; + __u32 len; + void *data[]; +}; + +#define DOWNSHIFT_DEV_DEFAULT_COUNT 0xff +#define DOWNSHIFT_DEV_DISABLE 0 + +/* Time in msecs after which link is reported as down + * 0 = lowest time supported by the PHY + * 0xff = off, link down detection according to standard + */ +#define ETHTOOL_PHY_FAST_LINK_DOWN_ON 0 +#define ETHTOOL_PHY_FAST_LINK_DOWN_OFF 0xff + +/* Energy Detect Power Down (EDPD) is a feature supported by some PHYs, where + * the PHY's RX & TX blocks are put into a low-power mode when there is no + * link detected (typically cable is un-plugged). For RX, only a minimal + * link-detection is available, and for TX the PHY wakes up to send link pulses + * to avoid any lock-ups in case the peer PHY may also be running in EDPD mode. + * + * Some PHYs may support configuration of the wake-up interval for TX pulses, + * and some PHYs may support only disabling TX pulses entirely. For the latter + * a special value is required (ETHTOOL_PHY_EDPD_NO_TX) so that this can be + * configured from userspace (should the user want it). + * + * The interval units for TX wake-up are in milliseconds, since this should + * cover a reasonable range of intervals: + * - from 1 millisecond, which does not sound like much of a power-saver + * - to ~65 seconds which is quite a lot to wait for a link to come up when + * plugging a cable + */ +#define ETHTOOL_PHY_EDPD_DFLT_TX_MSECS 0xffff +#define ETHTOOL_PHY_EDPD_NO_TX 0xfffe +#define ETHTOOL_PHY_EDPD_DISABLE 0 + +enum phy_tunable_id { + ETHTOOL_PHY_ID_UNSPEC, + ETHTOOL_PHY_DOWNSHIFT, + ETHTOOL_PHY_FAST_LINK_DOWN, + ETHTOOL_PHY_EDPD, + /* + * Add your fresh new phy tunable attribute above and remember to update + * phy_tunable_strings[] in net/ethtool/common.c + */ + __ETHTOOL_PHY_TUNABLE_COUNT, +}; + +/** + * struct ethtool_regs - hardware register dump + * @cmd: Command number = %ETHTOOL_GREGS + * @version: Dump format version. This is driver-specific and may + * distinguish different chips/revisions. Drivers must use new + * version numbers whenever the dump format changes in an + * incompatible way. + * @len: On entry, the real length of @data. On return, the number of + * bytes used. + * @data: Buffer for the register dump + * + * Users should use %ETHTOOL_GDRVINFO to find the maximum length of + * a register dump for the interface. They must allocate the buffer + * immediately following this structure. + */ +struct ethtool_regs { + __u32 cmd; + __u32 version; + __u32 len; + __u8 data[]; +}; + +/** + * struct ethtool_eeprom - EEPROM dump + * @cmd: Command number = %ETHTOOL_GEEPROM, %ETHTOOL_GMODULEEEPROM or + * %ETHTOOL_SEEPROM + * @magic: A 'magic cookie' value to guard against accidental changes. + * The value passed in to %ETHTOOL_SEEPROM must match the value + * returned by %ETHTOOL_GEEPROM for the same device. This is + * unused when @cmd is %ETHTOOL_GMODULEEEPROM. + * @offset: Offset within the EEPROM to begin reading/writing, in bytes + * @len: On entry, number of bytes to read/write. On successful + * return, number of bytes actually read/written. In case of + * error, this may indicate at what point the error occurred. + * @data: Buffer to read/write from + * + * Users may use %ETHTOOL_GDRVINFO or %ETHTOOL_GMODULEINFO to find + * the length of an on-board or module EEPROM, respectively. They + * must allocate the buffer immediately following this structure. + */ +struct ethtool_eeprom { + __u32 cmd; + __u32 magic; + __u32 offset; + __u32 len; + __u8 data[]; +}; + +/** + * struct ethtool_eee - Energy Efficient Ethernet information + * @cmd: ETHTOOL_{G,S}EEE + * @supported: Mask of %SUPPORTED_* flags for the speed/duplex combinations + * for which there is EEE support. + * @advertised: Mask of %ADVERTISED_* flags for the speed/duplex combinations + * advertised as eee capable. + * @lp_advertised: Mask of %ADVERTISED_* flags for the speed/duplex + * combinations advertised by the link partner as eee capable. + * @eee_active: Result of the eee auto negotiation. + * @eee_enabled: EEE configured mode (enabled/disabled). + * @tx_lpi_enabled: Whether the interface should assert its tx lpi, given + * that eee was negotiated. + * @tx_lpi_timer: Time in microseconds the interface delays prior to asserting + * its tx lpi (after reaching 'idle' state). Effective only when eee + * was negotiated and tx_lpi_enabled was set. + * @reserved: Reserved for future use; see the note on reserved space. + */ +struct ethtool_eee { + __u32 cmd; + __u32 supported; + __u32 advertised; + __u32 lp_advertised; + __u32 eee_active; + __u32 eee_enabled; + __u32 tx_lpi_enabled; + __u32 tx_lpi_timer; + __u32 reserved[2]; +}; + +/** + * struct ethtool_modinfo - plugin module eeprom information + * @cmd: %ETHTOOL_GMODULEINFO + * @type: Standard the module information conforms to %ETH_MODULE_SFF_xxxx + * @eeprom_len: Length of the eeprom + * @reserved: Reserved for future use; see the note on reserved space. + * + * This structure is used to return the information to + * properly size memory for a subsequent call to %ETHTOOL_GMODULEEEPROM. + * The type code indicates the eeprom data format + */ +struct ethtool_modinfo { + __u32 cmd; + __u32 type; + __u32 eeprom_len; + __u32 reserved[8]; +}; + +/** + * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates + * @cmd: ETHTOOL_{G,S}COALESCE + * @rx_coalesce_usecs: How many usecs to delay an RX interrupt after + * a packet arrives. + * @rx_max_coalesced_frames: Maximum number of packets to receive + * before an RX interrupt. + * @rx_coalesce_usecs_irq: Same as @rx_coalesce_usecs, except that + * this value applies while an IRQ is being serviced by the host. + * @rx_max_coalesced_frames_irq: Same as @rx_max_coalesced_frames, + * except that this value applies while an IRQ is being serviced + * by the host. + * @tx_coalesce_usecs: How many usecs to delay a TX interrupt after + * a packet is sent. + * @tx_max_coalesced_frames: Maximum number of packets to be sent + * before a TX interrupt. + * @tx_coalesce_usecs_irq: Same as @tx_coalesce_usecs, except that + * this value applies while an IRQ is being serviced by the host. + * @tx_max_coalesced_frames_irq: Same as @tx_max_coalesced_frames, + * except that this value applies while an IRQ is being serviced + * by the host. + * @stats_block_coalesce_usecs: How many usecs to delay in-memory + * statistics block updates. Some drivers do not have an + * in-memory statistic block, and in such cases this value is + * ignored. This value must not be zero. + * @use_adaptive_rx_coalesce: Enable adaptive RX coalescing. + * @use_adaptive_tx_coalesce: Enable adaptive TX coalescing. + * @pkt_rate_low: Threshold for low packet rate (packets per second). + * @rx_coalesce_usecs_low: How many usecs to delay an RX interrupt after + * a packet arrives, when the packet rate is below @pkt_rate_low. + * @rx_max_coalesced_frames_low: Maximum number of packets to be received + * before an RX interrupt, when the packet rate is below @pkt_rate_low. + * @tx_coalesce_usecs_low: How many usecs to delay a TX interrupt after + * a packet is sent, when the packet rate is below @pkt_rate_low. + * @tx_max_coalesced_frames_low: Maximum nuumber of packets to be sent before + * a TX interrupt, when the packet rate is below @pkt_rate_low. + * @pkt_rate_high: Threshold for high packet rate (packets per second). + * @rx_coalesce_usecs_high: How many usecs to delay an RX interrupt after + * a packet arrives, when the packet rate is above @pkt_rate_high. + * @rx_max_coalesced_frames_high: Maximum number of packets to be received + * before an RX interrupt, when the packet rate is above @pkt_rate_high. + * @tx_coalesce_usecs_high: How many usecs to delay a TX interrupt after + * a packet is sent, when the packet rate is above @pkt_rate_high. + * @tx_max_coalesced_frames_high: Maximum number of packets to be sent before + * a TX interrupt, when the packet rate is above @pkt_rate_high. + * @rate_sample_interval: How often to do adaptive coalescing packet rate + * sampling, measured in seconds. Must not be zero. + * + * Each pair of (usecs, max_frames) fields specifies that interrupts + * should be coalesced until + * (usecs > 0 && time_since_first_completion >= usecs) || + * (max_frames > 0 && completed_frames >= max_frames) + * + * It is illegal to set both usecs and max_frames to zero as this + * would cause interrupts to never be generated. To disable + * coalescing, set usecs = 0 and max_frames = 1. + * + * Some implementations ignore the value of max_frames and use the + * condition time_since_first_completion >= usecs + * + * This is deprecated. Drivers for hardware that does not support + * counting completions should validate that max_frames == !rx_usecs. + * + * Adaptive RX/TX coalescing is an algorithm implemented by some + * drivers to improve latency under low packet rates and improve + * throughput under high packet rates. Some drivers only implement + * one of RX or TX adaptive coalescing. Anything not implemented by + * the driver causes these values to be silently ignored. + * + * When the packet rate is below @pkt_rate_high but above + * @pkt_rate_low (both measured in packets per second) the + * normal {rx,tx}_* coalescing parameters are used. + */ +struct ethtool_coalesce { + __u32 cmd; + __u32 rx_coalesce_usecs; + __u32 rx_max_coalesced_frames; + __u32 rx_coalesce_usecs_irq; + __u32 rx_max_coalesced_frames_irq; + __u32 tx_coalesce_usecs; + __u32 tx_max_coalesced_frames; + __u32 tx_coalesce_usecs_irq; + __u32 tx_max_coalesced_frames_irq; + __u32 stats_block_coalesce_usecs; + __u32 use_adaptive_rx_coalesce; + __u32 use_adaptive_tx_coalesce; + __u32 pkt_rate_low; + __u32 rx_coalesce_usecs_low; + __u32 rx_max_coalesced_frames_low; + __u32 tx_coalesce_usecs_low; + __u32 tx_max_coalesced_frames_low; + __u32 pkt_rate_high; + __u32 rx_coalesce_usecs_high; + __u32 rx_max_coalesced_frames_high; + __u32 tx_coalesce_usecs_high; + __u32 tx_max_coalesced_frames_high; + __u32 rate_sample_interval; +}; + +/** + * struct ethtool_ringparam - RX/TX ring parameters + * @cmd: Command number = %ETHTOOL_GRINGPARAM or %ETHTOOL_SRINGPARAM + * @rx_max_pending: Maximum supported number of pending entries per + * RX ring. Read-only. + * @rx_mini_max_pending: Maximum supported number of pending entries + * per RX mini ring. Read-only. + * @rx_jumbo_max_pending: Maximum supported number of pending entries + * per RX jumbo ring. Read-only. + * @tx_max_pending: Maximum supported number of pending entries per + * TX ring. Read-only. + * @rx_pending: Current maximum number of pending entries per RX ring + * @rx_mini_pending: Current maximum number of pending entries per RX + * mini ring + * @rx_jumbo_pending: Current maximum number of pending entries per RX + * jumbo ring + * @tx_pending: Current maximum supported number of pending entries + * per TX ring + * + * If the interface does not have separate RX mini and/or jumbo rings, + * @rx_mini_max_pending and/or @rx_jumbo_max_pending will be 0. + * + * There may also be driver-dependent minimum values for the number + * of entries per ring. + */ +struct ethtool_ringparam { + __u32 cmd; + __u32 rx_max_pending; + __u32 rx_mini_max_pending; + __u32 rx_jumbo_max_pending; + __u32 tx_max_pending; + __u32 rx_pending; + __u32 rx_mini_pending; + __u32 rx_jumbo_pending; + __u32 tx_pending; +}; + +/** + * struct ethtool_channels - configuring number of network channel + * @cmd: ETHTOOL_{G,S}CHANNELS + * @max_rx: Read only. Maximum number of receive channel the driver support. + * @max_tx: Read only. Maximum number of transmit channel the driver support. + * @max_other: Read only. Maximum number of other channel the driver support. + * @max_combined: Read only. Maximum number of combined channel the driver + * support. Set of queues RX, TX or other. + * @rx_count: Valid values are in the range 1 to the max_rx. + * @tx_count: Valid values are in the range 1 to the max_tx. + * @other_count: Valid values are in the range 1 to the max_other. + * @combined_count: Valid values are in the range 1 to the max_combined. + * + * This can be used to configure RX, TX and other channels. + */ + +struct ethtool_channels { + __u32 cmd; + __u32 max_rx; + __u32 max_tx; + __u32 max_other; + __u32 max_combined; + __u32 rx_count; + __u32 tx_count; + __u32 other_count; + __u32 combined_count; +}; + +/** + * struct ethtool_pauseparam - Ethernet pause (flow control) parameters + * @cmd: Command number = %ETHTOOL_GPAUSEPARAM or %ETHTOOL_SPAUSEPARAM + * @autoneg: Flag to enable autonegotiation of pause frame use + * @rx_pause: Flag to enable reception of pause frames + * @tx_pause: Flag to enable transmission of pause frames + * + * Drivers should reject a non-zero setting of @autoneg when + * autoneogotiation is disabled (or not supported) for the link. + * + * If the link is autonegotiated, drivers should use + * mii_advertise_flowctrl() or similar code to set the advertised + * pause frame capabilities based on the @rx_pause and @tx_pause flags, + * even if @autoneg is zero. They should also allow the advertised + * pause frame capabilities to be controlled directly through the + * advertising field of &struct ethtool_cmd. + * + * If @autoneg is non-zero, the MAC is configured to send and/or + * receive pause frames according to the result of autonegotiation. + * Otherwise, it is configured directly based on the @rx_pause and + * @tx_pause flags. + */ +struct ethtool_pauseparam { + __u32 cmd; + __u32 autoneg; + __u32 rx_pause; + __u32 tx_pause; +}; + +/* Link extended state */ +enum ethtool_link_ext_state { + ETHTOOL_LINK_EXT_STATE_AUTONEG, + ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, + ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH, + ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY, + ETHTOOL_LINK_EXT_STATE_NO_CABLE, + ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, + ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE, + ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE, + ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED, + ETHTOOL_LINK_EXT_STATE_OVERHEAT, + ETHTOOL_LINK_EXT_STATE_MODULE, +}; + +/* More information in addition to ETHTOOL_LINK_EXT_STATE_AUTONEG. */ +enum ethtool_link_ext_substate_autoneg { + ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED = 1, + ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED, + ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED, + ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE, + ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE, + ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD, +}; + +/* More information in addition to ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE. + */ +enum ethtool_link_ext_substate_link_training { + ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED = 1, + ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT, + ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY, + ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT, +}; + +/* More information in addition to ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH. + */ +enum ethtool_link_ext_substate_link_logical_mismatch { + ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK = 1, + ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK, + ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS, + ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED, + ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED, +}; + +/* More information in addition to ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY. + */ +enum ethtool_link_ext_substate_bad_signal_integrity { + ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS = 1, + ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE, + ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_REFERENCE_CLOCK_LOST, + ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_ALOS, +}; + +/* More information in addition to ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE. */ +enum ethtool_link_ext_substate_cable_issue { + ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE = 1, + ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE, +}; + +/* More information in addition to ETHTOOL_LINK_EXT_STATE_MODULE. */ +enum ethtool_link_ext_substate_module { + ETHTOOL_LINK_EXT_SUBSTATE_MODULE_CMIS_NOT_READY = 1, +}; + +#define ETH_GSTRING_LEN 32 + +/** + * enum ethtool_stringset - string set ID + * @ETH_SS_TEST: Self-test result names, for use with %ETHTOOL_TEST + * @ETH_SS_STATS: Statistic names, for use with %ETHTOOL_GSTATS + * @ETH_SS_PRIV_FLAGS: Driver private flag names, for use with + * %ETHTOOL_GPFLAGS and %ETHTOOL_SPFLAGS + * @ETH_SS_NTUPLE_FILTERS: Previously used with %ETHTOOL_GRXNTUPLE; + * now deprecated + * @ETH_SS_FEATURES: Device feature names + * @ETH_SS_RSS_HASH_FUNCS: RSS hush function names + * @ETH_SS_TUNABLES: tunable names + * @ETH_SS_PHY_STATS: Statistic names, for use with %ETHTOOL_GPHYSTATS + * @ETH_SS_PHY_TUNABLES: PHY tunable names + * @ETH_SS_LINK_MODES: link mode names + * @ETH_SS_MSG_CLASSES: debug message class names + * @ETH_SS_WOL_MODES: wake-on-lan modes + * @ETH_SS_SOF_TIMESTAMPING: SOF_TIMESTAMPING_* flags + * @ETH_SS_TS_TX_TYPES: timestamping Tx types + * @ETH_SS_TS_RX_FILTERS: timestamping Rx filters + * @ETH_SS_UDP_TUNNEL_TYPES: UDP tunnel types + * @ETH_SS_STATS_STD: standardized stats + * @ETH_SS_STATS_ETH_PHY: names of IEEE 802.3 PHY statistics + * @ETH_SS_STATS_ETH_MAC: names of IEEE 802.3 MAC statistics + * @ETH_SS_STATS_ETH_CTRL: names of IEEE 802.3 MAC Control statistics + * @ETH_SS_STATS_RMON: names of RMON statistics + * + * @ETH_SS_COUNT: number of defined string sets + */ +enum ethtool_stringset { + ETH_SS_TEST = 0, + ETH_SS_STATS, + ETH_SS_PRIV_FLAGS, + ETH_SS_NTUPLE_FILTERS, + ETH_SS_FEATURES, + ETH_SS_RSS_HASH_FUNCS, + ETH_SS_TUNABLES, + ETH_SS_PHY_STATS, + ETH_SS_PHY_TUNABLES, + ETH_SS_LINK_MODES, + ETH_SS_MSG_CLASSES, + ETH_SS_WOL_MODES, + ETH_SS_SOF_TIMESTAMPING, + ETH_SS_TS_TX_TYPES, + ETH_SS_TS_RX_FILTERS, + ETH_SS_UDP_TUNNEL_TYPES, + ETH_SS_STATS_STD, + ETH_SS_STATS_ETH_PHY, + ETH_SS_STATS_ETH_MAC, + ETH_SS_STATS_ETH_CTRL, + ETH_SS_STATS_RMON, + + /* add new constants above here */ + ETH_SS_COUNT +}; + +/** + * enum ethtool_module_power_mode_policy - plug-in module power mode policy + * @ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH: Module is always in high power mode. + * @ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO: Module is transitioned by the host + * to high power mode when the first port using it is put administratively + * up and to low power mode when the last port using it is put + * administratively down. + */ +enum ethtool_module_power_mode_policy { + ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH = 1, + ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO, +}; + +/** + * enum ethtool_module_power_mode - plug-in module power mode + * @ETHTOOL_MODULE_POWER_MODE_LOW: Module is in low power mode. + * @ETHTOOL_MODULE_POWER_MODE_HIGH: Module is in high power mode. + */ +enum ethtool_module_power_mode { + ETHTOOL_MODULE_POWER_MODE_LOW = 1, + ETHTOOL_MODULE_POWER_MODE_HIGH, +}; + +/** + * enum ethtool_podl_pse_admin_state - operational state of the PoDL PSE + * functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState + * @ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN: state of PoDL PSE functions are + * unknown + * @ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED: PoDL PSE functions are disabled + * @ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED: PoDL PSE functions are enabled + */ +enum ethtool_podl_pse_admin_state { + ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN = 1, + ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED, + ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED, +}; + +/** + * enum ethtool_podl_pse_pw_d_status - power detection status of the PoDL PSE. + * IEEE 802.3-2018 30.15.1.1.3 aPoDLPSEPowerDetectionStatus: + * @ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN: PoDL PSE + * @ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED: "The enumeration “disabled” is + * asserted true when the PoDL PSE state diagram variable mr_pse_enable is + * false" + * @ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING: "The enumeration “searching” is + * asserted true when either of the PSE state diagram variables + * pi_detecting or pi_classifying is true." + * @ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING: "The enumeration “deliveringPower” + * is asserted true when the PoDL PSE state diagram variable pi_powered is + * true." + * @ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP: "The enumeration “sleep” is asserted + * true when the PoDL PSE state diagram variable pi_sleeping is true." + * @ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE: "The enumeration “idle” is asserted true + * when the logical combination of the PoDL PSE state diagram variables + * pi_prebiased*!pi_sleeping is true." + * @ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR: "The enumeration “error” is asserted + * true when the PoDL PSE state diagram variable overload_held is true." + */ +enum ethtool_podl_pse_pw_d_status { + ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN = 1, + ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED, + ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING, + ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING, + ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP, + ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE, + ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR, +}; + +/** + * struct ethtool_gstrings - string set for data tagging + * @cmd: Command number = %ETHTOOL_GSTRINGS + * @string_set: String set ID; one of &enum ethtool_stringset + * @len: On return, the number of strings in the string set + * @data: Buffer for strings. Each string is null-padded to a size of + * %ETH_GSTRING_LEN. + * + * Users must use %ETHTOOL_GSSET_INFO to find the number of strings in + * the string set. They must allocate a buffer of the appropriate + * size immediately following this structure. + */ +struct ethtool_gstrings { + __u32 cmd; + __u32 string_set; + __u32 len; + __u8 data[]; +}; + +/** + * struct ethtool_sset_info - string set information + * @cmd: Command number = %ETHTOOL_GSSET_INFO + * @reserved: Reserved for future use; see the note on reserved space. + * @sset_mask: On entry, a bitmask of string sets to query, with bits + * numbered according to &enum ethtool_stringset. On return, a + * bitmask of those string sets queried that are supported. + * @data: Buffer for string set sizes. On return, this contains the + * size of each string set that was queried and supported, in + * order of ID. + * + * Example: The user passes in @sset_mask = 0x7 (sets 0, 1, 2) and on + * return @sset_mask == 0x6 (sets 1, 2). Then @data[0] contains the + * size of set 1 and @data[1] contains the size of set 2. + * + * Users must allocate a buffer of the appropriate size (4 * number of + * sets queried) immediately following this structure. + */ +struct ethtool_sset_info { + __u32 cmd; + __u32 reserved; + __u64 sset_mask; + __u32 data[]; +}; + +/** + * enum ethtool_test_flags - flags definition of ethtool_test + * @ETH_TEST_FL_OFFLINE: if set perform online and offline tests, otherwise + * only online tests. + * @ETH_TEST_FL_FAILED: Driver set this flag if test fails. + * @ETH_TEST_FL_EXTERNAL_LB: Application request to perform external loopback + * test. + * @ETH_TEST_FL_EXTERNAL_LB_DONE: Driver performed the external loopback test + */ + +enum ethtool_test_flags { + ETH_TEST_FL_OFFLINE = (1 << 0), + ETH_TEST_FL_FAILED = (1 << 1), + ETH_TEST_FL_EXTERNAL_LB = (1 << 2), + ETH_TEST_FL_EXTERNAL_LB_DONE = (1 << 3), +}; + +/** + * struct ethtool_test - device self-test invocation + * @cmd: Command number = %ETHTOOL_TEST + * @flags: A bitmask of flags from &enum ethtool_test_flags. Some + * flags may be set by the user on entry; others may be set by + * the driver on return. + * @reserved: Reserved for future use; see the note on reserved space. + * @len: On return, the number of test results + * @data: Array of test results + * + * Users must use %ETHTOOL_GSSET_INFO or %ETHTOOL_GDRVINFO to find the + * number of test results that will be returned. They must allocate a + * buffer of the appropriate size (8 * number of results) immediately + * following this structure. + */ +struct ethtool_test { + __u32 cmd; + __u32 flags; + __u32 reserved; + __u32 len; + __u64 data[]; +}; + +/** + * struct ethtool_stats - device-specific statistics + * @cmd: Command number = %ETHTOOL_GSTATS + * @n_stats: On return, the number of statistics + * @data: Array of statistics + * + * Users must use %ETHTOOL_GSSET_INFO or %ETHTOOL_GDRVINFO to find the + * number of statistics that will be returned. They must allocate a + * buffer of the appropriate size (8 * number of statistics) + * immediately following this structure. + */ +struct ethtool_stats { + __u32 cmd; + __u32 n_stats; + __u64 data[]; +}; + +/** + * struct ethtool_perm_addr - permanent hardware address + * @cmd: Command number = %ETHTOOL_GPERMADDR + * @size: On entry, the size of the buffer. On return, the size of the + * address. The command fails if the buffer is too small. + * @data: Buffer for the address + * + * Users must allocate the buffer immediately following this structure. + * A buffer size of %MAX_ADDR_LEN should be sufficient for any address + * type. + */ +struct ethtool_perm_addr { + __u32 cmd; + __u32 size; + __u8 data[]; +}; + +/* boolean flags controlling per-interface behavior characteristics. + * When reading, the flag indicates whether or not a certain behavior + * is enabled/present. When writing, the flag indicates whether + * or not the driver should turn on (set) or off (clear) a behavior. + * + * Some behaviors may read-only (unconditionally absent or present). + * If such is the case, return EINVAL in the set-flags operation if the + * flag differs from the read-only value. + */ +enum ethtool_flags { + ETH_FLAG_TXVLAN = (1 << 7), /* TX VLAN offload enabled */ + ETH_FLAG_RXVLAN = (1 << 8), /* RX VLAN offload enabled */ + ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ + ETH_FLAG_NTUPLE = (1 << 27), /* N-tuple filters enabled */ + ETH_FLAG_RXHASH = (1 << 28), +}; + +/* The following structures are for supporting RX network flow + * classification and RX n-tuple configuration. Note, all multibyte + * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to + * be in network byte order. + */ + +/** + * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc. + * @ip4src: Source host + * @ip4dst: Destination host + * @psrc: Source port + * @pdst: Destination port + * @tos: Type-of-service + * + * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow. + */ +struct ethtool_tcpip4_spec { + __be32 ip4src; + __be32 ip4dst; + __be16 psrc; + __be16 pdst; + __u8 tos; +}; + +/** + * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4 + * @ip4src: Source host + * @ip4dst: Destination host + * @spi: Security parameters index + * @tos: Type-of-service + * + * This can be used to specify an IPsec transport or tunnel over IPv4. + */ +struct ethtool_ah_espip4_spec { + __be32 ip4src; + __be32 ip4dst; + __be32 spi; + __u8 tos; +}; + +#define ETH_RX_NFC_IP4 1 + +/** + * struct ethtool_usrip4_spec - general flow specification for IPv4 + * @ip4src: Source host + * @ip4dst: Destination host + * @l4_4_bytes: First 4 bytes of transport (layer 4) header + * @tos: Type-of-service + * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0 + * @proto: Transport protocol number; mask must be 0 + */ +struct ethtool_usrip4_spec { + __be32 ip4src; + __be32 ip4dst; + __be32 l4_4_bytes; + __u8 tos; + __u8 ip_ver; + __u8 proto; +}; + +/** + * struct ethtool_tcpip6_spec - flow specification for TCP/IPv6 etc. + * @ip6src: Source host + * @ip6dst: Destination host + * @psrc: Source port + * @pdst: Destination port + * @tclass: Traffic Class + * + * This can be used to specify a TCP/IPv6, UDP/IPv6 or SCTP/IPv6 flow. + */ +struct ethtool_tcpip6_spec { + __be32 ip6src[4]; + __be32 ip6dst[4]; + __be16 psrc; + __be16 pdst; + __u8 tclass; +}; + +/** + * struct ethtool_ah_espip6_spec - flow specification for IPsec/IPv6 + * @ip6src: Source host + * @ip6dst: Destination host + * @spi: Security parameters index + * @tclass: Traffic Class + * + * This can be used to specify an IPsec transport or tunnel over IPv6. + */ +struct ethtool_ah_espip6_spec { + __be32 ip6src[4]; + __be32 ip6dst[4]; + __be32 spi; + __u8 tclass; +}; + +/** + * struct ethtool_usrip6_spec - general flow specification for IPv6 + * @ip6src: Source host + * @ip6dst: Destination host + * @l4_4_bytes: First 4 bytes of transport (layer 4) header + * @tclass: Traffic Class + * @l4_proto: Transport protocol number (nexthdr after any Extension Headers) + */ +struct ethtool_usrip6_spec { + __be32 ip6src[4]; + __be32 ip6dst[4]; + __be32 l4_4_bytes; + __u8 tclass; + __u8 l4_proto; +}; + +union ethtool_flow_union { + struct ethtool_tcpip4_spec tcp_ip4_spec; + struct ethtool_tcpip4_spec udp_ip4_spec; + struct ethtool_tcpip4_spec sctp_ip4_spec; + struct ethtool_ah_espip4_spec ah_ip4_spec; + struct ethtool_ah_espip4_spec esp_ip4_spec; + struct ethtool_usrip4_spec usr_ip4_spec; + struct ethtool_tcpip6_spec tcp_ip6_spec; + struct ethtool_tcpip6_spec udp_ip6_spec; + struct ethtool_tcpip6_spec sctp_ip6_spec; + struct ethtool_ah_espip6_spec ah_ip6_spec; + struct ethtool_ah_espip6_spec esp_ip6_spec; + struct ethtool_usrip6_spec usr_ip6_spec; + struct ethhdr ether_spec; + __u8 hdata[52]; +}; + +/** + * struct ethtool_flow_ext - additional RX flow fields + * @h_dest: destination MAC address + * @vlan_etype: VLAN EtherType + * @vlan_tci: VLAN tag control information + * @data: user defined data + * @padding: Reserved for future use; see the note on reserved space. + * + * Note, @vlan_etype, @vlan_tci, and @data are only valid if %FLOW_EXT + * is set in &struct ethtool_rx_flow_spec @flow_type. + * @h_dest is valid if %FLOW_MAC_EXT is set. + */ +struct ethtool_flow_ext { + __u8 padding[2]; + unsigned char h_dest[ETH_ALEN]; + __be16 vlan_etype; + __be16 vlan_tci; + __be32 data[2]; +}; + +/** + * struct ethtool_rx_flow_spec - classification rule for RX flows + * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW + * @h_u: Flow fields to match (dependent on @flow_type) + * @h_ext: Additional fields to match + * @m_u: Masks for flow field bits to be matched + * @m_ext: Masks for additional field bits to be matched + * Note, all additional fields must be ignored unless @flow_type + * includes the %FLOW_EXT or %FLOW_MAC_EXT flag + * (see &struct ethtool_flow_ext description). + * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC + * if packets should be discarded, or %RX_CLS_FLOW_WAKE if the + * packets should be used for Wake-on-LAN with %WAKE_FILTER + * @location: Location of rule in the table. Locations must be + * numbered such that a flow matching multiple rules will be + * classified according to the first (lowest numbered) rule. + */ +struct ethtool_rx_flow_spec { + __u32 flow_type; + union ethtool_flow_union h_u; + struct ethtool_flow_ext h_ext; + union ethtool_flow_union m_u; + struct ethtool_flow_ext m_ext; + __u64 ring_cookie; + __u32 location; +}; + +/* How rings are laid out when accessing virtual functions or + * offloaded queues is device specific. To allow users to do flow + * steering and specify these queues the ring cookie is partitioned + * into a 32bit queue index with an 8 bit virtual function id. + * This also leaves the 3bytes for further specifiers. It is possible + * future devices may support more than 256 virtual functions if + * devices start supporting PCIe w/ARI. However at the moment I + * do not know of any devices that support this so I do not reserve + * space for this at this time. If a future patch consumes the next + * byte it should be aware of this possibility. + */ +#define ETHTOOL_RX_FLOW_SPEC_RING 0x00000000FFFFFFFFLL +#define ETHTOOL_RX_FLOW_SPEC_RING_VF 0x000000FF00000000LL +#define ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF 32 +static __inline__ __u64 ethtool_get_flow_spec_ring(__u64 ring_cookie) +{ + return ETHTOOL_RX_FLOW_SPEC_RING & ring_cookie; +} + +static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie) +{ + return (ETHTOOL_RX_FLOW_SPEC_RING_VF & ring_cookie) >> + ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF; +} + +/** + * struct ethtool_rxnfc - command to get or set RX flow classification rules + * @cmd: Specific command number - %ETHTOOL_GRXFH, %ETHTOOL_SRXFH, + * %ETHTOOL_GRXRINGS, %ETHTOOL_GRXCLSRLCNT, %ETHTOOL_GRXCLSRULE, + * %ETHTOOL_GRXCLSRLALL, %ETHTOOL_SRXCLSRLDEL or %ETHTOOL_SRXCLSRLINS + * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW + * @data: Command-dependent value + * @fs: Flow classification rule + * @rss_context: RSS context to be affected + * @rule_cnt: Number of rules to be affected + * @rule_locs: Array of used rule locations + * + * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating + * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following + * structure fields must not be used, except that if @flow_type includes + * the %FLOW_RSS flag, then @rss_context determines which RSS context to + * act on. + * + * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues + * on return. + * + * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined + * rules on return. If @data is non-zero on return then it is the + * size of the rule table, plus the flag %RX_CLS_LOC_SPECIAL if the + * driver supports any special location values. If that flag is not + * set in @data then special location values should not be used. + * + * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an + * existing rule on entry and @fs contains the rule on return; if + * @fs.@flow_type includes the %FLOW_RSS flag, then @rss_context is + * filled with the RSS context ID associated with the rule. + * + * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the + * user buffer for @rule_locs on entry. On return, @data is the size + * of the rule table, @rule_cnt is the number of defined rules, and + * @rule_locs contains the locations of the defined rules. Drivers + * must use the second parameter to get_rxnfc() instead of @rule_locs. + * + * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update. + * @fs.@location either specifies the location to use or is a special + * location value with %RX_CLS_LOC_SPECIAL flag set. On return, + * @fs.@location is the actual rule location. If @fs.@flow_type + * includes the %FLOW_RSS flag, @rss_context is the RSS context ID to + * use for flow spreading traffic which matches this rule. The value + * from the rxfh indirection table will be added to @fs.@ring_cookie + * to choose which ring to deliver to. + * + * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an + * existing rule on entry. + * + * A driver supporting the special location values for + * %ETHTOOL_SRXCLSRLINS may add the rule at any suitable unused + * location, and may remove a rule at a later location (lower + * priority) that matches exactly the same set of flows. The special + * values are %RX_CLS_LOC_ANY, selecting any location; + * %RX_CLS_LOC_FIRST, selecting the first suitable location (maximum + * priority); and %RX_CLS_LOC_LAST, selecting the last suitable + * location (minimum priority). Additional special values may be + * defined in future and drivers must return -%EINVAL for any + * unrecognised value. + */ +struct ethtool_rxnfc { + __u32 cmd; + __u32 flow_type; + __u64 data; + struct ethtool_rx_flow_spec fs; + union { + __u32 rule_cnt; + __u32 rss_context; + }; + __u32 rule_locs[0]; +}; + + +/** + * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection + * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR + * @size: On entry, the array size of the user buffer, which may be zero. + * On return from %ETHTOOL_GRXFHINDIR, the array size of the hardware + * indirection table. + * @ring_index: RX ring/queue index for each hash value + * + * For %ETHTOOL_GRXFHINDIR, a @size of zero means that only the size + * should be returned. For %ETHTOOL_SRXFHINDIR, a @size of zero means + * the table should be reset to default values. This last feature + * is not supported by the original implementations. + */ +struct ethtool_rxfh_indir { + __u32 cmd; + __u32 size; + __u32 ring_index[]; +}; + +/** + * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key. + * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH + * @rss_context: RSS context identifier. Context 0 is the default for normal + * traffic; other contexts can be referenced as the destination for RX flow + * classification rules. %ETH_RXFH_CONTEXT_ALLOC is used with command + * %ETHTOOL_SRSSH to allocate a new RSS context; on return this field will + * contain the ID of the newly allocated context. + * @indir_size: On entry, the array size of the user buffer for the + * indirection table, which may be zero, or (for %ETHTOOL_SRSSH), + * %ETH_RXFH_INDIR_NO_CHANGE. On return from %ETHTOOL_GRSSH, + * the array size of the hardware indirection table. + * @key_size: On entry, the array size of the user buffer for the hash key, + * which may be zero. On return from %ETHTOOL_GRSSH, the size of the + * hardware hash key. + * @hfunc: Defines the current RSS hash function used by HW (or to be set to). + * Valid values are one of the %ETH_RSS_HASH_*. + * @rsvd8: Reserved for future use; see the note on reserved space. + * @rsvd32: Reserved for future use; see the note on reserved space. + * @rss_config: RX ring/queue index for each hash value i.e., indirection table + * of @indir_size __u32 elements, followed by hash key of @key_size + * bytes. + * + * For %ETHTOOL_GRSSH, a @indir_size and key_size of zero means that only the + * size should be returned. For %ETHTOOL_SRSSH, an @indir_size of + * %ETH_RXFH_INDIR_NO_CHANGE means that indir table setting is not requested + * and a @indir_size of zero means the indir table should be reset to default + * values (if @rss_context == 0) or that the RSS context should be deleted. + * An hfunc of zero means that hash function setting is not requested. + */ +struct ethtool_rxfh { + __u32 cmd; + __u32 rss_context; + __u32 indir_size; + __u32 key_size; + __u8 hfunc; + __u8 rsvd8[3]; + __u32 rsvd32; + __u32 rss_config[]; +}; +#define ETH_RXFH_CONTEXT_ALLOC 0xffffffff +#define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff + +/** + * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter + * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW + * @h_u: Flow field values to match (dependent on @flow_type) + * @m_u: Masks for flow field value bits to be ignored + * @vlan_tag: VLAN tag to match + * @vlan_tag_mask: Mask for VLAN tag bits to be ignored + * @data: Driver-dependent data to match + * @data_mask: Mask for driver-dependent data bits to be ignored + * @action: RX ring/queue index to deliver to (non-negative) or other action + * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP) + * + * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where + * a field value and mask are both zero this is treated as if all mask + * bits are set i.e. the field is ignored. + */ +struct ethtool_rx_ntuple_flow_spec { + __u32 flow_type; + union { + struct ethtool_tcpip4_spec tcp_ip4_spec; + struct ethtool_tcpip4_spec udp_ip4_spec; + struct ethtool_tcpip4_spec sctp_ip4_spec; + struct ethtool_ah_espip4_spec ah_ip4_spec; + struct ethtool_ah_espip4_spec esp_ip4_spec; + struct ethtool_usrip4_spec usr_ip4_spec; + struct ethhdr ether_spec; + __u8 hdata[72]; + } h_u, m_u; + + __u16 vlan_tag; + __u16 vlan_tag_mask; + __u64 data; + __u64 data_mask; + + __s32 action; +#define ETHTOOL_RXNTUPLE_ACTION_DROP (-1) /* drop packet */ +#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2) /* clear filter */ +}; + +/** + * struct ethtool_rx_ntuple - command to set or clear RX flow filter + * @cmd: Command number - %ETHTOOL_SRXNTUPLE + * @fs: Flow filter specification + */ +struct ethtool_rx_ntuple { + __u32 cmd; + struct ethtool_rx_ntuple_flow_spec fs; +}; + +#define ETHTOOL_FLASH_MAX_FILENAME 128 +enum ethtool_flash_op_type { + ETHTOOL_FLASH_ALL_REGIONS = 0, +}; + +/* for passing firmware flashing related parameters */ +struct ethtool_flash { + __u32 cmd; + __u32 region; + char data[ETHTOOL_FLASH_MAX_FILENAME]; +}; + +/** + * struct ethtool_dump - used for retrieving, setting device dump + * @cmd: Command number - %ETHTOOL_GET_DUMP_FLAG, %ETHTOOL_GET_DUMP_DATA, or + * %ETHTOOL_SET_DUMP + * @version: FW version of the dump, filled in by driver + * @flag: driver dependent flag for dump setting, filled in by driver during + * get and filled in by ethtool for set operation. + * flag must be initialized by macro ETH_FW_DUMP_DISABLE value when + * firmware dump is disabled. + * @len: length of dump data, used as the length of the user buffer on entry to + * %ETHTOOL_GET_DUMP_DATA and this is returned as dump length by driver + * for %ETHTOOL_GET_DUMP_FLAG command + * @data: data collected for get dump data operation + */ +struct ethtool_dump { + __u32 cmd; + __u32 version; + __u32 flag; + __u32 len; + __u8 data[]; +}; + +#define ETH_FW_DUMP_DISABLE 0 + +/* for returning and changing feature sets */ + +/** + * struct ethtool_get_features_block - block with state of 32 features + * @available: mask of changeable features + * @requested: mask of features requested to be enabled if possible + * @active: mask of currently enabled features + * @never_changed: mask of features not changeable for any device + */ +struct ethtool_get_features_block { + __u32 available; + __u32 requested; + __u32 active; + __u32 never_changed; +}; + +/** + * struct ethtool_gfeatures - command to get state of device's features + * @cmd: command number = %ETHTOOL_GFEATURES + * @size: On entry, the number of elements in the features[] array; + * on return, the number of elements in features[] needed to hold + * all features + * @features: state of features + */ +struct ethtool_gfeatures { + __u32 cmd; + __u32 size; + struct ethtool_get_features_block features[]; +}; + +/** + * struct ethtool_set_features_block - block with request for 32 features + * @valid: mask of features to be changed + * @requested: values of features to be changed + */ +struct ethtool_set_features_block { + __u32 valid; + __u32 requested; +}; + +/** + * struct ethtool_sfeatures - command to request change in device's features + * @cmd: command number = %ETHTOOL_SFEATURES + * @size: array size of the features[] array + * @features: feature change masks + */ +struct ethtool_sfeatures { + __u32 cmd; + __u32 size; + struct ethtool_set_features_block features[]; +}; + +/** + * struct ethtool_ts_info - holds a device's timestamping and PHC association + * @cmd: command number = %ETHTOOL_GET_TS_INFO + * @so_timestamping: bit mask of the sum of the supported SO_TIMESTAMPING flags + * @phc_index: device index of the associated PHC, or -1 if there is none + * @tx_types: bit mask of the supported hwtstamp_tx_types enumeration values + * @tx_reserved: Reserved for future use; see the note on reserved space. + * @rx_filters: bit mask of the supported hwtstamp_rx_filters enumeration values + * @rx_reserved: Reserved for future use; see the note on reserved space. + * + * The bits in the 'tx_types' and 'rx_filters' fields correspond to + * the 'hwtstamp_tx_types' and 'hwtstamp_rx_filters' enumeration values, + * respectively. For example, if the device supports HWTSTAMP_TX_ON, + * then (1 << HWTSTAMP_TX_ON) in 'tx_types' will be set. + * + * Drivers should only report the filters they actually support without + * upscaling in the SIOCSHWTSTAMP ioctl. If the SIOCSHWSTAMP request for + * HWTSTAMP_FILTER_V1_SYNC is supported by HWTSTAMP_FILTER_V1_EVENT, then the + * driver should only report HWTSTAMP_FILTER_V1_EVENT in this op. + */ +struct ethtool_ts_info { + __u32 cmd; + __u32 so_timestamping; + __s32 phc_index; + __u32 tx_types; + __u32 tx_reserved[3]; + __u32 rx_filters; + __u32 rx_reserved[3]; +}; + +/* + * %ETHTOOL_SFEATURES changes features present in features[].valid to the + * values of corresponding bits in features[].requested. Bits in .requested + * not set in .valid or not changeable are ignored. + * + * Returns %EINVAL when .valid contains undefined or never-changeable bits + * or size is not equal to required number of features words (32-bit blocks). + * Returns >= 0 if request was completed; bits set in the value mean: + * %ETHTOOL_F_UNSUPPORTED - there were bits set in .valid that are not + * changeable (not present in %ETHTOOL_GFEATURES' features[].available) + * those bits were ignored. + * %ETHTOOL_F_WISH - some or all changes requested were recorded but the + * resulting state of bits masked by .valid is not equal to .requested. + * Probably there are other device-specific constraints on some features + * in the set. When %ETHTOOL_F_UNSUPPORTED is set, .valid is considered + * here as though ignored bits were cleared. + * %ETHTOOL_F_COMPAT - some or all changes requested were made by calling + * compatibility functions. Requested offload state cannot be properly + * managed by kernel. + * + * Meaning of bits in the masks are obtained by %ETHTOOL_GSSET_INFO (number of + * bits in the arrays - always multiple of 32) and %ETHTOOL_GSTRINGS commands + * for ETH_SS_FEATURES string set. First entry in the table corresponds to least + * significant bit in features[0] fields. Empty strings mark undefined features. + */ +enum ethtool_sfeatures_retval_bits { + ETHTOOL_F_UNSUPPORTED__BIT, + ETHTOOL_F_WISH__BIT, + ETHTOOL_F_COMPAT__BIT, +}; + +#define ETHTOOL_F_UNSUPPORTED (1 << ETHTOOL_F_UNSUPPORTED__BIT) +#define ETHTOOL_F_WISH (1 << ETHTOOL_F_WISH__BIT) +#define ETHTOOL_F_COMPAT (1 << ETHTOOL_F_COMPAT__BIT) + +#define MAX_NUM_QUEUE 4096 + +/** + * struct ethtool_per_queue_op - apply sub command to the queues in mask. + * @cmd: ETHTOOL_PERQUEUE + * @sub_command: the sub command which apply to each queues + * @queue_mask: Bitmap of the queues which sub command apply to + * @data: A complete command structure following for each of the queues addressed + */ +struct ethtool_per_queue_op { + __u32 cmd; + __u32 sub_command; + __u32 queue_mask[__KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32)]; + char data[]; +}; + +/** + * struct ethtool_fecparam - Ethernet Forward Error Correction parameters + * @cmd: Command number = %ETHTOOL_GFECPARAM or %ETHTOOL_SFECPARAM + * @active_fec: FEC mode which is active on the port, single bit set, GET only. + * @fec: Bitmask of configured FEC modes. + * @reserved: Reserved for future extensions, ignore on GET, write 0 for SET. + * + * Note that @reserved was never validated on input and ethtool user space + * left it uninitialized when calling SET. Hence going forward it can only be + * used to return a value to userspace with GET. + * + * FEC modes supported by the device can be read via %ETHTOOL_GLINKSETTINGS. + * FEC settings are configured by link autonegotiation whenever it's enabled. + * With autoneg on %ETHTOOL_GFECPARAM can be used to read the current mode. + * + * When autoneg is disabled %ETHTOOL_SFECPARAM controls the FEC settings. + * It is recommended that drivers only accept a single bit set in @fec. + * When multiple bits are set in @fec drivers may pick mode in an implementation + * dependent way. Drivers should reject mixing %ETHTOOL_FEC_AUTO_BIT with other + * FEC modes, because it's unclear whether in this case other modes constrain + * AUTO or are independent choices. + * Drivers must reject SET requests if they support none of the requested modes. + * + * If device does not support FEC drivers may use %ETHTOOL_FEC_NONE instead + * of returning %EOPNOTSUPP from %ETHTOOL_GFECPARAM. + * + * See enum ethtool_fec_config_bits for definition of valid bits for both + * @fec and @active_fec. + */ +struct ethtool_fecparam { + __u32 cmd; + /* bitmask of FEC modes */ + __u32 active_fec; + __u32 fec; + __u32 reserved; +}; + +/** + * enum ethtool_fec_config_bits - flags definition of ethtool_fec_configuration + * @ETHTOOL_FEC_NONE_BIT: FEC mode configuration is not supported. Should not + * be used together with other bits. GET only. + * @ETHTOOL_FEC_AUTO_BIT: Select default/best FEC mode automatically, usually + * based link mode and SFP parameters read from module's + * EEPROM. This bit does _not_ mean autonegotiation. + * @ETHTOOL_FEC_OFF_BIT: No FEC Mode + * @ETHTOOL_FEC_RS_BIT: Reed-Solomon FEC Mode + * @ETHTOOL_FEC_BASER_BIT: Base-R/Reed-Solomon FEC Mode + * @ETHTOOL_FEC_LLRS_BIT: Low Latency Reed Solomon FEC Mode (25G/50G Ethernet + * Consortium) + */ +enum ethtool_fec_config_bits { + ETHTOOL_FEC_NONE_BIT, + ETHTOOL_FEC_AUTO_BIT, + ETHTOOL_FEC_OFF_BIT, + ETHTOOL_FEC_RS_BIT, + ETHTOOL_FEC_BASER_BIT, + ETHTOOL_FEC_LLRS_BIT, +}; + +#define ETHTOOL_FEC_NONE (1 << ETHTOOL_FEC_NONE_BIT) +#define ETHTOOL_FEC_AUTO (1 << ETHTOOL_FEC_AUTO_BIT) +#define ETHTOOL_FEC_OFF (1 << ETHTOOL_FEC_OFF_BIT) +#define ETHTOOL_FEC_RS (1 << ETHTOOL_FEC_RS_BIT) +#define ETHTOOL_FEC_BASER (1 << ETHTOOL_FEC_BASER_BIT) +#define ETHTOOL_FEC_LLRS (1 << ETHTOOL_FEC_LLRS_BIT) + +/* CMDs currently supported */ +#define ETHTOOL_GSET 0x00000001 /* DEPRECATED, Get settings. + * Please use ETHTOOL_GLINKSETTINGS + */ +#define ETHTOOL_SSET 0x00000002 /* DEPRECATED, Set settings. + * Please use ETHTOOL_SLINKSETTINGS + */ +#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */ +#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers. */ +#define ETHTOOL_GWOL 0x00000005 /* Get wake-on-lan options. */ +#define ETHTOOL_SWOL 0x00000006 /* Set wake-on-lan options. */ +#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ +#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level. */ +#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation. */ +/* Get link status for host, i.e. whether the interface *and* the + * physical port (if there is one) are up (ethtool_value). */ +#define ETHTOOL_GLINK 0x0000000a +#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ +#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data. */ +#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ +#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */ +#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */ +#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters. */ +#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */ +#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */ +#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */ +#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */ +#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */ +#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */ +#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable + * (ethtool_value) */ +#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable + * (ethtool_value). */ +#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test. */ +#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */ +#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */ +#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */ +#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */ +#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */ +#define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */ +#define ETHTOOL_GUFO 0x00000021 /* Get UFO enable (ethtool_value) */ +#define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */ +#define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */ +#define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ +#define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */ +#define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */ +#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */ +#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */ + +#define ETHTOOL_GRXFH 0x00000029 /* Get RX flow hash configuration */ +#define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */ +#define ETHTOOL_GGRO 0x0000002b /* Get GRO enable (ethtool_value) */ +#define ETHTOOL_SGRO 0x0000002c /* Set GRO enable (ethtool_value) */ +#define ETHTOOL_GRXRINGS 0x0000002d /* Get RX rings available for LB */ +#define ETHTOOL_GRXCLSRLCNT 0x0000002e /* Get RX class rule count */ +#define ETHTOOL_GRXCLSRULE 0x0000002f /* Get RX classification rule */ +#define ETHTOOL_GRXCLSRLALL 0x00000030 /* Get all RX classification rule */ +#define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */ +#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */ +#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */ +#define ETHTOOL_RESET 0x00000034 /* Reset hardware */ +#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */ +#define ETHTOOL_GRXNTUPLE 0x00000036 /* deprecated */ +#define ETHTOOL_GSSET_INFO 0x00000037 /* Get string set info */ +#define ETHTOOL_GRXFHINDIR 0x00000038 /* Get RX flow hash indir'n table */ +#define ETHTOOL_SRXFHINDIR 0x00000039 /* Set RX flow hash indir'n table */ + +#define ETHTOOL_GFEATURES 0x0000003a /* Get device offload settings */ +#define ETHTOOL_SFEATURES 0x0000003b /* Change device offload settings */ +#define ETHTOOL_GCHANNELS 0x0000003c /* Get no of channels */ +#define ETHTOOL_SCHANNELS 0x0000003d /* Set no of channels */ +#define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */ +#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */ +#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */ +#define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */ +#define ETHTOOL_GMODULEINFO 0x00000042 /* Get plug-in module information */ +#define ETHTOOL_GMODULEEEPROM 0x00000043 /* Get plug-in module eeprom */ +#define ETHTOOL_GEEE 0x00000044 /* Get EEE settings */ +#define ETHTOOL_SEEE 0x00000045 /* Set EEE settings */ + +#define ETHTOOL_GRSSH 0x00000046 /* Get RX flow hash configuration */ +#define ETHTOOL_SRSSH 0x00000047 /* Set RX flow hash configuration */ +#define ETHTOOL_GTUNABLE 0x00000048 /* Get tunable configuration */ +#define ETHTOOL_STUNABLE 0x00000049 /* Set tunable configuration */ +#define ETHTOOL_GPHYSTATS 0x0000004a /* get PHY-specific statistics */ + +#define ETHTOOL_PERQUEUE 0x0000004b /* Set per queue options */ + +#define ETHTOOL_GLINKSETTINGS 0x0000004c /* Get ethtool_link_settings */ +#define ETHTOOL_SLINKSETTINGS 0x0000004d /* Set ethtool_link_settings */ +#define ETHTOOL_PHY_GTUNABLE 0x0000004e /* Get PHY tunable configuration */ +#define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */ +#define ETHTOOL_GFECPARAM 0x00000050 /* Get FEC settings */ +#define ETHTOOL_SFECPARAM 0x00000051 /* Set FEC settings */ + +/* compatibility with older code */ +#define SPARC_ETH_GSET ETHTOOL_GSET +#define SPARC_ETH_SSET ETHTOOL_SSET + +/* Link mode bit indices */ +enum ethtool_link_mode_bit_indices { + ETHTOOL_LINK_MODE_10baseT_Half_BIT = 0, + ETHTOOL_LINK_MODE_10baseT_Full_BIT = 1, + ETHTOOL_LINK_MODE_100baseT_Half_BIT = 2, + ETHTOOL_LINK_MODE_100baseT_Full_BIT = 3, + ETHTOOL_LINK_MODE_1000baseT_Half_BIT = 4, + ETHTOOL_LINK_MODE_1000baseT_Full_BIT = 5, + ETHTOOL_LINK_MODE_Autoneg_BIT = 6, + ETHTOOL_LINK_MODE_TP_BIT = 7, + ETHTOOL_LINK_MODE_AUI_BIT = 8, + ETHTOOL_LINK_MODE_MII_BIT = 9, + ETHTOOL_LINK_MODE_FIBRE_BIT = 10, + ETHTOOL_LINK_MODE_BNC_BIT = 11, + ETHTOOL_LINK_MODE_10000baseT_Full_BIT = 12, + ETHTOOL_LINK_MODE_Pause_BIT = 13, + ETHTOOL_LINK_MODE_Asym_Pause_BIT = 14, + ETHTOOL_LINK_MODE_2500baseX_Full_BIT = 15, + ETHTOOL_LINK_MODE_Backplane_BIT = 16, + ETHTOOL_LINK_MODE_1000baseKX_Full_BIT = 17, + ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT = 18, + ETHTOOL_LINK_MODE_10000baseKR_Full_BIT = 19, + ETHTOOL_LINK_MODE_10000baseR_FEC_BIT = 20, + ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT = 21, + ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT = 22, + ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT = 23, + ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT = 24, + ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT = 25, + ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT = 26, + ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT = 27, + ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT = 28, + ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT = 29, + ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT = 30, + ETHTOOL_LINK_MODE_25000baseCR_Full_BIT = 31, + + /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit + * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_* + * macro for bits > 31. The only way to use indices > 31 is to + * use the new ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API. + */ + + ETHTOOL_LINK_MODE_25000baseKR_Full_BIT = 32, + ETHTOOL_LINK_MODE_25000baseSR_Full_BIT = 33, + ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT = 34, + ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT = 35, + ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT = 36, + ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT = 37, + ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT = 38, + ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT = 39, + ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT = 40, + ETHTOOL_LINK_MODE_1000baseX_Full_BIT = 41, + ETHTOOL_LINK_MODE_10000baseCR_Full_BIT = 42, + ETHTOOL_LINK_MODE_10000baseSR_Full_BIT = 43, + ETHTOOL_LINK_MODE_10000baseLR_Full_BIT = 44, + ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT = 45, + ETHTOOL_LINK_MODE_10000baseER_Full_BIT = 46, + ETHTOOL_LINK_MODE_2500baseT_Full_BIT = 47, + ETHTOOL_LINK_MODE_5000baseT_Full_BIT = 48, + + ETHTOOL_LINK_MODE_FEC_NONE_BIT = 49, + ETHTOOL_LINK_MODE_FEC_RS_BIT = 50, + ETHTOOL_LINK_MODE_FEC_BASER_BIT = 51, + ETHTOOL_LINK_MODE_50000baseKR_Full_BIT = 52, + ETHTOOL_LINK_MODE_50000baseSR_Full_BIT = 53, + ETHTOOL_LINK_MODE_50000baseCR_Full_BIT = 54, + ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT = 55, + ETHTOOL_LINK_MODE_50000baseDR_Full_BIT = 56, + ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT = 57, + ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT = 58, + ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT = 59, + ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT = 60, + ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT = 61, + ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT = 62, + ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT = 63, + ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT = 64, + ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT = 65, + ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT = 66, + ETHTOOL_LINK_MODE_100baseT1_Full_BIT = 67, + ETHTOOL_LINK_MODE_1000baseT1_Full_BIT = 68, + ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT = 69, + ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT = 70, + ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT = 71, + ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT = 72, + ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT = 73, + ETHTOOL_LINK_MODE_FEC_LLRS_BIT = 74, + ETHTOOL_LINK_MODE_100000baseKR_Full_BIT = 75, + ETHTOOL_LINK_MODE_100000baseSR_Full_BIT = 76, + ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT = 77, + ETHTOOL_LINK_MODE_100000baseCR_Full_BIT = 78, + ETHTOOL_LINK_MODE_100000baseDR_Full_BIT = 79, + ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT = 80, + ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT = 81, + ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT = 82, + ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT = 83, + ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT = 84, + ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT = 85, + ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT = 86, + ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT = 87, + ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT = 88, + ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT = 89, + ETHTOOL_LINK_MODE_100baseFX_Half_BIT = 90, + ETHTOOL_LINK_MODE_100baseFX_Full_BIT = 91, + ETHTOOL_LINK_MODE_10baseT1L_Full_BIT = 92, + /* must be last entry */ + __ETHTOOL_LINK_MODE_MASK_NBITS +}; + +#define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) \ + (1UL << (ETHTOOL_LINK_MODE_ ## base_name ## _BIT)) + +/* DEPRECATED macros. Please migrate to + * ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API. Please do NOT + * define any new SUPPORTED_* macro for bits > 31. + */ +#define SUPPORTED_10baseT_Half __ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Half) +#define SUPPORTED_10baseT_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Full) +#define SUPPORTED_100baseT_Half __ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Half) +#define SUPPORTED_100baseT_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Full) +#define SUPPORTED_1000baseT_Half __ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Half) +#define SUPPORTED_1000baseT_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Full) +#define SUPPORTED_Autoneg __ETHTOOL_LINK_MODE_LEGACY_MASK(Autoneg) +#define SUPPORTED_TP __ETHTOOL_LINK_MODE_LEGACY_MASK(TP) +#define SUPPORTED_AUI __ETHTOOL_LINK_MODE_LEGACY_MASK(AUI) +#define SUPPORTED_MII __ETHTOOL_LINK_MODE_LEGACY_MASK(MII) +#define SUPPORTED_FIBRE __ETHTOOL_LINK_MODE_LEGACY_MASK(FIBRE) +#define SUPPORTED_BNC __ETHTOOL_LINK_MODE_LEGACY_MASK(BNC) +#define SUPPORTED_10000baseT_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseT_Full) +#define SUPPORTED_Pause __ETHTOOL_LINK_MODE_LEGACY_MASK(Pause) +#define SUPPORTED_Asym_Pause __ETHTOOL_LINK_MODE_LEGACY_MASK(Asym_Pause) +#define SUPPORTED_2500baseX_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(2500baseX_Full) +#define SUPPORTED_Backplane __ETHTOOL_LINK_MODE_LEGACY_MASK(Backplane) +#define SUPPORTED_1000baseKX_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseKX_Full) +#define SUPPORTED_10000baseKX4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKX4_Full) +#define SUPPORTED_10000baseKR_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKR_Full) +#define SUPPORTED_10000baseR_FEC __ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseR_FEC) +#define SUPPORTED_20000baseMLD2_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseMLD2_Full) +#define SUPPORTED_20000baseKR2_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseKR2_Full) +#define SUPPORTED_40000baseKR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseKR4_Full) +#define SUPPORTED_40000baseCR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseCR4_Full) +#define SUPPORTED_40000baseSR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseSR4_Full) +#define SUPPORTED_40000baseLR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseLR4_Full) +#define SUPPORTED_56000baseKR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseKR4_Full) +#define SUPPORTED_56000baseCR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseCR4_Full) +#define SUPPORTED_56000baseSR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseSR4_Full) +#define SUPPORTED_56000baseLR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseLR4_Full) +/* Please do not define any new SUPPORTED_* macro for bits > 31, see + * notice above. + */ + +/* + * DEPRECATED macros. Please migrate to + * ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API. Please do NOT + * define any new ADERTISE_* macro for bits > 31. + */ +#define ADVERTISED_10baseT_Half __ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Half) +#define ADVERTISED_10baseT_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Full) +#define ADVERTISED_100baseT_Half __ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Half) +#define ADVERTISED_100baseT_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(100baseT_Full) +#define ADVERTISED_1000baseT_Half __ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Half) +#define ADVERTISED_1000baseT_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseT_Full) +#define ADVERTISED_Autoneg __ETHTOOL_LINK_MODE_LEGACY_MASK(Autoneg) +#define ADVERTISED_TP __ETHTOOL_LINK_MODE_LEGACY_MASK(TP) +#define ADVERTISED_AUI __ETHTOOL_LINK_MODE_LEGACY_MASK(AUI) +#define ADVERTISED_MII __ETHTOOL_LINK_MODE_LEGACY_MASK(MII) +#define ADVERTISED_FIBRE __ETHTOOL_LINK_MODE_LEGACY_MASK(FIBRE) +#define ADVERTISED_BNC __ETHTOOL_LINK_MODE_LEGACY_MASK(BNC) +#define ADVERTISED_10000baseT_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseT_Full) +#define ADVERTISED_Pause __ETHTOOL_LINK_MODE_LEGACY_MASK(Pause) +#define ADVERTISED_Asym_Pause __ETHTOOL_LINK_MODE_LEGACY_MASK(Asym_Pause) +#define ADVERTISED_2500baseX_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(2500baseX_Full) +#define ADVERTISED_Backplane __ETHTOOL_LINK_MODE_LEGACY_MASK(Backplane) +#define ADVERTISED_1000baseKX_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(1000baseKX_Full) +#define ADVERTISED_10000baseKX4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKX4_Full) +#define ADVERTISED_10000baseKR_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseKR_Full) +#define ADVERTISED_10000baseR_FEC __ETHTOOL_LINK_MODE_LEGACY_MASK(10000baseR_FEC) +#define ADVERTISED_20000baseMLD2_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseMLD2_Full) +#define ADVERTISED_20000baseKR2_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(20000baseKR2_Full) +#define ADVERTISED_40000baseKR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseKR4_Full) +#define ADVERTISED_40000baseCR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseCR4_Full) +#define ADVERTISED_40000baseSR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseSR4_Full) +#define ADVERTISED_40000baseLR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(40000baseLR4_Full) +#define ADVERTISED_56000baseKR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseKR4_Full) +#define ADVERTISED_56000baseCR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseCR4_Full) +#define ADVERTISED_56000baseSR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseSR4_Full) +#define ADVERTISED_56000baseLR4_Full __ETHTOOL_LINK_MODE_LEGACY_MASK(56000baseLR4_Full) +/* Please do not define any new ADVERTISED_* macro for bits > 31, see + * notice above. + */ + +/* The following are all involved in forcing a particular link + * mode for the device for setting things. When getting the + * devices settings, these indicate the current mode and whether + * it was forced up into this mode or autonegotiated. + */ + +/* The forced speed, in units of 1Mb. All values 0 to INT_MAX are legal. + * Update drivers/net/phy/phy.c:phy_speed_to_str() and + * drivers/net/bonding/bond_3ad.c:__get_link_speed() when adding new values. + */ +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 +#define SPEED_2500 2500 +#define SPEED_5000 5000 +#define SPEED_10000 10000 +#define SPEED_14000 14000 +#define SPEED_20000 20000 +#define SPEED_25000 25000 +#define SPEED_40000 40000 +#define SPEED_50000 50000 +#define SPEED_56000 56000 +#define SPEED_100000 100000 +#define SPEED_200000 200000 +#define SPEED_400000 400000 + +#define SPEED_UNKNOWN -1 + +static __inline__ int ethtool_validate_speed(__u32 speed) +{ + return speed <= INT_MAX || speed == (__u32)SPEED_UNKNOWN; +} + +/* Duplex, half or full. */ +#define DUPLEX_HALF 0x00 +#define DUPLEX_FULL 0x01 +#define DUPLEX_UNKNOWN 0xff + +static __inline__ int ethtool_validate_duplex(__u8 duplex) +{ + switch (duplex) { + case DUPLEX_HALF: + case DUPLEX_FULL: + case DUPLEX_UNKNOWN: + return 1; + } + + return 0; +} + +#define MASTER_SLAVE_CFG_UNSUPPORTED 0 +#define MASTER_SLAVE_CFG_UNKNOWN 1 +#define MASTER_SLAVE_CFG_MASTER_PREFERRED 2 +#define MASTER_SLAVE_CFG_SLAVE_PREFERRED 3 +#define MASTER_SLAVE_CFG_MASTER_FORCE 4 +#define MASTER_SLAVE_CFG_SLAVE_FORCE 5 +#define MASTER_SLAVE_STATE_UNSUPPORTED 0 +#define MASTER_SLAVE_STATE_UNKNOWN 1 +#define MASTER_SLAVE_STATE_MASTER 2 +#define MASTER_SLAVE_STATE_SLAVE 3 +#define MASTER_SLAVE_STATE_ERR 4 + +/* These are used to throttle the rate of data on the phy interface when the + * native speed of the interface is higher than the link speed. These should + * not be used for phy interfaces which natively support multiple speeds (e.g. + * MII or SGMII). + */ +/* No rate matching performed. */ +#define RATE_MATCH_NONE 0 +/* The phy sends pause frames to throttle the MAC. */ +#define RATE_MATCH_PAUSE 1 +/* The phy asserts CRS to prevent the MAC from transmitting. */ +#define RATE_MATCH_CRS 2 +/* The MAC is programmed with a sufficiently-large IPG. */ +#define RATE_MATCH_OPEN_LOOP 3 + +/* Which connector port. */ +#define PORT_TP 0x00 +#define PORT_AUI 0x01 +#define PORT_MII 0x02 +#define PORT_FIBRE 0x03 +#define PORT_BNC 0x04 +#define PORT_DA 0x05 +#define PORT_NONE 0xef +#define PORT_OTHER 0xff + +/* Which transceiver to use. */ +#define XCVR_INTERNAL 0x00 /* PHY and MAC are in the same package */ +#define XCVR_EXTERNAL 0x01 /* PHY and MAC are in different packages */ +#define XCVR_DUMMY1 0x02 +#define XCVR_DUMMY2 0x03 +#define XCVR_DUMMY3 0x04 + +/* Enable or disable autonegotiation. */ +#define AUTONEG_DISABLE 0x00 +#define AUTONEG_ENABLE 0x01 + +/* MDI or MDI-X status/control - if MDI/MDI_X/AUTO is set then + * the driver is required to renegotiate link + */ +#define ETH_TP_MDI_INVALID 0x00 /* status: unknown; control: unsupported */ +#define ETH_TP_MDI 0x01 /* status: MDI; control: force MDI */ +#define ETH_TP_MDI_X 0x02 /* status: MDI-X; control: force MDI-X */ +#define ETH_TP_MDI_AUTO 0x03 /* control: auto-select */ + +/* Wake-On-Lan options. */ +#define WAKE_PHY (1 << 0) +#define WAKE_UCAST (1 << 1) +#define WAKE_MCAST (1 << 2) +#define WAKE_BCAST (1 << 3) +#define WAKE_ARP (1 << 4) +#define WAKE_MAGIC (1 << 5) +#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ +#define WAKE_FILTER (1 << 7) + +#define WOL_MODE_COUNT 8 + +/* L2-L4 network traffic flow types */ +#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */ +#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */ +#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */ +#define AH_ESP_V4_FLOW 0x04 /* hash only */ +#define TCP_V6_FLOW 0x05 /* hash or spec (tcp_ip6_spec; nfc only) */ +#define UDP_V6_FLOW 0x06 /* hash or spec (udp_ip6_spec; nfc only) */ +#define SCTP_V6_FLOW 0x07 /* hash or spec (sctp_ip6_spec; nfc only) */ +#define AH_ESP_V6_FLOW 0x08 /* hash only */ +#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */ +#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */ +#define AH_V6_FLOW 0x0b /* hash or spec (ah_ip6_spec; nfc only) */ +#define ESP_V6_FLOW 0x0c /* hash or spec (esp_ip6_spec; nfc only) */ +#define IPV4_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */ +#define IP_USER_FLOW IPV4_USER_FLOW +#define IPV6_USER_FLOW 0x0e /* spec only (usr_ip6_spec; nfc only) */ +#define IPV4_FLOW 0x10 /* hash only */ +#define IPV6_FLOW 0x11 /* hash only */ +#define ETHER_FLOW 0x12 /* spec only (ether_spec) */ +/* Flag to enable additional fields in struct ethtool_rx_flow_spec */ +#define FLOW_EXT 0x80000000 +#define FLOW_MAC_EXT 0x40000000 +/* Flag to enable RSS spreading of traffic matching rule (nfc only) */ +#define FLOW_RSS 0x20000000 + +/* L3-L4 network traffic flow hash options */ +#define RXH_L2DA (1 << 1) +#define RXH_VLAN (1 << 2) +#define RXH_L3_PROTO (1 << 3) +#define RXH_IP_SRC (1 << 4) +#define RXH_IP_DST (1 << 5) +#define RXH_L4_B_0_1 (1 << 6) /* src port in case of TCP/UDP/SCTP */ +#define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */ +#define RXH_DISCARD (1 << 31) + +#define RX_CLS_FLOW_DISC 0xffffffffffffffffULL +#define RX_CLS_FLOW_WAKE 0xfffffffffffffffeULL + +/* Special RX classification rule insert location values */ +#define RX_CLS_LOC_SPECIAL 0x80000000 /* flag */ +#define RX_CLS_LOC_ANY 0xffffffff +#define RX_CLS_LOC_FIRST 0xfffffffe +#define RX_CLS_LOC_LAST 0xfffffffd + +/* EEPROM Standards for plug in modules */ +#define ETH_MODULE_SFF_8079 0x1 +#define ETH_MODULE_SFF_8079_LEN 256 +#define ETH_MODULE_SFF_8472 0x2 +#define ETH_MODULE_SFF_8472_LEN 512 +#define ETH_MODULE_SFF_8636 0x3 +#define ETH_MODULE_SFF_8636_LEN 256 +#define ETH_MODULE_SFF_8436 0x4 +#define ETH_MODULE_SFF_8436_LEN 256 + +#define ETH_MODULE_SFF_8636_MAX_LEN 640 +#define ETH_MODULE_SFF_8436_MAX_LEN 640 + +/* Reset flags */ +/* The reset() operation must clear the flags for the components which + * were actually reset. On successful return, the flags indicate the + * components which were not reset, either because they do not exist + * in the hardware or because they cannot be reset independently. The + * driver must never reset any components that were not requested. + */ +enum ethtool_reset_flags { + /* These flags represent components dedicated to the interface + * the command is addressed to. Shift any flag left by + * ETH_RESET_SHARED_SHIFT to reset a shared component of the + * same type. + */ + ETH_RESET_MGMT = 1 << 0, /* Management processor */ + ETH_RESET_IRQ = 1 << 1, /* Interrupt requester */ + ETH_RESET_DMA = 1 << 2, /* DMA engine */ + ETH_RESET_FILTER = 1 << 3, /* Filtering/flow direction */ + ETH_RESET_OFFLOAD = 1 << 4, /* Protocol offload */ + ETH_RESET_MAC = 1 << 5, /* Media access controller */ + ETH_RESET_PHY = 1 << 6, /* Transceiver/PHY */ + ETH_RESET_RAM = 1 << 7, /* RAM shared between + * multiple components */ + ETH_RESET_AP = 1 << 8, /* Application processor */ + + ETH_RESET_DEDICATED = 0x0000ffff, /* All components dedicated to + * this interface */ + ETH_RESET_ALL = 0xffffffff, /* All components used by this + * interface, even if shared */ +}; +#define ETH_RESET_SHARED_SHIFT 16 + + +/** + * struct ethtool_link_settings - link control and status + * + * IMPORTANT, Backward compatibility notice: When implementing new + * user-space tools, please first try %ETHTOOL_GLINKSETTINGS, and + * if it succeeds use %ETHTOOL_SLINKSETTINGS to change link + * settings; do not use %ETHTOOL_SSET if %ETHTOOL_GLINKSETTINGS + * succeeded: stick to %ETHTOOL_GLINKSETTINGS/%SLINKSETTINGS in + * that case. Conversely, if %ETHTOOL_GLINKSETTINGS fails, use + * %ETHTOOL_GSET to query and %ETHTOOL_SSET to change link + * settings; do not use %ETHTOOL_SLINKSETTINGS if + * %ETHTOOL_GLINKSETTINGS failed: stick to + * %ETHTOOL_GSET/%ETHTOOL_SSET in that case. + * + * @cmd: Command number = %ETHTOOL_GLINKSETTINGS or %ETHTOOL_SLINKSETTINGS + * @speed: Link speed (Mbps) + * @duplex: Duplex mode; one of %DUPLEX_* + * @port: Physical connector type; one of %PORT_* + * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not + * applicable. For clause 45 PHYs this is the PRTAD. + * @autoneg: Enable/disable autonegotiation and auto-detection; + * either %AUTONEG_DISABLE or %AUTONEG_ENABLE + * @mdio_support: Bitmask of %ETH_MDIO_SUPPORTS_* flags for the MDIO + * protocols supported by the interface; 0 if unknown. + * Read-only. + * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of + * %ETH_TP_MDI_*. If the status is unknown or not applicable, the + * value will be %ETH_TP_MDI_INVALID. Read-only. + * @eth_tp_mdix_ctrl: Ethernet twisted pair MDI(-X) control; one of + * %ETH_TP_MDI_*. If MDI(-X) control is not implemented, reads + * yield %ETH_TP_MDI_INVALID and writes may be ignored or rejected. + * When written successfully, the link should be renegotiated if + * necessary. + * @link_mode_masks_nwords: Number of 32-bit words for each of the + * supported, advertising, lp_advertising link mode bitmaps. For + * %ETHTOOL_GLINKSETTINGS: on entry, number of words passed by user + * (>= 0); on return, if handshake in progress, negative if + * request size unsupported by kernel: absolute value indicates + * kernel expected size and all the other fields but cmd + * are 0; otherwise (handshake completed), strictly positive + * to indicate size used by kernel and cmd field stays + * %ETHTOOL_GLINKSETTINGS, all other fields populated by driver. For + * %ETHTOOL_SLINKSETTINGS: must be valid on entry, ie. a positive + * value returned previously by %ETHTOOL_GLINKSETTINGS, otherwise + * refused. For drivers: ignore this field (use kernel's + * __ETHTOOL_LINK_MODE_MASK_NBITS instead), any change to it will + * be overwritten by kernel. + * @supported: Bitmap with each bit meaning given by + * %ethtool_link_mode_bit_indices for the link modes, physical + * connectors and other link features for which the interface + * supports autonegotiation or auto-detection. Read-only. + * @advertising: Bitmap with each bit meaning given by + * %ethtool_link_mode_bit_indices for the link modes, physical + * connectors and other link features that are advertised through + * autonegotiation or enabled for auto-detection. + * @lp_advertising: Bitmap with each bit meaning given by + * %ethtool_link_mode_bit_indices for the link modes, and other + * link features that the link partner advertised through + * autonegotiation; 0 if unknown or not applicable. Read-only. + * @transceiver: Used to distinguish different possible PHY types, + * reported consistently by PHYLIB. Read-only. + * @master_slave_cfg: Master/slave port mode. + * @master_slave_state: Master/slave port state. + * @rate_matching: Rate adaptation performed by the PHY + * @reserved: Reserved for future use; see the note on reserved space. + * @link_mode_masks: Variable length bitmaps. + * + * If autonegotiation is disabled, the speed and @duplex represent the + * fixed link mode and are writable if the driver supports multiple + * link modes. If it is enabled then they are read-only; if the link + * is up they represent the negotiated link mode; if the link is down, + * the speed is 0, %SPEED_UNKNOWN or the highest enabled speed and + * @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode. + * + * Some hardware interfaces may have multiple PHYs and/or physical + * connectors fitted or do not allow the driver to detect which are + * fitted. For these interfaces @port and/or @phy_address may be + * writable, possibly dependent on @autoneg being %AUTONEG_DISABLE. + * Otherwise, attempts to write different values may be ignored or + * rejected. + * + * Deprecated %ethtool_cmd fields transceiver, maxtxpkt and maxrxpkt + * are not available in %ethtool_link_settings. These fields will be + * always set to zero in %ETHTOOL_GSET reply and %ETHTOOL_SSET will + * fail if any of them is set to non-zero value. + * + * Users should assume that all fields not marked read-only are + * writable and subject to validation by the driver. They should use + * %ETHTOOL_GLINKSETTINGS to get the current values before making specific + * changes and then applying them with %ETHTOOL_SLINKSETTINGS. + * + * Drivers that implement %get_link_ksettings and/or + * %set_link_ksettings should ignore the @cmd + * and @link_mode_masks_nwords fields (any change to them overwritten + * by kernel), and rely only on kernel's internal + * %__ETHTOOL_LINK_MODE_MASK_NBITS and + * %ethtool_link_mode_mask_t. Drivers that implement + * %set_link_ksettings() should validate all fields other than @cmd + * and @link_mode_masks_nwords that are not described as read-only or + * deprecated, and must ignore all fields described as read-only. + */ +struct ethtool_link_settings { + __u32 cmd; + __u32 speed; + __u8 duplex; + __u8 port; + __u8 phy_address; + __u8 autoneg; + __u8 mdio_support; + __u8 eth_tp_mdix; + __u8 eth_tp_mdix_ctrl; + __s8 link_mode_masks_nwords; + __u8 transceiver; + __u8 master_slave_cfg; + __u8 master_slave_state; + __u8 rate_matching; + __u32 reserved[7]; + __u32 link_mode_masks[]; + /* layout of link_mode_masks fields: + * __u32 map_supported[link_mode_masks_nwords]; + * __u32 map_advertising[link_mode_masks_nwords]; + * __u32 map_lp_advertising[link_mode_masks_nwords]; + */ +}; +#endif /* _LINUX_ETHTOOL_H */ diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h new file mode 100644 index 0000000..ed46d35 --- /dev/null +++ b/uapi/linux/ethtool_netlink.h @@ -0,0 +1,888 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +/* + * include/uapi/linux/ethtool_netlink.h - netlink interface for ethtool + * + * See Documentation/networking/ethtool-netlink.rst in kernel source tree for + * doucumentation of the interface. + */ + +#ifndef _LINUX_ETHTOOL_NETLINK_H_ +#define _LINUX_ETHTOOL_NETLINK_H_ + +#include + +/* message types - userspace to kernel */ +enum { + ETHTOOL_MSG_USER_NONE, + ETHTOOL_MSG_STRSET_GET, + ETHTOOL_MSG_LINKINFO_GET, + ETHTOOL_MSG_LINKINFO_SET, + ETHTOOL_MSG_LINKMODES_GET, + ETHTOOL_MSG_LINKMODES_SET, + ETHTOOL_MSG_LINKSTATE_GET, + ETHTOOL_MSG_DEBUG_GET, + ETHTOOL_MSG_DEBUG_SET, + ETHTOOL_MSG_WOL_GET, + ETHTOOL_MSG_WOL_SET, + ETHTOOL_MSG_FEATURES_GET, + ETHTOOL_MSG_FEATURES_SET, + ETHTOOL_MSG_PRIVFLAGS_GET, + ETHTOOL_MSG_PRIVFLAGS_SET, + ETHTOOL_MSG_RINGS_GET, + ETHTOOL_MSG_RINGS_SET, + ETHTOOL_MSG_CHANNELS_GET, + ETHTOOL_MSG_CHANNELS_SET, + ETHTOOL_MSG_COALESCE_GET, + ETHTOOL_MSG_COALESCE_SET, + ETHTOOL_MSG_PAUSE_GET, + ETHTOOL_MSG_PAUSE_SET, + ETHTOOL_MSG_EEE_GET, + ETHTOOL_MSG_EEE_SET, + ETHTOOL_MSG_TSINFO_GET, + ETHTOOL_MSG_CABLE_TEST_ACT, + ETHTOOL_MSG_CABLE_TEST_TDR_ACT, + ETHTOOL_MSG_TUNNEL_INFO_GET, + ETHTOOL_MSG_FEC_GET, + ETHTOOL_MSG_FEC_SET, + ETHTOOL_MSG_MODULE_EEPROM_GET, + ETHTOOL_MSG_STATS_GET, + ETHTOOL_MSG_PHC_VCLOCKS_GET, + ETHTOOL_MSG_MODULE_GET, + ETHTOOL_MSG_MODULE_SET, + ETHTOOL_MSG_PSE_GET, + ETHTOOL_MSG_PSE_SET, + + /* add new constants above here */ + __ETHTOOL_MSG_USER_CNT, + ETHTOOL_MSG_USER_MAX = __ETHTOOL_MSG_USER_CNT - 1 +}; + +/* message types - kernel to userspace */ +enum { + ETHTOOL_MSG_KERNEL_NONE, + ETHTOOL_MSG_STRSET_GET_REPLY, + ETHTOOL_MSG_LINKINFO_GET_REPLY, + ETHTOOL_MSG_LINKINFO_NTF, + ETHTOOL_MSG_LINKMODES_GET_REPLY, + ETHTOOL_MSG_LINKMODES_NTF, + ETHTOOL_MSG_LINKSTATE_GET_REPLY, + ETHTOOL_MSG_DEBUG_GET_REPLY, + ETHTOOL_MSG_DEBUG_NTF, + ETHTOOL_MSG_WOL_GET_REPLY, + ETHTOOL_MSG_WOL_NTF, + ETHTOOL_MSG_FEATURES_GET_REPLY, + ETHTOOL_MSG_FEATURES_SET_REPLY, + ETHTOOL_MSG_FEATURES_NTF, + ETHTOOL_MSG_PRIVFLAGS_GET_REPLY, + ETHTOOL_MSG_PRIVFLAGS_NTF, + ETHTOOL_MSG_RINGS_GET_REPLY, + ETHTOOL_MSG_RINGS_NTF, + ETHTOOL_MSG_CHANNELS_GET_REPLY, + ETHTOOL_MSG_CHANNELS_NTF, + ETHTOOL_MSG_COALESCE_GET_REPLY, + ETHTOOL_MSG_COALESCE_NTF, + ETHTOOL_MSG_PAUSE_GET_REPLY, + ETHTOOL_MSG_PAUSE_NTF, + ETHTOOL_MSG_EEE_GET_REPLY, + ETHTOOL_MSG_EEE_NTF, + ETHTOOL_MSG_TSINFO_GET_REPLY, + ETHTOOL_MSG_CABLE_TEST_NTF, + ETHTOOL_MSG_CABLE_TEST_TDR_NTF, + ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY, + ETHTOOL_MSG_FEC_GET_REPLY, + ETHTOOL_MSG_FEC_NTF, + ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY, + ETHTOOL_MSG_STATS_GET_REPLY, + ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY, + ETHTOOL_MSG_MODULE_GET_REPLY, + ETHTOOL_MSG_MODULE_NTF, + ETHTOOL_MSG_PSE_GET_REPLY, + + /* add new constants above here */ + __ETHTOOL_MSG_KERNEL_CNT, + ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1 +}; + +/* request header */ + +/* use compact bitsets in reply */ +#define ETHTOOL_FLAG_COMPACT_BITSETS (1 << 0) +/* provide optional reply for SET or ACT requests */ +#define ETHTOOL_FLAG_OMIT_REPLY (1 << 1) +/* request statistics, if supported by the driver */ +#define ETHTOOL_FLAG_STATS (1 << 2) + +#define ETHTOOL_FLAG_ALL (ETHTOOL_FLAG_COMPACT_BITSETS | \ + ETHTOOL_FLAG_OMIT_REPLY | \ + ETHTOOL_FLAG_STATS) + +enum { + ETHTOOL_A_HEADER_UNSPEC, + ETHTOOL_A_HEADER_DEV_INDEX, /* u32 */ + ETHTOOL_A_HEADER_DEV_NAME, /* string */ + ETHTOOL_A_HEADER_FLAGS, /* u32 - ETHTOOL_FLAG_* */ + + /* add new constants above here */ + __ETHTOOL_A_HEADER_CNT, + ETHTOOL_A_HEADER_MAX = __ETHTOOL_A_HEADER_CNT - 1 +}; + +/* bit sets */ + +enum { + ETHTOOL_A_BITSET_BIT_UNSPEC, + ETHTOOL_A_BITSET_BIT_INDEX, /* u32 */ + ETHTOOL_A_BITSET_BIT_NAME, /* string */ + ETHTOOL_A_BITSET_BIT_VALUE, /* flag */ + + /* add new constants above here */ + __ETHTOOL_A_BITSET_BIT_CNT, + ETHTOOL_A_BITSET_BIT_MAX = __ETHTOOL_A_BITSET_BIT_CNT - 1 +}; + +enum { + ETHTOOL_A_BITSET_BITS_UNSPEC, + ETHTOOL_A_BITSET_BITS_BIT, /* nest - _A_BITSET_BIT_* */ + + /* add new constants above here */ + __ETHTOOL_A_BITSET_BITS_CNT, + ETHTOOL_A_BITSET_BITS_MAX = __ETHTOOL_A_BITSET_BITS_CNT - 1 +}; + +enum { + ETHTOOL_A_BITSET_UNSPEC, + ETHTOOL_A_BITSET_NOMASK, /* flag */ + ETHTOOL_A_BITSET_SIZE, /* u32 */ + ETHTOOL_A_BITSET_BITS, /* nest - _A_BITSET_BITS_* */ + ETHTOOL_A_BITSET_VALUE, /* binary */ + ETHTOOL_A_BITSET_MASK, /* binary */ + + /* add new constants above here */ + __ETHTOOL_A_BITSET_CNT, + ETHTOOL_A_BITSET_MAX = __ETHTOOL_A_BITSET_CNT - 1 +}; + +/* string sets */ + +enum { + ETHTOOL_A_STRING_UNSPEC, + ETHTOOL_A_STRING_INDEX, /* u32 */ + ETHTOOL_A_STRING_VALUE, /* string */ + + /* add new constants above here */ + __ETHTOOL_A_STRING_CNT, + ETHTOOL_A_STRING_MAX = __ETHTOOL_A_STRING_CNT - 1 +}; + +enum { + ETHTOOL_A_STRINGS_UNSPEC, + ETHTOOL_A_STRINGS_STRING, /* nest - _A_STRINGS_* */ + + /* add new constants above here */ + __ETHTOOL_A_STRINGS_CNT, + ETHTOOL_A_STRINGS_MAX = __ETHTOOL_A_STRINGS_CNT - 1 +}; + +enum { + ETHTOOL_A_STRINGSET_UNSPEC, + ETHTOOL_A_STRINGSET_ID, /* u32 */ + ETHTOOL_A_STRINGSET_COUNT, /* u32 */ + ETHTOOL_A_STRINGSET_STRINGS, /* nest - _A_STRINGS_* */ + + /* add new constants above here */ + __ETHTOOL_A_STRINGSET_CNT, + ETHTOOL_A_STRINGSET_MAX = __ETHTOOL_A_STRINGSET_CNT - 1 +}; + +enum { + ETHTOOL_A_STRINGSETS_UNSPEC, + ETHTOOL_A_STRINGSETS_STRINGSET, /* nest - _A_STRINGSET_* */ + + /* add new constants above here */ + __ETHTOOL_A_STRINGSETS_CNT, + ETHTOOL_A_STRINGSETS_MAX = __ETHTOOL_A_STRINGSETS_CNT - 1 +}; + +/* STRSET */ + +enum { + ETHTOOL_A_STRSET_UNSPEC, + ETHTOOL_A_STRSET_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_STRSET_STRINGSETS, /* nest - _A_STRINGSETS_* */ + ETHTOOL_A_STRSET_COUNTS_ONLY, /* flag */ + + /* add new constants above here */ + __ETHTOOL_A_STRSET_CNT, + ETHTOOL_A_STRSET_MAX = __ETHTOOL_A_STRSET_CNT - 1 +}; + +/* LINKINFO */ + +enum { + ETHTOOL_A_LINKINFO_UNSPEC, + ETHTOOL_A_LINKINFO_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_LINKINFO_PORT, /* u8 */ + ETHTOOL_A_LINKINFO_PHYADDR, /* u8 */ + ETHTOOL_A_LINKINFO_TP_MDIX, /* u8 */ + ETHTOOL_A_LINKINFO_TP_MDIX_CTRL, /* u8 */ + ETHTOOL_A_LINKINFO_TRANSCEIVER, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_LINKINFO_CNT, + ETHTOOL_A_LINKINFO_MAX = __ETHTOOL_A_LINKINFO_CNT - 1 +}; + +/* LINKMODES */ + +enum { + ETHTOOL_A_LINKMODES_UNSPEC, + ETHTOOL_A_LINKMODES_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_LINKMODES_AUTONEG, /* u8 */ + ETHTOOL_A_LINKMODES_OURS, /* bitset */ + ETHTOOL_A_LINKMODES_PEER, /* bitset */ + ETHTOOL_A_LINKMODES_SPEED, /* u32 */ + ETHTOOL_A_LINKMODES_DUPLEX, /* u8 */ + ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, /* u8 */ + ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, /* u8 */ + ETHTOOL_A_LINKMODES_LANES, /* u32 */ + ETHTOOL_A_LINKMODES_RATE_MATCHING, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_LINKMODES_CNT, + ETHTOOL_A_LINKMODES_MAX = __ETHTOOL_A_LINKMODES_CNT - 1 +}; + +/* LINKSTATE */ + +enum { + ETHTOOL_A_LINKSTATE_UNSPEC, + ETHTOOL_A_LINKSTATE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_LINKSTATE_LINK, /* u8 */ + ETHTOOL_A_LINKSTATE_SQI, /* u32 */ + ETHTOOL_A_LINKSTATE_SQI_MAX, /* u32 */ + ETHTOOL_A_LINKSTATE_EXT_STATE, /* u8 */ + ETHTOOL_A_LINKSTATE_EXT_SUBSTATE, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_LINKSTATE_CNT, + ETHTOOL_A_LINKSTATE_MAX = __ETHTOOL_A_LINKSTATE_CNT - 1 +}; + +/* DEBUG */ + +enum { + ETHTOOL_A_DEBUG_UNSPEC, + ETHTOOL_A_DEBUG_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_DEBUG_MSGMASK, /* bitset */ + + /* add new constants above here */ + __ETHTOOL_A_DEBUG_CNT, + ETHTOOL_A_DEBUG_MAX = __ETHTOOL_A_DEBUG_CNT - 1 +}; + +/* WOL */ + +enum { + ETHTOOL_A_WOL_UNSPEC, + ETHTOOL_A_WOL_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_WOL_MODES, /* bitset */ + ETHTOOL_A_WOL_SOPASS, /* binary */ + + /* add new constants above here */ + __ETHTOOL_A_WOL_CNT, + ETHTOOL_A_WOL_MAX = __ETHTOOL_A_WOL_CNT - 1 +}; + +/* FEATURES */ + +enum { + ETHTOOL_A_FEATURES_UNSPEC, + ETHTOOL_A_FEATURES_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_FEATURES_HW, /* bitset */ + ETHTOOL_A_FEATURES_WANTED, /* bitset */ + ETHTOOL_A_FEATURES_ACTIVE, /* bitset */ + ETHTOOL_A_FEATURES_NOCHANGE, /* bitset */ + + /* add new constants above here */ + __ETHTOOL_A_FEATURES_CNT, + ETHTOOL_A_FEATURES_MAX = __ETHTOOL_A_FEATURES_CNT - 1 +}; + +/* PRIVFLAGS */ + +enum { + ETHTOOL_A_PRIVFLAGS_UNSPEC, + ETHTOOL_A_PRIVFLAGS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PRIVFLAGS_FLAGS, /* bitset */ + + /* add new constants above here */ + __ETHTOOL_A_PRIVFLAGS_CNT, + ETHTOOL_A_PRIVFLAGS_MAX = __ETHTOOL_A_PRIVFLAGS_CNT - 1 +}; + +/* RINGS */ + +enum { + ETHTOOL_TCP_DATA_SPLIT_UNKNOWN = 0, + ETHTOOL_TCP_DATA_SPLIT_DISABLED, + ETHTOOL_TCP_DATA_SPLIT_ENABLED, +}; + +enum { + ETHTOOL_A_RINGS_UNSPEC, + ETHTOOL_A_RINGS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_RINGS_RX_MAX, /* u32 */ + ETHTOOL_A_RINGS_RX_MINI_MAX, /* u32 */ + ETHTOOL_A_RINGS_RX_JUMBO_MAX, /* u32 */ + ETHTOOL_A_RINGS_TX_MAX, /* u32 */ + ETHTOOL_A_RINGS_RX, /* u32 */ + ETHTOOL_A_RINGS_RX_MINI, /* u32 */ + ETHTOOL_A_RINGS_RX_JUMBO, /* u32 */ + ETHTOOL_A_RINGS_TX, /* u32 */ + ETHTOOL_A_RINGS_RX_BUF_LEN, /* u32 */ + ETHTOOL_A_RINGS_TCP_DATA_SPLIT, /* u8 */ + ETHTOOL_A_RINGS_CQE_SIZE, /* u32 */ + ETHTOOL_A_RINGS_TX_PUSH, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_RINGS_CNT, + ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1) +}; + +/* CHANNELS */ + +enum { + ETHTOOL_A_CHANNELS_UNSPEC, + ETHTOOL_A_CHANNELS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_CHANNELS_RX_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_TX_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_OTHER_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_COMBINED_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_RX_COUNT, /* u32 */ + ETHTOOL_A_CHANNELS_TX_COUNT, /* u32 */ + ETHTOOL_A_CHANNELS_OTHER_COUNT, /* u32 */ + ETHTOOL_A_CHANNELS_COMBINED_COUNT, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_CHANNELS_CNT, + ETHTOOL_A_CHANNELS_MAX = (__ETHTOOL_A_CHANNELS_CNT - 1) +}; + +/* COALESCE */ + +enum { + ETHTOOL_A_COALESCE_UNSPEC, + ETHTOOL_A_COALESCE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_COALESCE_RX_USECS, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES, /* u32 */ + ETHTOOL_A_COALESCE_RX_USECS_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_STATS_BLOCK_USECS, /* u32 */ + ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX, /* u8 */ + ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX, /* u8 */ + ETHTOOL_A_COALESCE_PKT_RATE_LOW, /* u32 */ + ETHTOOL_A_COALESCE_RX_USECS_LOW, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS_LOW, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW, /* u32 */ + ETHTOOL_A_COALESCE_PKT_RATE_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_RX_USECS_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL, /* u32 */ + ETHTOOL_A_COALESCE_USE_CQE_MODE_TX, /* u8 */ + ETHTOOL_A_COALESCE_USE_CQE_MODE_RX, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_COALESCE_CNT, + ETHTOOL_A_COALESCE_MAX = (__ETHTOOL_A_COALESCE_CNT - 1) +}; + +/* PAUSE */ + +enum { + ETHTOOL_A_PAUSE_UNSPEC, + ETHTOOL_A_PAUSE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PAUSE_AUTONEG, /* u8 */ + ETHTOOL_A_PAUSE_RX, /* u8 */ + ETHTOOL_A_PAUSE_TX, /* u8 */ + ETHTOOL_A_PAUSE_STATS, /* nest - _PAUSE_STAT_* */ + + /* add new constants above here */ + __ETHTOOL_A_PAUSE_CNT, + ETHTOOL_A_PAUSE_MAX = (__ETHTOOL_A_PAUSE_CNT - 1) +}; + +enum { + ETHTOOL_A_PAUSE_STAT_UNSPEC, + ETHTOOL_A_PAUSE_STAT_PAD, + + ETHTOOL_A_PAUSE_STAT_TX_FRAMES, + ETHTOOL_A_PAUSE_STAT_RX_FRAMES, + + /* add new constants above here + * adjust ETHTOOL_PAUSE_STAT_CNT if adding non-stats! + */ + __ETHTOOL_A_PAUSE_STAT_CNT, + ETHTOOL_A_PAUSE_STAT_MAX = (__ETHTOOL_A_PAUSE_STAT_CNT - 1) +}; + +/* EEE */ + +enum { + ETHTOOL_A_EEE_UNSPEC, + ETHTOOL_A_EEE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_EEE_MODES_OURS, /* bitset */ + ETHTOOL_A_EEE_MODES_PEER, /* bitset */ + ETHTOOL_A_EEE_ACTIVE, /* u8 */ + ETHTOOL_A_EEE_ENABLED, /* u8 */ + ETHTOOL_A_EEE_TX_LPI_ENABLED, /* u8 */ + ETHTOOL_A_EEE_TX_LPI_TIMER, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_EEE_CNT, + ETHTOOL_A_EEE_MAX = (__ETHTOOL_A_EEE_CNT - 1) +}; + +/* TSINFO */ + +enum { + ETHTOOL_A_TSINFO_UNSPEC, + ETHTOOL_A_TSINFO_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_TSINFO_TIMESTAMPING, /* bitset */ + ETHTOOL_A_TSINFO_TX_TYPES, /* bitset */ + ETHTOOL_A_TSINFO_RX_FILTERS, /* bitset */ + ETHTOOL_A_TSINFO_PHC_INDEX, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_TSINFO_CNT, + ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1) +}; + +/* PHC VCLOCKS */ + +enum { + ETHTOOL_A_PHC_VCLOCKS_UNSPEC, + ETHTOOL_A_PHC_VCLOCKS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PHC_VCLOCKS_NUM, /* u32 */ + ETHTOOL_A_PHC_VCLOCKS_INDEX, /* array, s32 */ + + /* add new constants above here */ + __ETHTOOL_A_PHC_VCLOCKS_CNT, + ETHTOOL_A_PHC_VCLOCKS_MAX = (__ETHTOOL_A_PHC_VCLOCKS_CNT - 1) +}; + +/* CABLE TEST */ + +enum { + ETHTOOL_A_CABLE_TEST_UNSPEC, + ETHTOOL_A_CABLE_TEST_HEADER, /* nest - _A_HEADER_* */ + + /* add new constants above here */ + __ETHTOOL_A_CABLE_TEST_CNT, + ETHTOOL_A_CABLE_TEST_MAX = __ETHTOOL_A_CABLE_TEST_CNT - 1 +}; + +/* CABLE TEST NOTIFY */ +enum { + ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC, + ETHTOOL_A_CABLE_RESULT_CODE_OK, + ETHTOOL_A_CABLE_RESULT_CODE_OPEN, + ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT, + ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT, +}; + +enum { + ETHTOOL_A_CABLE_PAIR_A, + ETHTOOL_A_CABLE_PAIR_B, + ETHTOOL_A_CABLE_PAIR_C, + ETHTOOL_A_CABLE_PAIR_D, +}; + +enum { + ETHTOOL_A_CABLE_RESULT_UNSPEC, + ETHTOOL_A_CABLE_RESULT_PAIR, /* u8 ETHTOOL_A_CABLE_PAIR_ */ + ETHTOOL_A_CABLE_RESULT_CODE, /* u8 ETHTOOL_A_CABLE_RESULT_CODE_ */ + + __ETHTOOL_A_CABLE_RESULT_CNT, + ETHTOOL_A_CABLE_RESULT_MAX = (__ETHTOOL_A_CABLE_RESULT_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC, + ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR, /* u8 ETHTOOL_A_CABLE_PAIR_ */ + ETHTOOL_A_CABLE_FAULT_LENGTH_CM, /* u32 */ + + __ETHTOOL_A_CABLE_FAULT_LENGTH_CNT, + ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = (__ETHTOOL_A_CABLE_FAULT_LENGTH_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC, + ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED, + ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED +}; + +enum { + ETHTOOL_A_CABLE_NEST_UNSPEC, + ETHTOOL_A_CABLE_NEST_RESULT, /* nest - ETHTOOL_A_CABLE_RESULT_ */ + ETHTOOL_A_CABLE_NEST_FAULT_LENGTH, /* nest - ETHTOOL_A_CABLE_FAULT_LENGTH_ */ + __ETHTOOL_A_CABLE_NEST_CNT, + ETHTOOL_A_CABLE_NEST_MAX = (__ETHTOOL_A_CABLE_NEST_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_NTF_UNSPEC, + ETHTOOL_A_CABLE_TEST_NTF_HEADER, /* nest - ETHTOOL_A_HEADER_* */ + ETHTOOL_A_CABLE_TEST_NTF_STATUS, /* u8 - _STARTED/_COMPLETE */ + ETHTOOL_A_CABLE_TEST_NTF_NEST, /* nest - of results: */ + + __ETHTOOL_A_CABLE_TEST_NTF_CNT, + ETHTOOL_A_CABLE_TEST_NTF_MAX = (__ETHTOOL_A_CABLE_TEST_NTF_CNT - 1) +}; + +/* CABLE TEST TDR */ + +enum { + ETHTOOL_A_CABLE_TEST_TDR_CFG_UNSPEC, + ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST, /* u32 */ + ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST, /* u32 */ + ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP, /* u32 */ + ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_CABLE_TEST_TDR_CFG_CNT, + ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX = __ETHTOOL_A_CABLE_TEST_TDR_CFG_CNT - 1 +}; + +enum { + ETHTOOL_A_CABLE_TEST_TDR_UNSPEC, + ETHTOOL_A_CABLE_TEST_TDR_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_CABLE_TEST_TDR_CFG, /* nest - *_TDR_CFG_* */ + + /* add new constants above here */ + __ETHTOOL_A_CABLE_TEST_TDR_CNT, + ETHTOOL_A_CABLE_TEST_TDR_MAX = __ETHTOOL_A_CABLE_TEST_TDR_CNT - 1 +}; + +/* CABLE TEST TDR NOTIFY */ + +enum { + ETHTOOL_A_CABLE_AMPLITUDE_UNSPEC, + ETHTOOL_A_CABLE_AMPLITUDE_PAIR, /* u8 */ + ETHTOOL_A_CABLE_AMPLITUDE_mV, /* s16 */ + + __ETHTOOL_A_CABLE_AMPLITUDE_CNT, + ETHTOOL_A_CABLE_AMPLITUDE_MAX = (__ETHTOOL_A_CABLE_AMPLITUDE_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_PULSE_UNSPEC, + ETHTOOL_A_CABLE_PULSE_mV, /* s16 */ + + __ETHTOOL_A_CABLE_PULSE_CNT, + ETHTOOL_A_CABLE_PULSE_MAX = (__ETHTOOL_A_CABLE_PULSE_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_STEP_UNSPEC, + ETHTOOL_A_CABLE_STEP_FIRST_DISTANCE, /* u32 */ + ETHTOOL_A_CABLE_STEP_LAST_DISTANCE, /* u32 */ + ETHTOOL_A_CABLE_STEP_STEP_DISTANCE, /* u32 */ + + __ETHTOOL_A_CABLE_STEP_CNT, + ETHTOOL_A_CABLE_STEP_MAX = (__ETHTOOL_A_CABLE_STEP_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TDR_NEST_UNSPEC, + ETHTOOL_A_CABLE_TDR_NEST_STEP, /* nest - ETHTTOOL_A_CABLE_STEP */ + ETHTOOL_A_CABLE_TDR_NEST_AMPLITUDE, /* nest - ETHTOOL_A_CABLE_AMPLITUDE */ + ETHTOOL_A_CABLE_TDR_NEST_PULSE, /* nest - ETHTOOL_A_CABLE_PULSE */ + + __ETHTOOL_A_CABLE_TDR_NEST_CNT, + ETHTOOL_A_CABLE_TDR_NEST_MAX = (__ETHTOOL_A_CABLE_TDR_NEST_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_TDR_NTF_UNSPEC, + ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER, /* nest - ETHTOOL_A_HEADER_* */ + ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS, /* u8 - _STARTED/_COMPLETE */ + ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST, /* nest - of results: */ + + /* add new constants above here */ + __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT, + ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX = __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT - 1 +}; + +/* TUNNEL INFO */ + +enum { + ETHTOOL_UDP_TUNNEL_TYPE_VXLAN, + ETHTOOL_UDP_TUNNEL_TYPE_GENEVE, + ETHTOOL_UDP_TUNNEL_TYPE_VXLAN_GPE, + + __ETHTOOL_UDP_TUNNEL_TYPE_CNT +}; + +enum { + ETHTOOL_A_TUNNEL_UDP_ENTRY_UNSPEC, + + ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT, /* be16 */ + ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT, + ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX = (__ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_UDP_TABLE_UNSPEC, + + ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE, /* u32 */ + ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES, /* bitset */ + ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY, /* nest - _UDP_ENTRY_* */ + + /* add new constants above here */ + __ETHTOOL_A_TUNNEL_UDP_TABLE_CNT, + ETHTOOL_A_TUNNEL_UDP_TABLE_MAX = (__ETHTOOL_A_TUNNEL_UDP_TABLE_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_UDP_UNSPEC, + + ETHTOOL_A_TUNNEL_UDP_TABLE, /* nest - _UDP_TABLE_* */ + + /* add new constants above here */ + __ETHTOOL_A_TUNNEL_UDP_CNT, + ETHTOOL_A_TUNNEL_UDP_MAX = (__ETHTOOL_A_TUNNEL_UDP_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_INFO_UNSPEC, + ETHTOOL_A_TUNNEL_INFO_HEADER, /* nest - _A_HEADER_* */ + + ETHTOOL_A_TUNNEL_INFO_UDP_PORTS, /* nest - _UDP_TABLE */ + + /* add new constants above here */ + __ETHTOOL_A_TUNNEL_INFO_CNT, + ETHTOOL_A_TUNNEL_INFO_MAX = (__ETHTOOL_A_TUNNEL_INFO_CNT - 1) +}; + +/* FEC */ + +enum { + ETHTOOL_A_FEC_UNSPEC, + ETHTOOL_A_FEC_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_FEC_MODES, /* bitset */ + ETHTOOL_A_FEC_AUTO, /* u8 */ + ETHTOOL_A_FEC_ACTIVE, /* u32 */ + ETHTOOL_A_FEC_STATS, /* nest - _A_FEC_STAT */ + + __ETHTOOL_A_FEC_CNT, + ETHTOOL_A_FEC_MAX = (__ETHTOOL_A_FEC_CNT - 1) +}; + +enum { + ETHTOOL_A_FEC_STAT_UNSPEC, + ETHTOOL_A_FEC_STAT_PAD, + + ETHTOOL_A_FEC_STAT_CORRECTED, /* array, u64 */ + ETHTOOL_A_FEC_STAT_UNCORR, /* array, u64 */ + ETHTOOL_A_FEC_STAT_CORR_BITS, /* array, u64 */ + + /* add new constants above here */ + __ETHTOOL_A_FEC_STAT_CNT, + ETHTOOL_A_FEC_STAT_MAX = (__ETHTOOL_A_FEC_STAT_CNT - 1) +}; + +/* MODULE EEPROM */ + +enum { + ETHTOOL_A_MODULE_EEPROM_UNSPEC, + ETHTOOL_A_MODULE_EEPROM_HEADER, /* nest - _A_HEADER_* */ + + ETHTOOL_A_MODULE_EEPROM_OFFSET, /* u32 */ + ETHTOOL_A_MODULE_EEPROM_LENGTH, /* u32 */ + ETHTOOL_A_MODULE_EEPROM_PAGE, /* u8 */ + ETHTOOL_A_MODULE_EEPROM_BANK, /* u8 */ + ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS, /* u8 */ + ETHTOOL_A_MODULE_EEPROM_DATA, /* binary */ + + __ETHTOOL_A_MODULE_EEPROM_CNT, + ETHTOOL_A_MODULE_EEPROM_MAX = (__ETHTOOL_A_MODULE_EEPROM_CNT - 1) +}; + +/* STATS */ + +enum { + ETHTOOL_A_STATS_UNSPEC, + ETHTOOL_A_STATS_PAD, + ETHTOOL_A_STATS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_STATS_GROUPS, /* bitset */ + + ETHTOOL_A_STATS_GRP, /* nest - _A_STATS_GRP_* */ + + /* add new constants above here */ + __ETHTOOL_A_STATS_CNT, + ETHTOOL_A_STATS_MAX = (__ETHTOOL_A_STATS_CNT - 1) +}; + +enum { + ETHTOOL_STATS_ETH_PHY, + ETHTOOL_STATS_ETH_MAC, + ETHTOOL_STATS_ETH_CTRL, + ETHTOOL_STATS_RMON, + + /* add new constants above here */ + __ETHTOOL_STATS_CNT +}; + +enum { + ETHTOOL_A_STATS_GRP_UNSPEC, + ETHTOOL_A_STATS_GRP_PAD, + + ETHTOOL_A_STATS_GRP_ID, /* u32 */ + ETHTOOL_A_STATS_GRP_SS_ID, /* u32 */ + + ETHTOOL_A_STATS_GRP_STAT, /* nest */ + + ETHTOOL_A_STATS_GRP_HIST_RX, /* nest */ + ETHTOOL_A_STATS_GRP_HIST_TX, /* nest */ + + ETHTOOL_A_STATS_GRP_HIST_BKT_LOW, /* u32 */ + ETHTOOL_A_STATS_GRP_HIST_BKT_HI, /* u32 */ + ETHTOOL_A_STATS_GRP_HIST_VAL, /* u64 */ + + /* add new constants above here */ + __ETHTOOL_A_STATS_GRP_CNT, + ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_CNT - 1) +}; + +enum { + /* 30.3.2.1.5 aSymbolErrorDuringCarrier */ + ETHTOOL_A_STATS_ETH_PHY_5_SYM_ERR, + + /* add new constants above here */ + __ETHTOOL_A_STATS_ETH_PHY_CNT, + ETHTOOL_A_STATS_ETH_PHY_MAX = (__ETHTOOL_A_STATS_ETH_PHY_CNT - 1) +}; + +enum { + /* 30.3.1.1.2 aFramesTransmittedOK */ + ETHTOOL_A_STATS_ETH_MAC_2_TX_PKT, + /* 30.3.1.1.3 aSingleCollisionFrames */ + ETHTOOL_A_STATS_ETH_MAC_3_SINGLE_COL, + /* 30.3.1.1.4 aMultipleCollisionFrames */ + ETHTOOL_A_STATS_ETH_MAC_4_MULTI_COL, + /* 30.3.1.1.5 aFramesReceivedOK */ + ETHTOOL_A_STATS_ETH_MAC_5_RX_PKT, + /* 30.3.1.1.6 aFrameCheckSequenceErrors */ + ETHTOOL_A_STATS_ETH_MAC_6_FCS_ERR, + /* 30.3.1.1.7 aAlignmentErrors */ + ETHTOOL_A_STATS_ETH_MAC_7_ALIGN_ERR, + /* 30.3.1.1.8 aOctetsTransmittedOK */ + ETHTOOL_A_STATS_ETH_MAC_8_TX_BYTES, + /* 30.3.1.1.9 aFramesWithDeferredXmissions */ + ETHTOOL_A_STATS_ETH_MAC_9_TX_DEFER, + /* 30.3.1.1.10 aLateCollisions */ + ETHTOOL_A_STATS_ETH_MAC_10_LATE_COL, + /* 30.3.1.1.11 aFramesAbortedDueToXSColls */ + ETHTOOL_A_STATS_ETH_MAC_11_XS_COL, + /* 30.3.1.1.12 aFramesLostDueToIntMACXmitError */ + ETHTOOL_A_STATS_ETH_MAC_12_TX_INT_ERR, + /* 30.3.1.1.13 aCarrierSenseErrors */ + ETHTOOL_A_STATS_ETH_MAC_13_CS_ERR, + /* 30.3.1.1.14 aOctetsReceivedOK */ + ETHTOOL_A_STATS_ETH_MAC_14_RX_BYTES, + /* 30.3.1.1.15 aFramesLostDueToIntMACRcvError */ + ETHTOOL_A_STATS_ETH_MAC_15_RX_INT_ERR, + + /* 30.3.1.1.18 aMulticastFramesXmittedOK */ + ETHTOOL_A_STATS_ETH_MAC_18_TX_MCAST, + /* 30.3.1.1.19 aBroadcastFramesXmittedOK */ + ETHTOOL_A_STATS_ETH_MAC_19_TX_BCAST, + /* 30.3.1.1.20 aFramesWithExcessiveDeferral */ + ETHTOOL_A_STATS_ETH_MAC_20_XS_DEFER, + /* 30.3.1.1.21 aMulticastFramesReceivedOK */ + ETHTOOL_A_STATS_ETH_MAC_21_RX_MCAST, + /* 30.3.1.1.22 aBroadcastFramesReceivedOK */ + ETHTOOL_A_STATS_ETH_MAC_22_RX_BCAST, + /* 30.3.1.1.23 aInRangeLengthErrors */ + ETHTOOL_A_STATS_ETH_MAC_23_IR_LEN_ERR, + /* 30.3.1.1.24 aOutOfRangeLengthField */ + ETHTOOL_A_STATS_ETH_MAC_24_OOR_LEN, + /* 30.3.1.1.25 aFrameTooLongErrors */ + ETHTOOL_A_STATS_ETH_MAC_25_TOO_LONG_ERR, + + /* add new constants above here */ + __ETHTOOL_A_STATS_ETH_MAC_CNT, + ETHTOOL_A_STATS_ETH_MAC_MAX = (__ETHTOOL_A_STATS_ETH_MAC_CNT - 1) +}; + +enum { + /* 30.3.3.3 aMACControlFramesTransmitted */ + ETHTOOL_A_STATS_ETH_CTRL_3_TX, + /* 30.3.3.4 aMACControlFramesReceived */ + ETHTOOL_A_STATS_ETH_CTRL_4_RX, + /* 30.3.3.5 aUnsupportedOpcodesReceived */ + ETHTOOL_A_STATS_ETH_CTRL_5_RX_UNSUP, + + /* add new constants above here */ + __ETHTOOL_A_STATS_ETH_CTRL_CNT, + ETHTOOL_A_STATS_ETH_CTRL_MAX = (__ETHTOOL_A_STATS_ETH_CTRL_CNT - 1) +}; + +enum { + /* etherStatsUndersizePkts */ + ETHTOOL_A_STATS_RMON_UNDERSIZE, + /* etherStatsOversizePkts */ + ETHTOOL_A_STATS_RMON_OVERSIZE, + /* etherStatsFragments */ + ETHTOOL_A_STATS_RMON_FRAG, + /* etherStatsJabbers */ + ETHTOOL_A_STATS_RMON_JABBER, + + /* add new constants above here */ + __ETHTOOL_A_STATS_RMON_CNT, + ETHTOOL_A_STATS_RMON_MAX = (__ETHTOOL_A_STATS_RMON_CNT - 1) +}; + +/* MODULE */ + +enum { + ETHTOOL_A_MODULE_UNSPEC, + ETHTOOL_A_MODULE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_MODULE_POWER_MODE_POLICY, /* u8 */ + ETHTOOL_A_MODULE_POWER_MODE, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_MODULE_CNT, + ETHTOOL_A_MODULE_MAX = (__ETHTOOL_A_MODULE_CNT - 1) +}; + +/* Power Sourcing Equipment */ +enum { + ETHTOOL_A_PSE_UNSPEC, + ETHTOOL_A_PSE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PODL_PSE_ADMIN_STATE, /* u32 */ + ETHTOOL_A_PODL_PSE_ADMIN_CONTROL, /* u32 */ + ETHTOOL_A_PODL_PSE_PW_D_STATUS, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_PSE_CNT, + ETHTOOL_A_PSE_MAX = (__ETHTOOL_A_PSE_CNT - 1) +}; + +/* generic netlink info */ +#define ETHTOOL_GENL_NAME "ethtool" +#define ETHTOOL_GENL_VERSION 1 + +#define ETHTOOL_MCGRP_MONITOR_NAME "monitor" + +#endif /* _LINUX_ETHTOOL_NETLINK_H_ */ diff --git a/uapi/linux/genetlink.h b/uapi/linux/genetlink.h new file mode 100644 index 0000000..e9b8117 --- /dev/null +++ b/uapi/linux/genetlink.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef __LINUX_GENERIC_NETLINK_H +#define __LINUX_GENERIC_NETLINK_H + +#include +#include + +#define GENL_NAMSIZ 16 /* length of family name */ + +#define GENL_MIN_ID NLMSG_MIN_TYPE +#define GENL_MAX_ID 1023 + +struct genlmsghdr { + __u8 cmd; + __u8 version; + __u16 reserved; +}; + +#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr)) + +#define GENL_ADMIN_PERM 0x01 +#define GENL_CMD_CAP_DO 0x02 +#define GENL_CMD_CAP_DUMP 0x04 +#define GENL_CMD_CAP_HASPOL 0x08 +#define GENL_UNS_ADMIN_PERM 0x10 + +/* + * List of reserved static generic netlink identifiers: + */ +#define GENL_ID_CTRL NLMSG_MIN_TYPE +#define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1) +#define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2) +/* must be last reserved + 1 */ +#define GENL_START_ALLOC (NLMSG_MIN_TYPE + 3) + +/************************************************************************** + * Controller + **************************************************************************/ + +enum { + CTRL_CMD_UNSPEC, + CTRL_CMD_NEWFAMILY, + CTRL_CMD_DELFAMILY, + CTRL_CMD_GETFAMILY, + CTRL_CMD_NEWOPS, + CTRL_CMD_DELOPS, + CTRL_CMD_GETOPS, + CTRL_CMD_NEWMCAST_GRP, + CTRL_CMD_DELMCAST_GRP, + CTRL_CMD_GETMCAST_GRP, /* unused */ + CTRL_CMD_GETPOLICY, + __CTRL_CMD_MAX, +}; + +#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1) + +enum { + CTRL_ATTR_UNSPEC, + CTRL_ATTR_FAMILY_ID, + CTRL_ATTR_FAMILY_NAME, + CTRL_ATTR_VERSION, + CTRL_ATTR_HDRSIZE, + CTRL_ATTR_MAXATTR, + CTRL_ATTR_OPS, + CTRL_ATTR_MCAST_GROUPS, + CTRL_ATTR_POLICY, + CTRL_ATTR_OP_POLICY, + CTRL_ATTR_OP, + __CTRL_ATTR_MAX, +}; + +#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1) + +enum { + CTRL_ATTR_OP_UNSPEC, + CTRL_ATTR_OP_ID, + CTRL_ATTR_OP_FLAGS, + __CTRL_ATTR_OP_MAX, +}; + +#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1) + +enum { + CTRL_ATTR_MCAST_GRP_UNSPEC, + CTRL_ATTR_MCAST_GRP_NAME, + CTRL_ATTR_MCAST_GRP_ID, + __CTRL_ATTR_MCAST_GRP_MAX, +}; + +#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1) + +enum { + CTRL_ATTR_POLICY_UNSPEC, + CTRL_ATTR_POLICY_DO, + CTRL_ATTR_POLICY_DUMP, + + __CTRL_ATTR_POLICY_DUMP_MAX, + CTRL_ATTR_POLICY_DUMP_MAX = __CTRL_ATTR_POLICY_DUMP_MAX - 1 +}; + +#define CTRL_ATTR_POLICY_MAX (__CTRL_ATTR_POLICY_DUMP_MAX - 1) + +#endif /* __LINUX_GENERIC_NETLINK_H */ diff --git a/uapi/linux/if_link.h b/uapi/linux/if_link.h new file mode 100644 index 0000000..153fcb9 --- /dev/null +++ b/uapi/linux/if_link.h @@ -0,0 +1,1387 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _LINUX_IF_LINK_H +#define _LINUX_IF_LINK_H + +#include +#include + +/* This struct should be in sync with struct rtnl_link_stats64 */ +struct rtnl_link_stats { + __u32 rx_packets; + __u32 tx_packets; + __u32 rx_bytes; + __u32 tx_bytes; + __u32 rx_errors; + __u32 tx_errors; + __u32 rx_dropped; + __u32 tx_dropped; + __u32 multicast; + __u32 collisions; + /* detailed rx_errors: */ + __u32 rx_length_errors; + __u32 rx_over_errors; + __u32 rx_crc_errors; + __u32 rx_frame_errors; + __u32 rx_fifo_errors; + __u32 rx_missed_errors; + + /* detailed tx_errors */ + __u32 tx_aborted_errors; + __u32 tx_carrier_errors; + __u32 tx_fifo_errors; + __u32 tx_heartbeat_errors; + __u32 tx_window_errors; + + /* for cslip etc */ + __u32 rx_compressed; + __u32 tx_compressed; + + __u32 rx_nohandler; +}; + +/** + * struct rtnl_link_stats64 - The main device statistics structure. + * + * @rx_packets: Number of good packets received by the interface. + * For hardware interfaces counts all good packets received from the device + * by the host, including packets which host had to drop at various stages + * of processing (even in the driver). + * + * @tx_packets: Number of packets successfully transmitted. + * For hardware interfaces counts packets which host was able to successfully + * hand over to the device, which does not necessarily mean that packets + * had been successfully transmitted out of the device, only that device + * acknowledged it copied them out of host memory. + * + * @rx_bytes: Number of good received bytes, corresponding to @rx_packets. + * + * For IEEE 802.3 devices should count the length of Ethernet Frames + * excluding the FCS. + * + * @tx_bytes: Number of good transmitted bytes, corresponding to @tx_packets. + * + * For IEEE 802.3 devices should count the length of Ethernet Frames + * excluding the FCS. + * + * @rx_errors: Total number of bad packets received on this network device. + * This counter must include events counted by @rx_length_errors, + * @rx_crc_errors, @rx_frame_errors and other errors not otherwise + * counted. + * + * @tx_errors: Total number of transmit problems. + * This counter must include events counter by @tx_aborted_errors, + * @tx_carrier_errors, @tx_fifo_errors, @tx_heartbeat_errors, + * @tx_window_errors and other errors not otherwise counted. + * + * @rx_dropped: Number of packets received but not processed, + * e.g. due to lack of resources or unsupported protocol. + * For hardware interfaces this counter may include packets discarded + * due to L2 address filtering but should not include packets dropped + * by the device due to buffer exhaustion which are counted separately in + * @rx_missed_errors (since procfs folds those two counters together). + * + * @tx_dropped: Number of packets dropped on their way to transmission, + * e.g. due to lack of resources. + * + * @multicast: Multicast packets received. + * For hardware interfaces this statistic is commonly calculated + * at the device level (unlike @rx_packets) and therefore may include + * packets which did not reach the host. + * + * For IEEE 802.3 devices this counter may be equivalent to: + * + * - 30.3.1.1.21 aMulticastFramesReceivedOK + * + * @collisions: Number of collisions during packet transmissions. + * + * @rx_length_errors: Number of packets dropped due to invalid length. + * Part of aggregate "frame" errors in `/proc/net/dev`. + * + * For IEEE 802.3 devices this counter should be equivalent to a sum + * of the following attributes: + * + * - 30.3.1.1.23 aInRangeLengthErrors + * - 30.3.1.1.24 aOutOfRangeLengthField + * - 30.3.1.1.25 aFrameTooLongErrors + * + * @rx_over_errors: Receiver FIFO overflow event counter. + * + * Historically the count of overflow events. Such events may be + * reported in the receive descriptors or via interrupts, and may + * not correspond one-to-one with dropped packets. + * + * The recommended interpretation for high speed interfaces is - + * number of packets dropped because they did not fit into buffers + * provided by the host, e.g. packets larger than MTU or next buffer + * in the ring was not available for a scatter transfer. + * + * Part of aggregate "frame" errors in `/proc/net/dev`. + * + * This statistics was historically used interchangeably with + * @rx_fifo_errors. + * + * This statistic corresponds to hardware events and is not commonly used + * on software devices. + * + * @rx_crc_errors: Number of packets received with a CRC error. + * Part of aggregate "frame" errors in `/proc/net/dev`. + * + * For IEEE 802.3 devices this counter must be equivalent to: + * + * - 30.3.1.1.6 aFrameCheckSequenceErrors + * + * @rx_frame_errors: Receiver frame alignment errors. + * Part of aggregate "frame" errors in `/proc/net/dev`. + * + * For IEEE 802.3 devices this counter should be equivalent to: + * + * - 30.3.1.1.7 aAlignmentErrors + * + * @rx_fifo_errors: Receiver FIFO error counter. + * + * Historically the count of overflow events. Those events may be + * reported in the receive descriptors or via interrupts, and may + * not correspond one-to-one with dropped packets. + * + * This statistics was used interchangeably with @rx_over_errors. + * Not recommended for use in drivers for high speed interfaces. + * + * This statistic is used on software devices, e.g. to count software + * packet queue overflow (can) or sequencing errors (GRE). + * + * @rx_missed_errors: Count of packets missed by the host. + * Folded into the "drop" counter in `/proc/net/dev`. + * + * Counts number of packets dropped by the device due to lack + * of buffer space. This usually indicates that the host interface + * is slower than the network interface, or host is not keeping up + * with the receive packet rate. + * + * This statistic corresponds to hardware events and is not used + * on software devices. + * + * @tx_aborted_errors: + * Part of aggregate "carrier" errors in `/proc/net/dev`. + * For IEEE 802.3 devices capable of half-duplex operation this counter + * must be equivalent to: + * + * - 30.3.1.1.11 aFramesAbortedDueToXSColls + * + * High speed interfaces may use this counter as a general device + * discard counter. + * + * @tx_carrier_errors: Number of frame transmission errors due to loss + * of carrier during transmission. + * Part of aggregate "carrier" errors in `/proc/net/dev`. + * + * For IEEE 802.3 devices this counter must be equivalent to: + * + * - 30.3.1.1.13 aCarrierSenseErrors + * + * @tx_fifo_errors: Number of frame transmission errors due to device + * FIFO underrun / underflow. This condition occurs when the device + * begins transmission of a frame but is unable to deliver the + * entire frame to the transmitter in time for transmission. + * Part of aggregate "carrier" errors in `/proc/net/dev`. + * + * @tx_heartbeat_errors: Number of Heartbeat / SQE Test errors for + * old half-duplex Ethernet. + * Part of aggregate "carrier" errors in `/proc/net/dev`. + * + * For IEEE 802.3 devices possibly equivalent to: + * + * - 30.3.2.1.4 aSQETestErrors + * + * @tx_window_errors: Number of frame transmission errors due + * to late collisions (for Ethernet - after the first 64B of transmission). + * Part of aggregate "carrier" errors in `/proc/net/dev`. + * + * For IEEE 802.3 devices this counter must be equivalent to: + * + * - 30.3.1.1.10 aLateCollisions + * + * @rx_compressed: Number of correctly received compressed packets. + * This counters is only meaningful for interfaces which support + * packet compression (e.g. CSLIP, PPP). + * + * @tx_compressed: Number of transmitted compressed packets. + * This counters is only meaningful for interfaces which support + * packet compression (e.g. CSLIP, PPP). + * + * @rx_nohandler: Number of packets received on the interface + * but dropped by the networking stack because the device is + * not designated to receive packets (e.g. backup link in a bond). + * + * @rx_otherhost_dropped: Number of packets dropped due to mismatch + * in destination MAC address. + */ +struct rtnl_link_stats64 { + __u64 rx_packets; + __u64 tx_packets; + __u64 rx_bytes; + __u64 tx_bytes; + __u64 rx_errors; + __u64 tx_errors; + __u64 rx_dropped; + __u64 tx_dropped; + __u64 multicast; + __u64 collisions; + + /* detailed rx_errors: */ + __u64 rx_length_errors; + __u64 rx_over_errors; + __u64 rx_crc_errors; + __u64 rx_frame_errors; + __u64 rx_fifo_errors; + __u64 rx_missed_errors; + + /* detailed tx_errors */ + __u64 tx_aborted_errors; + __u64 tx_carrier_errors; + __u64 tx_fifo_errors; + __u64 tx_heartbeat_errors; + __u64 tx_window_errors; + + /* for cslip etc */ + __u64 rx_compressed; + __u64 tx_compressed; + __u64 rx_nohandler; + + __u64 rx_otherhost_dropped; +}; + +/* Subset of link stats useful for in-HW collection. Meaning of the fields is as + * for struct rtnl_link_stats64. + */ +struct rtnl_hw_stats64 { + __u64 rx_packets; + __u64 tx_packets; + __u64 rx_bytes; + __u64 tx_bytes; + __u64 rx_errors; + __u64 tx_errors; + __u64 rx_dropped; + __u64 tx_dropped; + __u64 multicast; +}; + +/* The struct should be in sync with struct ifmap */ +struct rtnl_link_ifmap { + __u64 mem_start; + __u64 mem_end; + __u64 base_addr; + __u16 irq; + __u8 dma; + __u8 port; +}; + +/* + * IFLA_AF_SPEC + * Contains nested attributes for address family specific attributes. + * Each address family may create a attribute with the address family + * number as type and create its own attribute structure in it. + * + * Example: + * [IFLA_AF_SPEC] = { + * [AF_INET] = { + * [IFLA_INET_CONF] = ..., + * }, + * [AF_INET6] = { + * [IFLA_INET6_FLAGS] = ..., + * [IFLA_INET6_CONF] = ..., + * } + * } + */ + +enum { + IFLA_UNSPEC, + IFLA_ADDRESS, + IFLA_BROADCAST, + IFLA_IFNAME, + IFLA_MTU, + IFLA_LINK, + IFLA_QDISC, + IFLA_STATS, + IFLA_COST, +#define IFLA_COST IFLA_COST + IFLA_PRIORITY, +#define IFLA_PRIORITY IFLA_PRIORITY + IFLA_MASTER, +#define IFLA_MASTER IFLA_MASTER + IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */ +#define IFLA_WIRELESS IFLA_WIRELESS + IFLA_PROTINFO, /* Protocol specific information for a link */ +#define IFLA_PROTINFO IFLA_PROTINFO + IFLA_TXQLEN, +#define IFLA_TXQLEN IFLA_TXQLEN + IFLA_MAP, +#define IFLA_MAP IFLA_MAP + IFLA_WEIGHT, +#define IFLA_WEIGHT IFLA_WEIGHT + IFLA_OPERSTATE, + IFLA_LINKMODE, + IFLA_LINKINFO, +#define IFLA_LINKINFO IFLA_LINKINFO + IFLA_NET_NS_PID, + IFLA_IFALIAS, + IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */ + IFLA_VFINFO_LIST, + IFLA_STATS64, + IFLA_VF_PORTS, + IFLA_PORT_SELF, + IFLA_AF_SPEC, + IFLA_GROUP, /* Group the device belongs to */ + IFLA_NET_NS_FD, + IFLA_EXT_MASK, /* Extended info mask, VFs, etc */ + IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */ +#define IFLA_PROMISCUITY IFLA_PROMISCUITY + IFLA_NUM_TX_QUEUES, + IFLA_NUM_RX_QUEUES, + IFLA_CARRIER, + IFLA_PHYS_PORT_ID, + IFLA_CARRIER_CHANGES, + IFLA_PHYS_SWITCH_ID, + IFLA_LINK_NETNSID, + IFLA_PHYS_PORT_NAME, + IFLA_PROTO_DOWN, + IFLA_GSO_MAX_SEGS, + IFLA_GSO_MAX_SIZE, + IFLA_PAD, + IFLA_XDP, + IFLA_EVENT, + IFLA_NEW_NETNSID, + IFLA_IF_NETNSID, + IFLA_TARGET_NETNSID = IFLA_IF_NETNSID, /* new alias */ + IFLA_CARRIER_UP_COUNT, + IFLA_CARRIER_DOWN_COUNT, + IFLA_NEW_IFINDEX, + IFLA_MIN_MTU, + IFLA_MAX_MTU, + IFLA_PROP_LIST, + IFLA_ALT_IFNAME, /* Alternative ifname */ + IFLA_PERM_ADDRESS, + IFLA_PROTO_DOWN_REASON, + + /* device (sysfs) name as parent, used instead + * of IFLA_LINK where there's no parent netdev + */ + IFLA_PARENT_DEV_NAME, + IFLA_PARENT_DEV_BUS_NAME, + IFLA_GRO_MAX_SIZE, + IFLA_TSO_MAX_SIZE, + IFLA_TSO_MAX_SEGS, + IFLA_ALLMULTI, /* Allmulti count: > 0 means acts ALLMULTI */ + + __IFLA_MAX +}; + + +#define IFLA_MAX (__IFLA_MAX - 1) + +enum { + IFLA_PROTO_DOWN_REASON_UNSPEC, + IFLA_PROTO_DOWN_REASON_MASK, /* u32, mask for reason bits */ + IFLA_PROTO_DOWN_REASON_VALUE, /* u32, reason bit value */ + + __IFLA_PROTO_DOWN_REASON_CNT, + IFLA_PROTO_DOWN_REASON_MAX = __IFLA_PROTO_DOWN_REASON_CNT - 1 +}; + +/* backwards compatibility for userspace */ +#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) +#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) + +enum { + IFLA_INET_UNSPEC, + IFLA_INET_CONF, + __IFLA_INET_MAX, +}; + +#define IFLA_INET_MAX (__IFLA_INET_MAX - 1) + +/* ifi_flags. + + IFF_* flags. + + The only change is: + IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are + more not changeable by user. They describe link media + characteristics and set by device driver. + + Comments: + - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid + - If neither of these three flags are set; + the interface is NBMA. + + - IFF_MULTICAST does not mean anything special: + multicasts can be used on all not-NBMA links. + IFF_MULTICAST means that this media uses special encapsulation + for multicast frames. Apparently, all IFF_POINTOPOINT and + IFF_BROADCAST devices are able to use multicasts too. + */ + +/* IFLA_LINK. + For usual devices it is equal ifi_index. + If it is a "virtual interface" (f.e. tunnel), ifi_link + can point to real physical interface (f.e. for bandwidth calculations), + or maybe 0, what means, that real media is unknown (usual + for IPIP tunnels, when route to endpoint is allowed to change) + */ + +/* Subtype attributes for IFLA_PROTINFO */ +enum { + IFLA_INET6_UNSPEC, + IFLA_INET6_FLAGS, /* link flags */ + IFLA_INET6_CONF, /* sysctl parameters */ + IFLA_INET6_STATS, /* statistics */ + IFLA_INET6_MCAST, /* MC things. What of them? */ + IFLA_INET6_CACHEINFO, /* time values and max reasm size */ + IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */ + IFLA_INET6_TOKEN, /* device token */ + IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */ + IFLA_INET6_RA_MTU, /* mtu carried in the RA message */ + __IFLA_INET6_MAX +}; + +#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) + +enum in6_addr_gen_mode { + IN6_ADDR_GEN_MODE_EUI64, + IN6_ADDR_GEN_MODE_NONE, + IN6_ADDR_GEN_MODE_STABLE_PRIVACY, + IN6_ADDR_GEN_MODE_RANDOM, +}; + +/* Bridge section */ + +enum { + IFLA_BR_UNSPEC, + IFLA_BR_FORWARD_DELAY, + IFLA_BR_HELLO_TIME, + IFLA_BR_MAX_AGE, + IFLA_BR_AGEING_TIME, + IFLA_BR_STP_STATE, + IFLA_BR_PRIORITY, + IFLA_BR_VLAN_FILTERING, + IFLA_BR_VLAN_PROTOCOL, + IFLA_BR_GROUP_FWD_MASK, + IFLA_BR_ROOT_ID, + IFLA_BR_BRIDGE_ID, + IFLA_BR_ROOT_PORT, + IFLA_BR_ROOT_PATH_COST, + IFLA_BR_TOPOLOGY_CHANGE, + IFLA_BR_TOPOLOGY_CHANGE_DETECTED, + IFLA_BR_HELLO_TIMER, + IFLA_BR_TCN_TIMER, + IFLA_BR_TOPOLOGY_CHANGE_TIMER, + IFLA_BR_GC_TIMER, + IFLA_BR_GROUP_ADDR, + IFLA_BR_FDB_FLUSH, + IFLA_BR_MCAST_ROUTER, + IFLA_BR_MCAST_SNOOPING, + IFLA_BR_MCAST_QUERY_USE_IFADDR, + IFLA_BR_MCAST_QUERIER, + IFLA_BR_MCAST_HASH_ELASTICITY, + IFLA_BR_MCAST_HASH_MAX, + IFLA_BR_MCAST_LAST_MEMBER_CNT, + IFLA_BR_MCAST_STARTUP_QUERY_CNT, + IFLA_BR_MCAST_LAST_MEMBER_INTVL, + IFLA_BR_MCAST_MEMBERSHIP_INTVL, + IFLA_BR_MCAST_QUERIER_INTVL, + IFLA_BR_MCAST_QUERY_INTVL, + IFLA_BR_MCAST_QUERY_RESPONSE_INTVL, + IFLA_BR_MCAST_STARTUP_QUERY_INTVL, + IFLA_BR_NF_CALL_IPTABLES, + IFLA_BR_NF_CALL_IP6TABLES, + IFLA_BR_NF_CALL_ARPTABLES, + IFLA_BR_VLAN_DEFAULT_PVID, + IFLA_BR_PAD, + IFLA_BR_VLAN_STATS_ENABLED, + IFLA_BR_MCAST_STATS_ENABLED, + IFLA_BR_MCAST_IGMP_VERSION, + IFLA_BR_MCAST_MLD_VERSION, + IFLA_BR_VLAN_STATS_PER_PORT, + IFLA_BR_MULTI_BOOLOPT, + IFLA_BR_MCAST_QUERIER_STATE, + __IFLA_BR_MAX, +}; + +#define IFLA_BR_MAX (__IFLA_BR_MAX - 1) + +struct ifla_bridge_id { + __u8 prio[2]; + __u8 addr[6]; /* ETH_ALEN */ +}; + +enum { + BRIDGE_MODE_UNSPEC, + BRIDGE_MODE_HAIRPIN, +}; + +enum { + IFLA_BRPORT_UNSPEC, + IFLA_BRPORT_STATE, /* Spanning tree state */ + IFLA_BRPORT_PRIORITY, /* " priority */ + IFLA_BRPORT_COST, /* " cost */ + IFLA_BRPORT_MODE, /* mode (hairpin) */ + IFLA_BRPORT_GUARD, /* bpdu guard */ + IFLA_BRPORT_PROTECT, /* root port protection */ + IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */ + IFLA_BRPORT_LEARNING, /* mac learning */ + IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ + IFLA_BRPORT_PROXYARP, /* proxy ARP */ + IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */ + IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */ + IFLA_BRPORT_ROOT_ID, /* designated root */ + IFLA_BRPORT_BRIDGE_ID, /* designated bridge */ + IFLA_BRPORT_DESIGNATED_PORT, + IFLA_BRPORT_DESIGNATED_COST, + IFLA_BRPORT_ID, + IFLA_BRPORT_NO, + IFLA_BRPORT_TOPOLOGY_CHANGE_ACK, + IFLA_BRPORT_CONFIG_PENDING, + IFLA_BRPORT_MESSAGE_AGE_TIMER, + IFLA_BRPORT_FORWARD_DELAY_TIMER, + IFLA_BRPORT_HOLD_TIMER, + IFLA_BRPORT_FLUSH, + IFLA_BRPORT_MULTICAST_ROUTER, + IFLA_BRPORT_PAD, + IFLA_BRPORT_MCAST_FLOOD, + IFLA_BRPORT_MCAST_TO_UCAST, + IFLA_BRPORT_VLAN_TUNNEL, + IFLA_BRPORT_BCAST_FLOOD, + IFLA_BRPORT_GROUP_FWD_MASK, + IFLA_BRPORT_NEIGH_SUPPRESS, + IFLA_BRPORT_ISOLATED, + IFLA_BRPORT_BACKUP_PORT, + IFLA_BRPORT_MRP_RING_OPEN, + IFLA_BRPORT_MRP_IN_OPEN, + IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT, + IFLA_BRPORT_MCAST_EHT_HOSTS_CNT, + IFLA_BRPORT_LOCKED, + __IFLA_BRPORT_MAX +}; +#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) + +struct ifla_cacheinfo { + __u32 max_reasm_len; + __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ + __u32 reachable_time; + __u32 retrans_time; +}; + +enum { + IFLA_INFO_UNSPEC, + IFLA_INFO_KIND, + IFLA_INFO_DATA, + IFLA_INFO_XSTATS, + IFLA_INFO_SLAVE_KIND, + IFLA_INFO_SLAVE_DATA, + __IFLA_INFO_MAX, +}; + +#define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1) + +/* VLAN section */ + +enum { + IFLA_VLAN_UNSPEC, + IFLA_VLAN_ID, + IFLA_VLAN_FLAGS, + IFLA_VLAN_EGRESS_QOS, + IFLA_VLAN_INGRESS_QOS, + IFLA_VLAN_PROTOCOL, + __IFLA_VLAN_MAX, +}; + +#define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1) + +struct ifla_vlan_flags { + __u32 flags; + __u32 mask; +}; + +enum { + IFLA_VLAN_QOS_UNSPEC, + IFLA_VLAN_QOS_MAPPING, + __IFLA_VLAN_QOS_MAX +}; + +#define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1) + +struct ifla_vlan_qos_mapping { + __u32 from; + __u32 to; +}; + +/* MACVLAN section */ +enum { + IFLA_MACVLAN_UNSPEC, + IFLA_MACVLAN_MODE, + IFLA_MACVLAN_FLAGS, + IFLA_MACVLAN_MACADDR_MODE, + IFLA_MACVLAN_MACADDR, + IFLA_MACVLAN_MACADDR_DATA, + IFLA_MACVLAN_MACADDR_COUNT, + IFLA_MACVLAN_BC_QUEUE_LEN, + IFLA_MACVLAN_BC_QUEUE_LEN_USED, + __IFLA_MACVLAN_MAX, +}; + +#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1) + +enum macvlan_mode { + MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */ + MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */ + MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */ + MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */ + MACVLAN_MODE_SOURCE = 16,/* use source MAC address list to assign */ +}; + +enum macvlan_macaddr_mode { + MACVLAN_MACADDR_ADD, + MACVLAN_MACADDR_DEL, + MACVLAN_MACADDR_FLUSH, + MACVLAN_MACADDR_SET, +}; + +#define MACVLAN_FLAG_NOPROMISC 1 +#define MACVLAN_FLAG_NODST 2 /* skip dst macvlan if matching src macvlan */ + +/* VRF section */ +enum { + IFLA_VRF_UNSPEC, + IFLA_VRF_TABLE, + __IFLA_VRF_MAX +}; + +#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1) + +enum { + IFLA_VRF_PORT_UNSPEC, + IFLA_VRF_PORT_TABLE, + __IFLA_VRF_PORT_MAX +}; + +#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1) + +/* MACSEC section */ +enum { + IFLA_MACSEC_UNSPEC, + IFLA_MACSEC_SCI, + IFLA_MACSEC_PORT, + IFLA_MACSEC_ICV_LEN, + IFLA_MACSEC_CIPHER_SUITE, + IFLA_MACSEC_WINDOW, + IFLA_MACSEC_ENCODING_SA, + IFLA_MACSEC_ENCRYPT, + IFLA_MACSEC_PROTECT, + IFLA_MACSEC_INC_SCI, + IFLA_MACSEC_ES, + IFLA_MACSEC_SCB, + IFLA_MACSEC_REPLAY_PROTECT, + IFLA_MACSEC_VALIDATION, + IFLA_MACSEC_PAD, + IFLA_MACSEC_OFFLOAD, + __IFLA_MACSEC_MAX, +}; + +#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1) + +/* XFRM section */ +enum { + IFLA_XFRM_UNSPEC, + IFLA_XFRM_LINK, + IFLA_XFRM_IF_ID, + IFLA_XFRM_COLLECT_METADATA, + __IFLA_XFRM_MAX +}; + +#define IFLA_XFRM_MAX (__IFLA_XFRM_MAX - 1) + +enum macsec_validation_type { + MACSEC_VALIDATE_DISABLED = 0, + MACSEC_VALIDATE_CHECK = 1, + MACSEC_VALIDATE_STRICT = 2, + __MACSEC_VALIDATE_END, + MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1, +}; + +enum macsec_offload { + MACSEC_OFFLOAD_OFF = 0, + MACSEC_OFFLOAD_PHY = 1, + MACSEC_OFFLOAD_MAC = 2, + __MACSEC_OFFLOAD_END, + MACSEC_OFFLOAD_MAX = __MACSEC_OFFLOAD_END - 1, +}; + +/* IPVLAN section */ +enum { + IFLA_IPVLAN_UNSPEC, + IFLA_IPVLAN_MODE, + IFLA_IPVLAN_FLAGS, + __IFLA_IPVLAN_MAX +}; + +#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1) + +enum ipvlan_mode { + IPVLAN_MODE_L2 = 0, + IPVLAN_MODE_L3, + IPVLAN_MODE_L3S, + IPVLAN_MODE_MAX +}; + +#define IPVLAN_F_PRIVATE 0x01 +#define IPVLAN_F_VEPA 0x02 + +/* Tunnel RTM header */ +struct tunnel_msg { + __u8 family; + __u8 flags; + __u16 reserved2; + __u32 ifindex; +}; + +/* VXLAN section */ + +/* include statistics in the dump */ +#define TUNNEL_MSG_FLAG_STATS 0x01 + +#define TUNNEL_MSG_VALID_USER_FLAGS TUNNEL_MSG_FLAG_STATS + +/* Embedded inside VXLAN_VNIFILTER_ENTRY_STATS */ +enum { + VNIFILTER_ENTRY_STATS_UNSPEC, + VNIFILTER_ENTRY_STATS_RX_BYTES, + VNIFILTER_ENTRY_STATS_RX_PKTS, + VNIFILTER_ENTRY_STATS_RX_DROPS, + VNIFILTER_ENTRY_STATS_RX_ERRORS, + VNIFILTER_ENTRY_STATS_TX_BYTES, + VNIFILTER_ENTRY_STATS_TX_PKTS, + VNIFILTER_ENTRY_STATS_TX_DROPS, + VNIFILTER_ENTRY_STATS_TX_ERRORS, + VNIFILTER_ENTRY_STATS_PAD, + __VNIFILTER_ENTRY_STATS_MAX +}; +#define VNIFILTER_ENTRY_STATS_MAX (__VNIFILTER_ENTRY_STATS_MAX - 1) + +enum { + VXLAN_VNIFILTER_ENTRY_UNSPEC, + VXLAN_VNIFILTER_ENTRY_START, + VXLAN_VNIFILTER_ENTRY_END, + VXLAN_VNIFILTER_ENTRY_GROUP, + VXLAN_VNIFILTER_ENTRY_GROUP6, + VXLAN_VNIFILTER_ENTRY_STATS, + __VXLAN_VNIFILTER_ENTRY_MAX +}; +#define VXLAN_VNIFILTER_ENTRY_MAX (__VXLAN_VNIFILTER_ENTRY_MAX - 1) + +enum { + VXLAN_VNIFILTER_UNSPEC, + VXLAN_VNIFILTER_ENTRY, + __VXLAN_VNIFILTER_MAX +}; +#define VXLAN_VNIFILTER_MAX (__VXLAN_VNIFILTER_MAX - 1) + +enum { + IFLA_VXLAN_UNSPEC, + IFLA_VXLAN_ID, + IFLA_VXLAN_GROUP, /* group or remote address */ + IFLA_VXLAN_LINK, + IFLA_VXLAN_LOCAL, + IFLA_VXLAN_TTL, + IFLA_VXLAN_TOS, + IFLA_VXLAN_LEARNING, + IFLA_VXLAN_AGEING, + IFLA_VXLAN_LIMIT, + IFLA_VXLAN_PORT_RANGE, /* source port */ + IFLA_VXLAN_PROXY, + IFLA_VXLAN_RSC, + IFLA_VXLAN_L2MISS, + IFLA_VXLAN_L3MISS, + IFLA_VXLAN_PORT, /* destination port */ + IFLA_VXLAN_GROUP6, + IFLA_VXLAN_LOCAL6, + IFLA_VXLAN_UDP_CSUM, + IFLA_VXLAN_UDP_ZERO_CSUM6_TX, + IFLA_VXLAN_UDP_ZERO_CSUM6_RX, + IFLA_VXLAN_REMCSUM_TX, + IFLA_VXLAN_REMCSUM_RX, + IFLA_VXLAN_GBP, + IFLA_VXLAN_REMCSUM_NOPARTIAL, + IFLA_VXLAN_COLLECT_METADATA, + IFLA_VXLAN_LABEL, + IFLA_VXLAN_GPE, + IFLA_VXLAN_TTL_INHERIT, + IFLA_VXLAN_DF, + IFLA_VXLAN_VNIFILTER, /* only applicable with COLLECT_METADATA mode */ + __IFLA_VXLAN_MAX +}; +#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) + +struct ifla_vxlan_port_range { + __be16 low; + __be16 high; +}; + +enum ifla_vxlan_df { + VXLAN_DF_UNSET = 0, + VXLAN_DF_SET, + VXLAN_DF_INHERIT, + __VXLAN_DF_END, + VXLAN_DF_MAX = __VXLAN_DF_END - 1, +}; + +/* GENEVE section */ +enum { + IFLA_GENEVE_UNSPEC, + IFLA_GENEVE_ID, + IFLA_GENEVE_REMOTE, + IFLA_GENEVE_TTL, + IFLA_GENEVE_TOS, + IFLA_GENEVE_PORT, /* destination port */ + IFLA_GENEVE_COLLECT_METADATA, + IFLA_GENEVE_REMOTE6, + IFLA_GENEVE_UDP_CSUM, + IFLA_GENEVE_UDP_ZERO_CSUM6_TX, + IFLA_GENEVE_UDP_ZERO_CSUM6_RX, + IFLA_GENEVE_LABEL, + IFLA_GENEVE_TTL_INHERIT, + IFLA_GENEVE_DF, + IFLA_GENEVE_INNER_PROTO_INHERIT, + __IFLA_GENEVE_MAX +}; +#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1) + +enum ifla_geneve_df { + GENEVE_DF_UNSET = 0, + GENEVE_DF_SET, + GENEVE_DF_INHERIT, + __GENEVE_DF_END, + GENEVE_DF_MAX = __GENEVE_DF_END - 1, +}; + +/* Bareudp section */ +enum { + IFLA_BAREUDP_UNSPEC, + IFLA_BAREUDP_PORT, + IFLA_BAREUDP_ETHERTYPE, + IFLA_BAREUDP_SRCPORT_MIN, + IFLA_BAREUDP_MULTIPROTO_MODE, + __IFLA_BAREUDP_MAX +}; + +#define IFLA_BAREUDP_MAX (__IFLA_BAREUDP_MAX - 1) + +/* PPP section */ +enum { + IFLA_PPP_UNSPEC, + IFLA_PPP_DEV_FD, + __IFLA_PPP_MAX +}; +#define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1) + +/* GTP section */ + +enum ifla_gtp_role { + GTP_ROLE_GGSN = 0, + GTP_ROLE_SGSN, +}; + +enum { + IFLA_GTP_UNSPEC, + IFLA_GTP_FD0, + IFLA_GTP_FD1, + IFLA_GTP_PDP_HASHSIZE, + IFLA_GTP_ROLE, + IFLA_GTP_CREATE_SOCKETS, + IFLA_GTP_RESTART_COUNT, + __IFLA_GTP_MAX, +}; +#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1) + +/* Bonding section */ + +enum { + IFLA_BOND_UNSPEC, + IFLA_BOND_MODE, + IFLA_BOND_ACTIVE_SLAVE, + IFLA_BOND_MIIMON, + IFLA_BOND_UPDELAY, + IFLA_BOND_DOWNDELAY, + IFLA_BOND_USE_CARRIER, + IFLA_BOND_ARP_INTERVAL, + IFLA_BOND_ARP_IP_TARGET, + IFLA_BOND_ARP_VALIDATE, + IFLA_BOND_ARP_ALL_TARGETS, + IFLA_BOND_PRIMARY, + IFLA_BOND_PRIMARY_RESELECT, + IFLA_BOND_FAIL_OVER_MAC, + IFLA_BOND_XMIT_HASH_POLICY, + IFLA_BOND_RESEND_IGMP, + IFLA_BOND_NUM_PEER_NOTIF, + IFLA_BOND_ALL_SLAVES_ACTIVE, + IFLA_BOND_MIN_LINKS, + IFLA_BOND_LP_INTERVAL, + IFLA_BOND_PACKETS_PER_SLAVE, + IFLA_BOND_AD_LACP_RATE, + IFLA_BOND_AD_SELECT, + IFLA_BOND_AD_INFO, + IFLA_BOND_AD_ACTOR_SYS_PRIO, + IFLA_BOND_AD_USER_PORT_KEY, + IFLA_BOND_AD_ACTOR_SYSTEM, + IFLA_BOND_TLB_DYNAMIC_LB, + IFLA_BOND_PEER_NOTIF_DELAY, + IFLA_BOND_AD_LACP_ACTIVE, + IFLA_BOND_MISSED_MAX, + IFLA_BOND_NS_IP6_TARGET, + __IFLA_BOND_MAX, +}; + +#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1) + +enum { + IFLA_BOND_AD_INFO_UNSPEC, + IFLA_BOND_AD_INFO_AGGREGATOR, + IFLA_BOND_AD_INFO_NUM_PORTS, + IFLA_BOND_AD_INFO_ACTOR_KEY, + IFLA_BOND_AD_INFO_PARTNER_KEY, + IFLA_BOND_AD_INFO_PARTNER_MAC, + __IFLA_BOND_AD_INFO_MAX, +}; + +#define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1) + +enum { + IFLA_BOND_SLAVE_UNSPEC, + IFLA_BOND_SLAVE_STATE, + IFLA_BOND_SLAVE_MII_STATUS, + IFLA_BOND_SLAVE_LINK_FAILURE_COUNT, + IFLA_BOND_SLAVE_PERM_HWADDR, + IFLA_BOND_SLAVE_QUEUE_ID, + IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, + IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE, + IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE, + IFLA_BOND_SLAVE_PRIO, + __IFLA_BOND_SLAVE_MAX, +}; + +#define IFLA_BOND_SLAVE_MAX (__IFLA_BOND_SLAVE_MAX - 1) + +/* SR-IOV virtual function management section */ + +enum { + IFLA_VF_INFO_UNSPEC, + IFLA_VF_INFO, + __IFLA_VF_INFO_MAX, +}; + +#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1) + +enum { + IFLA_VF_UNSPEC, + IFLA_VF_MAC, /* Hardware queue specific attributes */ + IFLA_VF_VLAN, /* VLAN ID and QoS */ + IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */ + IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ + IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ + IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */ + IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query + * on/off switch + */ + IFLA_VF_STATS, /* network device statistics */ + IFLA_VF_TRUST, /* Trust VF */ + IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */ + IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */ + IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */ + IFLA_VF_BROADCAST, /* VF broadcast */ + __IFLA_VF_MAX, +}; + +#define IFLA_VF_MAX (__IFLA_VF_MAX - 1) + +struct ifla_vf_mac { + __u32 vf; + __u8 mac[32]; /* MAX_ADDR_LEN */ +}; + +struct ifla_vf_broadcast { + __u8 broadcast[32]; +}; + +struct ifla_vf_vlan { + __u32 vf; + __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ + __u32 qos; +}; + +enum { + IFLA_VF_VLAN_INFO_UNSPEC, + IFLA_VF_VLAN_INFO, /* VLAN ID, QoS and VLAN protocol */ + __IFLA_VF_VLAN_INFO_MAX, +}; + +#define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1) +#define MAX_VLAN_LIST_LEN 1 + +struct ifla_vf_vlan_info { + __u32 vf; + __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ + __u32 qos; + __be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */ +}; + +struct ifla_vf_tx_rate { + __u32 vf; + __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ +}; + +struct ifla_vf_rate { + __u32 vf; + __u32 min_tx_rate; /* Min Bandwidth in Mbps */ + __u32 max_tx_rate; /* Max Bandwidth in Mbps */ +}; + +struct ifla_vf_spoofchk { + __u32 vf; + __u32 setting; +}; + +struct ifla_vf_guid { + __u32 vf; + __u64 guid; +}; + +enum { + IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */ + IFLA_VF_LINK_STATE_ENABLE, /* link always up */ + IFLA_VF_LINK_STATE_DISABLE, /* link always down */ + __IFLA_VF_LINK_STATE_MAX, +}; + +struct ifla_vf_link_state { + __u32 vf; + __u32 link_state; +}; + +struct ifla_vf_rss_query_en { + __u32 vf; + __u32 setting; +}; + +enum { + IFLA_VF_STATS_RX_PACKETS, + IFLA_VF_STATS_TX_PACKETS, + IFLA_VF_STATS_RX_BYTES, + IFLA_VF_STATS_TX_BYTES, + IFLA_VF_STATS_BROADCAST, + IFLA_VF_STATS_MULTICAST, + IFLA_VF_STATS_PAD, + IFLA_VF_STATS_RX_DROPPED, + IFLA_VF_STATS_TX_DROPPED, + __IFLA_VF_STATS_MAX, +}; + +#define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1) + +struct ifla_vf_trust { + __u32 vf; + __u32 setting; +}; + +/* VF ports management section + * + * Nested layout of set/get msg is: + * + * [IFLA_NUM_VF] + * [IFLA_VF_PORTS] + * [IFLA_VF_PORT] + * [IFLA_PORT_*], ... + * [IFLA_VF_PORT] + * [IFLA_PORT_*], ... + * ... + * [IFLA_PORT_SELF] + * [IFLA_PORT_*], ... + */ + +enum { + IFLA_VF_PORT_UNSPEC, + IFLA_VF_PORT, /* nest */ + __IFLA_VF_PORT_MAX, +}; + +#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1) + +enum { + IFLA_PORT_UNSPEC, + IFLA_PORT_VF, /* __u32 */ + IFLA_PORT_PROFILE, /* string */ + IFLA_PORT_VSI_TYPE, /* 802.1Qbg (pre-)standard VDP */ + IFLA_PORT_INSTANCE_UUID, /* binary UUID */ + IFLA_PORT_HOST_UUID, /* binary UUID */ + IFLA_PORT_REQUEST, /* __u8 */ + IFLA_PORT_RESPONSE, /* __u16, output only */ + __IFLA_PORT_MAX, +}; + +#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1) + +#define PORT_PROFILE_MAX 40 +#define PORT_UUID_MAX 16 +#define PORT_SELF_VF -1 + +enum { + PORT_REQUEST_PREASSOCIATE = 0, + PORT_REQUEST_PREASSOCIATE_RR, + PORT_REQUEST_ASSOCIATE, + PORT_REQUEST_DISASSOCIATE, +}; + +enum { + PORT_VDP_RESPONSE_SUCCESS = 0, + PORT_VDP_RESPONSE_INVALID_FORMAT, + PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES, + PORT_VDP_RESPONSE_UNUSED_VTID, + PORT_VDP_RESPONSE_VTID_VIOLATION, + PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION, + PORT_VDP_RESPONSE_OUT_OF_SYNC, + /* 0x08-0xFF reserved for future VDP use */ + PORT_PROFILE_RESPONSE_SUCCESS = 0x100, + PORT_PROFILE_RESPONSE_INPROGRESS, + PORT_PROFILE_RESPONSE_INVALID, + PORT_PROFILE_RESPONSE_BADSTATE, + PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES, + PORT_PROFILE_RESPONSE_ERROR, +}; + +struct ifla_port_vsi { + __u8 vsi_mgr_id; + __u8 vsi_type_id[3]; + __u8 vsi_type_version; + __u8 pad[3]; +}; + + +/* IPoIB section */ + +enum { + IFLA_IPOIB_UNSPEC, + IFLA_IPOIB_PKEY, + IFLA_IPOIB_MODE, + IFLA_IPOIB_UMCAST, + __IFLA_IPOIB_MAX +}; + +enum { + IPOIB_MODE_DATAGRAM = 0, /* using unreliable datagram QPs */ + IPOIB_MODE_CONNECTED = 1, /* using connected QPs */ +}; + +#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1) + + +/* HSR/PRP section, both uses same interface */ + +/* Different redundancy protocols for hsr device */ +enum { + HSR_PROTOCOL_HSR, + HSR_PROTOCOL_PRP, + HSR_PROTOCOL_MAX, +}; + +enum { + IFLA_HSR_UNSPEC, + IFLA_HSR_SLAVE1, + IFLA_HSR_SLAVE2, + IFLA_HSR_MULTICAST_SPEC, /* Last byte of supervision addr */ + IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */ + IFLA_HSR_SEQ_NR, + IFLA_HSR_VERSION, /* HSR version */ + IFLA_HSR_PROTOCOL, /* Indicate different protocol than + * HSR. For example PRP. + */ + __IFLA_HSR_MAX, +}; + +#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1) + +/* STATS section */ + +struct if_stats_msg { + __u8 family; + __u8 pad1; + __u16 pad2; + __u32 ifindex; + __u32 filter_mask; +}; + +/* A stats attribute can be netdev specific or a global stat. + * For netdev stats, lets use the prefix IFLA_STATS_LINK_* + */ +enum { + IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */ + IFLA_STATS_LINK_64, + IFLA_STATS_LINK_XSTATS, + IFLA_STATS_LINK_XSTATS_SLAVE, + IFLA_STATS_LINK_OFFLOAD_XSTATS, + IFLA_STATS_AF_SPEC, + __IFLA_STATS_MAX, +}; + +#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1) + +#define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR - 1)) + +enum { + IFLA_STATS_GETSET_UNSPEC, + IFLA_STATS_GET_FILTERS, /* Nest of IFLA_STATS_LINK_xxx, each a u32 with + * a filter mask for the corresponding group. + */ + IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS, /* 0 or 1 as u8 */ + __IFLA_STATS_GETSET_MAX, +}; + +#define IFLA_STATS_GETSET_MAX (__IFLA_STATS_GETSET_MAX - 1) + +/* These are embedded into IFLA_STATS_LINK_XSTATS: + * [IFLA_STATS_LINK_XSTATS] + * -> [LINK_XSTATS_TYPE_xxx] + * -> [rtnl link type specific attributes] + */ +enum { + LINK_XSTATS_TYPE_UNSPEC, + LINK_XSTATS_TYPE_BRIDGE, + LINK_XSTATS_TYPE_BOND, + __LINK_XSTATS_TYPE_MAX +}; +#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1) + +/* These are stats embedded into IFLA_STATS_LINK_OFFLOAD_XSTATS */ +enum { + IFLA_OFFLOAD_XSTATS_UNSPEC, + IFLA_OFFLOAD_XSTATS_CPU_HIT, /* struct rtnl_link_stats64 */ + IFLA_OFFLOAD_XSTATS_HW_S_INFO, /* HW stats info. A nest */ + IFLA_OFFLOAD_XSTATS_L3_STATS, /* struct rtnl_hw_stats64 */ + __IFLA_OFFLOAD_XSTATS_MAX +}; +#define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1) + +enum { + IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC, + IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST, /* u8 */ + IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED, /* u8 */ + __IFLA_OFFLOAD_XSTATS_HW_S_INFO_MAX, +}; +#define IFLA_OFFLOAD_XSTATS_HW_S_INFO_MAX \ + (__IFLA_OFFLOAD_XSTATS_HW_S_INFO_MAX - 1) + +/* XDP section */ + +#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0) +#define XDP_FLAGS_SKB_MODE (1U << 1) +#define XDP_FLAGS_DRV_MODE (1U << 2) +#define XDP_FLAGS_HW_MODE (1U << 3) +#define XDP_FLAGS_REPLACE (1U << 4) +#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \ + XDP_FLAGS_DRV_MODE | \ + XDP_FLAGS_HW_MODE) +#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \ + XDP_FLAGS_MODES | XDP_FLAGS_REPLACE) + +/* These are stored into IFLA_XDP_ATTACHED on dump. */ +enum { + XDP_ATTACHED_NONE = 0, + XDP_ATTACHED_DRV, + XDP_ATTACHED_SKB, + XDP_ATTACHED_HW, + XDP_ATTACHED_MULTI, +}; + +enum { + IFLA_XDP_UNSPEC, + IFLA_XDP_FD, + IFLA_XDP_ATTACHED, + IFLA_XDP_FLAGS, + IFLA_XDP_PROG_ID, + IFLA_XDP_DRV_PROG_ID, + IFLA_XDP_SKB_PROG_ID, + IFLA_XDP_HW_PROG_ID, + IFLA_XDP_EXPECTED_FD, + __IFLA_XDP_MAX, +}; + +#define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1) + +enum { + IFLA_EVENT_NONE, + IFLA_EVENT_REBOOT, /* internal reset / reboot */ + IFLA_EVENT_FEATURES, /* change in offload features */ + IFLA_EVENT_BONDING_FAILOVER, /* change in active slave */ + IFLA_EVENT_NOTIFY_PEERS, /* re-sent grat. arp/ndisc */ + IFLA_EVENT_IGMP_RESEND, /* re-sent IGMP JOIN */ + IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */ +}; + +/* tun section */ + +enum { + IFLA_TUN_UNSPEC, + IFLA_TUN_OWNER, + IFLA_TUN_GROUP, + IFLA_TUN_TYPE, + IFLA_TUN_PI, + IFLA_TUN_VNET_HDR, + IFLA_TUN_PERSIST, + IFLA_TUN_MULTI_QUEUE, + IFLA_TUN_NUM_QUEUES, + IFLA_TUN_NUM_DISABLED_QUEUES, + __IFLA_TUN_MAX, +}; + +#define IFLA_TUN_MAX (__IFLA_TUN_MAX - 1) + +/* rmnet section */ + +#define RMNET_FLAGS_INGRESS_DEAGGREGATION (1U << 0) +#define RMNET_FLAGS_INGRESS_MAP_COMMANDS (1U << 1) +#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4 (1U << 2) +#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4 (1U << 3) +#define RMNET_FLAGS_INGRESS_MAP_CKSUMV5 (1U << 4) +#define RMNET_FLAGS_EGRESS_MAP_CKSUMV5 (1U << 5) + +enum { + IFLA_RMNET_UNSPEC, + IFLA_RMNET_MUX_ID, + IFLA_RMNET_FLAGS, + __IFLA_RMNET_MAX, +}; + +#define IFLA_RMNET_MAX (__IFLA_RMNET_MAX - 1) + +struct ifla_rmnet_flags { + __u32 flags; + __u32 mask; +}; + +/* MCTP section */ + +enum { + IFLA_MCTP_UNSPEC, + IFLA_MCTP_NET, + __IFLA_MCTP_MAX, +}; + +#define IFLA_MCTP_MAX (__IFLA_MCTP_MAX - 1) + +/* DSA section */ + +enum { + IFLA_DSA_UNSPEC, + IFLA_DSA_MASTER, + __IFLA_DSA_MAX, +}; + +#define IFLA_DSA_MAX (__IFLA_DSA_MAX - 1) + +#endif /* _LINUX_IF_LINK_H */ diff --git a/uapi/linux/net_tstamp.h b/uapi/linux/net_tstamp.h new file mode 100644 index 0000000..55501e5 --- /dev/null +++ b/uapi/linux/net_tstamp.h @@ -0,0 +1,204 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Userspace API for hardware time stamping of network packets + * + * Copyright (C) 2008,2009 Intel Corporation + * Author: Patrick Ohly + * + */ + +#ifndef _NET_TIMESTAMPING_H +#define _NET_TIMESTAMPING_H + +#include +#include /* for SO_TIMESTAMPING */ + +/* SO_TIMESTAMPING flags */ +enum { + SOF_TIMESTAMPING_TX_HARDWARE = (1<<0), + SOF_TIMESTAMPING_TX_SOFTWARE = (1<<1), + SOF_TIMESTAMPING_RX_HARDWARE = (1<<2), + SOF_TIMESTAMPING_RX_SOFTWARE = (1<<3), + SOF_TIMESTAMPING_SOFTWARE = (1<<4), + SOF_TIMESTAMPING_SYS_HARDWARE = (1<<5), + SOF_TIMESTAMPING_RAW_HARDWARE = (1<<6), + SOF_TIMESTAMPING_OPT_ID = (1<<7), + SOF_TIMESTAMPING_TX_SCHED = (1<<8), + SOF_TIMESTAMPING_TX_ACK = (1<<9), + SOF_TIMESTAMPING_OPT_CMSG = (1<<10), + SOF_TIMESTAMPING_OPT_TSONLY = (1<<11), + SOF_TIMESTAMPING_OPT_STATS = (1<<12), + SOF_TIMESTAMPING_OPT_PKTINFO = (1<<13), + SOF_TIMESTAMPING_OPT_TX_SWHW = (1<<14), + SOF_TIMESTAMPING_BIND_PHC = (1 << 15), + + SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_BIND_PHC, + SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | + SOF_TIMESTAMPING_LAST +}; + +/* + * SO_TIMESTAMPING flags are either for recording a packet timestamp or for + * reporting the timestamp to user space. + * Recording flags can be set both via socket options and control messages. + */ +#define SOF_TIMESTAMPING_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_HARDWARE | \ + SOF_TIMESTAMPING_TX_SOFTWARE | \ + SOF_TIMESTAMPING_TX_SCHED | \ + SOF_TIMESTAMPING_TX_ACK) + +/** + * struct so_timestamping - SO_TIMESTAMPING parameter + * + * @flags: SO_TIMESTAMPING flags + * @bind_phc: Index of PTP virtual clock bound to sock. This is available + * if flag SOF_TIMESTAMPING_BIND_PHC is set. + */ +struct so_timestamping { + int flags; + int bind_phc; +}; + +/** + * struct hwtstamp_config - %SIOCGHWTSTAMP and %SIOCSHWTSTAMP parameter + * + * @flags: one of HWTSTAMP_FLAG_* + * @tx_type: one of HWTSTAMP_TX_* + * @rx_filter: one of HWTSTAMP_FILTER_* + * + * %SIOCGHWTSTAMP and %SIOCSHWTSTAMP expect a &struct ifreq with a + * ifr_data pointer to this structure. For %SIOCSHWTSTAMP, if the + * driver or hardware does not support the requested @rx_filter value, + * the driver may use a more general filter mode. In this case + * @rx_filter will indicate the actual mode on return. + */ +struct hwtstamp_config { + int flags; + int tx_type; + int rx_filter; +}; + +/* possible values for hwtstamp_config->flags */ +enum hwtstamp_flags { + /* + * With this flag, the user could get bond active interface's + * PHC index. Note this PHC index is not stable as when there + * is a failover, the bond active interface will be changed, so + * will be the PHC index. + */ + HWTSTAMP_FLAG_BONDED_PHC_INDEX = (1<<0), +#define HWTSTAMP_FLAG_BONDED_PHC_INDEX HWTSTAMP_FLAG_BONDED_PHC_INDEX + + HWTSTAMP_FLAG_LAST = HWTSTAMP_FLAG_BONDED_PHC_INDEX, + HWTSTAMP_FLAG_MASK = (HWTSTAMP_FLAG_LAST - 1) | HWTSTAMP_FLAG_LAST +}; + +/* possible values for hwtstamp_config->tx_type */ +enum hwtstamp_tx_types { + /* + * No outgoing packet will need hardware time stamping; + * should a packet arrive which asks for it, no hardware + * time stamping will be done. + */ + HWTSTAMP_TX_OFF, + + /* + * Enables hardware time stamping for outgoing packets; + * the sender of the packet decides which are to be + * time stamped by setting %SOF_TIMESTAMPING_TX_SOFTWARE + * before sending the packet. + */ + HWTSTAMP_TX_ON, + + /* + * Enables time stamping for outgoing packets just as + * HWTSTAMP_TX_ON does, but also enables time stamp insertion + * directly into Sync packets. In this case, transmitted Sync + * packets will not received a time stamp via the socket error + * queue. + */ + HWTSTAMP_TX_ONESTEP_SYNC, + + /* + * Same as HWTSTAMP_TX_ONESTEP_SYNC, but also enables time + * stamp insertion directly into PDelay_Resp packets. In this + * case, neither transmitted Sync nor PDelay_Resp packets will + * receive a time stamp via the socket error queue. + */ + HWTSTAMP_TX_ONESTEP_P2P, + + /* add new constants above here */ + __HWTSTAMP_TX_CNT +}; + +/* possible values for hwtstamp_config->rx_filter */ +enum hwtstamp_rx_filters { + /* time stamp no incoming packet at all */ + HWTSTAMP_FILTER_NONE, + + /* time stamp any incoming packet */ + HWTSTAMP_FILTER_ALL, + + /* return value: time stamp all packets requested plus some others */ + HWTSTAMP_FILTER_SOME, + + /* PTP v1, UDP, any kind of event packet */ + HWTSTAMP_FILTER_PTP_V1_L4_EVENT, + /* PTP v1, UDP, Sync packet */ + HWTSTAMP_FILTER_PTP_V1_L4_SYNC, + /* PTP v1, UDP, Delay_req packet */ + HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ, + /* PTP v2, UDP, any kind of event packet */ + HWTSTAMP_FILTER_PTP_V2_L4_EVENT, + /* PTP v2, UDP, Sync packet */ + HWTSTAMP_FILTER_PTP_V2_L4_SYNC, + /* PTP v2, UDP, Delay_req packet */ + HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ, + + /* 802.AS1, Ethernet, any kind of event packet */ + HWTSTAMP_FILTER_PTP_V2_L2_EVENT, + /* 802.AS1, Ethernet, Sync packet */ + HWTSTAMP_FILTER_PTP_V2_L2_SYNC, + /* 802.AS1, Ethernet, Delay_req packet */ + HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ, + + /* PTP v2/802.AS1, any layer, any kind of event packet */ + HWTSTAMP_FILTER_PTP_V2_EVENT, + /* PTP v2/802.AS1, any layer, Sync packet */ + HWTSTAMP_FILTER_PTP_V2_SYNC, + /* PTP v2/802.AS1, any layer, Delay_req packet */ + HWTSTAMP_FILTER_PTP_V2_DELAY_REQ, + + /* NTP, UDP, all versions and packet modes */ + HWTSTAMP_FILTER_NTP_ALL, + + /* add new constants above here */ + __HWTSTAMP_FILTER_CNT +}; + +/* SCM_TIMESTAMPING_PKTINFO control message */ +struct scm_ts_pktinfo { + __u32 if_index; + __u32 pkt_length; + __u32 reserved[2]; +}; + +/* + * SO_TXTIME gets a struct sock_txtime with flags being an integer bit + * field comprised of these values. + */ +enum txtime_flags { + SOF_TXTIME_DEADLINE_MODE = (1 << 0), + SOF_TXTIME_REPORT_ERRORS = (1 << 1), + + SOF_TXTIME_FLAGS_LAST = SOF_TXTIME_REPORT_ERRORS, + SOF_TXTIME_FLAGS_MASK = (SOF_TXTIME_FLAGS_LAST - 1) | + SOF_TXTIME_FLAGS_LAST +}; + +struct sock_txtime { + __kernel_clockid_t clockid;/* reference clockid */ + __u32 flags; /* as defined by enum txtime_flags */ +}; + +#endif /* _NET_TIMESTAMPING_H */ diff --git a/uapi/linux/netlink.h b/uapi/linux/netlink.h new file mode 100644 index 0000000..47bac97 --- /dev/null +++ b/uapi/linux/netlink.h @@ -0,0 +1,374 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef __LINUX_NETLINK_H +#define __LINUX_NETLINK_H + +#include +#include /* for __kernel_sa_family_t */ +#include + +#define NETLINK_ROUTE 0 /* Routing/device hook */ +#define NETLINK_UNUSED 1 /* Unused number */ +#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ +#define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */ +#define NETLINK_SOCK_DIAG 4 /* socket monitoring */ +#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */ +#define NETLINK_XFRM 6 /* ipsec */ +#define NETLINK_SELINUX 7 /* SELinux event notifications */ +#define NETLINK_ISCSI 8 /* Open-iSCSI */ +#define NETLINK_AUDIT 9 /* auditing */ +#define NETLINK_FIB_LOOKUP 10 +#define NETLINK_CONNECTOR 11 +#define NETLINK_NETFILTER 12 /* netfilter subsystem */ +#define NETLINK_IP6_FW 13 +#define NETLINK_DNRTMSG 14 /* DECnet routing messages (obsolete) */ +#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */ +#define NETLINK_GENERIC 16 +/* leave room for NETLINK_DM (DM Events) */ +#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */ +#define NETLINK_ECRYPTFS 19 +#define NETLINK_RDMA 20 +#define NETLINK_CRYPTO 21 /* Crypto layer */ +#define NETLINK_SMC 22 /* SMC monitoring */ + +#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG + +#define MAX_LINKS 32 + +struct sockaddr_nl { + __kernel_sa_family_t nl_family; /* AF_NETLINK */ + unsigned short nl_pad; /* zero */ + __u32 nl_pid; /* port ID */ + __u32 nl_groups; /* multicast groups mask */ +}; + +/** + * struct nlmsghdr - fixed format metadata header of Netlink messages + * @nlmsg_len: Length of message including header + * @nlmsg_type: Message content type + * @nlmsg_flags: Additional flags + * @nlmsg_seq: Sequence number + * @nlmsg_pid: Sending process port ID + */ +struct nlmsghdr { + __u32 nlmsg_len; + __u16 nlmsg_type; + __u16 nlmsg_flags; + __u32 nlmsg_seq; + __u32 nlmsg_pid; +}; + +/* Flags values */ + +#define NLM_F_REQUEST 0x01 /* It is request message. */ +#define NLM_F_MULTI 0x02 /* Multipart message, terminated by NLMSG_DONE */ +#define NLM_F_ACK 0x04 /* Reply with ack, with zero or error code */ +#define NLM_F_ECHO 0x08 /* Receive resulting notifications */ +#define NLM_F_DUMP_INTR 0x10 /* Dump was inconsistent due to sequence change */ +#define NLM_F_DUMP_FILTERED 0x20 /* Dump was filtered as requested */ + +/* Modifiers to GET request */ +#define NLM_F_ROOT 0x100 /* specify tree root */ +#define NLM_F_MATCH 0x200 /* return all matching */ +#define NLM_F_ATOMIC 0x400 /* atomic GET */ +#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH) + +/* Modifiers to NEW request */ +#define NLM_F_REPLACE 0x100 /* Override existing */ +#define NLM_F_EXCL 0x200 /* Do not touch, if it exists */ +#define NLM_F_CREATE 0x400 /* Create, if it does not exist */ +#define NLM_F_APPEND 0x800 /* Add to end of list */ + +/* Modifiers to DELETE request */ +#define NLM_F_NONREC 0x100 /* Do not delete recursively */ +#define NLM_F_BULK 0x200 /* Delete multiple objects */ + +/* Flags for ACK message */ +#define NLM_F_CAPPED 0x100 /* request was capped */ +#define NLM_F_ACK_TLVS 0x200 /* extended ACK TVLs were included */ + +/* + 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL + 4.4BSD CHANGE NLM_F_REPLACE + + True CHANGE NLM_F_CREATE|NLM_F_REPLACE + Append NLM_F_CREATE + Check NLM_F_EXCL + */ + +#define NLMSG_ALIGNTO 4U +#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) +#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) +#define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN) +#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) +#define NLMSG_DATA(nlh) ((void *)(((char *)nlh) + NLMSG_HDRLEN)) +#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \ + (struct nlmsghdr *)(((char *)(nlh)) + \ + NLMSG_ALIGN((nlh)->nlmsg_len))) +#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \ + (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \ + (nlh)->nlmsg_len <= (len)) +#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len))) + +#define NLMSG_NOOP 0x1 /* Nothing. */ +#define NLMSG_ERROR 0x2 /* Error */ +#define NLMSG_DONE 0x3 /* End of a dump */ +#define NLMSG_OVERRUN 0x4 /* Data lost */ + +#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */ + +struct nlmsgerr { + int error; + struct nlmsghdr msg; + /* + * followed by the message contents unless NETLINK_CAP_ACK was set + * or the ACK indicates success (error == 0) + * message length is aligned with NLMSG_ALIGN() + */ + /* + * followed by TLVs defined in enum nlmsgerr_attrs + * if NETLINK_EXT_ACK was set + */ +}; + +/** + * enum nlmsgerr_attrs - nlmsgerr attributes + * @NLMSGERR_ATTR_UNUSED: unused + * @NLMSGERR_ATTR_MSG: error message string (string) + * @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original + * message, counting from the beginning of the header (u32) + * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to + * be used - in the success case - to identify a created + * object or operation or similar (binary) + * @NLMSGERR_ATTR_POLICY: policy for a rejected attribute + * @NLMSGERR_ATTR_MISS_TYPE: type of a missing required attribute, + * %NLMSGERR_ATTR_MISS_NEST will not be present if the attribute was + * missing at the message level + * @NLMSGERR_ATTR_MISS_NEST: offset of the nest where attribute was missing + * @__NLMSGERR_ATTR_MAX: number of attributes + * @NLMSGERR_ATTR_MAX: highest attribute number + */ +enum nlmsgerr_attrs { + NLMSGERR_ATTR_UNUSED, + NLMSGERR_ATTR_MSG, + NLMSGERR_ATTR_OFFS, + NLMSGERR_ATTR_COOKIE, + NLMSGERR_ATTR_POLICY, + NLMSGERR_ATTR_MISS_TYPE, + NLMSGERR_ATTR_MISS_NEST, + + __NLMSGERR_ATTR_MAX, + NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1 +}; + +#define NETLINK_ADD_MEMBERSHIP 1 +#define NETLINK_DROP_MEMBERSHIP 2 +#define NETLINK_PKTINFO 3 +#define NETLINK_BROADCAST_ERROR 4 +#define NETLINK_NO_ENOBUFS 5 +#define NETLINK_RX_RING 6 +#define NETLINK_TX_RING 7 +#define NETLINK_LISTEN_ALL_NSID 8 +#define NETLINK_LIST_MEMBERSHIPS 9 +#define NETLINK_CAP_ACK 10 +#define NETLINK_EXT_ACK 11 +#define NETLINK_GET_STRICT_CHK 12 + +struct nl_pktinfo { + __u32 group; +}; + +struct nl_mmap_req { + unsigned int nm_block_size; + unsigned int nm_block_nr; + unsigned int nm_frame_size; + unsigned int nm_frame_nr; +}; + +struct nl_mmap_hdr { + unsigned int nm_status; + unsigned int nm_len; + __u32 nm_group; + /* credentials */ + __u32 nm_pid; + __u32 nm_uid; + __u32 nm_gid; +}; + +enum nl_mmap_status { + NL_MMAP_STATUS_UNUSED, + NL_MMAP_STATUS_RESERVED, + NL_MMAP_STATUS_VALID, + NL_MMAP_STATUS_COPY, + NL_MMAP_STATUS_SKIP, +}; + +#define NL_MMAP_MSG_ALIGNMENT NLMSG_ALIGNTO +#define NL_MMAP_MSG_ALIGN(sz) __ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT) +#define NL_MMAP_HDRLEN NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr)) + +#define NET_MAJOR 36 /* Major 36 is reserved for networking */ + +enum { + NETLINK_UNCONNECTED = 0, + NETLINK_CONNECTED, +}; + +/* + * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)--> + * +---------------------+- - -+- - - - - - - - - -+- - -+ + * | Header | Pad | Payload | Pad | + * | (struct nlattr) | ing | | ing | + * +---------------------+- - -+- - - - - - - - - -+- - -+ + * <-------------- nlattr->nla_len --------------> + */ + +struct nlattr { + __u16 nla_len; + __u16 nla_type; +}; + +/* + * nla_type (16 bits) + * +---+---+-------------------------------+ + * | N | O | Attribute Type | + * +---+---+-------------------------------+ + * N := Carries nested attributes + * O := Payload stored in network byte order + * + * Note: The N and O flag are mutually exclusive. + */ +#define NLA_F_NESTED (1 << 15) +#define NLA_F_NET_BYTEORDER (1 << 14) +#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER) + +#define NLA_ALIGNTO 4 +#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) +#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) + +/* Generic 32 bitflags attribute content sent to the kernel. + * + * The value is a bitmap that defines the values being set + * The selector is a bitmask that defines which value is legit + * + * Examples: + * value = 0x0, and selector = 0x1 + * implies we are selecting bit 1 and we want to set its value to 0. + * + * value = 0x2, and selector = 0x2 + * implies we are selecting bit 2 and we want to set its value to 1. + * + */ +struct nla_bitfield32 { + __u32 value; + __u32 selector; +}; + +/* + * policy descriptions - it's specific to each family how this is used + * Normally, it should be retrieved via a dump inside another attribute + * specifying where it applies. + */ + +/** + * enum netlink_attribute_type - type of an attribute + * @NL_ATTR_TYPE_INVALID: unused + * @NL_ATTR_TYPE_FLAG: flag attribute (present/not present) + * @NL_ATTR_TYPE_U8: 8-bit unsigned attribute + * @NL_ATTR_TYPE_U16: 16-bit unsigned attribute + * @NL_ATTR_TYPE_U32: 32-bit unsigned attribute + * @NL_ATTR_TYPE_U64: 64-bit unsigned attribute + * @NL_ATTR_TYPE_S8: 8-bit signed attribute + * @NL_ATTR_TYPE_S16: 16-bit signed attribute + * @NL_ATTR_TYPE_S32: 32-bit signed attribute + * @NL_ATTR_TYPE_S64: 64-bit signed attribute + * @NL_ATTR_TYPE_BINARY: binary data, min/max length may be specified + * @NL_ATTR_TYPE_STRING: string, min/max length may be specified + * @NL_ATTR_TYPE_NUL_STRING: NUL-terminated string, + * min/max length may be specified + * @NL_ATTR_TYPE_NESTED: nested, i.e. the content of this attribute + * consists of sub-attributes. The nested policy and maxtype + * inside may be specified. + * @NL_ATTR_TYPE_NESTED_ARRAY: nested array, i.e. the content of this + * attribute contains sub-attributes whose type is irrelevant + * (just used to separate the array entries) and each such array + * entry has attributes again, the policy for those inner ones + * and the corresponding maxtype may be specified. + * @NL_ATTR_TYPE_BITFIELD32: &struct nla_bitfield32 attribute + */ +enum netlink_attribute_type { + NL_ATTR_TYPE_INVALID, + + NL_ATTR_TYPE_FLAG, + + NL_ATTR_TYPE_U8, + NL_ATTR_TYPE_U16, + NL_ATTR_TYPE_U32, + NL_ATTR_TYPE_U64, + + NL_ATTR_TYPE_S8, + NL_ATTR_TYPE_S16, + NL_ATTR_TYPE_S32, + NL_ATTR_TYPE_S64, + + NL_ATTR_TYPE_BINARY, + NL_ATTR_TYPE_STRING, + NL_ATTR_TYPE_NUL_STRING, + + NL_ATTR_TYPE_NESTED, + NL_ATTR_TYPE_NESTED_ARRAY, + + NL_ATTR_TYPE_BITFIELD32, +}; + +/** + * enum netlink_policy_type_attr - policy type attributes + * @NL_POLICY_TYPE_ATTR_UNSPEC: unused + * @NL_POLICY_TYPE_ATTR_TYPE: type of the attribute, + * &enum netlink_attribute_type (U32) + * @NL_POLICY_TYPE_ATTR_MIN_VALUE_S: minimum value for signed + * integers (S64) + * @NL_POLICY_TYPE_ATTR_MAX_VALUE_S: maximum value for signed + * integers (S64) + * @NL_POLICY_TYPE_ATTR_MIN_VALUE_U: minimum value for unsigned + * integers (U64) + * @NL_POLICY_TYPE_ATTR_MAX_VALUE_U: maximum value for unsigned + * integers (U64) + * @NL_POLICY_TYPE_ATTR_MIN_LENGTH: minimum length for binary + * attributes, no minimum if not given (U32) + * @NL_POLICY_TYPE_ATTR_MAX_LENGTH: maximum length for binary + * attributes, no maximum if not given (U32) + * @NL_POLICY_TYPE_ATTR_POLICY_IDX: sub policy for nested and + * nested array types (U32) + * @NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE: maximum sub policy + * attribute for nested and nested array types, this can + * in theory be < the size of the policy pointed to by + * the index, if limited inside the nesting (U32) + * @NL_POLICY_TYPE_ATTR_BITFIELD32_MASK: valid mask for the + * bitfield32 type (U32) + * @NL_POLICY_TYPE_ATTR_MASK: mask of valid bits for unsigned integers (U64) + * @NL_POLICY_TYPE_ATTR_PAD: pad attribute for 64-bit alignment + * + * @__NL_POLICY_TYPE_ATTR_MAX: number of attributes + * @NL_POLICY_TYPE_ATTR_MAX: highest attribute number + */ +enum netlink_policy_type_attr { + NL_POLICY_TYPE_ATTR_UNSPEC, + NL_POLICY_TYPE_ATTR_TYPE, + NL_POLICY_TYPE_ATTR_MIN_VALUE_S, + NL_POLICY_TYPE_ATTR_MAX_VALUE_S, + NL_POLICY_TYPE_ATTR_MIN_VALUE_U, + NL_POLICY_TYPE_ATTR_MAX_VALUE_U, + NL_POLICY_TYPE_ATTR_MIN_LENGTH, + NL_POLICY_TYPE_ATTR_MAX_LENGTH, + NL_POLICY_TYPE_ATTR_POLICY_IDX, + NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE, + NL_POLICY_TYPE_ATTR_BITFIELD32_MASK, + NL_POLICY_TYPE_ATTR_PAD, + NL_POLICY_TYPE_ATTR_MASK, + + /* keep last */ + __NL_POLICY_TYPE_ATTR_MAX, + NL_POLICY_TYPE_ATTR_MAX = __NL_POLICY_TYPE_ATTR_MAX - 1 +}; + +#endif /* __LINUX_NETLINK_H */ diff --git a/uapi/linux/rtnetlink.h b/uapi/linux/rtnetlink.h new file mode 100644 index 0000000..f4a540c --- /dev/null +++ b/uapi/linux/rtnetlink.h @@ -0,0 +1,824 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef __LINUX_RTNETLINK_H +#define __LINUX_RTNETLINK_H + +#include +#include +#include +#include +#include + +/* rtnetlink families. Values up to 127 are reserved for real address + * families, values above 128 may be used arbitrarily. + */ +#define RTNL_FAMILY_IPMR 128 +#define RTNL_FAMILY_IP6MR 129 +#define RTNL_FAMILY_MAX 129 + +/**** + * Routing/neighbour discovery messages. + ****/ + +/* Types of messages */ + +enum { + RTM_BASE = 16, +#define RTM_BASE RTM_BASE + + RTM_NEWLINK = 16, +#define RTM_NEWLINK RTM_NEWLINK + RTM_DELLINK, +#define RTM_DELLINK RTM_DELLINK + RTM_GETLINK, +#define RTM_GETLINK RTM_GETLINK + RTM_SETLINK, +#define RTM_SETLINK RTM_SETLINK + + RTM_NEWADDR = 20, +#define RTM_NEWADDR RTM_NEWADDR + RTM_DELADDR, +#define RTM_DELADDR RTM_DELADDR + RTM_GETADDR, +#define RTM_GETADDR RTM_GETADDR + + RTM_NEWROUTE = 24, +#define RTM_NEWROUTE RTM_NEWROUTE + RTM_DELROUTE, +#define RTM_DELROUTE RTM_DELROUTE + RTM_GETROUTE, +#define RTM_GETROUTE RTM_GETROUTE + + RTM_NEWNEIGH = 28, +#define RTM_NEWNEIGH RTM_NEWNEIGH + RTM_DELNEIGH, +#define RTM_DELNEIGH RTM_DELNEIGH + RTM_GETNEIGH, +#define RTM_GETNEIGH RTM_GETNEIGH + + RTM_NEWRULE = 32, +#define RTM_NEWRULE RTM_NEWRULE + RTM_DELRULE, +#define RTM_DELRULE RTM_DELRULE + RTM_GETRULE, +#define RTM_GETRULE RTM_GETRULE + + RTM_NEWQDISC = 36, +#define RTM_NEWQDISC RTM_NEWQDISC + RTM_DELQDISC, +#define RTM_DELQDISC RTM_DELQDISC + RTM_GETQDISC, +#define RTM_GETQDISC RTM_GETQDISC + + RTM_NEWTCLASS = 40, +#define RTM_NEWTCLASS RTM_NEWTCLASS + RTM_DELTCLASS, +#define RTM_DELTCLASS RTM_DELTCLASS + RTM_GETTCLASS, +#define RTM_GETTCLASS RTM_GETTCLASS + + RTM_NEWTFILTER = 44, +#define RTM_NEWTFILTER RTM_NEWTFILTER + RTM_DELTFILTER, +#define RTM_DELTFILTER RTM_DELTFILTER + RTM_GETTFILTER, +#define RTM_GETTFILTER RTM_GETTFILTER + + RTM_NEWACTION = 48, +#define RTM_NEWACTION RTM_NEWACTION + RTM_DELACTION, +#define RTM_DELACTION RTM_DELACTION + RTM_GETACTION, +#define RTM_GETACTION RTM_GETACTION + + RTM_NEWPREFIX = 52, +#define RTM_NEWPREFIX RTM_NEWPREFIX + + RTM_GETMULTICAST = 58, +#define RTM_GETMULTICAST RTM_GETMULTICAST + + RTM_GETANYCAST = 62, +#define RTM_GETANYCAST RTM_GETANYCAST + + RTM_NEWNEIGHTBL = 64, +#define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL + RTM_GETNEIGHTBL = 66, +#define RTM_GETNEIGHTBL RTM_GETNEIGHTBL + RTM_SETNEIGHTBL, +#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL + + RTM_NEWNDUSEROPT = 68, +#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT + + RTM_NEWADDRLABEL = 72, +#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL + RTM_DELADDRLABEL, +#define RTM_DELADDRLABEL RTM_DELADDRLABEL + RTM_GETADDRLABEL, +#define RTM_GETADDRLABEL RTM_GETADDRLABEL + + RTM_GETDCB = 78, +#define RTM_GETDCB RTM_GETDCB + RTM_SETDCB, +#define RTM_SETDCB RTM_SETDCB + + RTM_NEWNETCONF = 80, +#define RTM_NEWNETCONF RTM_NEWNETCONF + RTM_DELNETCONF, +#define RTM_DELNETCONF RTM_DELNETCONF + RTM_GETNETCONF = 82, +#define RTM_GETNETCONF RTM_GETNETCONF + + RTM_NEWMDB = 84, +#define RTM_NEWMDB RTM_NEWMDB + RTM_DELMDB = 85, +#define RTM_DELMDB RTM_DELMDB + RTM_GETMDB = 86, +#define RTM_GETMDB RTM_GETMDB + + RTM_NEWNSID = 88, +#define RTM_NEWNSID RTM_NEWNSID + RTM_DELNSID = 89, +#define RTM_DELNSID RTM_DELNSID + RTM_GETNSID = 90, +#define RTM_GETNSID RTM_GETNSID + + RTM_NEWSTATS = 92, +#define RTM_NEWSTATS RTM_NEWSTATS + RTM_GETSTATS = 94, +#define RTM_GETSTATS RTM_GETSTATS + RTM_SETSTATS, +#define RTM_SETSTATS RTM_SETSTATS + + RTM_NEWCACHEREPORT = 96, +#define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT + + RTM_NEWCHAIN = 100, +#define RTM_NEWCHAIN RTM_NEWCHAIN + RTM_DELCHAIN, +#define RTM_DELCHAIN RTM_DELCHAIN + RTM_GETCHAIN, +#define RTM_GETCHAIN RTM_GETCHAIN + + RTM_NEWNEXTHOP = 104, +#define RTM_NEWNEXTHOP RTM_NEWNEXTHOP + RTM_DELNEXTHOP, +#define RTM_DELNEXTHOP RTM_DELNEXTHOP + RTM_GETNEXTHOP, +#define RTM_GETNEXTHOP RTM_GETNEXTHOP + + RTM_NEWLINKPROP = 108, +#define RTM_NEWLINKPROP RTM_NEWLINKPROP + RTM_DELLINKPROP, +#define RTM_DELLINKPROP RTM_DELLINKPROP + RTM_GETLINKPROP, +#define RTM_GETLINKPROP RTM_GETLINKPROP + + RTM_NEWVLAN = 112, +#define RTM_NEWNVLAN RTM_NEWVLAN + RTM_DELVLAN, +#define RTM_DELVLAN RTM_DELVLAN + RTM_GETVLAN, +#define RTM_GETVLAN RTM_GETVLAN + + RTM_NEWNEXTHOPBUCKET = 116, +#define RTM_NEWNEXTHOPBUCKET RTM_NEWNEXTHOPBUCKET + RTM_DELNEXTHOPBUCKET, +#define RTM_DELNEXTHOPBUCKET RTM_DELNEXTHOPBUCKET + RTM_GETNEXTHOPBUCKET, +#define RTM_GETNEXTHOPBUCKET RTM_GETNEXTHOPBUCKET + + RTM_NEWTUNNEL = 120, +#define RTM_NEWTUNNEL RTM_NEWTUNNEL + RTM_DELTUNNEL, +#define RTM_DELTUNNEL RTM_DELTUNNEL + RTM_GETTUNNEL, +#define RTM_GETTUNNEL RTM_GETTUNNEL + + __RTM_MAX, +#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) +}; + +#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE) +#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2) +#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2) + +/* + Generic structure for encapsulation of optional route information. + It is reminiscent of sockaddr, but with sa_family replaced + with attribute type. + */ + +struct rtattr { + unsigned short rta_len; + unsigned short rta_type; +}; + +/* Macros to handle rtattributes */ + +#define RTA_ALIGNTO 4U +#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) ) +#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \ + (rta)->rta_len >= sizeof(struct rtattr) && \ + (rta)->rta_len <= (len)) +#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \ + (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len))) +#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) +#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len)) +#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0))) +#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) + + + + +/****************************************************************************** + * Definitions used in routing table administration. + ****/ + +struct rtmsg { + unsigned char rtm_family; + unsigned char rtm_dst_len; + unsigned char rtm_src_len; + unsigned char rtm_tos; + + unsigned char rtm_table; /* Routing table id */ + unsigned char rtm_protocol; /* Routing protocol; see below */ + unsigned char rtm_scope; /* See below */ + unsigned char rtm_type; /* See below */ + + unsigned rtm_flags; +}; + +/* rtm_type */ + +enum { + RTN_UNSPEC, + RTN_UNICAST, /* Gateway or direct route */ + RTN_LOCAL, /* Accept locally */ + RTN_BROADCAST, /* Accept locally as broadcast, + send as broadcast */ + RTN_ANYCAST, /* Accept locally as broadcast, + but send as unicast */ + RTN_MULTICAST, /* Multicast route */ + RTN_BLACKHOLE, /* Drop */ + RTN_UNREACHABLE, /* Destination is unreachable */ + RTN_PROHIBIT, /* Administratively prohibited */ + RTN_THROW, /* Not in this table */ + RTN_NAT, /* Translate this address */ + RTN_XRESOLVE, /* Use external resolver */ + __RTN_MAX +}; + +#define RTN_MAX (__RTN_MAX - 1) + + +/* rtm_protocol */ + +#define RTPROT_UNSPEC 0 +#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects; + not used by current IPv4 */ +#define RTPROT_KERNEL 2 /* Route installed by kernel */ +#define RTPROT_BOOT 3 /* Route installed during boot */ +#define RTPROT_STATIC 4 /* Route installed by administrator */ + +/* Values of protocol >= RTPROT_STATIC are not interpreted by kernel; + they are just passed from user and back as is. + It will be used by hypothetical multiple routing daemons. + Note that protocol values should be standardized in order to + avoid conflicts. + */ + +#define RTPROT_GATED 8 /* Apparently, GateD */ +#define RTPROT_RA 9 /* RDISC/ND router advertisements */ +#define RTPROT_MRT 10 /* Merit MRT */ +#define RTPROT_ZEBRA 11 /* Zebra */ +#define RTPROT_BIRD 12 /* BIRD */ +#define RTPROT_DNROUTED 13 /* DECnet routing daemon */ +#define RTPROT_XORP 14 /* XORP */ +#define RTPROT_NTK 15 /* Netsukuku */ +#define RTPROT_DHCP 16 /* DHCP client */ +#define RTPROT_MROUTED 17 /* Multicast daemon */ +#define RTPROT_KEEPALIVED 18 /* Keepalived daemon */ +#define RTPROT_BABEL 42 /* Babel daemon */ +#define RTPROT_OPENR 99 /* Open Routing (Open/R) Routes */ +#define RTPROT_BGP 186 /* BGP Routes */ +#define RTPROT_ISIS 187 /* ISIS Routes */ +#define RTPROT_OSPF 188 /* OSPF Routes */ +#define RTPROT_RIP 189 /* RIP Routes */ +#define RTPROT_EIGRP 192 /* EIGRP Routes */ + +/* rtm_scope + + Really it is not scope, but sort of distance to the destination. + NOWHERE are reserved for not existing destinations, HOST is our + local addresses, LINK are destinations, located on directly attached + link and UNIVERSE is everywhere in the Universe. + + Intermediate values are also possible f.e. interior routes + could be assigned a value between UNIVERSE and LINK. +*/ + +enum rt_scope_t { + RT_SCOPE_UNIVERSE=0, +/* User defined values */ + RT_SCOPE_SITE=200, + RT_SCOPE_LINK=253, + RT_SCOPE_HOST=254, + RT_SCOPE_NOWHERE=255 +}; + +/* rtm_flags */ + +#define RTM_F_NOTIFY 0x100 /* Notify user of route change */ +#define RTM_F_CLONED 0x200 /* This route is cloned */ +#define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */ +#define RTM_F_PREFIX 0x800 /* Prefix addresses */ +#define RTM_F_LOOKUP_TABLE 0x1000 /* set rtm_table to FIB lookup result */ +#define RTM_F_FIB_MATCH 0x2000 /* return full fib lookup match */ +#define RTM_F_OFFLOAD 0x4000 /* route is offloaded */ +#define RTM_F_TRAP 0x8000 /* route is trapping packets */ +#define RTM_F_OFFLOAD_FAILED 0x20000000 /* route offload failed, this value + * is chosen to avoid conflicts with + * other flags defined in + * include/uapi/linux/ipv6_route.h + */ + +/* Reserved table identifiers */ + +enum rt_class_t { + RT_TABLE_UNSPEC=0, +/* User defined values */ + RT_TABLE_COMPAT=252, + RT_TABLE_DEFAULT=253, + RT_TABLE_MAIN=254, + RT_TABLE_LOCAL=255, + RT_TABLE_MAX=0xFFFFFFFF +}; + + +/* Routing message attributes */ + +enum rtattr_type_t { + RTA_UNSPEC, + RTA_DST, + RTA_SRC, + RTA_IIF, + RTA_OIF, + RTA_GATEWAY, + RTA_PRIORITY, + RTA_PREFSRC, + RTA_METRICS, + RTA_MULTIPATH, + RTA_PROTOINFO, /* no longer used */ + RTA_FLOW, + RTA_CACHEINFO, + RTA_SESSION, /* no longer used */ + RTA_MP_ALGO, /* no longer used */ + RTA_TABLE, + RTA_MARK, + RTA_MFC_STATS, + RTA_VIA, + RTA_NEWDST, + RTA_PREF, + RTA_ENCAP_TYPE, + RTA_ENCAP, + RTA_EXPIRES, + RTA_PAD, + RTA_UID, + RTA_TTL_PROPAGATE, + RTA_IP_PROTO, + RTA_SPORT, + RTA_DPORT, + RTA_NH_ID, + __RTA_MAX +}; + +#define RTA_MAX (__RTA_MAX - 1) + +#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg)))) +#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg)) + +/* RTM_MULTIPATH --- array of struct rtnexthop. + * + * "struct rtnexthop" describes all necessary nexthop information, + * i.e. parameters of path to a destination via this nexthop. + * + * At the moment it is impossible to set different prefsrc, mtu, window + * and rtt for different paths from multipath. + */ + +struct rtnexthop { + unsigned short rtnh_len; + unsigned char rtnh_flags; + unsigned char rtnh_hops; + int rtnh_ifindex; +}; + +/* rtnh_flags */ + +#define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */ +#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */ +#define RTNH_F_ONLINK 4 /* Gateway is forced on link */ +#define RTNH_F_OFFLOAD 8 /* Nexthop is offloaded */ +#define RTNH_F_LINKDOWN 16 /* carrier-down on nexthop */ +#define RTNH_F_UNRESOLVED 32 /* The entry is unresolved (ipmr) */ +#define RTNH_F_TRAP 64 /* Nexthop is trapping packets */ + +#define RTNH_COMPARE_MASK (RTNH_F_DEAD | RTNH_F_LINKDOWN | \ + RTNH_F_OFFLOAD | RTNH_F_TRAP) + +/* Macros to handle hexthops */ + +#define RTNH_ALIGNTO 4 +#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) ) +#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \ + ((int)(rtnh)->rtnh_len) <= (len)) +#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len))) +#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len)) +#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len)) +#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0))) + +/* RTA_VIA */ +struct rtvia { + __kernel_sa_family_t rtvia_family; + __u8 rtvia_addr[]; +}; + +/* RTM_CACHEINFO */ + +struct rta_cacheinfo { + __u32 rta_clntref; + __u32 rta_lastuse; + __s32 rta_expires; + __u32 rta_error; + __u32 rta_used; + +#define RTNETLINK_HAVE_PEERINFO 1 + __u32 rta_id; + __u32 rta_ts; + __u32 rta_tsage; +}; + +/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */ + +enum { + RTAX_UNSPEC, +#define RTAX_UNSPEC RTAX_UNSPEC + RTAX_LOCK, +#define RTAX_LOCK RTAX_LOCK + RTAX_MTU, +#define RTAX_MTU RTAX_MTU + RTAX_WINDOW, +#define RTAX_WINDOW RTAX_WINDOW + RTAX_RTT, +#define RTAX_RTT RTAX_RTT + RTAX_RTTVAR, +#define RTAX_RTTVAR RTAX_RTTVAR + RTAX_SSTHRESH, +#define RTAX_SSTHRESH RTAX_SSTHRESH + RTAX_CWND, +#define RTAX_CWND RTAX_CWND + RTAX_ADVMSS, +#define RTAX_ADVMSS RTAX_ADVMSS + RTAX_REORDERING, +#define RTAX_REORDERING RTAX_REORDERING + RTAX_HOPLIMIT, +#define RTAX_HOPLIMIT RTAX_HOPLIMIT + RTAX_INITCWND, +#define RTAX_INITCWND RTAX_INITCWND + RTAX_FEATURES, +#define RTAX_FEATURES RTAX_FEATURES + RTAX_RTO_MIN, +#define RTAX_RTO_MIN RTAX_RTO_MIN + RTAX_INITRWND, +#define RTAX_INITRWND RTAX_INITRWND + RTAX_QUICKACK, +#define RTAX_QUICKACK RTAX_QUICKACK + RTAX_CC_ALGO, +#define RTAX_CC_ALGO RTAX_CC_ALGO + RTAX_FASTOPEN_NO_COOKIE, +#define RTAX_FASTOPEN_NO_COOKIE RTAX_FASTOPEN_NO_COOKIE + __RTAX_MAX +}; + +#define RTAX_MAX (__RTAX_MAX - 1) + +#define RTAX_FEATURE_ECN (1 << 0) +#define RTAX_FEATURE_SACK (1 << 1) +#define RTAX_FEATURE_TIMESTAMP (1 << 2) +#define RTAX_FEATURE_ALLFRAG (1 << 3) + +#define RTAX_FEATURE_MASK (RTAX_FEATURE_ECN | RTAX_FEATURE_SACK | \ + RTAX_FEATURE_TIMESTAMP | RTAX_FEATURE_ALLFRAG) + +struct rta_session { + __u8 proto; + __u8 pad1; + __u16 pad2; + + union { + struct { + __u16 sport; + __u16 dport; + } ports; + + struct { + __u8 type; + __u8 code; + __u16 ident; + } icmpt; + + __u32 spi; + } u; +}; + +struct rta_mfc_stats { + __u64 mfcs_packets; + __u64 mfcs_bytes; + __u64 mfcs_wrong_if; +}; + +/**** + * General form of address family dependent message. + ****/ + +struct rtgenmsg { + unsigned char rtgen_family; +}; + +/***************************************************************** + * Link layer specific messages. + ****/ + +/* struct ifinfomsg + * passes link level specific information, not dependent + * on network protocol. + */ + +struct ifinfomsg { + unsigned char ifi_family; + unsigned char __ifi_pad; + unsigned short ifi_type; /* ARPHRD_* */ + int ifi_index; /* Link index */ + unsigned ifi_flags; /* IFF_* flags */ + unsigned ifi_change; /* IFF_* change mask */ +}; + +/******************************************************************** + * prefix information + ****/ + +struct prefixmsg { + unsigned char prefix_family; + unsigned char prefix_pad1; + unsigned short prefix_pad2; + int prefix_ifindex; + unsigned char prefix_type; + unsigned char prefix_len; + unsigned char prefix_flags; + unsigned char prefix_pad3; +}; + +enum +{ + PREFIX_UNSPEC, + PREFIX_ADDRESS, + PREFIX_CACHEINFO, + __PREFIX_MAX +}; + +#define PREFIX_MAX (__PREFIX_MAX - 1) + +struct prefix_cacheinfo { + __u32 preferred_time; + __u32 valid_time; +}; + + +/***************************************************************** + * Traffic control messages. + ****/ + +struct tcmsg { + unsigned char tcm_family; + unsigned char tcm__pad1; + unsigned short tcm__pad2; + int tcm_ifindex; + __u32 tcm_handle; + __u32 tcm_parent; +/* tcm_block_index is used instead of tcm_parent + * in case tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK + */ +#define tcm_block_index tcm_parent + __u32 tcm_info; +}; + +/* For manipulation of filters in shared block, tcm_ifindex is set to + * TCM_IFINDEX_MAGIC_BLOCK, and tcm_parent is aliased to tcm_block_index + * which is the block index. + */ +#define TCM_IFINDEX_MAGIC_BLOCK (0xFFFFFFFFU) + +enum { + TCA_UNSPEC, + TCA_KIND, + TCA_OPTIONS, + TCA_STATS, + TCA_XSTATS, + TCA_RATE, + TCA_FCNT, + TCA_STATS2, + TCA_STAB, + TCA_PAD, + TCA_DUMP_INVISIBLE, + TCA_CHAIN, + TCA_HW_OFFLOAD, + TCA_INGRESS_BLOCK, + TCA_EGRESS_BLOCK, + TCA_DUMP_FLAGS, + __TCA_MAX +}; + +#define TCA_MAX (__TCA_MAX - 1) + +#define TCA_DUMP_FLAGS_TERSE (1 << 0) /* Means that in dump user gets only basic + * data necessary to identify the objects + * (handle, cookie, etc.) and stats. + */ + +#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg)))) +#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg)) + +/******************************************************************** + * Neighbor Discovery userland options + ****/ + +struct nduseroptmsg { + unsigned char nduseropt_family; + unsigned char nduseropt_pad1; + unsigned short nduseropt_opts_len; /* Total length of options */ + int nduseropt_ifindex; + __u8 nduseropt_icmp_type; + __u8 nduseropt_icmp_code; + unsigned short nduseropt_pad2; + unsigned int nduseropt_pad3; + /* Followed by one or more ND options */ +}; + +enum { + NDUSEROPT_UNSPEC, + NDUSEROPT_SRCADDR, + __NDUSEROPT_MAX +}; + +#define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1) + +/* RTnetlink multicast groups - backwards compatibility for userspace */ +#define RTMGRP_LINK 1 +#define RTMGRP_NOTIFY 2 +#define RTMGRP_NEIGH 4 +#define RTMGRP_TC 8 + +#define RTMGRP_IPV4_IFADDR 0x10 +#define RTMGRP_IPV4_MROUTE 0x20 +#define RTMGRP_IPV4_ROUTE 0x40 +#define RTMGRP_IPV4_RULE 0x80 + +#define RTMGRP_IPV6_IFADDR 0x100 +#define RTMGRP_IPV6_MROUTE 0x200 +#define RTMGRP_IPV6_ROUTE 0x400 +#define RTMGRP_IPV6_IFINFO 0x800 + +#define RTMGRP_DECnet_IFADDR 0x1000 +#define RTMGRP_DECnet_ROUTE 0x4000 + +#define RTMGRP_IPV6_PREFIX 0x20000 + +/* RTnetlink multicast groups */ +enum rtnetlink_groups { + RTNLGRP_NONE, +#define RTNLGRP_NONE RTNLGRP_NONE + RTNLGRP_LINK, +#define RTNLGRP_LINK RTNLGRP_LINK + RTNLGRP_NOTIFY, +#define RTNLGRP_NOTIFY RTNLGRP_NOTIFY + RTNLGRP_NEIGH, +#define RTNLGRP_NEIGH RTNLGRP_NEIGH + RTNLGRP_TC, +#define RTNLGRP_TC RTNLGRP_TC + RTNLGRP_IPV4_IFADDR, +#define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR + RTNLGRP_IPV4_MROUTE, +#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE + RTNLGRP_IPV4_ROUTE, +#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE + RTNLGRP_IPV4_RULE, +#define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE + RTNLGRP_IPV6_IFADDR, +#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR + RTNLGRP_IPV6_MROUTE, +#define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE + RTNLGRP_IPV6_ROUTE, +#define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE + RTNLGRP_IPV6_IFINFO, +#define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO + RTNLGRP_DECnet_IFADDR, +#define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR + RTNLGRP_NOP2, + RTNLGRP_DECnet_ROUTE, +#define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE + RTNLGRP_DECnet_RULE, +#define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE + RTNLGRP_NOP4, + RTNLGRP_IPV6_PREFIX, +#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX + RTNLGRP_IPV6_RULE, +#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE + RTNLGRP_ND_USEROPT, +#define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT + RTNLGRP_PHONET_IFADDR, +#define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR + RTNLGRP_PHONET_ROUTE, +#define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE + RTNLGRP_DCB, +#define RTNLGRP_DCB RTNLGRP_DCB + RTNLGRP_IPV4_NETCONF, +#define RTNLGRP_IPV4_NETCONF RTNLGRP_IPV4_NETCONF + RTNLGRP_IPV6_NETCONF, +#define RTNLGRP_IPV6_NETCONF RTNLGRP_IPV6_NETCONF + RTNLGRP_MDB, +#define RTNLGRP_MDB RTNLGRP_MDB + RTNLGRP_MPLS_ROUTE, +#define RTNLGRP_MPLS_ROUTE RTNLGRP_MPLS_ROUTE + RTNLGRP_NSID, +#define RTNLGRP_NSID RTNLGRP_NSID + RTNLGRP_MPLS_NETCONF, +#define RTNLGRP_MPLS_NETCONF RTNLGRP_MPLS_NETCONF + RTNLGRP_IPV4_MROUTE_R, +#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R + RTNLGRP_IPV6_MROUTE_R, +#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R + RTNLGRP_NEXTHOP, +#define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP + RTNLGRP_BRVLAN, +#define RTNLGRP_BRVLAN RTNLGRP_BRVLAN + RTNLGRP_MCTP_IFADDR, +#define RTNLGRP_MCTP_IFADDR RTNLGRP_MCTP_IFADDR + RTNLGRP_TUNNEL, +#define RTNLGRP_TUNNEL RTNLGRP_TUNNEL + RTNLGRP_STATS, +#define RTNLGRP_STATS RTNLGRP_STATS + __RTNLGRP_MAX +}; +#define RTNLGRP_MAX (__RTNLGRP_MAX - 1) + +/* TC action piece */ +struct tcamsg { + unsigned char tca_family; + unsigned char tca__pad1; + unsigned short tca__pad2; +}; + +enum { + TCA_ROOT_UNSPEC, + TCA_ROOT_TAB, +#define TCA_ACT_TAB TCA_ROOT_TAB +#define TCAA_MAX TCA_ROOT_TAB + TCA_ROOT_FLAGS, + TCA_ROOT_COUNT, + TCA_ROOT_TIME_DELTA, /* in msecs */ + __TCA_ROOT_MAX, +#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1) +}; + +#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg)))) +#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg)) +/* tcamsg flags stored in attribute TCA_ROOT_FLAGS + * + * TCA_ACT_FLAG_LARGE_DUMP_ON user->kernel to request for larger than + * TCA_ACT_MAX_PRIO actions in a dump. All dump responses will contain the + * number of actions being dumped stored in for user app's consumption in + * TCA_ROOT_COUNT + * + * TCA_ACT_FLAG_TERSE_DUMP user->kernel to request terse (brief) dump that only + * includes essential action info (kind, index, etc.) + * + */ +#define TCA_FLAG_LARGE_DUMP_ON (1 << 0) +#define TCA_ACT_FLAG_LARGE_DUMP_ON TCA_FLAG_LARGE_DUMP_ON +#define TCA_ACT_FLAG_TERSE_DUMP (1 << 1) + +/* New extended info filters for IFLA_EXT_MASK */ +#define RTEXT_FILTER_VF (1 << 0) +#define RTEXT_FILTER_BRVLAN (1 << 1) +#define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2) +#define RTEXT_FILTER_SKIP_STATS (1 << 3) +#define RTEXT_FILTER_MRP (1 << 4) +#define RTEXT_FILTER_CFM_CONFIG (1 << 5) +#define RTEXT_FILTER_CFM_STATUS (1 << 6) +#define RTEXT_FILTER_MST (1 << 7) + +/* End of information exported to user level */ + + + +#endif /* __LINUX_RTNETLINK_H */ diff --git a/vioc.c b/vioc.c new file mode 100644 index 0000000..c04a6dc --- /dev/null +++ b/vioc.c @@ -0,0 +1,34 @@ +/* Copyright 2006 Fabric7 Systems, Inc */ + +#include +#include +#include "internal.h" + +struct regs_line { + u32 addr; + u32 data; +}; + +#define VIOC_REGS_LINE_SIZE sizeof(struct regs_line) + +int vioc_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + unsigned int i; + unsigned int num_regs; + struct regs_line *reg_info = (struct regs_line *) regs->data; + + printf("ethtool_regs\n" + "%-20s = %04x\n" + "%-20s = %04x\n", + "cmd", regs->cmd, + "version", regs->version); + + num_regs = regs->len/VIOC_REGS_LINE_SIZE; + + for (i = 0; i < num_regs; i++){ + printf("%08x = %08x\n", reg_info[i].addr, reg_info[i].data); + } + + return 0; +} diff --git a/vmxnet3.c b/vmxnet3.c new file mode 100644 index 0000000..6872682 --- /dev/null +++ b/vmxnet3.c @@ -0,0 +1,199 @@ +/* Copyright (c) 2015 VMware Inc.*/ +#include +#include "internal.h" + +int +vmxnet3_dump_regs(struct ethtool_drvinfo *info __maybe_unused, + struct ethtool_regs *regs) +{ + u32 *regs_buff = (u32 *)regs->data; + u32 version = regs->version; + int i = 0, j = 0, cnt; + + if (version != 2) + return -1; + + fprintf(stdout, "Control Registers\n"); + fprintf(stdout, "=================\n"); + + fprintf(stdout, + " VRRS (Vmxnet3 Revision Report and Selection) 0x%x\n", + regs_buff[j++]); + fprintf(stdout, + " UVRS (UPT Version Report and Selection) 0x%x\n", + regs_buff[j++]); + fprintf(stdout, + " DSA (Driver Shared Address) 0x%08x%08x\n", + regs_buff[j+1], regs_buff[j]); + j += 2; + fprintf(stdout, + " CMD (Command Register) 0x%x\n", + regs_buff[j++]); + fprintf(stdout, + " MAC (Media Access Control address) %02x:%02x:%02x:%02x:%02x:%02x\n", + regs_buff[j] & 0xff, + (regs_buff[j] >> 8) & 0xff, + (regs_buff[j] >> 16) & 0xff, + (regs_buff[j] >> 24) & 0xff, + regs_buff[j + 1] & 0xff, + (regs_buff[j + 1] >> 8) & 0xff); + j += 2; + fprintf(stdout, + " ICR (Interrupt Cause Register) 0x%x\n", + regs_buff[j++]); + fprintf(stdout, + " ECR (Event Cause Register) 0x%x\n", + regs_buff[j++]); + + fprintf(stdout, "Datapath Registers\n"); + fprintf(stdout, "==================\n"); + + /* Interrupt Mask Registers */ + cnt = regs_buff[j++]; + for (i = 0; i < cnt; i++) { + fprintf(stdout, + " IMR (Interrupt Mask Register) %d 0x%x\n", + i, regs_buff[j++]); + } + + /* Transmit Queue Registers */ + cnt = regs_buff[j++]; + for (i = 0; i < cnt; i++) { + fprintf(stdout, " Transmit Queue %d\n", i); + fprintf(stdout, " ----------------\n"); + fprintf(stdout, + " TXPROD (Transmit Ring Producer Register) 0x%x\n", + regs_buff[j++]); + fprintf(stdout, + " Transmit Ring\n"); + fprintf(stdout, + " Base Address 0x%08x%08x\n", + regs_buff[j+1], regs_buff[j]); + j += 2; + fprintf(stdout, + " Size %u\n", + regs_buff[j++]); + fprintf(stdout, + " next2fill %u\n", + regs_buff[j++]); + fprintf(stdout, + " next2comp %u\n", + regs_buff[j++]); + fprintf(stdout, + " gen %u\n", + regs_buff[j++]); + + fprintf(stdout, + " Transmit Data Ring\n"); + fprintf(stdout, + " Base Address 0x%08x%08x\n", + regs_buff[j+1], regs_buff[j]); + j += 2; + fprintf(stdout, + " Size %u\n", + regs_buff[j++]); + fprintf(stdout, + " Buffer Size %u\n", + regs_buff[j++]); + + fprintf(stdout, + " Transmit Completion Ring\n"); + fprintf(stdout, + " Base Address 0x%08x%08x\n", + regs_buff[j+1], regs_buff[j]); + j += 2; + fprintf(stdout, + " size %u\n", + regs_buff[j++]); + fprintf(stdout, + " next2proc %u\n", + regs_buff[j++]); + fprintf(stdout, + " gen %u\n", + regs_buff[j++]); + fprintf(stdout, + " stopped %u\n", + regs_buff[j++]); + } + + /* Receive Queue Registers */ + cnt = regs_buff[j++]; + for (i = 0; i < cnt; i++) { + fprintf(stdout, " Receive Queue %d\n", i); + fprintf(stdout, " ----------------\n"); + fprintf(stdout, + " RXPROD1 (Receive Ring Producer Register) 1 0x%x\n", + regs_buff[j++]); + fprintf(stdout, + " RXPROD2 (Receive Ring Producer Register) 2 0x%x\n", + regs_buff[j++]); + fprintf(stdout, + " Receive Ring 0\n"); + fprintf(stdout, + " Base Address 0x%08x%08x\n", + regs_buff[j+1], regs_buff[j]); + j += 2; + fprintf(stdout, + " Size %u\n", + regs_buff[j++]); + fprintf(stdout, + " next2fill %u\n", + regs_buff[j++]); + fprintf(stdout, + " next2comp %u\n", + regs_buff[j++]); + fprintf(stdout, + " gen %u\n", + regs_buff[j++]); + + fprintf(stdout, + " Receive Ring 1\n"); + fprintf(stdout, + " Base Address 0x%08x%08x\n", + regs_buff[j+1], regs_buff[j]); + j += 2; + fprintf(stdout, + " Size %u\n", + regs_buff[j++]); + fprintf(stdout, + " next2fill %u\n", + regs_buff[j++]); + fprintf(stdout, + " next2comp %u\n", + regs_buff[j++]); + fprintf(stdout, + " gen %u\n", + regs_buff[j++]); + + fprintf(stdout, + " Receive Data Ring\n"); + fprintf(stdout, + " Base Address 0x%08x%08x\n", + regs_buff[j+1], regs_buff[j]); + j += 2; + fprintf(stdout, + " Size %u\n", + regs_buff[j++]); + fprintf(stdout, + " Buffer Size %u\n", + regs_buff[j++]); + + fprintf(stdout, + " Receive Completion Ring\n"); + fprintf(stdout, + " Base Address 0x%08x%08x\n", + regs_buff[j+1], regs_buff[j]); + j += 2; + fprintf(stdout, + " size %u\n", + regs_buff[j++]); + fprintf(stdout, + " next2proc %u\n", + regs_buff[j++]); + fprintf(stdout, + " gen %u\n", + regs_buff[j++]); + } + + return 0; +} -- cgit v1.2.3