diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2019-01-15 17:43:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-17 00:12:21 -0500 |
commit | da7b9e9b00d4859d0fa563d7fe9a2b2dff59e852 (patch) | |
tree | 780c33a93ca4a8a13ca6dc3e5012e345fe5e5fe2 /net/dsa | |
parent | 44543f1dd2a39d56c9afdc3778aa050b5a4725b4 (diff) |
net: dsa: Add ndo_get_phys_port_name() for CPU port
There is not currently way to infer the port number through sysfs that
is being used as the CPU port number. Overlay a ndo_get_phys_port_name()
operation onto the DSA master network device in order to retrieve that
information.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r-- | net/dsa/master.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/net/dsa/master.c b/net/dsa/master.c index 71bb15f491c8..79e97d2f2d9b 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c | |||
@@ -126,6 +126,17 @@ static void dsa_master_get_strings(struct net_device *dev, uint32_t stringset, | |||
126 | } | 126 | } |
127 | } | 127 | } |
128 | 128 | ||
129 | static int dsa_master_get_phys_port_name(struct net_device *dev, | ||
130 | char *name, size_t len) | ||
131 | { | ||
132 | struct dsa_port *cpu_dp = dev->dsa_ptr; | ||
133 | |||
134 | if (snprintf(name, len, "p%d", cpu_dp->index) >= len) | ||
135 | return -EINVAL; | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
129 | static int dsa_master_ethtool_setup(struct net_device *dev) | 140 | static int dsa_master_ethtool_setup(struct net_device *dev) |
130 | { | 141 | { |
131 | struct dsa_port *cpu_dp = dev->dsa_ptr; | 142 | struct dsa_port *cpu_dp = dev->dsa_ptr; |
@@ -158,6 +169,38 @@ static void dsa_master_ethtool_teardown(struct net_device *dev) | |||
158 | cpu_dp->orig_ethtool_ops = NULL; | 169 | cpu_dp->orig_ethtool_ops = NULL; |
159 | } | 170 | } |
160 | 171 | ||
172 | static int dsa_master_ndo_setup(struct net_device *dev) | ||
173 | { | ||
174 | struct dsa_port *cpu_dp = dev->dsa_ptr; | ||
175 | struct dsa_switch *ds = cpu_dp->ds; | ||
176 | struct net_device_ops *ops; | ||
177 | |||
178 | if (dev->netdev_ops->ndo_get_phys_port_name) | ||
179 | return 0; | ||
180 | |||
181 | ops = devm_kzalloc(ds->dev, sizeof(*ops), GFP_KERNEL); | ||
182 | if (!ops) | ||
183 | return -ENOMEM; | ||
184 | |||
185 | cpu_dp->orig_ndo_ops = dev->netdev_ops; | ||
186 | if (cpu_dp->orig_ndo_ops) | ||
187 | memcpy(ops, cpu_dp->orig_ndo_ops, sizeof(*ops)); | ||
188 | |||
189 | ops->ndo_get_phys_port_name = dsa_master_get_phys_port_name; | ||
190 | |||
191 | dev->netdev_ops = ops; | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static void dsa_master_ndo_teardown(struct net_device *dev) | ||
197 | { | ||
198 | struct dsa_port *cpu_dp = dev->dsa_ptr; | ||
199 | |||
200 | dev->netdev_ops = cpu_dp->orig_ndo_ops; | ||
201 | cpu_dp->orig_ndo_ops = NULL; | ||
202 | } | ||
203 | |||
161 | static ssize_t tagging_show(struct device *d, struct device_attribute *attr, | 204 | static ssize_t tagging_show(struct device *d, struct device_attribute *attr, |
162 | char *buf) | 205 | char *buf) |
163 | { | 206 | { |
@@ -223,16 +266,27 @@ int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp) | |||
223 | if (ret) | 266 | if (ret) |
224 | return ret; | 267 | return ret; |
225 | 268 | ||
269 | ret = dsa_master_ndo_setup(dev); | ||
270 | if (ret) | ||
271 | goto out_err_ethtool_teardown; | ||
272 | |||
226 | ret = sysfs_create_group(&dev->dev.kobj, &dsa_group); | 273 | ret = sysfs_create_group(&dev->dev.kobj, &dsa_group); |
227 | if (ret) | 274 | if (ret) |
228 | dsa_master_ethtool_teardown(dev); | 275 | goto out_err_ndo_teardown; |
276 | |||
277 | return ret; | ||
229 | 278 | ||
279 | out_err_ndo_teardown: | ||
280 | dsa_master_ndo_teardown(dev); | ||
281 | out_err_ethtool_teardown: | ||
282 | dsa_master_ethtool_teardown(dev); | ||
230 | return ret; | 283 | return ret; |
231 | } | 284 | } |
232 | 285 | ||
233 | void dsa_master_teardown(struct net_device *dev) | 286 | void dsa_master_teardown(struct net_device *dev) |
234 | { | 287 | { |
235 | sysfs_remove_group(&dev->dev.kobj, &dsa_group); | 288 | sysfs_remove_group(&dev->dev.kobj, &dsa_group); |
289 | dsa_master_ndo_teardown(dev); | ||
236 | dsa_master_ethtool_teardown(dev); | 290 | dsa_master_ethtool_teardown(dev); |
237 | dsa_master_reset_mtu(dev); | 291 | dsa_master_reset_mtu(dev); |
238 | 292 | ||