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

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

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ 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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /net/ethtool/pause.c (Version linux-6.12-rc7) and /net/ethtool/pause.c (Version linux-6.9.12)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 // SPDX-License-Identifier: GPL-2.0-only
  2                                                     2 
  3 #include "netlink.h"                                3 #include "netlink.h"
  4 #include "common.h"                                 4 #include "common.h"
  5                                                     5 
  6 struct pause_req_info {                             6 struct pause_req_info {
  7         struct ethnl_req_info           base;       7         struct ethnl_req_info           base;
  8         enum ethtool_mac_stats_src      src;        8         enum ethtool_mac_stats_src      src;
  9 };                                                  9 };
 10                                                    10 
 11 #define PAUSE_REQINFO(__req_base) \                11 #define PAUSE_REQINFO(__req_base) \
 12         container_of(__req_base, struct pause_     12         container_of(__req_base, struct pause_req_info, base)
 13                                                    13 
 14 struct pause_reply_data {                          14 struct pause_reply_data {
 15         struct ethnl_reply_data         base;      15         struct ethnl_reply_data         base;
 16         struct ethtool_pauseparam       pausep     16         struct ethtool_pauseparam       pauseparam;
 17         struct ethtool_pause_stats      pauses     17         struct ethtool_pause_stats      pausestat;
 18 };                                                 18 };
 19                                                    19 
 20 #define PAUSE_REPDATA(__reply_base) \              20 #define PAUSE_REPDATA(__reply_base) \
 21         container_of(__reply_base, struct paus     21         container_of(__reply_base, struct pause_reply_data, base)
 22                                                    22 
 23 const struct nla_policy ethnl_pause_get_policy     23 const struct nla_policy ethnl_pause_get_policy[] = {
 24         [ETHTOOL_A_PAUSE_HEADER]                   24         [ETHTOOL_A_PAUSE_HEADER]                =
 25                 NLA_POLICY_NESTED(ethnl_header     25                 NLA_POLICY_NESTED(ethnl_header_policy_stats),
 26         [ETHTOOL_A_PAUSE_STATS_SRC]                26         [ETHTOOL_A_PAUSE_STATS_SRC]             =
 27                 NLA_POLICY_MAX(NLA_U32, ETHTOO     27                 NLA_POLICY_MAX(NLA_U32, ETHTOOL_MAC_STATS_SRC_PMAC),
 28 };                                                 28 };
 29                                                    29 
 30 static int pause_parse_request(struct ethnl_re     30 static int pause_parse_request(struct ethnl_req_info *req_base,
 31                                struct nlattr *     31                                struct nlattr **tb,
 32                                struct netlink_     32                                struct netlink_ext_ack *extack)
 33 {                                                  33 {
 34         enum ethtool_mac_stats_src src = ETHTO     34         enum ethtool_mac_stats_src src = ETHTOOL_MAC_STATS_SRC_AGGREGATE;
 35         struct pause_req_info *req_info = PAUS     35         struct pause_req_info *req_info = PAUSE_REQINFO(req_base);
 36                                                    36 
 37         if (tb[ETHTOOL_A_PAUSE_STATS_SRC]) {       37         if (tb[ETHTOOL_A_PAUSE_STATS_SRC]) {
 38                 if (!(req_base->flags & ETHTOO     38                 if (!(req_base->flags & ETHTOOL_FLAG_STATS)) {
 39                         NL_SET_ERR_MSG_MOD(ext     39                         NL_SET_ERR_MSG_MOD(extack,
 40                                            "ET     40                                            "ETHTOOL_FLAG_STATS must be set when requesting a source of stats");
 41                         return -EINVAL;            41                         return -EINVAL;
 42                 }                                  42                 }
 43                                                    43 
 44                 src = nla_get_u32(tb[ETHTOOL_A     44                 src = nla_get_u32(tb[ETHTOOL_A_PAUSE_STATS_SRC]);
 45         }                                          45         }
 46                                                    46 
 47         req_info->src = src;                       47         req_info->src = src;
 48                                                    48 
 49         return 0;                                  49         return 0;
 50 }                                                  50 }
 51                                                    51 
 52 static int pause_prepare_data(const struct eth     52 static int pause_prepare_data(const struct ethnl_req_info *req_base,
 53                               struct ethnl_rep     53                               struct ethnl_reply_data *reply_base,
 54                               const struct gen     54                               const struct genl_info *info)
 55 {                                                  55 {
 56         const struct pause_req_info *req_info      56         const struct pause_req_info *req_info = PAUSE_REQINFO(req_base);
 57         struct pause_reply_data *data = PAUSE_     57         struct pause_reply_data *data = PAUSE_REPDATA(reply_base);
 58         enum ethtool_mac_stats_src src = req_i     58         enum ethtool_mac_stats_src src = req_info->src;
 59         struct net_device *dev = reply_base->d     59         struct net_device *dev = reply_base->dev;
 60         int ret;                                   60         int ret;
 61                                                    61 
 62         if (!dev->ethtool_ops->get_pauseparam)     62         if (!dev->ethtool_ops->get_pauseparam)
 63                 return -EOPNOTSUPP;                63                 return -EOPNOTSUPP;
 64                                                    64 
 65         ethtool_stats_init((u64 *)&data->pause     65         ethtool_stats_init((u64 *)&data->pausestat,
 66                            sizeof(data->pauses     66                            sizeof(data->pausestat) / 8);
 67         data->pausestat.src = src;                 67         data->pausestat.src = src;
 68                                                    68 
 69         ret = ethnl_ops_begin(dev);                69         ret = ethnl_ops_begin(dev);
 70         if (ret < 0)                               70         if (ret < 0)
 71                 return ret;                        71                 return ret;
 72                                                    72 
 73         if ((src == ETHTOOL_MAC_STATS_SRC_EMAC     73         if ((src == ETHTOOL_MAC_STATS_SRC_EMAC ||
 74              src == ETHTOOL_MAC_STATS_SRC_PMAC     74              src == ETHTOOL_MAC_STATS_SRC_PMAC) &&
 75             !__ethtool_dev_mm_supported(dev))      75             !__ethtool_dev_mm_supported(dev)) {
 76                 NL_SET_ERR_MSG_MOD(info->extac     76                 NL_SET_ERR_MSG_MOD(info->extack,
 77                                    "Device doe     77                                    "Device does not support MAC merge layer");
 78                 ethnl_ops_complete(dev);           78                 ethnl_ops_complete(dev);
 79                 return -EOPNOTSUPP;                79                 return -EOPNOTSUPP;
 80         }                                          80         }
 81                                                    81 
 82         dev->ethtool_ops->get_pauseparam(dev,      82         dev->ethtool_ops->get_pauseparam(dev, &data->pauseparam);
 83         if (req_base->flags & ETHTOOL_FLAG_STA     83         if (req_base->flags & ETHTOOL_FLAG_STATS &&
 84             dev->ethtool_ops->get_pause_stats)     84             dev->ethtool_ops->get_pause_stats)
 85                 dev->ethtool_ops->get_pause_st     85                 dev->ethtool_ops->get_pause_stats(dev, &data->pausestat);
 86                                                    86 
 87         ethnl_ops_complete(dev);                   87         ethnl_ops_complete(dev);
 88                                                    88 
 89         return 0;                                  89         return 0;
 90 }                                                  90 }
 91                                                    91 
 92 static int pause_reply_size(const struct ethnl     92 static int pause_reply_size(const struct ethnl_req_info *req_base,
 93                             const struct ethnl     93                             const struct ethnl_reply_data *reply_base)
 94 {                                                  94 {
 95         int n = nla_total_size(sizeof(u8)) +       95         int n = nla_total_size(sizeof(u8)) +    /* _PAUSE_AUTONEG */
 96                 nla_total_size(sizeof(u8)) +       96                 nla_total_size(sizeof(u8)) +    /* _PAUSE_RX */
 97                 nla_total_size(sizeof(u8));        97                 nla_total_size(sizeof(u8));     /* _PAUSE_TX */
 98                                                    98 
 99         if (req_base->flags & ETHTOOL_FLAG_STA     99         if (req_base->flags & ETHTOOL_FLAG_STATS)
100                 n += nla_total_size(0) +          100                 n += nla_total_size(0) +        /* _PAUSE_STATS */
101                      nla_total_size(sizeof(u32    101                      nla_total_size(sizeof(u32)) + /* _PAUSE_STATS_SRC */
102                      nla_total_size_64bit(size    102                      nla_total_size_64bit(sizeof(u64)) * ETHTOOL_PAUSE_STAT_CNT;
103         return n;                                 103         return n;
104 }                                                 104 }
105                                                   105 
106 static int ethtool_put_stat(struct sk_buff *sk    106 static int ethtool_put_stat(struct sk_buff *skb, u64 val, u16 attrtype,
107                             u16 padtype)          107                             u16 padtype)
108 {                                                 108 {
109         if (val == ETHTOOL_STAT_NOT_SET)          109         if (val == ETHTOOL_STAT_NOT_SET)
110                 return 0;                         110                 return 0;
111         if (nla_put_u64_64bit(skb, attrtype, v    111         if (nla_put_u64_64bit(skb, attrtype, val, padtype))
112                 return -EMSGSIZE;                 112                 return -EMSGSIZE;
113                                                   113 
114         return 0;                                 114         return 0;
115 }                                                 115 }
116                                                   116 
117 static int pause_put_stats(struct sk_buff *skb    117 static int pause_put_stats(struct sk_buff *skb,
118                            const struct ethtoo    118                            const struct ethtool_pause_stats *pause_stats)
119 {                                                 119 {
120         const u16 pad = ETHTOOL_A_PAUSE_STAT_P    120         const u16 pad = ETHTOOL_A_PAUSE_STAT_PAD;
121         struct nlattr *nest;                      121         struct nlattr *nest;
122                                                   122 
123         if (nla_put_u32(skb, ETHTOOL_A_PAUSE_S    123         if (nla_put_u32(skb, ETHTOOL_A_PAUSE_STATS_SRC, pause_stats->src))
124                 return -EMSGSIZE;                 124                 return -EMSGSIZE;
125                                                   125 
126         nest = nla_nest_start(skb, ETHTOOL_A_P    126         nest = nla_nest_start(skb, ETHTOOL_A_PAUSE_STATS);
127         if (!nest)                                127         if (!nest)
128                 return -EMSGSIZE;                 128                 return -EMSGSIZE;
129                                                   129 
130         if (ethtool_put_stat(skb, pause_stats-    130         if (ethtool_put_stat(skb, pause_stats->tx_pause_frames,
131                              ETHTOOL_A_PAUSE_S    131                              ETHTOOL_A_PAUSE_STAT_TX_FRAMES, pad) ||
132             ethtool_put_stat(skb, pause_stats-    132             ethtool_put_stat(skb, pause_stats->rx_pause_frames,
133                              ETHTOOL_A_PAUSE_S    133                              ETHTOOL_A_PAUSE_STAT_RX_FRAMES, pad))
134                 goto err_cancel;                  134                 goto err_cancel;
135                                                   135 
136         nla_nest_end(skb, nest);                  136         nla_nest_end(skb, nest);
137         return 0;                                 137         return 0;
138                                                   138 
139 err_cancel:                                       139 err_cancel:
140         nla_nest_cancel(skb, nest);               140         nla_nest_cancel(skb, nest);
141         return -EMSGSIZE;                         141         return -EMSGSIZE;
142 }                                                 142 }
143                                                   143 
144 static int pause_fill_reply(struct sk_buff *sk    144 static int pause_fill_reply(struct sk_buff *skb,
145                             const struct ethnl    145                             const struct ethnl_req_info *req_base,
146                             const struct ethnl    146                             const struct ethnl_reply_data *reply_base)
147 {                                                 147 {
148         const struct pause_reply_data *data =     148         const struct pause_reply_data *data = PAUSE_REPDATA(reply_base);
149         const struct ethtool_pauseparam *pause    149         const struct ethtool_pauseparam *pauseparam = &data->pauseparam;
150                                                   150 
151         if (nla_put_u8(skb, ETHTOOL_A_PAUSE_AU    151         if (nla_put_u8(skb, ETHTOOL_A_PAUSE_AUTONEG, !!pauseparam->autoneg) ||
152             nla_put_u8(skb, ETHTOOL_A_PAUSE_RX    152             nla_put_u8(skb, ETHTOOL_A_PAUSE_RX, !!pauseparam->rx_pause) ||
153             nla_put_u8(skb, ETHTOOL_A_PAUSE_TX    153             nla_put_u8(skb, ETHTOOL_A_PAUSE_TX, !!pauseparam->tx_pause))
154                 return -EMSGSIZE;                 154                 return -EMSGSIZE;
155                                                   155 
156         if (req_base->flags & ETHTOOL_FLAG_STA    156         if (req_base->flags & ETHTOOL_FLAG_STATS &&
157             pause_put_stats(skb, &data->pauses    157             pause_put_stats(skb, &data->pausestat))
158                 return -EMSGSIZE;                 158                 return -EMSGSIZE;
159                                                   159 
160         return 0;                                 160         return 0;
161 }                                                 161 }
162                                                   162 
163 /* PAUSE_SET */                                   163 /* PAUSE_SET */
164                                                   164 
165 const struct nla_policy ethnl_pause_set_policy    165 const struct nla_policy ethnl_pause_set_policy[] = {
166         [ETHTOOL_A_PAUSE_HEADER]                  166         [ETHTOOL_A_PAUSE_HEADER]                =
167                 NLA_POLICY_NESTED(ethnl_header    167                 NLA_POLICY_NESTED(ethnl_header_policy),
168         [ETHTOOL_A_PAUSE_AUTONEG]                 168         [ETHTOOL_A_PAUSE_AUTONEG]               = { .type = NLA_U8 },
169         [ETHTOOL_A_PAUSE_RX]                      169         [ETHTOOL_A_PAUSE_RX]                    = { .type = NLA_U8 },
170         [ETHTOOL_A_PAUSE_TX]                      170         [ETHTOOL_A_PAUSE_TX]                    = { .type = NLA_U8 },
171 };                                                171 };
172                                                   172 
173 static int                                        173 static int
174 ethnl_set_pause_validate(struct ethnl_req_info    174 ethnl_set_pause_validate(struct ethnl_req_info *req_info,
175                          struct genl_info *inf    175                          struct genl_info *info)
176 {                                                 176 {
177         const struct ethtool_ops *ops = req_in    177         const struct ethtool_ops *ops = req_info->dev->ethtool_ops;
178                                                   178 
179         return ops->get_pauseparam && ops->set    179         return ops->get_pauseparam && ops->set_pauseparam ? 1 : -EOPNOTSUPP;
180 }                                                 180 }
181                                                   181 
182 static int                                        182 static int
183 ethnl_set_pause(struct ethnl_req_info *req_inf    183 ethnl_set_pause(struct ethnl_req_info *req_info, struct genl_info *info)
184 {                                                 184 {
185         struct net_device *dev = req_info->dev    185         struct net_device *dev = req_info->dev;
186         struct ethtool_pauseparam params = {};    186         struct ethtool_pauseparam params = {};
187         struct nlattr **tb = info->attrs;         187         struct nlattr **tb = info->attrs;
188         bool mod = false;                         188         bool mod = false;
189         int ret;                                  189         int ret;
190                                                   190 
191         dev->ethtool_ops->get_pauseparam(dev,     191         dev->ethtool_ops->get_pauseparam(dev, &params);
192                                                   192 
193         ethnl_update_bool32(&params.autoneg, t    193         ethnl_update_bool32(&params.autoneg, tb[ETHTOOL_A_PAUSE_AUTONEG], &mod);
194         ethnl_update_bool32(&params.rx_pause,     194         ethnl_update_bool32(&params.rx_pause, tb[ETHTOOL_A_PAUSE_RX], &mod);
195         ethnl_update_bool32(&params.tx_pause,     195         ethnl_update_bool32(&params.tx_pause, tb[ETHTOOL_A_PAUSE_TX], &mod);
196         if (!mod)                                 196         if (!mod)
197                 return 0;                         197                 return 0;
198                                                   198 
199         ret = dev->ethtool_ops->set_pauseparam    199         ret = dev->ethtool_ops->set_pauseparam(dev, &params);
200         return ret < 0 ? ret : 1;                 200         return ret < 0 ? ret : 1;
201 }                                                 201 }
202                                                   202 
203 const struct ethnl_request_ops ethnl_pause_req    203 const struct ethnl_request_ops ethnl_pause_request_ops = {
204         .request_cmd            = ETHTOOL_MSG_    204         .request_cmd            = ETHTOOL_MSG_PAUSE_GET,
205         .reply_cmd              = ETHTOOL_MSG_    205         .reply_cmd              = ETHTOOL_MSG_PAUSE_GET_REPLY,
206         .hdr_attr               = ETHTOOL_A_PA    206         .hdr_attr               = ETHTOOL_A_PAUSE_HEADER,
207         .req_info_size          = sizeof(struc    207         .req_info_size          = sizeof(struct pause_req_info),
208         .reply_data_size        = sizeof(struc    208         .reply_data_size        = sizeof(struct pause_reply_data),
209                                                   209 
210         .parse_request          = pause_parse_    210         .parse_request          = pause_parse_request,
211         .prepare_data           = pause_prepar    211         .prepare_data           = pause_prepare_data,
212         .reply_size             = pause_reply_    212         .reply_size             = pause_reply_size,
213         .fill_reply             = pause_fill_r    213         .fill_reply             = pause_fill_reply,
214                                                   214 
215         .set_validate           = ethnl_set_pa    215         .set_validate           = ethnl_set_pause_validate,
216         .set                    = ethnl_set_pa    216         .set                    = ethnl_set_pause,
217         .set_ntf_cmd            = ETHTOOL_MSG_    217         .set_ntf_cmd            = ETHTOOL_MSG_PAUSE_NTF,
218 };                                                218 };
219                                                   219 

~ [ 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