diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-09-27 23:33:34 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-28 21:02:49 -0400 |
commit | 7fa6b06689085a3e2237cf810f5e0c114e00a2da (patch) | |
tree | 729eeef31a9ad44c0635f5e27b6c924767e17238 | |
parent | 1b0fee7d68f234be6b270cda51d9fcb71bebd780 (diff) |
[NET] loopback: minor statistics optimization
The loopback device status structure is a singleton and doesn't
need to be allocated. Add ethtool_ops hooks to show checksum always on,
and make ethtool_ops const.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/loopback.c | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index f429b19bf620..4178b4b1d2df 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
@@ -161,15 +161,13 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | |||
161 | return(0); | 161 | return(0); |
162 | } | 162 | } |
163 | 163 | ||
164 | static struct net_device_stats loopback_stats; | ||
165 | |||
164 | static struct net_device_stats *get_stats(struct net_device *dev) | 166 | static struct net_device_stats *get_stats(struct net_device *dev) |
165 | { | 167 | { |
166 | struct net_device_stats *stats = dev->priv; | 168 | struct net_device_stats *stats = &loopback_stats; |
167 | int i; | 169 | int i; |
168 | 170 | ||
169 | if (!stats) { | ||
170 | return NULL; | ||
171 | } | ||
172 | |||
173 | memset(stats, 0, sizeof(struct net_device_stats)); | 171 | memset(stats, 0, sizeof(struct net_device_stats)); |
174 | 172 | ||
175 | for_each_possible_cpu(i) { | 173 | for_each_possible_cpu(i) { |
@@ -185,19 +183,28 @@ static struct net_device_stats *get_stats(struct net_device *dev) | |||
185 | return stats; | 183 | return stats; |
186 | } | 184 | } |
187 | 185 | ||
188 | static u32 loopback_get_link(struct net_device *dev) | 186 | static u32 always_on(struct net_device *dev) |
189 | { | 187 | { |
190 | return 1; | 188 | return 1; |
191 | } | 189 | } |
192 | 190 | ||
193 | static const struct ethtool_ops loopback_ethtool_ops = { | 191 | static const struct ethtool_ops loopback_ethtool_ops = { |
194 | .get_link = loopback_get_link, | 192 | .get_link = always_on, |
195 | .get_tso = ethtool_op_get_tso, | 193 | .get_tso = ethtool_op_get_tso, |
196 | .set_tso = ethtool_op_set_tso, | 194 | .set_tso = ethtool_op_set_tso, |
195 | .get_tx_csum = always_on, | ||
196 | .get_sg = always_on, | ||
197 | .get_rx_csum = always_on, | ||
197 | }; | 198 | }; |
198 | 199 | ||
200 | /* | ||
201 | * The loopback device is special. There is only one instance and | ||
202 | * it is statically allocated. Don't do this for other devices. | ||
203 | */ | ||
199 | struct net_device loopback_dev = { | 204 | struct net_device loopback_dev = { |
200 | .name = "lo", | 205 | .name = "lo", |
206 | .get_stats = &get_stats, | ||
207 | .priv = &loopback_stats, | ||
201 | .mtu = (16 * 1024) + 20 + 20 + 12, | 208 | .mtu = (16 * 1024) + 20 + 20 + 12, |
202 | .hard_start_xmit = loopback_xmit, | 209 | .hard_start_xmit = loopback_xmit, |
203 | .hard_header = eth_header, | 210 | .hard_header = eth_header, |
@@ -221,16 +228,6 @@ struct net_device loopback_dev = { | |||
221 | /* Setup and register the loopback device. */ | 228 | /* Setup and register the loopback device. */ |
222 | int __init loopback_init(void) | 229 | int __init loopback_init(void) |
223 | { | 230 | { |
224 | struct net_device_stats *stats; | ||
225 | |||
226 | /* Can survive without statistics */ | ||
227 | stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); | ||
228 | if (stats) { | ||
229 | memset(stats, 0, sizeof(struct net_device_stats)); | ||
230 | loopback_dev.priv = stats; | ||
231 | loopback_dev.get_stats = &get_stats; | ||
232 | } | ||
233 | |||
234 | return register_netdev(&loopback_dev); | 231 | return register_netdev(&loopback_dev); |
235 | }; | 232 | }; |
236 | 233 | ||