ia64/linux-2.6.18-xen.hg

view drivers/net/gianfar_ethtool.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * drivers/net/gianfar_ethtool.c
3 *
4 * Gianfar Ethernet Driver
5 * Ethtool support for Gianfar Enet
6 * Based on e1000 ethtool support
7 *
8 * Author: Andy Fleming
9 * Maintainer: Kumar Gala
10 *
11 * Copyright (c) 2003,2004 Freescale Semiconductor, Inc.
12 *
13 * This software may be used and distributed according to
14 * the terms of the GNU Public License, Version 2, incorporated herein
15 * by reference.
16 */
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/string.h>
21 #include <linux/errno.h>
22 #include <linux/slab.h>
23 #include <linux/interrupt.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
26 #include <linux/netdevice.h>
27 #include <linux/etherdevice.h>
28 #include <linux/skbuff.h>
29 #include <linux/spinlock.h>
30 #include <linux/mm.h>
32 #include <asm/io.h>
33 #include <asm/irq.h>
34 #include <asm/uaccess.h>
35 #include <linux/module.h>
36 #include <linux/crc32.h>
37 #include <asm/types.h>
38 #include <asm/uaccess.h>
39 #include <linux/ethtool.h>
40 #include <linux/mii.h>
41 #include <linux/phy.h>
43 #include "gianfar.h"
45 #define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
47 extern void gfar_start(struct net_device *dev);
48 extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
50 #define GFAR_MAX_COAL_USECS 0xffff
51 #define GFAR_MAX_COAL_FRAMES 0xff
52 static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
53 u64 * buf);
54 static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
55 static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
56 static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
57 static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
58 static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
59 static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo);
61 static char stat_gstrings[][ETH_GSTRING_LEN] = {
62 "rx-dropped-by-kernel",
63 "rx-large-frame-errors",
64 "rx-short-frame-errors",
65 "rx-non-octet-errors",
66 "rx-crc-errors",
67 "rx-overrun-errors",
68 "rx-busy-errors",
69 "rx-babbling-errors",
70 "rx-truncated-frames",
71 "ethernet-bus-error",
72 "tx-babbling-errors",
73 "tx-underrun-errors",
74 "rx-skb-missing-errors",
75 "tx-timeout-errors",
76 "tx-rx-64-frames",
77 "tx-rx-65-127-frames",
78 "tx-rx-128-255-frames",
79 "tx-rx-256-511-frames",
80 "tx-rx-512-1023-frames",
81 "tx-rx-1024-1518-frames",
82 "tx-rx-1519-1522-good-vlan",
83 "rx-bytes",
84 "rx-packets",
85 "rx-fcs-errors",
86 "receive-multicast-packet",
87 "receive-broadcast-packet",
88 "rx-control-frame-packets",
89 "rx-pause-frame-packets",
90 "rx-unknown-op-code",
91 "rx-alignment-error",
92 "rx-frame-length-error",
93 "rx-code-error",
94 "rx-carrier-sense-error",
95 "rx-undersize-packets",
96 "rx-oversize-packets",
97 "rx-fragmented-frames",
98 "rx-jabber-frames",
99 "rx-dropped-frames",
100 "tx-byte-counter",
101 "tx-packets",
102 "tx-multicast-packets",
103 "tx-broadcast-packets",
104 "tx-pause-control-frames",
105 "tx-deferral-packets",
106 "tx-excessive-deferral-packets",
107 "tx-single-collision-packets",
108 "tx-multiple-collision-packets",
109 "tx-late-collision-packets",
110 "tx-excessive-collision-packets",
111 "tx-total-collision",
112 "reserved",
113 "tx-dropped-frames",
114 "tx-jabber-frames",
115 "tx-fcs-errors",
116 "tx-control-frames",
117 "tx-oversize-frames",
118 "tx-undersize-frames",
119 "tx-fragmented-frames",
120 };
122 /* Fill in a buffer with the strings which correspond to the
123 * stats */
124 static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
125 {
126 struct gfar_private *priv = netdev_priv(dev);
128 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
129 memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
130 else
131 memcpy(buf, stat_gstrings,
132 GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN);
133 }
135 /* Fill in an array of 64-bit statistics from various sources.
136 * This array will be appended to the end of the ethtool_stats
137 * structure, and returned to user space
138 */
139 static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf)
140 {
141 int i;
142 struct gfar_private *priv = netdev_priv(dev);
143 u64 *extra = (u64 *) & priv->extra_stats;
145 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
146 u32 __iomem *rmon = (u32 __iomem *) & priv->regs->rmon;
147 struct gfar_stats *stats = (struct gfar_stats *) buf;
149 for (i = 0; i < GFAR_RMON_LEN; i++)
150 stats->rmon[i] = (u64) gfar_read(&rmon[i]);
152 for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
153 stats->extra[i] = extra[i];
154 } else
155 for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
156 buf[i] = extra[i];
157 }
159 /* Returns the number of stats (and their corresponding strings) */
160 static int gfar_stats_count(struct net_device *dev)
161 {
162 struct gfar_private *priv = netdev_priv(dev);
164 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
165 return GFAR_STATS_LEN;
166 else
167 return GFAR_EXTRA_STATS_LEN;
168 }
170 /* Fills in the drvinfo structure with some basic info */
171 static void gfar_gdrvinfo(struct net_device *dev, struct
172 ethtool_drvinfo *drvinfo)
173 {
174 strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN);
175 strncpy(drvinfo->version, gfar_driver_version, GFAR_INFOSTR_LEN);
176 strncpy(drvinfo->fw_version, "N/A", GFAR_INFOSTR_LEN);
177 strncpy(drvinfo->bus_info, "N/A", GFAR_INFOSTR_LEN);
178 drvinfo->n_stats = GFAR_STATS_LEN;
179 drvinfo->testinfo_len = 0;
180 drvinfo->regdump_len = 0;
181 drvinfo->eedump_len = 0;
182 }
185 static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd)
186 {
187 struct gfar_private *priv = netdev_priv(dev);
188 struct phy_device *phydev = priv->phydev;
190 if (NULL == phydev)
191 return -ENODEV;
193 return phy_ethtool_sset(phydev, cmd);
194 }
197 /* Return the current settings in the ethtool_cmd structure */
198 static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
199 {
200 struct gfar_private *priv = netdev_priv(dev);
201 struct phy_device *phydev = priv->phydev;
203 if (NULL == phydev)
204 return -ENODEV;
206 cmd->maxtxpkt = priv->txcount;
207 cmd->maxrxpkt = priv->rxcount;
209 return phy_ethtool_gset(phydev, cmd);
210 }
212 /* Return the length of the register structure */
213 static int gfar_reglen(struct net_device *dev)
214 {
215 return sizeof (struct gfar);
216 }
218 /* Return a dump of the GFAR register space */
219 static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
220 {
221 int i;
222 struct gfar_private *priv = netdev_priv(dev);
223 u32 __iomem *theregs = (u32 __iomem *) priv->regs;
224 u32 *buf = (u32 *) regbuf;
226 for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++)
227 buf[i] = gfar_read(&theregs[i]);
228 }
230 /* Convert microseconds to ethernet clock ticks, which changes
231 * depending on what speed the controller is running at */
232 static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int usecs)
233 {
234 unsigned int count;
236 /* The timer is different, depending on the interface speed */
237 switch (priv->phydev->speed) {
238 case SPEED_1000:
239 count = GFAR_GBIT_TIME;
240 break;
241 case SPEED_100:
242 count = GFAR_100_TIME;
243 break;
244 case SPEED_10:
245 default:
246 count = GFAR_10_TIME;
247 break;
248 }
250 /* Make sure we return a number greater than 0
251 * if usecs > 0 */
252 return ((usecs * 1000 + count - 1) / count);
253 }
255 /* Convert ethernet clock ticks to microseconds */
256 static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int ticks)
257 {
258 unsigned int count;
260 /* The timer is different, depending on the interface speed */
261 switch (priv->phydev->speed) {
262 case SPEED_1000:
263 count = GFAR_GBIT_TIME;
264 break;
265 case SPEED_100:
266 count = GFAR_100_TIME;
267 break;
268 case SPEED_10:
269 default:
270 count = GFAR_10_TIME;
271 break;
272 }
274 /* Make sure we return a number greater than 0 */
275 /* if ticks is > 0 */
276 return ((ticks * count) / 1000);
277 }
279 /* Get the coalescing parameters, and put them in the cvals
280 * structure. */
281 static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
282 {
283 struct gfar_private *priv = netdev_priv(dev);
285 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
286 return -EOPNOTSUPP;
288 if (NULL == priv->phydev)
289 return -ENODEV;
291 cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
292 cvals->rx_max_coalesced_frames = priv->rxcount;
294 cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, priv->txtime);
295 cvals->tx_max_coalesced_frames = priv->txcount;
297 cvals->use_adaptive_rx_coalesce = 0;
298 cvals->use_adaptive_tx_coalesce = 0;
300 cvals->pkt_rate_low = 0;
301 cvals->rx_coalesce_usecs_low = 0;
302 cvals->rx_max_coalesced_frames_low = 0;
303 cvals->tx_coalesce_usecs_low = 0;
304 cvals->tx_max_coalesced_frames_low = 0;
306 /* When the packet rate is below pkt_rate_high but above
307 * pkt_rate_low (both measured in packets per second) the
308 * normal {rx,tx}_* coalescing parameters are used.
309 */
311 /* When the packet rate is (measured in packets per second)
312 * is above pkt_rate_high, the {rx,tx}_*_high parameters are
313 * used.
314 */
315 cvals->pkt_rate_high = 0;
316 cvals->rx_coalesce_usecs_high = 0;
317 cvals->rx_max_coalesced_frames_high = 0;
318 cvals->tx_coalesce_usecs_high = 0;
319 cvals->tx_max_coalesced_frames_high = 0;
321 /* How often to do adaptive coalescing packet rate sampling,
322 * measured in seconds. Must not be zero.
323 */
324 cvals->rate_sample_interval = 0;
326 return 0;
327 }
329 /* Change the coalescing values.
330 * Both cvals->*_usecs and cvals->*_frames have to be > 0
331 * in order for coalescing to be active
332 */
333 static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
334 {
335 struct gfar_private *priv = netdev_priv(dev);
337 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
338 return -EOPNOTSUPP;
340 /* Set up rx coalescing */
341 if ((cvals->rx_coalesce_usecs == 0) ||
342 (cvals->rx_max_coalesced_frames == 0))
343 priv->rxcoalescing = 0;
344 else
345 priv->rxcoalescing = 1;
347 if (NULL == priv->phydev)
348 return -ENODEV;
350 /* Check the bounds of the values */
351 if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
352 pr_info("Coalescing is limited to %d microseconds\n",
353 GFAR_MAX_COAL_USECS);
354 return -EINVAL;
355 }
357 if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
358 pr_info("Coalescing is limited to %d frames\n",
359 GFAR_MAX_COAL_FRAMES);
360 return -EINVAL;
361 }
363 priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
364 priv->rxcount = cvals->rx_max_coalesced_frames;
366 /* Set up tx coalescing */
367 if ((cvals->tx_coalesce_usecs == 0) ||
368 (cvals->tx_max_coalesced_frames == 0))
369 priv->txcoalescing = 0;
370 else
371 priv->txcoalescing = 1;
373 /* Check the bounds of the values */
374 if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
375 pr_info("Coalescing is limited to %d microseconds\n",
376 GFAR_MAX_COAL_USECS);
377 return -EINVAL;
378 }
380 if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
381 pr_info("Coalescing is limited to %d frames\n",
382 GFAR_MAX_COAL_FRAMES);
383 return -EINVAL;
384 }
386 priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
387 priv->txcount = cvals->tx_max_coalesced_frames;
389 if (priv->rxcoalescing)
390 gfar_write(&priv->regs->rxic,
391 mk_ic_value(priv->rxcount, priv->rxtime));
392 else
393 gfar_write(&priv->regs->rxic, 0);
395 if (priv->txcoalescing)
396 gfar_write(&priv->regs->txic,
397 mk_ic_value(priv->txcount, priv->txtime));
398 else
399 gfar_write(&priv->regs->txic, 0);
401 return 0;
402 }
404 /* Fills in rvals with the current ring parameters. Currently,
405 * rx, rx_mini, and rx_jumbo rings are the same size, as mini and
406 * jumbo are ignored by the driver */
407 static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
408 {
409 struct gfar_private *priv = netdev_priv(dev);
411 rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE;
412 rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE;
413 rvals->rx_jumbo_max_pending = GFAR_RX_MAX_RING_SIZE;
414 rvals->tx_max_pending = GFAR_TX_MAX_RING_SIZE;
416 /* Values changeable by the user. The valid values are
417 * in the range 1 to the "*_max_pending" counterpart above.
418 */
419 rvals->rx_pending = priv->rx_ring_size;
420 rvals->rx_mini_pending = priv->rx_ring_size;
421 rvals->rx_jumbo_pending = priv->rx_ring_size;
422 rvals->tx_pending = priv->tx_ring_size;
423 }
425 /* Change the current ring parameters, stopping the controller if
426 * necessary so that we don't mess things up while we're in
427 * motion. We wait for the ring to be clean before reallocating
428 * the rings. */
429 static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
430 {
431 struct gfar_private *priv = netdev_priv(dev);
432 int err = 0;
434 if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE)
435 return -EINVAL;
437 if (!is_power_of_2(rvals->rx_pending)) {
438 printk("%s: Ring sizes must be a power of 2\n",
439 dev->name);
440 return -EINVAL;
441 }
443 if (rvals->tx_pending > GFAR_TX_MAX_RING_SIZE)
444 return -EINVAL;
446 if (!is_power_of_2(rvals->tx_pending)) {
447 printk("%s: Ring sizes must be a power of 2\n",
448 dev->name);
449 return -EINVAL;
450 }
452 if (dev->flags & IFF_UP) {
453 unsigned long flags;
455 /* Halt TX and RX, and process the frames which
456 * have already been received */
457 spin_lock_irqsave(&priv->txlock, flags);
458 spin_lock(&priv->rxlock);
460 gfar_halt(dev);
461 gfar_clean_rx_ring(dev, priv->rx_ring_size);
463 spin_unlock(&priv->rxlock);
464 spin_unlock_irqrestore(&priv->txlock, flags);
466 /* Now we take down the rings to rebuild them */
467 stop_gfar(dev);
468 }
470 /* Change the size */
471 priv->rx_ring_size = rvals->rx_pending;
472 priv->tx_ring_size = rvals->tx_pending;
474 /* Rebuild the rings with the new size */
475 if (dev->flags & IFF_UP)
476 err = startup_gfar(dev);
478 return err;
479 }
481 static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
482 {
483 struct gfar_private *priv = netdev_priv(dev);
484 int err = 0;
486 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
487 return -EOPNOTSUPP;
489 if (dev->flags & IFF_UP) {
490 unsigned long flags;
492 /* Halt TX and RX, and process the frames which
493 * have already been received */
494 spin_lock_irqsave(&priv->txlock, flags);
495 spin_lock(&priv->rxlock);
497 gfar_halt(dev);
498 gfar_clean_rx_ring(dev, priv->rx_ring_size);
500 spin_unlock(&priv->rxlock);
501 spin_unlock_irqrestore(&priv->txlock, flags);
503 /* Now we take down the rings to rebuild them */
504 stop_gfar(dev);
505 }
507 priv->rx_csum_enable = data;
509 if (dev->flags & IFF_UP)
510 err = startup_gfar(dev);
512 return err;
513 }
515 static uint32_t gfar_get_rx_csum(struct net_device *dev)
516 {
517 struct gfar_private *priv = netdev_priv(dev);
519 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
520 return 0;
522 return priv->rx_csum_enable;
523 }
525 static int gfar_set_tx_csum(struct net_device *dev, uint32_t data)
526 {
527 unsigned long flags;
528 struct gfar_private *priv = netdev_priv(dev);
530 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
531 return -EOPNOTSUPP;
533 spin_lock_irqsave(&priv->txlock, flags);
534 gfar_halt(dev);
536 if (data)
537 dev->features |= NETIF_F_IP_CSUM;
538 else
539 dev->features &= ~NETIF_F_IP_CSUM;
541 gfar_start(dev);
542 spin_unlock_irqrestore(&priv->txlock, flags);
544 return 0;
545 }
547 static uint32_t gfar_get_tx_csum(struct net_device *dev)
548 {
549 struct gfar_private *priv = netdev_priv(dev);
551 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
552 return 0;
554 return (dev->features & NETIF_F_IP_CSUM) != 0;
555 }
557 static uint32_t gfar_get_msglevel(struct net_device *dev)
558 {
559 struct gfar_private *priv = netdev_priv(dev);
560 return priv->msg_enable;
561 }
563 static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
564 {
565 struct gfar_private *priv = netdev_priv(dev);
566 priv->msg_enable = data;
567 }
570 struct ethtool_ops gfar_ethtool_ops = {
571 .get_settings = gfar_gsettings,
572 .set_settings = gfar_ssettings,
573 .get_drvinfo = gfar_gdrvinfo,
574 .get_regs_len = gfar_reglen,
575 .get_regs = gfar_get_regs,
576 .get_link = ethtool_op_get_link,
577 .get_coalesce = gfar_gcoalesce,
578 .set_coalesce = gfar_scoalesce,
579 .get_ringparam = gfar_gringparam,
580 .set_ringparam = gfar_sringparam,
581 .get_strings = gfar_gstrings,
582 .get_stats_count = gfar_stats_count,
583 .get_ethtool_stats = gfar_fill_stats,
584 .get_rx_csum = gfar_get_rx_csum,
585 .get_tx_csum = gfar_get_tx_csum,
586 .set_rx_csum = gfar_set_rx_csum,
587 .set_tx_csum = gfar_set_tx_csum,
588 .get_msglevel = gfar_get_msglevel,
589 .set_msglevel = gfar_set_msglevel,
590 };