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

TOMOYO Linux Cross Reference
Linux/net/ethtool/phy.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/phy.c (Version linux-6.12-rc7) and /net/ethtool/phy.c (Version linux-4.19.323)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * Copyright 2023 Bootlin                         
  4  *                                                
  5  */                                               
  6 #include "common.h"                               
  7 #include "netlink.h"                              
  8                                                   
  9 #include <linux/phy.h>                            
 10 #include <linux/phy_link_topology.h>              
 11 #include <linux/sfp.h>                            
 12                                                   
 13 struct phy_req_info {                             
 14         struct ethnl_req_info           base;     
 15         struct phy_device_node          *pdn;     
 16 };                                                
 17                                                   
 18 #define PHY_REQINFO(__req_base) \                 
 19         container_of(__req_base, struct phy_re    
 20                                                   
 21 const struct nla_policy ethnl_phy_get_policy[E    
 22         [ETHTOOL_A_PHY_HEADER] = NLA_POLICY_NE    
 23 };                                                
 24                                                   
 25 /* Caller holds rtnl */                           
 26 static ssize_t                                    
 27 ethnl_phy_reply_size(const struct ethnl_req_in    
 28                      struct netlink_ext_ack *e    
 29 {                                                 
 30         struct phy_req_info *req_info = PHY_RE    
 31         struct phy_device_node *pdn = req_info    
 32         struct phy_device *phydev = pdn->phy;     
 33         size_t size = 0;                          
 34                                                   
 35         ASSERT_RTNL();                            
 36                                                   
 37         /* ETHTOOL_A_PHY_INDEX */                 
 38         size += nla_total_size(sizeof(u32));      
 39                                                   
 40         /* ETHTOOL_A_DRVNAME */                   
 41         if (phydev->drv)                          
 42                 size += nla_total_size(strlen(    
 43                                                   
 44         /* ETHTOOL_A_NAME */                      
 45         size += nla_total_size(strlen(dev_name    
 46                                                   
 47         /* ETHTOOL_A_PHY_UPSTREAM_TYPE */         
 48         size += nla_total_size(sizeof(u32));      
 49                                                   
 50         if (phy_on_sfp(phydev)) {                 
 51                 const char *upstream_sfp_name     
 52                                                   
 53                 /* ETHTOOL_A_PHY_UPSTREAM_SFP_    
 54                 if (upstream_sfp_name)            
 55                         size += nla_total_size    
 56                                                   
 57                 /* ETHTOOL_A_PHY_UPSTREAM_INDE    
 58                 size += nla_total_size(sizeof(    
 59         }                                         
 60                                                   
 61         /* ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME *    
 62         if (phydev->sfp_bus) {                    
 63                 const char *sfp_name = sfp_get    
 64                                                   
 65                 if (sfp_name)                     
 66                         size += nla_total_size    
 67         }                                         
 68                                                   
 69         return size;                              
 70 }                                                 
 71                                                   
 72 static int                                        
 73 ethnl_phy_fill_reply(const struct ethnl_req_in    
 74 {                                                 
 75         struct phy_req_info *req_info = PHY_RE    
 76         struct phy_device_node *pdn = req_info    
 77         struct phy_device *phydev = pdn->phy;     
 78         enum phy_upstream ptype;                  
 79                                                   
 80         ptype = pdn->upstream_type;               
 81                                                   
 82         if (nla_put_u32(skb, ETHTOOL_A_PHY_IND    
 83             nla_put_string(skb, ETHTOOL_A_PHY_    
 84             nla_put_u32(skb, ETHTOOL_A_PHY_UPS    
 85                 return -EMSGSIZE;                 
 86                                                   
 87         if (phydev->drv &&                        
 88             nla_put_string(skb, ETHTOOL_A_PHY_    
 89                 return -EMSGSIZE;                 
 90                                                   
 91         if (ptype == PHY_UPSTREAM_PHY) {          
 92                 struct phy_device *upstream =     
 93                 const char *sfp_upstream_name;    
 94                                                   
 95                 /* Parent index */                
 96                 if (nla_put_u32(skb, ETHTOOL_A    
 97                         return -EMSGSIZE;         
 98                                                   
 99                 if (pdn->parent_sfp_bus) {        
100                         sfp_upstream_name = sf    
101                         if (sfp_upstream_name     
102                             nla_put_string(skb    
103                                            sfp    
104                                 return -EMSGSI    
105                 }                                 
106         }                                         
107                                                   
108         if (phydev->sfp_bus) {                    
109                 const char *sfp_name = sfp_get    
110                                                   
111                 if (sfp_name &&                   
112                     nla_put_string(skb, ETHTOO    
113                                    sfp_name))     
114                         return -EMSGSIZE;         
115         }                                         
116                                                   
117         return 0;                                 
118 }                                                 
119                                                   
120 static int ethnl_phy_parse_request(struct ethn    
121                                    struct nlat    
122                                    struct netl    
123 {                                                 
124         struct phy_link_topology *topo = req_b    
125         struct phy_req_info *req_info = PHY_RE    
126         struct phy_device *phydev;                
127                                                   
128         phydev = ethnl_req_get_phydev(req_base    
129                                       extack);    
130         if (!phydev)                              
131                 return 0;                         
132                                                   
133         if (IS_ERR(phydev))                       
134                 return PTR_ERR(phydev);           
135                                                   
136         if (!topo)                                
137                 return 0;                         
138                                                   
139         req_info->pdn = xa_load(&topo->phys, p    
140                                                   
141         return 0;                                 
142 }                                                 
143                                                   
144 int ethnl_phy_doit(struct sk_buff *skb, struct    
145 {                                                 
146         struct phy_req_info req_info = {};        
147         struct nlattr **tb = info->attrs;         
148         struct sk_buff *rskb;                     
149         void *reply_payload;                      
150         int reply_len;                            
151         int ret;                                  
152                                                   
153         ret = ethnl_parse_header_dev_get(&req_    
154                                          tb[ET    
155                                          genl_    
156                                          true)    
157         if (ret < 0)                              
158                 return ret;                       
159                                                   
160         rtnl_lock();                              
161                                                   
162         ret = ethnl_phy_parse_request(&req_inf    
163         if (ret < 0)                              
164                 goto err_unlock_rtnl;             
165                                                   
166         /* No PHY, return early */                
167         if (!req_info.pdn)                        
168                 goto err_unlock_rtnl;             
169                                                   
170         ret = ethnl_phy_reply_size(&req_info.b    
171         if (ret < 0)                              
172                 goto err_unlock_rtnl;             
173         reply_len = ret + ethnl_reply_header_s    
174                                                   
175         rskb = ethnl_reply_init(reply_len, req    
176                                 ETHTOOL_MSG_PH    
177                                 ETHTOOL_A_PHY_    
178                                 info, &reply_p    
179         if (!rskb) {                              
180                 ret = -ENOMEM;                    
181                 goto err_unlock_rtnl;             
182         }                                         
183                                                   
184         ret = ethnl_phy_fill_reply(&req_info.b    
185         if (ret)                                  
186                 goto err_free_msg;                
187                                                   
188         rtnl_unlock();                            
189         ethnl_parse_header_dev_put(&req_info.b    
190         genlmsg_end(rskb, reply_payload);         
191                                                   
192         return genlmsg_reply(rskb, info);         
193                                                   
194 err_free_msg:                                     
195         nlmsg_free(rskb);                         
196 err_unlock_rtnl:                                  
197         rtnl_unlock();                            
198         ethnl_parse_header_dev_put(&req_info.b    
199         return ret;                               
200 }                                                 
201                                                   
202 struct ethnl_phy_dump_ctx {                       
203         struct phy_req_info     *phy_req_info;    
204         unsigned long ifindex;                    
205         unsigned long phy_index;                  
206 };                                                
207                                                   
208 int ethnl_phy_start(struct netlink_callback *c    
209 {                                                 
210         const struct genl_info *info = genl_in    
211         struct ethnl_phy_dump_ctx *ctx = (void    
212         int ret;                                  
213                                                   
214         BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb-    
215                                                   
216         ctx->phy_req_info = kzalloc(sizeof(*ct    
217         if (!ctx->phy_req_info)                   
218                 return -ENOMEM;                   
219                                                   
220         ret = ethnl_parse_header_dev_get(&ctx-    
221                                          info-    
222                                          sock_    
223                                          false    
224         ctx->ifindex = 0;                         
225         ctx->phy_index = 0;                       
226                                                   
227         if (ret)                                  
228                 kfree(ctx->phy_req_info);         
229                                                   
230         return ret;                               
231 }                                                 
232                                                   
233 int ethnl_phy_done(struct netlink_callback *cb    
234 {                                                 
235         struct ethnl_phy_dump_ctx *ctx = (void    
236                                                   
237         if (ctx->phy_req_info->base.dev)          
238                 ethnl_parse_header_dev_put(&ct    
239                                                   
240         kfree(ctx->phy_req_info);                 
241                                                   
242         return 0;                                 
243 }                                                 
244                                                   
245 static int ethnl_phy_dump_one_dev(struct sk_bu    
246                                   struct netli    
247 {                                                 
248         struct ethnl_phy_dump_ctx *ctx = (void    
249         struct phy_req_info *pri = ctx->phy_re    
250         struct phy_device_node *pdn;              
251         int ret = 0;                              
252         void *ehdr;                               
253                                                   
254         if (!dev->link_topo)                      
255                 return 0;                         
256                                                   
257         xa_for_each_start(&dev->link_topo->phy    
258                 ehdr = ethnl_dump_put(skb, cb,    
259                 if (!ehdr) {                      
260                         ret = -EMSGSIZE;          
261                         break;                    
262                 }                                 
263                                                   
264                 ret = ethnl_fill_reply_header(    
265                 if (ret < 0) {                    
266                         genlmsg_cancel(skb, eh    
267                         break;                    
268                 }                                 
269                                                   
270                 pri->pdn = pdn;                   
271                 ret = ethnl_phy_fill_reply(&pr    
272                 if (ret < 0) {                    
273                         genlmsg_cancel(skb, eh    
274                         break;                    
275                 }                                 
276                                                   
277                 genlmsg_end(skb, ehdr);           
278         }                                         
279                                                   
280         return ret;                               
281 }                                                 
282                                                   
283 int ethnl_phy_dumpit(struct sk_buff *skb, stru    
284 {                                                 
285         struct ethnl_phy_dump_ctx *ctx = (void    
286         struct net *net = sock_net(skb->sk);      
287         struct net_device *dev;                   
288         int ret = 0;                              
289                                                   
290         rtnl_lock();                              
291                                                   
292         if (ctx->phy_req_info->base.dev) {        
293                 ret = ethnl_phy_dump_one_dev(s    
294         } else {                                  
295                 for_each_netdev_dump(net, dev,    
296                         ret = ethnl_phy_dump_o    
297                         if (ret)                  
298                                 break;            
299                                                   
300                         ctx->phy_index = 0;       
301                 }                                 
302         }                                         
303         rtnl_unlock();                            
304                                                   
305         return ret;                               
306 }                                                 
307                                                   

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