ia64/linux-2.6.18-xen.hg

view drivers/net/netx-eth.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/netx-eth.c
3 *
4 * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
20 #include <linux/config.h>
21 #include <linux/init.h>
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/delay.h>
26 #include <linux/netdevice.h>
27 #include <linux/platform_device.h>
28 #include <linux/etherdevice.h>
29 #include <linux/skbuff.h>
30 #include <linux/mii.h>
32 #include <asm/io.h>
33 #include <asm/hardware.h>
34 #include <asm/arch/hardware.h>
35 #include <asm/arch/netx-regs.h>
36 #include <asm/arch/pfifo.h>
37 #include <asm/arch/xc.h>
38 #include <asm/arch/eth.h>
40 /* XC Fifo Offsets */
41 #define EMPTY_PTR_FIFO(xcno) (0 + ((xcno) << 3)) /* Index of the empty pointer FIFO */
42 #define IND_FIFO_PORT_HI(xcno) (1 + ((xcno) << 3)) /* Index of the FIFO where received */
43 /* Data packages are indicated by XC */
44 #define IND_FIFO_PORT_LO(xcno) (2 + ((xcno) << 3)) /* Index of the FIFO where received */
45 /* Data packages are indicated by XC */
46 #define REQ_FIFO_PORT_HI(xcno) (3 + ((xcno) << 3)) /* Index of the FIFO where Data packages */
47 /* have to be indicated by ARM which */
48 /* shall be sent */
49 #define REQ_FIFO_PORT_LO(xcno) (4 + ((xcno) << 3)) /* Index of the FIFO where Data packages */
50 /* have to be indicated by ARM which shall */
51 /* be sent */
52 #define CON_FIFO_PORT_HI(xcno) (5 + ((xcno) << 3)) /* Index of the FIFO where sent Data packages */
53 /* are confirmed */
54 #define CON_FIFO_PORT_LO(xcno) (6 + ((xcno) << 3)) /* Index of the FIFO where sent Data */
55 /* packages are confirmed */
56 #define PFIFO_MASK(xcno) (0x7f << (xcno*8))
58 #define FIFO_PTR_FRAMELEN_SHIFT 0
59 #define FIFO_PTR_FRAMELEN_MASK (0x7ff << 0)
60 #define FIFO_PTR_FRAMELEN(len) (((len) << 0) & FIFO_PTR_FRAMELEN_MASK)
61 #define FIFO_PTR_TIMETRIG (1<<11)
62 #define FIFO_PTR_MULTI_REQ
63 #define FIFO_PTR_ORIGIN (1<<14)
64 #define FIFO_PTR_VLAN (1<<15)
65 #define FIFO_PTR_FRAMENO_SHIFT 16
66 #define FIFO_PTR_FRAMENO_MASK (0x3f << 16)
67 #define FIFO_PTR_FRAMENO(no) (((no) << 16) & FIFO_PTR_FRAMENO_MASK)
68 #define FIFO_PTR_SEGMENT_SHIFT 22
69 #define FIFO_PTR_SEGMENT_MASK (0xf << 22)
70 #define FIFO_PTR_SEGMENT(seg) (((seg) & 0xf) << 22)
71 #define FIFO_PTR_ERROR_SHIFT 28
72 #define FIFO_PTR_ERROR_MASK (0xf << 28)
74 #define ISR_LINK_STATUS_CHANGE (1<<4)
75 #define ISR_IND_LO (1<<3)
76 #define ISR_CON_LO (1<<2)
77 #define ISR_IND_HI (1<<1)
78 #define ISR_CON_HI (1<<0)
80 #define ETH_MAC_LOCAL_CONFIG 0x1560
81 #define ETH_MAC_4321 0x1564
82 #define ETH_MAC_65 0x1568
84 #define MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT 16
85 #define MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK (0xf<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT)
86 #define MAC_TRAFFIC_CLASS_ARRANGEMENT(x) (((x)<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT) & MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK)
87 #define LOCAL_CONFIG_LINK_STATUS_IRQ_EN (1<<24)
88 #define LOCAL_CONFIG_CON_LO_IRQ_EN (1<<23)
89 #define LOCAL_CONFIG_CON_HI_IRQ_EN (1<<22)
90 #define LOCAL_CONFIG_IND_LO_IRQ_EN (1<<21)
91 #define LOCAL_CONFIG_IND_HI_IRQ_EN (1<<20)
93 #define CARDNAME "netx-eth"
95 /* LSB must be zero */
96 #define INTERNAL_PHY_ADR 0x1c
98 struct netx_eth_priv {
99 void __iomem *sram_base, *xpec_base, *xmac_base;
100 int id;
101 struct net_device_stats stats;
102 struct mii_if_info mii;
103 u32 msg_enable;
104 struct xc *xc;
105 spinlock_t lock;
106 };
108 static void netx_eth_set_multicast_list(struct net_device *ndev)
109 {
110 /* implement me */
111 }
113 static int
114 netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
115 {
116 struct netx_eth_priv *priv = netdev_priv(ndev);
117 unsigned char *buf = skb->data;
118 unsigned int len = skb->len;
120 spin_lock_irq(&priv->lock);
121 memcpy_toio(priv->sram_base + 1560, (void *)buf, len);
122 if (len < 60) {
123 memset_io(priv->sram_base + 1560 + len, 0, 60 - len);
124 len = 60;
125 }
127 pfifo_push(REQ_FIFO_PORT_LO(priv->id),
128 FIFO_PTR_SEGMENT(priv->id) |
129 FIFO_PTR_FRAMENO(1) |
130 FIFO_PTR_FRAMELEN(len));
132 ndev->trans_start = jiffies;
133 priv->stats.tx_packets++;
134 priv->stats.tx_bytes += skb->len;
136 netif_stop_queue(ndev);
137 spin_unlock_irq(&priv->lock);
138 dev_kfree_skb(skb);
140 return 0;
141 }
143 static void netx_eth_receive(struct net_device *ndev)
144 {
145 struct netx_eth_priv *priv = netdev_priv(ndev);
146 unsigned int val, frameno, seg, len;
147 unsigned char *data;
148 struct sk_buff *skb;
150 val = pfifo_pop(IND_FIFO_PORT_LO(priv->id));
152 frameno = (val & FIFO_PTR_FRAMENO_MASK) >> FIFO_PTR_FRAMENO_SHIFT;
153 seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT;
154 len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT;
156 skb = dev_alloc_skb(len);
157 if (unlikely(skb == NULL)) {
158 printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
159 ndev->name);
160 priv->stats.rx_dropped++;
161 return;
162 }
164 data = skb_put(skb, len);
166 memcpy_fromio(data, priv->sram_base + frameno * 1560, len);
168 pfifo_push(EMPTY_PTR_FIFO(priv->id),
169 FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno));
171 ndev->last_rx = jiffies;
172 skb->dev = ndev;
173 skb->protocol = eth_type_trans(skb, ndev);
174 netif_rx(skb);
175 priv->stats.rx_packets++;
176 priv->stats.rx_bytes += len;
177 }
179 static irqreturn_t
180 netx_eth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
181 {
182 struct net_device *ndev = dev_id;
183 struct netx_eth_priv *priv = netdev_priv(ndev);
184 int status;
185 unsigned long flags;
187 spin_lock_irqsave(&priv->lock, flags);
189 status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
190 while (status) {
191 int fill_level;
192 writel(status, NETX_PFIFO_XPEC_ISR(priv->id));
194 if ((status & ISR_CON_HI) || (status & ISR_IND_HI))
195 printk("%s: unexpected status: 0x%08x\n",
196 __FUNCTION__, status);
198 fill_level =
199 readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id)));
200 while (fill_level--)
201 netx_eth_receive(ndev);
203 if (status & ISR_CON_LO)
204 netif_wake_queue(ndev);
206 if (status & ISR_LINK_STATUS_CHANGE)
207 mii_check_media(&priv->mii, netif_msg_link(priv), 1);
209 status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
210 }
211 spin_unlock_irqrestore(&priv->lock, flags);
212 return IRQ_HANDLED;
213 }
215 static struct net_device_stats *netx_eth_query_statistics(struct net_device *ndev)
216 {
217 struct netx_eth_priv *priv = netdev_priv(ndev);
218 return &priv->stats;
219 }
221 static int netx_eth_open(struct net_device *ndev)
222 {
223 struct netx_eth_priv *priv = netdev_priv(ndev);
225 if (request_irq
226 (ndev->irq, &netx_eth_interrupt, IRQF_SHARED, ndev->name, ndev))
227 return -EAGAIN;
229 writel(ndev->dev_addr[0] |
230 ndev->dev_addr[1]<<8 |
231 ndev->dev_addr[2]<<16 |
232 ndev->dev_addr[3]<<24,
233 priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_4321);
234 writel(ndev->dev_addr[4] |
235 ndev->dev_addr[5]<<8,
236 priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_65);
238 writel(LOCAL_CONFIG_LINK_STATUS_IRQ_EN |
239 LOCAL_CONFIG_CON_LO_IRQ_EN |
240 LOCAL_CONFIG_CON_HI_IRQ_EN |
241 LOCAL_CONFIG_IND_LO_IRQ_EN |
242 LOCAL_CONFIG_IND_HI_IRQ_EN,
243 priv->xpec_base + NETX_XPEC_RAM_START_OFS +
244 ETH_MAC_LOCAL_CONFIG);
246 mii_check_media(&priv->mii, netif_msg_link(priv), 1);
247 netif_start_queue(ndev);
249 return 0;
250 }
252 static int netx_eth_close(struct net_device *ndev)
253 {
254 struct netx_eth_priv *priv = netdev_priv(ndev);
256 netif_stop_queue(ndev);
258 writel(0,
259 priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_LOCAL_CONFIG);
261 free_irq(ndev->irq, ndev);
263 return 0;
264 }
266 static void netx_eth_timeout(struct net_device *ndev)
267 {
268 struct netx_eth_priv *priv = netdev_priv(ndev);
269 int i;
271 printk(KERN_ERR "%s: transmit timed out, resetting\n", ndev->name);
273 spin_lock_irq(&priv->lock);
275 xc_reset(priv->xc);
276 xc_start(priv->xc);
278 for (i=2; i<=18; i++)
279 pfifo_push(EMPTY_PTR_FIFO(priv->id),
280 FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id));
282 spin_unlock_irq(&priv->lock);
284 netif_wake_queue(ndev);
285 }
287 static int
288 netx_eth_phy_read(struct net_device *ndev, int phy_id, int reg)
289 {
290 unsigned int val;
292 val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) |
293 MIIMU_REGADDR(reg) | MIIMU_PHY_NRES;
295 writel(val, NETX_MIIMU);
296 while (readl(NETX_MIIMU) & MIIMU_SNRDY);
298 return readl(NETX_MIIMU) >> 16;
300 }
302 static void
303 netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value)
304 {
305 unsigned int val;
307 val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) |
308 MIIMU_REGADDR(reg) | MIIMU_PHY_NRES | MIIMU_OPMODE_WRITE |
309 MIIMU_DATA(value);
311 writel(val, NETX_MIIMU);
312 while (readl(NETX_MIIMU) & MIIMU_SNRDY);
313 }
315 static int netx_eth_enable(struct net_device *ndev)
316 {
317 struct netx_eth_priv *priv = netdev_priv(ndev);
318 unsigned int mac4321, mac65;
319 int running, i;
321 ether_setup(ndev);
323 ndev->open = netx_eth_open;
324 ndev->stop = netx_eth_close;
325 ndev->hard_start_xmit = netx_eth_hard_start_xmit;
326 ndev->tx_timeout = netx_eth_timeout;
327 ndev->watchdog_timeo = msecs_to_jiffies(5000);
328 ndev->get_stats = netx_eth_query_statistics;
329 ndev->set_multicast_list = netx_eth_set_multicast_list;
331 priv->msg_enable = NETIF_MSG_LINK;
332 priv->mii.phy_id_mask = 0x1f;
333 priv->mii.reg_num_mask = 0x1f;
334 priv->mii.force_media = 0;
335 priv->mii.full_duplex = 0;
336 priv->mii.dev = ndev;
337 priv->mii.mdio_read = netx_eth_phy_read;
338 priv->mii.mdio_write = netx_eth_phy_write;
339 priv->mii.phy_id = INTERNAL_PHY_ADR + priv->id;
341 running = xc_running(priv->xc);
342 xc_stop(priv->xc);
344 /* if the xc engine is already running, assume the bootloader has
345 * loaded the firmware for us
346 */
347 if (running) {
348 /* get Node Address from hardware */
349 mac4321 = readl(priv->xpec_base +
350 NETX_XPEC_RAM_START_OFS + ETH_MAC_4321);
351 mac65 = readl(priv->xpec_base +
352 NETX_XPEC_RAM_START_OFS + ETH_MAC_65);
354 ndev->dev_addr[0] = mac4321 & 0xff;
355 ndev->dev_addr[1] = (mac4321 >> 8) & 0xff;
356 ndev->dev_addr[2] = (mac4321 >> 16) & 0xff;
357 ndev->dev_addr[3] = (mac4321 >> 24) & 0xff;
358 ndev->dev_addr[4] = mac65 & 0xff;
359 ndev->dev_addr[5] = (mac65 >> 8) & 0xff;
360 } else {
361 if (xc_request_firmware(priv->xc)) {
362 printk(CARDNAME ": requesting firmware failed\n");
363 return -ENODEV;
364 }
365 }
367 xc_reset(priv->xc);
368 xc_start(priv->xc);
370 if (!is_valid_ether_addr(ndev->dev_addr))
371 printk("%s: Invalid ethernet MAC address. Please "
372 "set using ifconfig\n", ndev->name);
374 for (i=2; i<=18; i++)
375 pfifo_push(EMPTY_PTR_FIFO(priv->id),
376 FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id));
378 return register_netdev(ndev);
380 }
382 static int netx_eth_drv_probe(struct platform_device *pdev)
383 {
384 struct netx_eth_priv *priv;
385 struct net_device *ndev;
386 struct netxeth_platform_data *pdata;
387 int ret;
389 ndev = alloc_etherdev(sizeof (struct netx_eth_priv));
390 if (!ndev) {
391 printk("%s: could not allocate device.\n", CARDNAME);
392 ret = -ENOMEM;
393 goto exit;
394 }
395 SET_MODULE_OWNER(ndev);
396 SET_NETDEV_DEV(ndev, &pdev->dev);
398 platform_set_drvdata(pdev, ndev);
400 priv = netdev_priv(ndev);
402 pdata = (struct netxeth_platform_data *)pdev->dev.platform_data;
403 priv->xc = request_xc(pdata->xcno, &pdev->dev);
404 if (!priv->xc) {
405 dev_err(&pdev->dev, "unable to request xc engine\n");
406 ret = -ENODEV;
407 goto exit_free_netdev;
408 }
410 ndev->irq = priv->xc->irq;
411 priv->id = pdev->id;
412 priv->xpec_base = priv->xc->xpec_base;
413 priv->xmac_base = priv->xc->xmac_base;
414 priv->sram_base = priv->xc->sram_base;
416 ret = pfifo_request(PFIFO_MASK(priv->id));
417 if (ret) {
418 printk("unable to request PFIFO\n");
419 goto exit_free_xc;
420 }
422 ret = netx_eth_enable(ndev);
423 if (ret)
424 goto exit_free_pfifo;
426 return 0;
427 exit_free_pfifo:
428 pfifo_free(PFIFO_MASK(priv->id));
429 exit_free_xc:
430 free_xc(priv->xc);
431 exit_free_netdev:
432 platform_set_drvdata(pdev, NULL);
433 free_netdev(ndev);
434 exit:
435 return ret;
436 }
438 static int netx_eth_drv_remove(struct platform_device *pdev)
439 {
440 struct net_device *ndev = dev_get_drvdata(&pdev->dev);
441 struct netx_eth_priv *priv = netdev_priv(ndev);
443 platform_set_drvdata(pdev, NULL);
445 unregister_netdev(ndev);
446 xc_stop(priv->xc);
447 free_xc(priv->xc);
448 free_netdev(ndev);
449 pfifo_free(PFIFO_MASK(priv->id));
451 return 0;
452 }
454 static int netx_eth_drv_suspend(struct platform_device *pdev, pm_message_t state)
455 {
456 dev_err(&pdev->dev, "suspend not implemented\n");
457 return 0;
458 }
460 static int netx_eth_drv_resume(struct platform_device *pdev)
461 {
462 dev_err(&pdev->dev, "resume not implemented\n");
463 return 0;
464 }
466 static struct platform_driver netx_eth_driver = {
467 .probe = netx_eth_drv_probe,
468 .remove = netx_eth_drv_remove,
469 .suspend = netx_eth_drv_suspend,
470 .resume = netx_eth_drv_resume,
471 .driver = {
472 .name = CARDNAME,
473 .owner = THIS_MODULE,
474 },
475 };
477 static int __init netx_eth_init(void)
478 {
479 unsigned int phy_control, val;
481 printk("NetX Ethernet driver\n");
483 phy_control = PHY_CONTROL_PHY_ADDRESS(INTERNAL_PHY_ADR>>1) |
484 PHY_CONTROL_PHY1_MODE(PHY_MODE_ALL) |
485 PHY_CONTROL_PHY1_AUTOMDIX |
486 PHY_CONTROL_PHY1_EN |
487 PHY_CONTROL_PHY0_MODE(PHY_MODE_ALL) |
488 PHY_CONTROL_PHY0_AUTOMDIX |
489 PHY_CONTROL_PHY0_EN |
490 PHY_CONTROL_CLK_XLATIN;
492 val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
493 writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
495 writel(phy_control | PHY_CONTROL_RESET, NETX_SYSTEM_PHY_CONTROL);
496 udelay(100);
498 val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
499 writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
501 writel(phy_control, NETX_SYSTEM_PHY_CONTROL);
503 return platform_driver_register(&netx_eth_driver);
504 }
506 static void __exit netx_eth_cleanup(void)
507 {
508 platform_driver_unregister(&netx_eth_driver);
509 }
511 module_init(netx_eth_init);
512 module_exit(netx_eth_cleanup);
514 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
515 MODULE_LICENSE("GPL");