blob: 805a0a32839141ffa20abc1d8dcc6e7f82cabb8f [file] [log] [blame]
Ian Campbellf942dc22011-03-15 00:06:18 +00001/*
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;
Paul Durrant7ab12332013-09-26 12:09:52 +010027
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
Ian Campbellf942dc22011-03-15 00:06:18 +000033 enum xenbus_state frontend_state;
34 struct xenbus_watch hotplug_status_watch;
Ian Campbell17938a62011-04-03 22:26:24 +000035 u8 have_hotplug_status_watch:1;
Ian Campbellf942dc22011-03-15 00:06:18 +000036};
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);
42
43static int netback_remove(struct xenbus_device *dev)
44{
45 struct backend_info *be = dev_get_drvdata(&dev->dev);
46
47 unregister_hotplug_status_watch(be);
48 if (be->vif) {
49 kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
50 xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
Paul Durrantf495ddc2013-10-08 14:22:56 +010051 xenvif_free(be->vif);
Ian Campbellf942dc22011-03-15 00:06:18 +000052 be->vif = NULL;
53 }
54 kfree(be);
55 dev_set_drvdata(&dev->dev, NULL);
56 return 0;
57}
58
59
60/**
61 * Entry point to this code when a new device is created. Allocate the basic
62 * structures and switch to InitWait.
63 */
64static int netback_probe(struct xenbus_device *dev,
65 const struct xenbus_device_id *id)
66{
67 const char *message;
68 struct xenbus_transaction xbt;
69 int err;
70 int sg;
71 struct backend_info *be = kzalloc(sizeof(struct backend_info),
72 GFP_KERNEL);
73 if (!be) {
74 xenbus_dev_fatal(dev, -ENOMEM,
75 "allocating backend structure");
76 return -ENOMEM;
77 }
78
79 be->dev = dev;
80 dev_set_drvdata(&dev->dev, be);
81
82 sg = 1;
83
84 do {
85 err = xenbus_transaction_start(&xbt);
86 if (err) {
87 xenbus_dev_fatal(dev, err, "starting transaction");
88 goto fail;
89 }
90
91 err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", sg);
92 if (err) {
93 message = "writing feature-sg";
94 goto abort_transaction;
95 }
96
97 err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4",
98 "%d", sg);
99 if (err) {
100 message = "writing feature-gso-tcpv4";
101 goto abort_transaction;
102 }
103
104 /* We support rx-copy path. */
105 err = xenbus_printf(xbt, dev->nodename,
106 "feature-rx-copy", "%d", 1);
107 if (err) {
108 message = "writing feature-rx-copy";
109 goto abort_transaction;
110 }
111
112 /*
113 * We don't support rx-flip path (except old guests who don't
114 * grok this feature flag).
115 */
116 err = xenbus_printf(xbt, dev->nodename,
117 "feature-rx-flip", "%d", 0);
118 if (err) {
119 message = "writing feature-rx-flip";
120 goto abort_transaction;
121 }
122
123 err = xenbus_transaction_end(xbt, 0);
124 } while (err == -EAGAIN);
125
126 if (err) {
127 xenbus_dev_fatal(dev, err, "completing transaction");
128 goto fail;
129 }
130
131 err = xenbus_switch_state(dev, XenbusStateInitWait);
132 if (err)
133 goto fail;
134
Paul Durrant7ab12332013-09-26 12:09:52 +0100135 be->state = XenbusStateInitWait;
136
Ian Campbellf942dc22011-03-15 00:06:18 +0000137 /* This kicks hotplug scripts, so do it immediately. */
138 backend_create_xenvif(be);
139
140 return 0;
141
142abort_transaction:
143 xenbus_transaction_end(xbt, 1);
144 xenbus_dev_fatal(dev, err, "%s", message);
145fail:
146 pr_debug("failed");
147 netback_remove(dev);
148 return err;
149}
150
151
152/*
153 * Handle the creation of the hotplug script environment. We add the script
154 * and vif variables to the environment, for the benefit of the vif-* hotplug
155 * scripts.
156 */
157static int netback_uevent(struct xenbus_device *xdev,
158 struct kobj_uevent_env *env)
159{
160 struct backend_info *be = dev_get_drvdata(&xdev->dev);
161 char *val;
162
163 val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL);
164 if (IS_ERR(val)) {
165 int err = PTR_ERR(val);
166 xenbus_dev_fatal(xdev, err, "reading script");
167 return err;
168 } else {
169 if (add_uevent_var(env, "script=%s", val)) {
170 kfree(val);
171 return -ENOMEM;
172 }
173 kfree(val);
174 }
175
176 if (!be || !be->vif)
177 return 0;
178
179 return add_uevent_var(env, "vif=%s", be->vif->dev->name);
180}
181
182
183static void backend_create_xenvif(struct backend_info *be)
184{
185 int err;
186 long handle;
187 struct xenbus_device *dev = be->dev;
188
189 if (be->vif != NULL)
190 return;
191
192 err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
193 if (err != 1) {
194 xenbus_dev_fatal(dev, err, "reading handle");
195 return;
196 }
197
198 be->vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle);
199 if (IS_ERR(be->vif)) {
200 err = PTR_ERR(be->vif);
201 be->vif = NULL;
202 xenbus_dev_fatal(dev, err, "creating interface");
203 return;
204 }
205
206 kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
207}
208
Paul Durrant7ab12332013-09-26 12:09:52 +0100209static void backend_disconnect(struct backend_info *be)
Ian Campbellf942dc22011-03-15 00:06:18 +0000210{
Paul Durrantf495ddc2013-10-08 14:22:56 +0100211 if (be->vif)
Ian Campbellf942dc22011-03-15 00:06:18 +0000212 xenvif_disconnect(be->vif);
Paul Durrantf495ddc2013-10-08 14:22:56 +0100213}
214
Paul Durrant7ab12332013-09-26 12:09:52 +0100215static void backend_connect(struct backend_info *be)
Paul Durrantf495ddc2013-10-08 14:22:56 +0100216{
Paul Durrant7ab12332013-09-26 12:09:52 +0100217 if (be->vif)
218 connect(be);
219}
Paul Durrantf495ddc2013-10-08 14:22:56 +0100220
Paul Durrant7ab12332013-09-26 12:09:52 +0100221static inline void backend_switch_state(struct backend_info *be,
222 enum xenbus_state state)
223{
224 struct xenbus_device *dev = be->dev;
225
226 pr_debug("%s -> %s\n", dev->nodename, xenbus_strstate(state));
227 be->state = state;
228
229 /* If we are waiting for a hotplug script then defer the
230 * actual xenbus state change.
231 */
232 if (!be->have_hotplug_status_watch)
233 xenbus_switch_state(dev, state);
234}
235
236/* Handle backend state transitions:
237 *
238 * The backend state starts in InitWait and the following transitions are
239 * allowed.
240 *
241 * InitWait -> Connected
242 *
243 * ^ \ |
244 * | \ |
245 * | \ |
246 * | \ |
247 * | \ |
248 * | \ |
249 * | V V
250 *
251 * Closed <-> Closing
252 *
253 * The state argument specifies the eventual state of the backend and the
254 * function transitions to that state via the shortest path.
255 */
256static void set_backend_state(struct backend_info *be,
257 enum xenbus_state state)
258{
259 while (be->state != state) {
260 switch (be->state) {
261 case XenbusStateClosed:
262 switch (state) {
263 case XenbusStateInitWait:
264 case XenbusStateConnected:
265 pr_info("%s: prepare for reconnect\n",
266 be->dev->nodename);
267 backend_switch_state(be, XenbusStateInitWait);
268 break;
269 case XenbusStateClosing:
270 backend_switch_state(be, XenbusStateClosing);
271 break;
272 default:
273 BUG();
274 }
275 break;
276 case XenbusStateInitWait:
277 switch (state) {
278 case XenbusStateConnected:
279 backend_connect(be);
280 backend_switch_state(be, XenbusStateConnected);
281 break;
282 case XenbusStateClosing:
283 case XenbusStateClosed:
284 backend_switch_state(be, XenbusStateClosing);
285 break;
286 default:
287 BUG();
288 }
289 break;
290 case XenbusStateConnected:
291 switch (state) {
292 case XenbusStateInitWait:
293 case XenbusStateClosing:
294 case XenbusStateClosed:
295 backend_disconnect(be);
296 backend_switch_state(be, XenbusStateClosing);
297 break;
298 default:
299 BUG();
300 }
301 break;
302 case XenbusStateClosing:
303 switch (state) {
304 case XenbusStateInitWait:
305 case XenbusStateConnected:
306 case XenbusStateClosed:
307 backend_switch_state(be, XenbusStateClosed);
308 break;
309 default:
310 BUG();
311 }
312 break;
313 default:
314 BUG();
315 }
Ian Campbellf942dc22011-03-15 00:06:18 +0000316 }
317}
318
319/**
320 * Callback received when the frontend's state changes.
321 */
322static void frontend_changed(struct xenbus_device *dev,
323 enum xenbus_state frontend_state)
324{
325 struct backend_info *be = dev_get_drvdata(&dev->dev);
326
Paul Durrant7ab12332013-09-26 12:09:52 +0100327 pr_debug("%s -> %s\n", dev->otherend, xenbus_strstate(frontend_state));
Ian Campbellf942dc22011-03-15 00:06:18 +0000328
329 be->frontend_state = frontend_state;
330
331 switch (frontend_state) {
332 case XenbusStateInitialising:
Paul Durrant7ab12332013-09-26 12:09:52 +0100333 set_backend_state(be, XenbusStateInitWait);
Ian Campbellf942dc22011-03-15 00:06:18 +0000334 break;
335
336 case XenbusStateInitialised:
337 break;
338
339 case XenbusStateConnected:
Paul Durrant7ab12332013-09-26 12:09:52 +0100340 set_backend_state(be, XenbusStateConnected);
Ian Campbellf942dc22011-03-15 00:06:18 +0000341 break;
342
343 case XenbusStateClosing:
Paul Durrant7ab12332013-09-26 12:09:52 +0100344 set_backend_state(be, XenbusStateClosing);
Ian Campbellf942dc22011-03-15 00:06:18 +0000345 break;
346
347 case XenbusStateClosed:
Paul Durrant7ab12332013-09-26 12:09:52 +0100348 set_backend_state(be, XenbusStateClosed);
Ian Campbellf942dc22011-03-15 00:06:18 +0000349 if (xenbus_dev_is_online(dev))
350 break;
351 /* fall through if not online */
352 case XenbusStateUnknown:
Paul Durrant7ab12332013-09-26 12:09:52 +0100353 set_backend_state(be, XenbusStateClosed);
Ian Campbellf942dc22011-03-15 00:06:18 +0000354 device_unregister(&dev->dev);
355 break;
356
357 default:
358 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
359 frontend_state);
360 break;
361 }
362}
363
364
365static void xen_net_read_rate(struct xenbus_device *dev,
366 unsigned long *bytes, unsigned long *usec)
367{
368 char *s, *e;
369 unsigned long b, u;
370 char *ratestr;
371
372 /* Default to unlimited bandwidth. */
373 *bytes = ~0UL;
374 *usec = 0;
375
376 ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL);
377 if (IS_ERR(ratestr))
378 return;
379
380 s = ratestr;
381 b = simple_strtoul(s, &e, 10);
382 if ((s == e) || (*e != ','))
383 goto fail;
384
385 s = e + 1;
386 u = simple_strtoul(s, &e, 10);
387 if ((s == e) || (*e != '\0'))
388 goto fail;
389
390 *bytes = b;
391 *usec = u;
392
393 kfree(ratestr);
394 return;
395
396 fail:
397 pr_warn("Failed to parse network rate limit. Traffic unlimited.\n");
398 kfree(ratestr);
399}
400
401static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
402{
403 char *s, *e, *macstr;
404 int i;
405
406 macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
407 if (IS_ERR(macstr))
408 return PTR_ERR(macstr);
409
410 for (i = 0; i < ETH_ALEN; i++) {
411 mac[i] = simple_strtoul(s, &e, 16);
412 if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
413 kfree(macstr);
414 return -ENOENT;
415 }
416 s = e+1;
417 }
418
419 kfree(macstr);
420 return 0;
421}
422
423static void unregister_hotplug_status_watch(struct backend_info *be)
424{
425 if (be->have_hotplug_status_watch) {
426 unregister_xenbus_watch(&be->hotplug_status_watch);
427 kfree(be->hotplug_status_watch.node);
428 }
429 be->have_hotplug_status_watch = 0;
430}
431
432static void hotplug_status_changed(struct xenbus_watch *watch,
433 const char **vec,
434 unsigned int vec_size)
435{
436 struct backend_info *be = container_of(watch,
437 struct backend_info,
438 hotplug_status_watch);
439 char *str;
440 unsigned int len;
441
442 str = xenbus_read(XBT_NIL, be->dev->nodename, "hotplug-status", &len);
443 if (IS_ERR(str))
444 return;
445 if (len == sizeof("connected")-1 && !memcmp(str, "connected", len)) {
Paul Durrant7ab12332013-09-26 12:09:52 +0100446 /* Complete any pending state change */
447 xenbus_switch_state(be->dev, be->state);
448
Ian Campbellf942dc22011-03-15 00:06:18 +0000449 /* Not interested in this watch anymore. */
450 unregister_hotplug_status_watch(be);
451 }
452 kfree(str);
453}
454
455static void connect(struct backend_info *be)
456{
457 int err;
458 struct xenbus_device *dev = be->dev;
459
460 err = connect_rings(be);
461 if (err)
462 return;
463
464 err = xen_net_read_mac(dev, be->vif->fe_dev_addr);
465 if (err) {
466 xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
467 return;
468 }
469
470 xen_net_read_rate(dev, &be->vif->credit_bytes,
471 &be->vif->credit_usec);
472 be->vif->remaining_credit = be->vif->credit_bytes;
473
474 unregister_hotplug_status_watch(be);
475 err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch,
476 hotplug_status_changed,
477 "%s/%s", dev->nodename, "hotplug-status");
Paul Durrant7ab12332013-09-26 12:09:52 +0100478 if (!err)
Ian Campbellf942dc22011-03-15 00:06:18 +0000479 be->have_hotplug_status_watch = 1;
Ian Campbellf942dc22011-03-15 00:06:18 +0000480
481 netif_wake_queue(be->vif->dev);
482}
483
484
485static int connect_rings(struct backend_info *be)
486{
487 struct xenvif *vif = be->vif;
488 struct xenbus_device *dev = be->dev;
489 unsigned long tx_ring_ref, rx_ring_ref;
490 unsigned int evtchn, rx_copy;
491 int err;
492 int val;
493
494 err = xenbus_gather(XBT_NIL, dev->otherend,
495 "tx-ring-ref", "%lu", &tx_ring_ref,
496 "rx-ring-ref", "%lu", &rx_ring_ref,
497 "event-channel", "%u", &evtchn, NULL);
498 if (err) {
499 xenbus_dev_fatal(dev, err,
500 "reading %s/ring-ref and event-channel",
501 dev->otherend);
502 return err;
503 }
504
505 err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u",
506 &rx_copy);
507 if (err == -ENOENT) {
508 err = 0;
509 rx_copy = 0;
510 }
511 if (err < 0) {
512 xenbus_dev_fatal(dev, err, "reading %s/request-rx-copy",
513 dev->otherend);
514 return err;
515 }
516 if (!rx_copy)
517 return -EOPNOTSUPP;
518
519 if (vif->dev->tx_queue_len != 0) {
520 if (xenbus_scanf(XBT_NIL, dev->otherend,
521 "feature-rx-notify", "%d", &val) < 0)
522 val = 0;
523 if (val)
524 vif->can_queue = 1;
525 else
526 /* Must be non-zero for pfifo_fast to work. */
527 vif->dev->tx_queue_len = 1;
528 }
529
530 if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg",
531 "%d", &val) < 0)
532 val = 0;
533 vif->can_sg = !!val;
534
535 if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4",
536 "%d", &val) < 0)
537 val = 0;
538 vif->gso = !!val;
539
540 if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4-prefix",
541 "%d", &val) < 0)
542 val = 0;
543 vif->gso_prefix = !!val;
544
545 if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload",
546 "%d", &val) < 0)
547 val = 0;
548 vif->csum = !val;
549
550 /* Map the shared frame, irq etc. */
551 err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref, evtchn);
552 if (err) {
553 xenbus_dev_fatal(dev, err,
554 "mapping shared-frames %lu/%lu port %u",
555 tx_ring_ref, rx_ring_ref, evtchn);
556 return err;
557 }
558 return 0;
559}
560
561
562/* ** Driver Registration ** */
563
564
565static const struct xenbus_device_id netback_ids[] = {
566 { "vif" },
567 { "" }
568};
569
570
Jan Beulich73db1442011-12-22 09:08:13 +0000571static DEFINE_XENBUS_DRIVER(netback, ,
Ian Campbellf942dc22011-03-15 00:06:18 +0000572 .probe = netback_probe,
573 .remove = netback_remove,
574 .uevent = netback_uevent,
575 .otherend_changed = frontend_changed,
Jan Beulich73db1442011-12-22 09:08:13 +0000576);
Ian Campbellf942dc22011-03-15 00:06:18 +0000577
578int xenvif_xenbus_init(void)
579{
Jan Beulich73db1442011-12-22 09:08:13 +0000580 return xenbus_register_backend(&netback_driver);
Ian Campbellf942dc22011-03-15 00:06:18 +0000581}