xen-netback: Unconditionally set NETIF_F_RXCSUM
[deliverable/linux.git] / drivers / net / xen-netback / xenbus.c
CommitLineData
f942dc25
IC
1/*
2 * Xenbus code for netif backend
3 *
4 * Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
5 * Copyright (C) 2005 XenSource Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20*/
21
22#include "common.h"
23
24struct backend_info {
25 struct xenbus_device *dev;
26 struct xenvif *vif;
ea732dff
PD
27
28 /* This is the state that will be reflected in xenstore when any
29 * active hotplug script completes.
30 */
31 enum xenbus_state state;
32
f942dc25
IC
33 enum xenbus_state frontend_state;
34 struct xenbus_watch hotplug_status_watch;
17938a69 35 u8 have_hotplug_status_watch:1;
f942dc25
IC
36};
37
38static int connect_rings(struct backend_info *);
39static void connect(struct backend_info *);
40static void backend_create_xenvif(struct backend_info *be);
41static void unregister_hotplug_status_watch(struct backend_info *be);
dc62ccac
DV
42static void set_backend_state(struct backend_info *be,
43 enum xenbus_state state);
f942dc25
IC
44
45static int netback_remove(struct xenbus_device *dev)
46{
47 struct backend_info *be = dev_get_drvdata(&dev->dev);
48
dc62ccac
DV
49 set_backend_state(be, XenbusStateClosed);
50
f942dc25
IC
51 unregister_hotplug_status_watch(be);
52 if (be->vif) {
53 kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
54 xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
279f438e 55 xenvif_free(be->vif);
f942dc25
IC
56 be->vif = NULL;
57 }
58 kfree(be);
59 dev_set_drvdata(&dev->dev, NULL);
60 return 0;
61}
62
63
64/**
65 * Entry point to this code when a new device is created. Allocate the basic
66 * structures and switch to InitWait.
67 */
68static int netback_probe(struct xenbus_device *dev,
69 const struct xenbus_device_id *id)
70{
71 const char *message;
72 struct xenbus_transaction xbt;
73 int err;
74 int sg;
75 struct backend_info *be = kzalloc(sizeof(struct backend_info),
76 GFP_KERNEL);
77 if (!be) {
78 xenbus_dev_fatal(dev, -ENOMEM,
79 "allocating backend structure");
80 return -ENOMEM;
81 }
82
83 be->dev = dev;
84 dev_set_drvdata(&dev->dev, be);
85
86 sg = 1;
87
88 do {
89 err = xenbus_transaction_start(&xbt);
90 if (err) {
91 xenbus_dev_fatal(dev, err, "starting transaction");
92 goto fail;
93 }
94
95 err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", sg);
96 if (err) {
97 message = "writing feature-sg";
98 goto abort_transaction;
99 }
100
101 err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4",
102 "%d", sg);
103 if (err) {
104 message = "writing feature-gso-tcpv4";
105 goto abort_transaction;
106 }
107
2eba61d5
PD
108 /* We support partial checksum setup for IPv6 packets */
109 err = xenbus_printf(xbt, dev->nodename,
110 "feature-ipv6-csum-offload",
111 "%d", 1);
112 if (err) {
113 message = "writing feature-ipv6-csum-offload";
114 goto abort_transaction;
115 }
116
f942dc25
IC
117 /* We support rx-copy path. */
118 err = xenbus_printf(xbt, dev->nodename,
119 "feature-rx-copy", "%d", 1);
120 if (err) {
121 message = "writing feature-rx-copy";
122 goto abort_transaction;
123 }
124
125 /*
126 * We don't support rx-flip path (except old guests who don't
127 * grok this feature flag).
128 */
129 err = xenbus_printf(xbt, dev->nodename,
130 "feature-rx-flip", "%d", 0);
131 if (err) {
132 message = "writing feature-rx-flip";
133 goto abort_transaction;
134 }
135
136 err = xenbus_transaction_end(xbt, 0);
137 } while (err == -EAGAIN);
138
139 if (err) {
140 xenbus_dev_fatal(dev, err, "completing transaction");
141 goto fail;
142 }
143
e1f00a69
WL
144 /*
145 * Split event channels support, this is optional so it is not
146 * put inside the above loop.
147 */
148 err = xenbus_printf(XBT_NIL, dev->nodename,
149 "feature-split-event-channels",
150 "%u", separate_tx_rx_irq);
151 if (err)
8ef2c3bc 152 pr_debug("Error writing feature-split-event-channels\n");
e1f00a69 153
f942dc25
IC
154 err = xenbus_switch_state(dev, XenbusStateInitWait);
155 if (err)
156 goto fail;
157
ea732dff
PD
158 be->state = XenbusStateInitWait;
159
f942dc25
IC
160 /* This kicks hotplug scripts, so do it immediately. */
161 backend_create_xenvif(be);
162
163 return 0;
164
165abort_transaction:
166 xenbus_transaction_end(xbt, 1);
167 xenbus_dev_fatal(dev, err, "%s", message);
168fail:
8ef2c3bc 169 pr_debug("failed\n");
f942dc25
IC
170 netback_remove(dev);
171 return err;
172}
173
174
175/*
176 * Handle the creation of the hotplug script environment. We add the script
177 * and vif variables to the environment, for the benefit of the vif-* hotplug
178 * scripts.
179 */
180static int netback_uevent(struct xenbus_device *xdev,
181 struct kobj_uevent_env *env)
182{
183 struct backend_info *be = dev_get_drvdata(&xdev->dev);
184 char *val;
185
186 val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL);
187 if (IS_ERR(val)) {
188 int err = PTR_ERR(val);
189 xenbus_dev_fatal(xdev, err, "reading script");
190 return err;
191 } else {
192 if (add_uevent_var(env, "script=%s", val)) {
193 kfree(val);
194 return -ENOMEM;
195 }
196 kfree(val);
197 }
198
199 if (!be || !be->vif)
200 return 0;
201
202 return add_uevent_var(env, "vif=%s", be->vif->dev->name);
203}
204
205
206static void backend_create_xenvif(struct backend_info *be)
207{
208 int err;
209 long handle;
210 struct xenbus_device *dev = be->dev;
211
212 if (be->vif != NULL)
213 return;
214
215 err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
216 if (err != 1) {
217 xenbus_dev_fatal(dev, err, "reading handle");
218 return;
219 }
220
221 be->vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle);
222 if (IS_ERR(be->vif)) {
223 err = PTR_ERR(be->vif);
224 be->vif = NULL;
225 xenbus_dev_fatal(dev, err, "creating interface");
226 return;
227 }
228
229 kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
230}
231
ea732dff 232static void backend_disconnect(struct backend_info *be)
f942dc25 233{
279f438e
PD
234 if (be->vif)
235 xenvif_disconnect(be->vif);
236}
237
ea732dff 238static void backend_connect(struct backend_info *be)
279f438e 239{
ea732dff
PD
240 if (be->vif)
241 connect(be);
242}
279f438e 243
ea732dff
PD
244static inline void backend_switch_state(struct backend_info *be,
245 enum xenbus_state state)
246{
247 struct xenbus_device *dev = be->dev;
248
249 pr_debug("%s -> %s\n", dev->nodename, xenbus_strstate(state));
250 be->state = state;
251
252 /* If we are waiting for a hotplug script then defer the
253 * actual xenbus state change.
254 */
255 if (!be->have_hotplug_status_watch)
256 xenbus_switch_state(dev, state);
257}
258
259/* Handle backend state transitions:
260 *
261 * The backend state starts in InitWait and the following transitions are
262 * allowed.
263 *
264 * InitWait -> Connected
265 *
266 * ^ \ |
267 * | \ |
268 * | \ |
269 * | \ |
270 * | \ |
271 * | \ |
272 * | V V
273 *
274 * Closed <-> Closing
275 *
276 * The state argument specifies the eventual state of the backend and the
277 * function transitions to that state via the shortest path.
278 */
279static void set_backend_state(struct backend_info *be,
280 enum xenbus_state state)
281{
282 while (be->state != state) {
283 switch (be->state) {
284 case XenbusStateClosed:
285 switch (state) {
286 case XenbusStateInitWait:
287 case XenbusStateConnected:
288 pr_info("%s: prepare for reconnect\n",
289 be->dev->nodename);
290 backend_switch_state(be, XenbusStateInitWait);
291 break;
292 case XenbusStateClosing:
293 backend_switch_state(be, XenbusStateClosing);
294 break;
295 default:
296 BUG();
297 }
298 break;
299 case XenbusStateInitWait:
300 switch (state) {
301 case XenbusStateConnected:
302 backend_connect(be);
303 backend_switch_state(be, XenbusStateConnected);
304 break;
305 case XenbusStateClosing:
306 case XenbusStateClosed:
307 backend_switch_state(be, XenbusStateClosing);
308 break;
309 default:
310 BUG();
311 }
312 break;
313 case XenbusStateConnected:
314 switch (state) {
315 case XenbusStateInitWait:
316 case XenbusStateClosing:
317 case XenbusStateClosed:
318 backend_disconnect(be);
319 backend_switch_state(be, XenbusStateClosing);
320 break;
321 default:
322 BUG();
323 }
324 break;
325 case XenbusStateClosing:
326 switch (state) {
327 case XenbusStateInitWait:
328 case XenbusStateConnected:
329 case XenbusStateClosed:
330 backend_switch_state(be, XenbusStateClosed);
331 break;
332 default:
333 BUG();
334 }
335 break;
336 default:
337 BUG();
338 }
f942dc25
IC
339 }
340}
341
342/**
343 * Callback received when the frontend's state changes.
344 */
345static void frontend_changed(struct xenbus_device *dev,
346 enum xenbus_state frontend_state)
347{
348 struct backend_info *be = dev_get_drvdata(&dev->dev);
349
ea732dff 350 pr_debug("%s -> %s\n", dev->otherend, xenbus_strstate(frontend_state));
f942dc25
IC
351
352 be->frontend_state = frontend_state;
353
354 switch (frontend_state) {
355 case XenbusStateInitialising:
ea732dff 356 set_backend_state(be, XenbusStateInitWait);
f942dc25
IC
357 break;
358
359 case XenbusStateInitialised:
360 break;
361
362 case XenbusStateConnected:
ea732dff 363 set_backend_state(be, XenbusStateConnected);
f942dc25
IC
364 break;
365
366 case XenbusStateClosing:
ea732dff 367 set_backend_state(be, XenbusStateClosing);
f942dc25
IC
368 break;
369
370 case XenbusStateClosed:
ea732dff 371 set_backend_state(be, XenbusStateClosed);
f942dc25
IC
372 if (xenbus_dev_is_online(dev))
373 break;
374 /* fall through if not online */
375 case XenbusStateUnknown:
ea732dff 376 set_backend_state(be, XenbusStateClosed);
f942dc25
IC
377 device_unregister(&dev->dev);
378 break;
379
380 default:
381 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
382 frontend_state);
383 break;
384 }
385}
386
387
388static void xen_net_read_rate(struct xenbus_device *dev,
389 unsigned long *bytes, unsigned long *usec)
390{
391 char *s, *e;
392 unsigned long b, u;
393 char *ratestr;
394
395 /* Default to unlimited bandwidth. */
396 *bytes = ~0UL;
397 *usec = 0;
398
399 ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL);
400 if (IS_ERR(ratestr))
401 return;
402
403 s = ratestr;
404 b = simple_strtoul(s, &e, 10);
405 if ((s == e) || (*e != ','))
406 goto fail;
407
408 s = e + 1;
409 u = simple_strtoul(s, &e, 10);
410 if ((s == e) || (*e != '\0'))
411 goto fail;
412
413 *bytes = b;
414 *usec = u;
415
416 kfree(ratestr);
417 return;
418
419 fail:
420 pr_warn("Failed to parse network rate limit. Traffic unlimited.\n");
421 kfree(ratestr);
422}
423
424static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
425{
426 char *s, *e, *macstr;
427 int i;
428
429 macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
430 if (IS_ERR(macstr))
431 return PTR_ERR(macstr);
432
433 for (i = 0; i < ETH_ALEN; i++) {
434 mac[i] = simple_strtoul(s, &e, 16);
435 if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
436 kfree(macstr);
437 return -ENOENT;
438 }
439 s = e+1;
440 }
441
442 kfree(macstr);
443 return 0;
444}
445
446static void unregister_hotplug_status_watch(struct backend_info *be)
447{
448 if (be->have_hotplug_status_watch) {
449 unregister_xenbus_watch(&be->hotplug_status_watch);
450 kfree(be->hotplug_status_watch.node);
451 }
452 be->have_hotplug_status_watch = 0;
453}
454
455static void hotplug_status_changed(struct xenbus_watch *watch,
456 const char **vec,
457 unsigned int vec_size)
458{
459 struct backend_info *be = container_of(watch,
460 struct backend_info,
461 hotplug_status_watch);
462 char *str;
463 unsigned int len;
464
465 str = xenbus_read(XBT_NIL, be->dev->nodename, "hotplug-status", &len);
466 if (IS_ERR(str))
467 return;
468 if (len == sizeof("connected")-1 && !memcmp(str, "connected", len)) {
ea732dff
PD
469 /* Complete any pending state change */
470 xenbus_switch_state(be->dev, be->state);
471
f942dc25
IC
472 /* Not interested in this watch anymore. */
473 unregister_hotplug_status_watch(be);
474 }
475 kfree(str);
476}
477
478static void connect(struct backend_info *be)
479{
480 int err;
481 struct xenbus_device *dev = be->dev;
482
483 err = connect_rings(be);
484 if (err)
485 return;
486
487 err = xen_net_read_mac(dev, be->vif->fe_dev_addr);
488 if (err) {
489 xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
490 return;
491 }
492
493 xen_net_read_rate(dev, &be->vif->credit_bytes,
494 &be->vif->credit_usec);
495 be->vif->remaining_credit = be->vif->credit_bytes;
496
497 unregister_hotplug_status_watch(be);
498 err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch,
499 hotplug_status_changed,
500 "%s/%s", dev->nodename, "hotplug-status");
ea732dff 501 if (!err)
f942dc25 502 be->have_hotplug_status_watch = 1;
f942dc25
IC
503
504 netif_wake_queue(be->vif->dev);
505}
506
507
508static int connect_rings(struct backend_info *be)
509{
510 struct xenvif *vif = be->vif;
511 struct xenbus_device *dev = be->dev;
512 unsigned long tx_ring_ref, rx_ring_ref;
e1f00a69 513 unsigned int tx_evtchn, rx_evtchn, rx_copy;
f942dc25
IC
514 int err;
515 int val;
516
517 err = xenbus_gather(XBT_NIL, dev->otherend,
518 "tx-ring-ref", "%lu", &tx_ring_ref,
e1f00a69 519 "rx-ring-ref", "%lu", &rx_ring_ref, NULL);
f942dc25
IC
520 if (err) {
521 xenbus_dev_fatal(dev, err,
e1f00a69 522 "reading %s/ring-ref",
f942dc25
IC
523 dev->otherend);
524 return err;
525 }
526
e1f00a69
WL
527 /* Try split event channels first, then single event channel. */
528 err = xenbus_gather(XBT_NIL, dev->otherend,
529 "event-channel-tx", "%u", &tx_evtchn,
530 "event-channel-rx", "%u", &rx_evtchn, NULL);
531 if (err < 0) {
532 err = xenbus_scanf(XBT_NIL, dev->otherend,
533 "event-channel", "%u", &tx_evtchn);
534 if (err < 0) {
535 xenbus_dev_fatal(dev, err,
536 "reading %s/event-channel(-tx/rx)",
537 dev->otherend);
538 return err;
539 }
540 rx_evtchn = tx_evtchn;
541 }
542
f942dc25
IC
543 err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u",
544 &rx_copy);
545 if (err == -ENOENT) {
546 err = 0;
547 rx_copy = 0;
548 }
549 if (err < 0) {
550 xenbus_dev_fatal(dev, err, "reading %s/request-rx-copy",
551 dev->otherend);
552 return err;
553 }
554 if (!rx_copy)
555 return -EOPNOTSUPP;
556
557 if (vif->dev->tx_queue_len != 0) {
558 if (xenbus_scanf(XBT_NIL, dev->otherend,
559 "feature-rx-notify", "%d", &val) < 0)
560 val = 0;
561 if (val)
562 vif->can_queue = 1;
563 else
564 /* Must be non-zero for pfifo_fast to work. */
565 vif->dev->tx_queue_len = 1;
566 }
567
568 if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg",
569 "%d", &val) < 0)
570 val = 0;
571 vif->can_sg = !!val;
572
573 if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4",
574 "%d", &val) < 0)
575 val = 0;
576 vif->gso = !!val;
577
578 if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4-prefix",
579 "%d", &val) < 0)
580 val = 0;
581 vif->gso_prefix = !!val;
582
583 if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload",
584 "%d", &val) < 0)
585 val = 0;
146c8a77
PD
586 vif->ip_csum = !val;
587
588 if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-ipv6-csum-offload",
589 "%d", &val) < 0)
590 val = 0;
591 vif->ipv6_csum = !!val;
f942dc25
IC
592
593 /* Map the shared frame, irq etc. */
e1f00a69
WL
594 err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref,
595 tx_evtchn, rx_evtchn);
f942dc25
IC
596 if (err) {
597 xenbus_dev_fatal(dev, err,
e1f00a69
WL
598 "mapping shared-frames %lu/%lu port tx %u rx %u",
599 tx_ring_ref, rx_ring_ref,
600 tx_evtchn, rx_evtchn);
f942dc25
IC
601 return err;
602 }
603 return 0;
604}
605
606
607/* ** Driver Registration ** */
608
609
610static const struct xenbus_device_id netback_ids[] = {
611 { "vif" },
612 { "" }
613};
614
615
73db144b 616static DEFINE_XENBUS_DRIVER(netback, ,
f942dc25
IC
617 .probe = netback_probe,
618 .remove = netback_remove,
619 .uevent = netback_uevent,
620 .otherend_changed = frontend_changed,
73db144b 621);
f942dc25
IC
622
623int xenvif_xenbus_init(void)
624{
73db144b 625 return xenbus_register_backend(&netback_driver);
f942dc25 626}
b103f358
WL
627
628void xenvif_xenbus_fini(void)
629{
630 return xenbus_unregister_driver(&netback_driver);
631}
This page took 0.222228 seconds and 5 git commands to generate.