~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/ethtool/eee.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 
  3 #include "netlink.h"
  4 #include "common.h"
  5 #include "bitset.h"
  6 
  7 struct eee_req_info {
  8         struct ethnl_req_info           base;
  9 };
 10 
 11 struct eee_reply_data {
 12         struct ethnl_reply_data         base;
 13         struct ethtool_keee             eee;
 14 };
 15 
 16 #define EEE_REPDATA(__reply_base) \
 17         container_of(__reply_base, struct eee_reply_data, base)
 18 
 19 const struct nla_policy ethnl_eee_get_policy[] = {
 20         [ETHTOOL_A_EEE_HEADER]          =
 21                 NLA_POLICY_NESTED(ethnl_header_policy),
 22 };
 23 
 24 static int eee_prepare_data(const struct ethnl_req_info *req_base,
 25                             struct ethnl_reply_data *reply_base,
 26                             const struct genl_info *info)
 27 {
 28         struct eee_reply_data *data = EEE_REPDATA(reply_base);
 29         struct net_device *dev = reply_base->dev;
 30         struct ethtool_keee *eee = &data->eee;
 31         int ret;
 32 
 33         if (!dev->ethtool_ops->get_eee)
 34                 return -EOPNOTSUPP;
 35         ret = ethnl_ops_begin(dev);
 36         if (ret < 0)
 37                 return ret;
 38         ret = dev->ethtool_ops->get_eee(dev, eee);
 39         ethnl_ops_complete(dev);
 40 
 41         return ret;
 42 }
 43 
 44 static int eee_reply_size(const struct ethnl_req_info *req_base,
 45                           const struct ethnl_reply_data *reply_base)
 46 {
 47         bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
 48         const struct eee_reply_data *data = EEE_REPDATA(reply_base);
 49         const struct ethtool_keee *eee = &data->eee;
 50         int len = 0;
 51         int ret;
 52 
 53         /* MODES_OURS */
 54         ret = ethnl_bitset_size(eee->advertised, eee->supported,
 55                                 __ETHTOOL_LINK_MODE_MASK_NBITS,
 56                                 link_mode_names, compact);
 57         if (ret < 0)
 58                 return ret;
 59         len += ret;
 60         /* MODES_PEERS */
 61         ret = ethnl_bitset_size(eee->lp_advertised, NULL,
 62                                 __ETHTOOL_LINK_MODE_MASK_NBITS,
 63                                 link_mode_names, compact);
 64         if (ret < 0)
 65                 return ret;
 66         len += ret;
 67 
 68         len += nla_total_size(sizeof(u8)) +     /* _EEE_ACTIVE */
 69                nla_total_size(sizeof(u8)) +     /* _EEE_ENABLED */
 70                nla_total_size(sizeof(u8)) +     /* _EEE_TX_LPI_ENABLED */
 71                nla_total_size(sizeof(u32));     /* _EEE_TX_LPI_TIMER */
 72 
 73         return len;
 74 }
 75 
 76 static int eee_fill_reply(struct sk_buff *skb,
 77                           const struct ethnl_req_info *req_base,
 78                           const struct ethnl_reply_data *reply_base)
 79 {
 80         bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
 81         const struct eee_reply_data *data = EEE_REPDATA(reply_base);
 82         const struct ethtool_keee *eee = &data->eee;
 83         int ret;
 84 
 85         ret = ethnl_put_bitset(skb, ETHTOOL_A_EEE_MODES_OURS,
 86                                eee->advertised, eee->supported,
 87                                __ETHTOOL_LINK_MODE_MASK_NBITS,
 88                                link_mode_names, compact);
 89         if (ret < 0)
 90                 return ret;
 91         ret = ethnl_put_bitset(skb, ETHTOOL_A_EEE_MODES_PEER,
 92                                eee->lp_advertised, NULL,
 93                                __ETHTOOL_LINK_MODE_MASK_NBITS,
 94                                link_mode_names, compact);
 95         if (ret < 0)
 96                 return ret;
 97 
 98         if (nla_put_u8(skb, ETHTOOL_A_EEE_ACTIVE, eee->eee_active) ||
 99             nla_put_u8(skb, ETHTOOL_A_EEE_ENABLED, eee->eee_enabled) ||
100             nla_put_u8(skb, ETHTOOL_A_EEE_TX_LPI_ENABLED,
101                        eee->tx_lpi_enabled) ||
102             nla_put_u32(skb, ETHTOOL_A_EEE_TX_LPI_TIMER, eee->tx_lpi_timer))
103                 return -EMSGSIZE;
104 
105         return 0;
106 }
107 
108 /* EEE_SET */
109 
110 const struct nla_policy ethnl_eee_set_policy[] = {
111         [ETHTOOL_A_EEE_HEADER]          =
112                 NLA_POLICY_NESTED(ethnl_header_policy),
113         [ETHTOOL_A_EEE_MODES_OURS]      = { .type = NLA_NESTED },
114         [ETHTOOL_A_EEE_ENABLED]         = { .type = NLA_U8 },
115         [ETHTOOL_A_EEE_TX_LPI_ENABLED]  = { .type = NLA_U8 },
116         [ETHTOOL_A_EEE_TX_LPI_TIMER]    = { .type = NLA_U32 },
117 };
118 
119 static int
120 ethnl_set_eee_validate(struct ethnl_req_info *req_info, struct genl_info *info)
121 {
122         const struct ethtool_ops *ops = req_info->dev->ethtool_ops;
123 
124         return ops->get_eee && ops->set_eee ? 1 : -EOPNOTSUPP;
125 }
126 
127 static int
128 ethnl_set_eee(struct ethnl_req_info *req_info, struct genl_info *info)
129 {
130         struct net_device *dev = req_info->dev;
131         struct nlattr **tb = info->attrs;
132         struct ethtool_keee eee = {};
133         bool mod = false;
134         int ret;
135 
136         ret = dev->ethtool_ops->get_eee(dev, &eee);
137         if (ret < 0)
138                 return ret;
139 
140         ret = ethnl_update_bitset(eee.advertised,
141                                   __ETHTOOL_LINK_MODE_MASK_NBITS,
142                                   tb[ETHTOOL_A_EEE_MODES_OURS],
143                                   link_mode_names, info->extack, &mod);
144         if (ret < 0)
145                 return ret;
146         ethnl_update_bool(&eee.eee_enabled, tb[ETHTOOL_A_EEE_ENABLED], &mod);
147         ethnl_update_bool(&eee.tx_lpi_enabled, tb[ETHTOOL_A_EEE_TX_LPI_ENABLED],
148                           &mod);
149         ethnl_update_u32(&eee.tx_lpi_timer, tb[ETHTOOL_A_EEE_TX_LPI_TIMER],
150                          &mod);
151         if (!mod)
152                 return 0;
153 
154         ret = dev->ethtool_ops->set_eee(dev, &eee);
155         return ret < 0 ? ret : 1;
156 }
157 
158 const struct ethnl_request_ops ethnl_eee_request_ops = {
159         .request_cmd            = ETHTOOL_MSG_EEE_GET,
160         .reply_cmd              = ETHTOOL_MSG_EEE_GET_REPLY,
161         .hdr_attr               = ETHTOOL_A_EEE_HEADER,
162         .req_info_size          = sizeof(struct eee_req_info),
163         .reply_data_size        = sizeof(struct eee_reply_data),
164 
165         .prepare_data           = eee_prepare_data,
166         .reply_size             = eee_reply_size,
167         .fill_reply             = eee_fill_reply,
168 
169         .set_validate           = ethnl_set_eee_validate,
170         .set                    = ethnl_set_eee,
171         .set_ntf_cmd            = ETHTOOL_MSG_EEE_NTF,
172 };
173 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php