libnl 3.0
|
00001 /* 00002 * lib/route/ethtool.c Ethtool (link) 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup link 00014 * @defgroup ethtool Ethtool 00015 * @{ 00016 */ 00017 00018 #include <netlink-local.h> 00019 #include <netlink/netlink.h> 00020 #include <netlink/attr.h> 00021 #include <netlink/utils.h> 00022 #include <netlink/object.h> 00023 #include <netlink/route/rtnl.h> 00024 #include <netlink/route/link.h> 00025 #include <netlink/route/ethtool.h> 00026 #include <netlink/route/link/api.h> 00027 00028 /** @cond SKIP */ 00029 #define ETHTOOL_ATTR_SETTINGS 0x0001 00030 #define ETHTOOL_ATTR_DRVINFO 0x0002 00031 /** @endcond */ 00032 00033 static int settings_parse(struct rtnl_link *link, struct nlattr *attr) 00034 { 00035 nla_memcpy(&link->l_ethtool.e_settings, attr, sizeof(struct ethtool_cmd)); 00036 link->l_ethtool.e_mask |= ETHTOOL_ATTR_SETTINGS; 00037 return 0; 00038 } 00039 00040 static struct { 00041 int (*parse)(struct rtnl_link *, struct nlattr *); 00042 } ethtool_ops[] = { 00043 [IFLA_ETHTOOL_SETTINGS] = { .parse = settings_parse, }, 00044 }; 00045 00046 static struct nla_policy ethtool_policy[IFLA_ETHTOOL_MAX+1] = { 00047 [IFLA_ETHTOOL_SETTINGS] = { .minlen = sizeof(struct ethtool_cmd) }, 00048 [IFLA_ETHTOOL_DRVINFO] = { .type = NLA_NESTED }, 00049 }; 00050 00051 static int parse_attr(struct rtnl_link *link, struct nlattr *attr) 00052 { 00053 int type = nla_type(attr) - 1; 00054 00055 if (type < 0 || type >= ARRAY_SIZE(ethtool_ops)) 00056 return -NLE_INVAL; 00057 00058 if (ethtool_ops[type].parse) 00059 return ethtool_ops[type].parse(link, attr); 00060 00061 return 0; 00062 } 00063 00064 int rtnl_ethtool_parse(struct rtnl_link *link, struct nlattr *attr) 00065 { 00066 int remaining, err; 00067 struct nlattr *a; 00068 00069 err = nla_validate(nla_data(attr), nla_len(attr), IFLA_ETHTOOL_MAX, 00070 ethtool_policy); 00071 if (err < 0) 00072 return err; 00073 00074 nla_for_each_nested(a, attr, remaining) 00075 parse_attr(link, a); 00076 00077 return 0; 00078 } 00079 00080 void rtnl_ethtool_dump_details(struct rtnl_link *link, struct nl_dump_params *p) 00081 { 00082 struct rtnl_ethtool *e = &link->l_ethtool; 00083 00084 if (e->e_mask & ETHTOOL_ATTR_SETTINGS) { 00085 struct ethtool_cmd *cmd = &e->e_settings; 00086 char buf[256]; 00087 00088 nl_dump_line(p, " ethtool:\n"); 00089 nl_dump_line(p, " supported: %s\n", 00090 rtnl_ethtool_supported2str(cmd->supported, buf, sizeof(buf))); 00091 nl_dump_line(p, " advertising: %s\n", 00092 rtnl_ethtool_supported2str(cmd->advertising, buf, sizeof(buf))); 00093 00094 nl_dump_line(p, " duplex: %u\n", cmd->duplex); 00095 00096 nl_dump_line(p, " connector: %s\n", 00097 rtnl_ethtool_connector2str(cmd->port, buf, sizeof(buf))); 00098 nl_dump_line(p, " phy-address: %#x\n", cmd->phy_address); 00099 nl_dump_line(p, " transceiver: %s\n", 00100 rtnl_ethtool_transceiver2str(cmd->transceiver, buf, sizeof(buf))); 00101 00102 nl_dump_line(p, " autonegotiation: %s\n", 00103 cmd->autoneg ? "enabled" : "disabled"); 00104 00105 nl_dump_line(p, " max-tx-pkts: %u\n", cmd->maxtxpkt); 00106 nl_dump_line(p, " max-rx-pkts: %u\n", cmd->maxrxpkt); 00107 00108 #if 0 00109 __u16 speed; /* The forced speed (lower bits) in 00110 * Mbps. Please use 00111 * ethtool_cmd_speed()/_set() to 00112 * access it */ 00113 __u8 mdio_support; 00114 __u16 speed_hi; /* The forced speed (upper 00115 * bits) in Mbps. Please use 00116 * ethtool_cmd_speed()/_set() to 00117 * access it */ 00118 __u8 eth_tp_mdix; 00119 __u8 reserved2; 00120 __u32 lp_advertising; /* Features the link partner advertises */ 00121 __u32 reserved[2]; 00122 #endif 00123 00124 } 00125 } 00126 00127 static const struct trans_tbl ethtool_supported[] = { 00128 __ADD(SUPPORTED_10baseT_Half, 10baseT-Half) 00129 __ADD(SUPPORTED_10baseT_Full, 10baseT-Full) 00130 __ADD(SUPPORTED_100baseT_Half, 100baseT-Half) 00131 __ADD(SUPPORTED_100baseT_Full, 100baseT-Full) 00132 __ADD(SUPPORTED_1000baseT_Half, 1000baseT-Half) 00133 __ADD(SUPPORTED_1000baseT_Full, 1000baseT-Full) 00134 __ADD(SUPPORTED_Autoneg, Autoneg) 00135 __ADD(SUPPORTED_TP, TP) 00136 __ADD(SUPPORTED_AUI, AUI) 00137 __ADD(SUPPORTED_MII, MII) 00138 __ADD(SUPPORTED_FIBRE, FIBRE) 00139 __ADD(SUPPORTED_BNC, BNC) 00140 __ADD(SUPPORTED_10000baseT_Full, 10000baseT-Full) 00141 __ADD(SUPPORTED_Pause, Pause) 00142 __ADD(SUPPORTED_Asym_Pause, Asym-Pause) 00143 __ADD(SUPPORTED_2500baseX_Full, 2500baseX-Full) 00144 __ADD(SUPPORTED_Backplane, Backplane) 00145 __ADD(SUPPORTED_1000baseKX_Full, 1000baseKX-Full) 00146 __ADD(SUPPORTED_10000baseKX4_Full, 10000baseKX4-Full) 00147 __ADD(SUPPORTED_10000baseKR_Full, 10000baseKR-Full) 00148 __ADD(SUPPORTED_10000baseR_FEC, 1000baseR-FEC) 00149 __ADD(SUPPORTED_20000baseMLD2_Full, 20000baseMLD2-Full) 00150 __ADD(SUPPORTED_20000baseKR2_Full, 20000baseKR2-Full) 00151 }; 00152 00153 char *rtnl_ethtool_supported2str(int supported, char *buf, size_t len) 00154 { 00155 return __flags2str(supported, buf, len, ethtool_supported, 00156 ARRAY_SIZE(ethtool_supported)); 00157 } 00158 00159 uint32_t rtnl_ethtool_get_supported(struct rtnl_link *link) 00160 { 00161 return 0; 00162 } 00163 00164 uint32_t rtnl_ethtool_get_advertising(struct rtnl_link *link) 00165 { 00166 return 0; 00167 } 00168 00169 static const struct trans_tbl ethtool_connectors[] = { 00170 __ADD(PORT_TP, tp) 00171 __ADD(PORT_AUI, aui) 00172 __ADD(PORT_MII, mii) 00173 __ADD(PORT_FIBRE, fibre) 00174 __ADD(PORT_BNC, bnc) 00175 __ADD(PORT_DA, da) 00176 __ADD(PORT_NONE, none) 00177 __ADD(PORT_OTHER, other) 00178 }; 00179 00180 char *rtnl_ethtool_connector2str(int connector, char *buf, size_t len) 00181 { 00182 return __type2str(connector, buf, len, ethtool_connectors, 00183 ARRAY_SIZE(ethtool_connectors)); 00184 } 00185 00186 int rtnl_ethtool_str2connector(const char *name) 00187 { 00188 return __str2type(name, ethtool_connectors, 00189 ARRAY_SIZE(ethtool_connectors)); 00190 } 00191 00192 static const struct trans_tbl ethtool_xcvrs[] = { 00193 __ADD(XCVR_INTERNAL, internal) 00194 __ADD(XCVR_EXTERNAL, external) 00195 __ADD(XCVR_DUMMY1, dummy1) 00196 __ADD(XCVR_DUMMY2, dummy2) 00197 __ADD(XCVR_DUMMY3, dummy3) 00198 }; 00199 00200 char *rtnl_ethtool_transceiver2str(int xcvr, char *buf, size_t len) 00201 { 00202 return __type2str(xcvr, buf, len, ethtool_xcvrs, 00203 ARRAY_SIZE(ethtool_xcvrs)); 00204 } 00205 00206 int rtnl_ethtool_str2transceiver(const char *name) 00207 { 00208 return __str2type(name, ethtool_xcvrs, ARRAY_SIZE(ethtool_xcvrs)); 00209 } 00210 00211 00212 /** @} */